Merge "Fixed storage calculation when SD card is adopted as internal storage." into nyc-mr1-dev
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