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);