diff --git a/res/layout/installed_app_details.xml b/res/layout/installed_app_details.xml
index 6392ee904d7..afec51771e3 100644
--- a/res/layout/installed_app_details.xml
+++ b/res/layout/installed_app_details.xml
@@ -134,6 +134,43 @@
+
+
+
+
+
+
+
Total
Application
+
+ USB storage app
Data
- USB storage
+ USB storage data
- SD card
+ SD card
Uninstall
diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java
index 31fd078a65b..519c2033a36 100644
--- a/src/com/android/settings/applications/ApplicationsState.java
+++ b/src/com/android/settings/applications/ApplicationsState.java
@@ -5,14 +5,11 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
@@ -74,7 +71,8 @@ public class ApplicationsState {
long cacheSize;
long codeSize;
long dataSize;
- long externalSize;
+ long externalCodeSize;
+ long externalDataSize;
}
public static class AppEntry extends SizeInfo {
@@ -97,6 +95,8 @@ public class ApplicationsState {
ApplicationInfo info;
Drawable icon;
String sizeStr;
+ String internalSizeStr;
+ String externalSizeStr;
boolean sizeStale;
long sizeLoadStart;
@@ -660,8 +660,8 @@ public class ApplicationsState {
private long getTotalExternalSize(PackageStats ps) {
if (ps != null) {
- return ps.externalDataSize + ps.externalMediaSize + ps.externalCacheSize
- + ps.externalObbSize;
+ return ps.externalCodeSize + ps.externalDataSize
+ + ps.externalMediaSize + ps.externalObbSize;
}
return SIZE_INVALID;
}
@@ -693,19 +693,27 @@ public class ApplicationsState {
synchronized (entry) {
entry.sizeStale = false;
entry.sizeLoadStart = 0;
- long externalSize = getTotalExternalSize(stats);
- long newSize = externalSize + getTotalInternalSize(stats);
+ long externalCodeSize = stats.externalCodeSize
+ + stats.externalObbSize;
+ long externalDataSize = stats.externalDataSize
+ + stats.externalMediaSize + stats.externalCacheSize;
+ long newSize = externalCodeSize + externalDataSize
+ + getTotalInternalSize(stats);
if (entry.size != newSize ||
entry.cacheSize != stats.cacheSize ||
entry.codeSize != stats.codeSize ||
entry.dataSize != stats.dataSize ||
- entry.externalSize != externalSize) {
+ entry.externalCodeSize != externalCodeSize ||
+ entry.externalDataSize != externalDataSize) {
entry.size = newSize;
entry.cacheSize = stats.cacheSize;
entry.codeSize = stats.codeSize;
entry.dataSize = stats.dataSize;
- entry.externalSize = externalSize;
+ entry.externalCodeSize = externalCodeSize;
+ entry.externalDataSize = externalDataSize;
entry.sizeStr = getSizeStr(entry.size);
+ entry.internalSizeStr = getSizeStr(getTotalInternalSize(stats));
+ entry.externalSizeStr = getSizeStr(getTotalExternalSize(stats));
if (DEBUG) Log.i(TAG, "Set size of " + entry.label + " " + entry
+ ": " + entry.sizeStr);
sizeChanged = true;
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 1c02f74dcc9..ab46661b03c 100644
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -103,7 +103,8 @@ public class InstalledAppDetails extends Fragment
private TextView mTotalSize;
private TextView mAppSize;
private TextView mDataSize;
- private TextView mExternalSize;
+ private TextView mExternalCodeSize;
+ private TextView mExternalDataSize;
private ClearUserDataObserver mClearDataObserver;
// Views related to cache info
private TextView mCacheSize;
@@ -118,7 +119,8 @@ public class InstalledAppDetails extends Fragment
private boolean mHaveSizes = false;
private long mLastCodeSize = -1;
private long mLastDataSize = -1;
- private long mLastExternalSize = -1;
+ private long mLastExternalCodeSize = -1;
+ private long mLastExternalDataSize = -1;
private long mLastCacheSize = -1;
private long mLastTotalSize = -1;
@@ -331,7 +333,8 @@ public class InstalledAppDetails extends Fragment
mTotalSize = (TextView)view.findViewById(R.id.total_size_text);
mAppSize = (TextView)view.findViewById(R.id.application_size_text);
mDataSize = (TextView)view.findViewById(R.id.data_size_text);
- mExternalSize = (TextView)view.findViewById(R.id.external_size_text);
+ mExternalCodeSize = (TextView)view.findViewById(R.id.external_code_size_text);
+ mExternalDataSize = (TextView)view.findViewById(R.id.external_data_size_text);
// Get Control button panel
View btnPanel = view.findViewById(R.id.control_buttons_panel);
@@ -547,9 +550,13 @@ public class InstalledAppDetails extends Fragment
mLastDataSize = mAppEntry.dataSize;
mDataSize.setText(getSizeStr(mAppEntry.dataSize));
}
- if (mLastExternalSize != mAppEntry.externalSize) {
- mLastExternalSize = mAppEntry.externalSize;
- mExternalSize.setText(getSizeStr(mAppEntry.externalSize));
+ if (mLastExternalCodeSize != mAppEntry.externalCodeSize) {
+ mLastExternalCodeSize = mAppEntry.externalCodeSize;
+ mExternalCodeSize.setText(getSizeStr(mAppEntry.externalCodeSize));
+ }
+ if (mLastExternalDataSize != mAppEntry.externalDataSize) {
+ mLastExternalDataSize = mAppEntry.externalDataSize;
+ mExternalDataSize.setText(getSizeStr(mAppEntry.externalDataSize));
}
if (mLastCacheSize != mAppEntry.cacheSize) {
mLastCacheSize = mAppEntry.cacheSize;
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 85db45e6478..554ece36ea7 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -121,6 +121,10 @@ public class ManageApplications extends Fragment implements
// constant value that can be used to check return code from sub activity.
private static final int INSTALLED_APP_DETAILS = 1;
+ public static final int SIZE_TOTAL = 0;
+ public static final int SIZE_INTERNAL = 1;
+ public static final int SIZE_EXTERNAL = 2;
+
// sort order that can be changed through the menu can be sorted alphabetically
// or size(descending)
private static final int MENU_OPTIONS_BASE = 0;
@@ -208,11 +212,21 @@ public class ManageApplications extends Fragment implements
TextView disabled;
CheckBox checkBox;
- void updateSizeText(ManageApplications ma) {
+ void updateSizeText(ManageApplications ma, int whichSize) {
if (DEBUG) Log.i(TAG, "updateSizeText of " + entry.label + " " + entry
+ ": " + entry.sizeStr);
if (entry.sizeStr != null) {
- appSize.setText(entry.sizeStr);
+ switch (whichSize) {
+ case SIZE_INTERNAL:
+ appSize.setText(entry.internalSizeStr);
+ break;
+ case SIZE_EXTERNAL:
+ appSize.setText(entry.externalSizeStr);
+ break;
+ default:
+ appSize.setText(entry.sizeStr);
+ break;
+ }
} else if (entry.size == ApplicationsState.SIZE_INVALID) {
appSize.setText(ma.mInvalidSizeStr);
}
@@ -237,6 +251,7 @@ public class ManageApplications extends Fragment implements
private boolean mResumed;
private int mLastFilterMode=-1, mLastSortMode=-1;
private boolean mWaitingForData;
+ private int mWhichSize = SIZE_TOTAL;
CharSequence mCurFilterPrefix;
private Filter mFilter = new Filter() {
@@ -296,12 +311,21 @@ public class ManageApplications extends Fragment implements
if (DEBUG) Log.i(TAG, "Rebuilding app list...");
ApplicationsState.AppFilter filterObj;
Comparator comparatorObj;
+ boolean emulated = Environment.isExternalStorageEmulated();
+ if (emulated) {
+ mWhichSize = SIZE_TOTAL;
+ } else {
+ mWhichSize = SIZE_INTERNAL;
+ }
switch (mLastFilterMode) {
case FILTER_APPS_THIRD_PARTY:
filterObj = ApplicationsState.THIRD_PARTY_FILTER;
break;
case FILTER_APPS_SDCARD:
filterObj = ApplicationsState.ON_SD_CARD_FILTER;
+ if (!emulated) {
+ mWhichSize = SIZE_EXTERNAL;
+ }
break;
default:
filterObj = null;
@@ -399,7 +423,7 @@ public class ManageApplications extends Fragment implements
AppViewHolder holder = (AppViewHolder)mActive.get(i).getTag();
if (holder.entry.info.packageName.equals(packageName)) {
synchronized (holder.entry) {
- holder.updateSizeText(ManageApplications.this);
+ holder.updateSizeText(ManageApplications.this, mWhichSize);
}
if (holder.entry.info.packageName.equals(mCurrentPkgName)
&& mLastSortMode == SORT_ORDER_SIZE) {
@@ -478,7 +502,7 @@ public class ManageApplications extends Fragment implements
if (entry.icon != null) {
holder.appIcon.setImageDrawable(entry.icon);
}
- holder.updateSizeText(ManageApplications.this);
+ holder.updateSizeText(ManageApplications.this, mWhichSize);
if (InstalledAppDetails.SUPPORT_DISABLE_APPS) {
holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
} else {
@@ -777,6 +801,11 @@ public class ManageApplications extends Fragment implements
} catch (IllegalArgumentException e) {
// use the old value of mFreeMem
}
+ final int N = mApplicationsAdapter.getCount();
+ for (int i=0; i sInstances =
new ConcurrentHashMap();
+ private static StorageMeasurement sInternalInstance;
private volatile WeakReference mReceiver;
@@ -100,6 +101,7 @@ public class StorageMeasurement {
final private StorageVolume mStorageVolume;
final private boolean mIsPrimary;
+ final private boolean mIsInternal;
List mFileInfoForMisc;
@@ -110,7 +112,8 @@ public class StorageMeasurement {
private StorageMeasurement(Context context, StorageVolume storageVolume, boolean isPrimary) {
mStorageVolume = storageVolume;
- mIsPrimary = isPrimary;
+ mIsInternal = storageVolume == null;
+ mIsPrimary = !mIsInternal && isPrimary;
// Start the thread that will measure the disk usage.
final HandlerThread handlerThread = new HandlerThread("MemoryMeasurement");
@@ -126,6 +129,13 @@ public class StorageMeasurement {
*/
public static StorageMeasurement getInstance(Context context, StorageVolume storageVolume,
boolean isPrimary) {
+ if (storageVolume == null) {
+ if (sInternalInstance == null) {
+ sInternalInstance =
+ new StorageMeasurement(context.getApplicationContext(), storageVolume, isPrimary);
+ }
+ return sInternalInstance;
+ }
if (sInstances.containsKey(storageVolume)) {
return sInstances.get(storageVolume);
} else {
@@ -317,9 +327,18 @@ public class StorageMeasurement {
}
if (succeeded) {
- mAppsSizeForThisStatsObserver += stats.codeSize + stats.dataSize +
- stats.externalCacheSize + stats.externalDataSize +
- stats.externalMediaSize + stats.externalObbSize;
+ if (mIsInternal) {
+ mAppsSizeForThisStatsObserver += stats.codeSize + stats.dataSize;
+ } else if (!Environment.isExternalStorageEmulated()) {
+ mAppsSizeForThisStatsObserver += stats.externalObbSize +
+ stats.externalCodeSize + stats.externalDataSize +
+ stats.externalCacheSize + stats.externalMediaSize;
+ } else {
+ mAppsSizeForThisStatsObserver += stats.codeSize + stats.dataSize +
+ stats.externalCodeSize + stats.externalDataSize +
+ stats.externalCacheSize + stats.externalMediaSize +
+ stats.externalObbSize;
+ }
}
synchronized (mAppsList) {
@@ -349,7 +368,8 @@ public class StorageMeasurement {
}
private void measureApproximateStorage() {
- final StatFs stat = new StatFs(mStorageVolume.getPath());
+ final StatFs stat = new StatFs(mStorageVolume != null
+ ? mStorageVolume.getPath() : Environment.getDataDirectory().getPath());
final long blockSize = stat.getBlockSize();
final long totalBlocks = stat.getBlockCount();
final long availableBlocks = stat.getAvailableBlocks();
@@ -434,7 +454,7 @@ public class StorageMeasurement {
return;
}
final List apps;
- if (mIsPrimary) {
+ if (mIsPrimary || mIsInternal) {
apps = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES |
PackageManager.GET_DISABLED_COMPONENTS);
} else {
diff --git a/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java b/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
index 9dbff88757e..70b76e470d3 100644
--- a/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
+++ b/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
@@ -162,12 +162,13 @@ public class StorageVolumePreferenceCategory extends PreferenceCategory implemen
mResources = resources;
mStorageVolume = storageVolume;
mStorageManager = storageManager;
- setTitle(storageVolume.getDescription());
+ setTitle(storageVolume != null ? storageVolume.getDescription()
+ : resources.getText(R.string.internal_storage));
mMeasurement = StorageMeasurement.getInstance(context, storageVolume, isPrimary);
mMeasurement.setReceiver(this);
// Cannot format emulated storage
- mAllowFormat = !mStorageVolume.isEmulated();
+ mAllowFormat = mStorageVolume != null && !mStorageVolume.isEmulated();
// For now we are disabling reformatting secondary external storage
// until some interoperability problems with MTP are fixed
if (!isPrimary) mAllowFormat = false;
@@ -240,7 +241,9 @@ public class StorageVolumePreferenceCategory extends PreferenceCategory implemen
private void updatePreferencesFromState() {
resetPreferences();
- String state = mStorageManager.getVolumeState(mStorageVolume.getPath());
+ String state = mStorageVolume != null
+ ? mStorageManager.getVolumeState(mStorageVolume.getPath())
+ : Environment.MEDIA_MOUNTED;
String readOnly = "";
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
@@ -255,7 +258,8 @@ public class StorageVolumePreferenceCategory extends PreferenceCategory implemen
removePreference(mFormatPreference);
}
- if (!mStorageVolume.isRemovable() && !Environment.MEDIA_UNMOUNTED.equals(state)) {
+ if ((mStorageVolume == null || !mStorageVolume.isRemovable())
+ && !Environment.MEDIA_UNMOUNTED.equals(state)) {
// This device has built-in storage that is not removable.
// There is no reason for the user to unmount it.
removePreference(mMountTogglePreference);