Merge "Import translations. DO NOT MERGE"
diff --git a/res/layout/user_dictionary_add_word.xml b/res/layout/user_dictionary_add_word.xml
index 3624dad..2b8c19a 100644
--- a/res/layout/user_dictionary_add_word.xml
+++ b/res/layout/user_dictionary_add_word.xml
@@ -14,72 +14,73 @@
      limitations under the License.
   -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/user_dict_settings_add_dialog_top"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:orientation="vertical">
+        android:id="@+id/user_dict_settings_add_dialog_top"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
 
   <LinearLayout android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical">
+          android:layout_height="wrap_content"
+          android:orientation="vertical">
     <com.android.internal.widget.DialogTitle
-          style="?android:attr/windowTitleStyle"
-          android:singleLine="true"
-          android:ellipsize="end"
-          android:layout_width="match_parent"
-          android:layout_height="64dip"
-          android:layout_marginStart="16dip"
-          android:layout_marginEnd="16dip"
-          android:gravity="center_vertical|start"
-          android:text="@string/user_dict_settings_add_dialog_title" />
-    <View android:layout_width="match_parent"
-          android:layout_height="2dip"
-          android:background="@android:color/holo_blue_light" />
+            style="?android:attr/windowTitleStyle"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="24dip"
+            android:layout_marginEnd="24dip"
+            android:layout_marginTop="24dip"
+            android:layout_marginBottom="0dip"
+            android:ellipsize="end"
+            android:gravity="center_vertical|start"
+            android:singleLine="true"
+            android:text="@string/user_dict_settings_add_dialog_title" />
   </LinearLayout>
 
   <EditText android:id="@+id/user_dictionary_add_word_text"
-            android:maxLength="@integer/maximum_user_dictionary_word_length"
-            android:layout_height="match_parent"
-            android:layout_width="match_parent"
-            android:layout_gravity="fill_horizontal|center_vertical"
-            android:layout_marginStart="8dip"
-            android:layout_marginBottom="8dip"
-            android:layout_marginTop="8dip"
-            android:hint="@string/user_dict_settings_add_word_hint"
-            android:inputType="textNoSuggestions"
-            android:imeOptions="flagNoFullscreen">
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"
+          android:layout_gravity="fill_horizontal|center_vertical"
+          android:layout_marginStart="24dip"
+          android:layout_marginEnd="24dip"
+          android:layout_marginTop="20dip"
+          android:layout_marginBottom="24dip"
+          android:hint="@string/user_dict_settings_add_word_hint"
+          android:imeOptions="flagNoFullscreen"
+          android:inputType="textNoSuggestions"
+          android:maxLength="@integer/maximum_user_dictionary_word_length">
     <requestFocus />
   </EditText>
 
   <LinearLayout android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:divider="?android:attr/dividerHorizontal"
-                android:showDividers="beginning"
-                android:dividerPadding="0dip">
+          android:layout_height="wrap_content"
+          android:divider="?android:attr/dividerHorizontal"
+          android:dividerPadding="0dip"
+          android:orientation="vertical"
+          android:showDividers="beginning">
     <LinearLayout style="?android:attr/buttonBarStyle"
-                  android:layout_width="match_parent"
-                  android:layout_height="wrap_content"
-                  android:orientation="horizontal"
-                  android:measureWithLargestChild="true">
-      <Button android:layout_width="0dip"
-              android:layout_gravity="start"
-              android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="end"
+            android:orientation="horizontal">
+      <Button style="?android:attr/buttonBarButtonStyle"
+              android:layout_width="wrap_content"
+              android:layout_height="36dip"
+              android:layout_marginTop="8dip"
+              android:layout_marginBottom="8dip"
+              android:layout_marginLeft="8dip"
+              android:layout_marginRight="0dip"
               android:maxLines="2"
-              style="?android:attr/buttonBarButtonStyle"
+              android:onClick="onClickCancel"
               android:textSize="14sp"
-              android:text="@string/cancel"
-              android:layout_height="wrap_content"
-              android:onClick="onClickCancel" />
-      <Button android:layout_width="0dip"
-              android:layout_gravity="end"
-              android:layout_weight="1"
+              android:text="@string/cancel" />
+      <Button style="?android:attr/buttonBarButtonStyle"
+              android:layout_width="wrap_content"
+              android:layout_height="36dip"
+              android:layout_margin="8dip"
               android:maxLines="2"
-              style="?android:attr/buttonBarButtonStyle"
+              android:onClick="onClickConfirm"
               android:textSize="14sp"
-              android:text="@string/user_dict_settings_add_dialog_confirm"
-              android:layout_height="wrap_content"
-              android:onClick="onClickConfirm" />
+              android:text="@string/user_dict_settings_add_dialog_confirm" />
     </LinearLayout>
   </LinearLayout>
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
index b735230..3ade1a8 100644
--- a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
@@ -193,7 +193,6 @@
                 (TrustManager) getActivity().getSystemService(Context.TRUST_SERVICE);
             trustManager.setDeviceLockedForUser(mEffectiveUserId, false);
             authenticationSucceeded();
-            authenticationSucceeded();
             checkForPendingIntent();
         }
     }
diff --git a/src/com/android/settings/applications/DefaultPhonePreference.java b/src/com/android/settings/applications/DefaultPhonePreference.java
index 5689c83..e151274 100644
--- a/src/com/android/settings/applications/DefaultPhonePreference.java
+++ b/src/com/android/settings/applications/DefaultPhonePreference.java
@@ -82,9 +82,13 @@
             return false;
         }
 
-        final UserManager um =
-                (UserManager) context.getSystemService(Context.USER_SERVICE);
-        return !um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS);
+        final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        final boolean hasUserRestriction =
+                um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS);
+        final CharSequence[] entries = getEntries();
+        return !hasUserRestriction
+                && entries != null
+                && entries.length > 0;
     }
 
     public static boolean hasPhonePreference(String pkg, Context context) {
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index 532c720..ee68311 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -58,6 +58,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 
@@ -165,17 +166,14 @@
 
         for (VolumeInfo vol : volumes) {
             if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
+                final long volumeTotalBytes = getTotalSize(vol);
                 final int color = COLOR_PRIVATE[privateCount++ % COLOR_PRIVATE.length];
                 mInternalCategory.addPreference(
-                        new StorageVolumePreference(context, vol, color, sTotalInternalStorage));
+                        new StorageVolumePreference(context, vol, color, volumeTotalBytes));
                 if (vol.isMountedReadable()) {
                     final File path = vol.getPath();
-                    privateUsedBytes += path.getTotalSpace() - path.getFreeSpace();
-                    if (sTotalInternalStorage > 0) {
-                        privateTotalBytes = sTotalInternalStorage;
-                    } else {
-                        privateTotalBytes += path.getTotalSpace();
-                    }
+                    privateUsedBytes += (volumeTotalBytes - path.getFreeSpace());
+                    privateTotalBytes += volumeTotalBytes;
                 }
             } else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) {
                 mExternalCategory.addPreference(
@@ -277,7 +275,7 @@
             if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
                 final Bundle args = new Bundle();
                 args.putString(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
-                PrivateVolumeSettings.setVolumeSize(args, sTotalInternalStorage);
+                PrivateVolumeSettings.setVolumeSize(args, getTotalSize(vol));
                 startFragment(this, PrivateVolumeSettings.class.getCanonicalName(),
                         -1, 0, args);
                 return true;
@@ -495,19 +493,11 @@
             long privateFreeBytes = 0;
             long privateTotalBytes = 0;
             for (VolumeInfo info : volumes) {
-                if (info.getType() != VolumeInfo.TYPE_PUBLIC
-                        && info.getType() != VolumeInfo.TYPE_PRIVATE) {
-                    continue;
-                }
                 final File path = info.getPath();
-                if (path == null) {
+                if (info.getType() != VolumeInfo.TYPE_PRIVATE || path == null) {
                     continue;
                 }
-                if (info.getType() == VolumeInfo.TYPE_PRIVATE && sTotalInternalStorage > 0) {
-                    privateTotalBytes = sTotalInternalStorage;
-                } else {
-                    privateTotalBytes += path.getTotalSpace();
-                }
+                privateTotalBytes += getTotalSize(info);
                 privateFreeBytes += path.getFreeSpace();
             }
             long privateUsedBytes = privateTotalBytes - privateFreeBytes;
@@ -517,6 +507,27 @@
         }
     }
 
+    private static long getTotalSize(VolumeInfo info) {
+        // Device could have more than one primary storage, which could be located in the
+        // internal flash (UUID_PRIVATE_INTERNAL) or in an external disk.
+        // If it's internal, try to get its total size from StorageManager first
+        // (sTotalInternalStorage), since that size is more precise because it accounts for
+        // the system partition.
+        if (info.getType() == VolumeInfo.TYPE_PRIVATE
+                && Objects.equals(info.getFsUuid(), StorageManager.UUID_PRIVATE_INTERNAL)
+                && sTotalInternalStorage > 0) {
+            return sTotalInternalStorage;
+        } else {
+            final File path = info.getPath();
+            if (path == null) {
+                // Should not happen, caller should have checked.
+                Log.e(TAG, "info's path is null on getTotalSize(): " + info);
+                return 0;
+            }
+            return path.getTotalSpace();
+        }
+    }
+
     public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
             = new SummaryLoader.SummaryProviderFactory() {
         @Override
diff --git a/src/com/android/settings/vpn2/ConfigDialogFragment.java b/src/com/android/settings/vpn2/ConfigDialogFragment.java
index 788b9a9..1880a6b 100644
--- a/src/com/android/settings/vpn2/ConfigDialogFragment.java
+++ b/src/com/android/settings/vpn2/ConfigDialogFragment.java
@@ -110,8 +110,10 @@
             KeyStore.getInstance().put(Credentials.VPN + profile.key, profile.encode(),
                     KeyStore.UID_SELF, /* flags */ 0);
 
-            // Flush out old version of profile
-            disconnect(profile);
+            // Flush out previous connection, which may be an old version of the profile
+            if (!disconnect(profile)) {
+                Log.w(TAG, "Unable to remove previous connection. Continuing anyway.");
+            }
 
             updateLockdownVpn(dialog.isVpnAlwaysOn(), profile);
 
@@ -125,7 +127,10 @@
             }
         } else if (button == DialogInterface.BUTTON_NEUTRAL) {
             // Disable profile if connected
-            disconnect(profile);
+            if (!disconnect(profile)) {
+                Log.e(TAG, "Failed to disconnect VPN. Leaving profile in keystore.");
+                return;
+            }
 
             // Delete from KeyStore
             KeyStore keyStore = KeyStore.getInstance();
@@ -172,16 +177,27 @@
         }
     }
 
-    private void disconnect(VpnProfile profile) {
+    /**
+     * Ensure that the VPN profile pointed at by {@param profile} is disconnected.
+     *
+     * @return {@code true} iff this VPN profile is no longer connected. Note that another profile
+     *         may still be active - this function will then do nothing but still return success.
+     */
+    private boolean disconnect(VpnProfile profile) {
         try {
-            LegacyVpnInfo connected = mService.getLegacyVpnInfo(UserHandle.myUserId());
-            if (connected != null && profile.key.equals(connected.key)) {
-                VpnUtils.clearLockdownVpn(getContext());
-                mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN,
-                        UserHandle.myUserId());
+            if (!isConnected(profile)) {
+                return true;
             }
+            VpnUtils.clearLockdownVpn(getContext());
+            return mService.prepareVpn(null, VpnConfig.LEGACY_VPN, UserHandle.myUserId());
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to disconnect", e);
+            return false;
         }
     }
+
+    private boolean isConnected(VpnProfile profile) throws RemoteException {
+        LegacyVpnInfo connected = mService.getLegacyVpnInfo(UserHandle.myUserId());
+        return connected != null && profile.key.equals(connected.key);
+    }
 }