AppStorageSettings.java revision 39b467482d1bf256a111c757e9b7621c6f523271
1cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk/* 2cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * Copyright (C) 2015 The Android Open Source Project 3cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * 4cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 5cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * you may not use this file except in compliance with the License. 6cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * You may obtain a copy of the License at 7cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * 8cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * http://www.apache.org/licenses/LICENSE-2.0 9cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * 10cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * Unless required by applicable law or agreed to in writing, software 11cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * distributed under the License is distributed on an "AS IS" BASIS, 12cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * See the License for the specific language governing permissions and 14cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * limitations under the License. 15cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk */ 16cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 17cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkpackage com.android.settings.applications; 18cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 19cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.app.ActivityManager; 20cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.app.AlertDialog; 2116634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkeyimport android.app.AppGlobals; 22cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.Context; 23cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.DialogInterface; 24cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.Intent; 25cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.pm.ApplicationInfo; 26cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.pm.IPackageDataObserver; 2716634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkeyimport android.content.pm.IPackageManager; 28cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Bundle; 29cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Environment; 30cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Handler; 31cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Message; 3216634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkeyimport android.os.RemoteException; 331f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport android.os.storage.StorageManager; 341f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport android.os.storage.VolumeInfo; 3539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference; 3639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceCategory; 37cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.text.format.Formatter; 38cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.util.Log; 39cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.view.View; 40cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.view.View.OnClickListener; 41cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.widget.Button; 42cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 438a963babe2e36b7a41f77b8d2598c97658196e58Chris Wrenimport com.android.internal.logging.MetricsLogger; 44cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.R; 45cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.Utils; 461f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport com.android.settings.deviceinfo.StorageWizardMoveConfirm; 4767cd6ab93a526fe65877743e458590f4e6f187eeTony Mantlerimport com.android.settingslib.applications.ApplicationsState; 4867cd6ab93a526fe65877743e458590f4e6f187eeTony Mantlerimport com.android.settingslib.applications.ApplicationsState.AppEntry; 4967cd6ab93a526fe65877743e458590f4e6f187eeTony Mantlerimport com.android.settingslib.applications.ApplicationsState.Callbacks; 501f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey 511f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.Collections; 521f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.List; 531f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.Objects; 54cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 5560a09ea2388db01a661beeb9995a7ecf770a4200Jason Monkpublic class AppStorageSettings extends AppInfoWithHeader 56e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk implements OnClickListener, Callbacks, DialogInterface.OnClickListener { 57588a0881c13d8ed63ba67b3145254c22211a2019Jason Monk private static final String TAG = AppStorageSettings.class.getSimpleName(); 58cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 59cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk //internal constants used in Handler 60cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static final int OP_SUCCESSFUL = 1; 61cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static final int OP_FAILED = 2; 62cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static final int MSG_CLEAR_USER_DATA = 1; 63cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static final int MSG_CLEAR_CACHE = 3; 64cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 65cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // invalid size value used initially and also when size retrieval through PackageManager 66cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // fails for whatever reason 67cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static final int SIZE_INVALID = -1; 68cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 69cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Result code identifiers 70cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public static final int REQUEST_MANAGE_SPACE = 2; 71cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 72cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static final int DLG_CLEAR_DATA = DLG_BASE + 1; 73cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static final int DLG_CANNOT_CLEAR_DATA = DLG_BASE + 2; 74cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 75e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk private static final String KEY_STORAGE_USED = "storage_used"; 76e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk private static final String KEY_CHANGE_STORAGE = "change_storage_button"; 77bd45c3cbe0ccb9d5a1ebeabccda1e803d613e729Jason Monk private static final String KEY_STORAGE_SPACE = "storage_space"; 78c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_STORAGE_CATEGORY = "storage_category"; 7960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk 80c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_TOTAL_SIZE = "total_size"; 81c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_APP_SIZE = "app_size"; 82c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_EXTERNAL_CODE_SIZE = "external_code_size"; 83c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_DATA_SIZE = "data_size"; 84c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_EXTERNAL_DATA_SIZE = "external_data_size"; 85c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_CACHE_SIZE = "cache_size"; 86c27f9e179adef2061e0000385f350874a7772c4eJason Monk 87c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_CLEAR_DATA = "clear_data_button"; 88c27f9e179adef2061e0000385f350874a7772c4eJason Monk private static final String KEY_CLEAR_CACHE = "clear_cache_button"; 89c27f9e179adef2061e0000385f350874a7772c4eJason Monk 90c27f9e179adef2061e0000385f350874a7772c4eJason Monk private Preference mTotalSize; 91c27f9e179adef2061e0000385f350874a7772c4eJason Monk private Preference mAppSize; 92c27f9e179adef2061e0000385f350874a7772c4eJason Monk private Preference mDataSize; 93c27f9e179adef2061e0000385f350874a7772c4eJason Monk private Preference mExternalCodeSize; 94c27f9e179adef2061e0000385f350874a7772c4eJason Monk private Preference mExternalDataSize; 95cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 96cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Views related to cache info 97c27f9e179adef2061e0000385f350874a7772c4eJason Monk private Preference mCacheSize; 98cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private Button mClearDataButton; 99cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private Button mClearCacheButton; 10060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk 101e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk private Preference mStorageUsed; 102e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk private Button mChangeStorageButton; 103cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 104cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private boolean mCanClearData = true; 105cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private boolean mHaveSizes = false; 106cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 107cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private long mLastCodeSize = -1; 108cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private long mLastDataSize = -1; 109cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private long mLastExternalCodeSize = -1; 110cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private long mLastExternalDataSize = -1; 111cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private long mLastCacheSize = -1; 112cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private long mLastTotalSize = -1; 113cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 114cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private ClearCacheObserver mClearCacheObserver; 115cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private ClearUserDataObserver mClearDataObserver; 116cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 117cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Resource strings 118cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private CharSequence mInvalidSizeStr; 119cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private CharSequence mComputingStr; 120cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 121e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk private VolumeInfo[] mCandidates; 122e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk private AlertDialog.Builder mDialogBuilder; 123e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk 124cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk @Override 125cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void onCreate(Bundle savedInstanceState) { 126cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk super.onCreate(savedInstanceState); 127cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 12860a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk addPreferencesFromResource(R.xml.app_storage_settings); 12960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk setupViews(); 130cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 131cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 132ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk @Override 133ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk public void onResume() { 134ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk super.onResume(); 135ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk mState.requestSize(mPackageName, mUserId); 136ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk } 137ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk 13860a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk private void setupViews() { 139cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mComputingStr = getActivity().getText(R.string.computing_size); 140cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value); 141cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 142cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Set default values on sizes 143c27f9e179adef2061e0000385f350874a7772c4eJason Monk mTotalSize = findPreference(KEY_TOTAL_SIZE); 144c27f9e179adef2061e0000385f350874a7772c4eJason Monk mAppSize = findPreference(KEY_APP_SIZE); 145c27f9e179adef2061e0000385f350874a7772c4eJason Monk mDataSize = findPreference(KEY_DATA_SIZE); 146c27f9e179adef2061e0000385f350874a7772c4eJason Monk mExternalCodeSize = findPreference(KEY_EXTERNAL_CODE_SIZE); 147c27f9e179adef2061e0000385f350874a7772c4eJason Monk mExternalDataSize = findPreference(KEY_EXTERNAL_DATA_SIZE); 148cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 149cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (Environment.isExternalStorageEmulated()) { 150c27f9e179adef2061e0000385f350874a7772c4eJason Monk PreferenceCategory category = (PreferenceCategory) findPreference(KEY_STORAGE_CATEGORY); 151c27f9e179adef2061e0000385f350874a7772c4eJason Monk category.removePreference(mExternalCodeSize); 152c27f9e179adef2061e0000385f350874a7772c4eJason Monk category.removePreference(mExternalDataSize); 153cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 154c27f9e179adef2061e0000385f350874a7772c4eJason Monk mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_DATA)) 15560a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk .findViewById(R.id.button); 156cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 157e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mStorageUsed = findPreference(KEY_STORAGE_USED); 158e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mChangeStorageButton = (Button) ((LayoutPreference) findPreference(KEY_CHANGE_STORAGE)) 159e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk .findViewById(R.id.button); 160e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mChangeStorageButton.setText(R.string.change); 161e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mChangeStorageButton.setOnClickListener(this); 162cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 163cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Cache section 164c27f9e179adef2061e0000385f350874a7772c4eJason Monk mCacheSize = findPreference(KEY_CACHE_SIZE); 165c27f9e179adef2061e0000385f350874a7772c4eJason Monk mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_CACHE)) 16660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk .findViewById(R.id.button); 16760a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk mClearCacheButton.setText(R.string.clear_cache_btn_text); 168cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 169cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 170cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk @Override 171cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void onClick(View v) { 172cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (v == mClearCacheButton) { 173cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Lazy initialization of observer 174cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mClearCacheObserver == null) { 175cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearCacheObserver = new ClearCacheObserver(); 176cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 177cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mPm.deleteApplicationCacheFiles(mPackageName, mClearCacheObserver); 178e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk } else if (v == mClearDataButton) { 179cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mAppEntry.info.manageSpaceActivityName != null) { 180cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (!Utils.isMonkeyRunning()) { 181cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk Intent intent = new Intent(Intent.ACTION_DEFAULT); 182cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk intent.setClassName(mAppEntry.info.packageName, 183cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mAppEntry.info.manageSpaceActivityName); 184cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk startActivityForResult(intent, REQUEST_MANAGE_SPACE); 185cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 186cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 187cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk showDialogInner(DLG_CLEAR_DATA, 0); 188cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 18916634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey } else if (v == mChangeStorageButton && mDialogBuilder != null && !isMoveInProgress()) { 190e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mDialogBuilder.show(); 19160a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk } 19260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk } 19360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk 19416634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey private boolean isMoveInProgress() { 19516634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey final IPackageManager pm = AppGlobals.getPackageManager(); 19616634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey try { 19716634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey // TODO: define a cleaner API for this 19816634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey return pm.isPackageFrozen(mPackageName); 19916634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey } catch (RemoteException e) { 20016634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey return false; 20116634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey } 20216634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey } 20316634fd0ff74f243aa26ad4714df3a0921bdbe20Jeff Sharkey 20460a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk @Override 205e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk public void onClick(DialogInterface dialog, int which) { 2061f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey final Context context = getActivity(); 2071f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey 2081f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey // If not current volume, kick off move wizard 209e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk final VolumeInfo targetVol = mCandidates[which]; 210954d8dad5e395544f95ca211466bcc7195d31877Jeff Sharkey final VolumeInfo currentVol = context.getPackageManager().getPackageCurrentVolume( 2111f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey mAppEntry.info); 2121f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey if (!Objects.equals(targetVol, currentVol)) { 2131f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey final Intent intent = new Intent(context, StorageWizardMoveConfirm.class); 2141f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, targetVol.getId()); 2151f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName); 2161f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey startActivity(intent); 217cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 218e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk dialog.dismiss(); 219cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 220cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 221cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private String getSizeStr(long size) { 222cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (size == SIZE_INVALID) { 223cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return mInvalidSizeStr.toString(); 224cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 225cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return Formatter.formatFileSize(getActivity(), size); 226cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 227cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 228cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private void refreshSizeInfo() { 229cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mAppEntry.size == ApplicationsState.SIZE_INVALID 230cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk || mAppEntry.size == ApplicationsState.SIZE_UNKNOWN) { 231cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mLastCodeSize = mLastDataSize = mLastCacheSize = mLastTotalSize = -1; 232cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (!mHaveSizes) { 233c27f9e179adef2061e0000385f350874a7772c4eJason Monk mAppSize.setSummary(mComputingStr); 234c27f9e179adef2061e0000385f350874a7772c4eJason Monk mDataSize.setSummary(mComputingStr); 235c27f9e179adef2061e0000385f350874a7772c4eJason Monk mCacheSize.setSummary(mComputingStr); 236c27f9e179adef2061e0000385f350874a7772c4eJason Monk mTotalSize.setSummary(mComputingStr); 237cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 238cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(false); 239cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearCacheButton.setEnabled(false); 240cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 241cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 242cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mHaveSizes = true; 243cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk long codeSize = mAppEntry.codeSize; 244cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk long dataSize = mAppEntry.dataSize; 245cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (Environment.isExternalStorageEmulated()) { 246cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk codeSize += mAppEntry.externalCodeSize; 247cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk dataSize += mAppEntry.externalDataSize; 248cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 249cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mLastExternalCodeSize != mAppEntry.externalCodeSize) { 250cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mLastExternalCodeSize = mAppEntry.externalCodeSize; 251c27f9e179adef2061e0000385f350874a7772c4eJason Monk mExternalCodeSize.setSummary(getSizeStr(mAppEntry.externalCodeSize)); 252cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 253cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mLastExternalDataSize != mAppEntry.externalDataSize) { 254cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mLastExternalDataSize = mAppEntry.externalDataSize; 255c27f9e179adef2061e0000385f350874a7772c4eJason Monk mExternalDataSize.setSummary(getSizeStr( mAppEntry.externalDataSize)); 256cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 257cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 258cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mLastCodeSize != codeSize) { 259cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mLastCodeSize = codeSize; 260c27f9e179adef2061e0000385f350874a7772c4eJason Monk mAppSize.setSummary(getSizeStr(codeSize)); 261cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 262cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mLastDataSize != dataSize) { 263cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mLastDataSize = dataSize; 264c27f9e179adef2061e0000385f350874a7772c4eJason Monk mDataSize.setSummary(getSizeStr(dataSize)); 265cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 266cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk long cacheSize = mAppEntry.cacheSize + mAppEntry.externalCacheSize; 267cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mLastCacheSize != cacheSize) { 268cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mLastCacheSize = cacheSize; 269c27f9e179adef2061e0000385f350874a7772c4eJason Monk mCacheSize.setSummary(getSizeStr(cacheSize)); 270cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 271cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mLastTotalSize != mAppEntry.size) { 272cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mLastTotalSize = mAppEntry.size; 273c27f9e179adef2061e0000385f350874a7772c4eJason Monk mTotalSize.setSummary(getSizeStr(mAppEntry.size)); 274cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 275cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 276cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if ((mAppEntry.dataSize+ mAppEntry.externalDataSize) <= 0 || !mCanClearData) { 277cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(false); 278cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 279cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(true); 280cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setOnClickListener(this); 281cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 282cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (cacheSize <= 0) { 283cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearCacheButton.setEnabled(false); 284cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 285cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearCacheButton.setEnabled(true); 286cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearCacheButton.setOnClickListener(this); 287cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 288cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 289cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mAppControlRestricted) { 290cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearCacheButton.setEnabled(false); 291cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(false); 292cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 293cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 294cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 295cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk @Override 296cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk protected boolean refreshUi() { 297cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk retrieveAppEntry(); 2989a1c0dce7a496f51087cf0497b931a31c64b0a65Julia Reynolds if (mAppEntry == null) { 2999a1c0dce7a496f51087cf0497b931a31c64b0a65Julia Reynolds return false; 3009a1c0dce7a496f51087cf0497b931a31c64b0a65Julia Reynolds } 301cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk refreshSizeInfo(); 3021f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey 3031f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey final VolumeInfo currentVol = getActivity().getPackageManager() 304954d8dad5e395544f95ca211466bcc7195d31877Jeff Sharkey .getPackageCurrentVolume(mAppEntry.info); 305e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk final StorageManager storage = getContext().getSystemService(StorageManager.class); 306e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mStorageUsed.setSummary(storage.getBestVolumeDescription(currentVol)); 307e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk 308e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk refreshButtons(); 3091f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey 310cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return true; 311cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 312cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 313cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private void refreshButtons() { 314e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk initMoveDialog(); 3151f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey initDataButtons(); 316cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 317cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 318cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private void initDataButtons() { 319cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // If the app doesn't have its own space management UI 320cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // And it's a system app that doesn't allow clearing user data or is an active admin 321cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Then disable the Clear Data button. 322cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mAppEntry.info.manageSpaceActivityName == null 323cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk && ((mAppEntry.info.flags&(ApplicationInfo.FLAG_SYSTEM 324cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk | ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)) 325cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk == ApplicationInfo.FLAG_SYSTEM 326cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk || mDpm.packageHasActiveAdmins(mPackageName))) { 327cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setText(R.string.clear_user_data_text); 328cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(false); 329cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mCanClearData = false; 330cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 331cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mAppEntry.info.manageSpaceActivityName != null) { 332cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setText(R.string.manage_space_text); 333cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 334cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setText(R.string.clear_user_data_text); 335cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 336cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setOnClickListener(this); 337cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 338cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 339cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mAppControlRestricted) { 340cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(false); 341cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 342cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 343cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 344e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk private void initMoveDialog() { 3451f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey final Context context = getActivity(); 3461f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey final StorageManager storage = context.getSystemService(StorageManager.class); 3471f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey 3481f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey final List<VolumeInfo> candidates = context.getPackageManager() 349954d8dad5e395544f95ca211466bcc7195d31877Jeff Sharkey .getPackageCandidateVolumes(mAppEntry.info); 350c27f9e179adef2061e0000385f350874a7772c4eJason Monk if (candidates.size() > 1) { 351c27f9e179adef2061e0000385f350874a7772c4eJason Monk Collections.sort(candidates, VolumeInfo.getDescriptionComparator()); 3521f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey 353e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk CharSequence[] labels = new CharSequence[candidates.size()]; 354e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk int current = -1; 355e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk for (int i = 0; i < candidates.size(); i++) { 356e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk final String volDescrip = storage.getBestVolumeDescription(candidates.get(i)); 357e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk if (Objects.equals(volDescrip, mStorageUsed.getSummary())) { 358e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk current = i; 359e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk } 360e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk labels[i] = volDescrip; 361c27f9e179adef2061e0000385f350874a7772c4eJason Monk } 362e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mCandidates = candidates.toArray(new VolumeInfo[candidates.size()]); 363e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk mDialogBuilder = new AlertDialog.Builder(getContext()) 364e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk .setTitle(R.string.change_storage) 365e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk .setSingleChoiceItems(labels, current, this) 366e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk .setNegativeButton(R.string.cancel, null); 367c27f9e179adef2061e0000385f350874a7772c4eJason Monk } else { 368e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk removePreference(KEY_STORAGE_USED); 369e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk removePreference(KEY_CHANGE_STORAGE); 370bd45c3cbe0ccb9d5a1ebeabccda1e803d613e729Jason Monk removePreference(KEY_STORAGE_SPACE); 371cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 372cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 373cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 374cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk /* 375cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * Private method to initiate clearing user data when the user clicks the clear data 376cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * button for a system package 377cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk */ 378cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private void initiateClearUserData() { 379cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(false); 380cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Invoke uninstall or clear user data based on sysPackage 381cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk String packageName = mAppEntry.info.packageName; 382cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk Log.i(TAG, "Clearing user data for package : " + packageName); 383cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (mClearDataObserver == null) { 384cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataObserver = new ClearUserDataObserver(); 385cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 386cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk ActivityManager am = (ActivityManager) 387cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk getActivity().getSystemService(Context.ACTIVITY_SERVICE); 388cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk boolean res = am.clearApplicationUserData(packageName, mClearDataObserver); 389cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (!res) { 390cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Clearing data failed for some obscure reason. Just log error for now 391cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk Log.i(TAG, "Couldnt clear application user data for package:"+packageName); 392cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk showDialogInner(DLG_CANNOT_CLEAR_DATA, 0); 393cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 394cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setText(R.string.recompute_size); 395cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 396cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 397cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 398cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk /* 399cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * Private method to handle clear message notification from observer when 400cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk * the async operation from PackageManager is complete 401cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk */ 402cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private void processClearMsg(Message msg) { 403cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk int result = msg.arg1; 404cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk String packageName = mAppEntry.info.packageName; 405cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setText(R.string.clear_user_data_text); 40660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk if (result == OP_SUCCESSFUL) { 407cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk Log.i(TAG, "Cleared user data for package : "+packageName); 40807025891683aef83d850b0a91b37aa75b11ce33cJason Monk mState.requestSize(mPackageName, mUserId); 409cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 410cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(true); 411cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 412cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 413cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 414cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk @Override 415cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk protected AlertDialog createDialog(int id, int errorCode) { 416cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk switch (id) { 417cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk case DLG_CLEAR_DATA: 418cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return new AlertDialog.Builder(getActivity()) 419cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .setTitle(getActivity().getText(R.string.clear_data_dlg_title)) 420cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .setMessage(getActivity().getText(R.string.clear_data_dlg_text)) 421cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() { 422cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void onClick(DialogInterface dialog, int which) { 423cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Clear user data here 424cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk initiateClearUserData(); 425cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 426cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk }) 427cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .setNegativeButton(R.string.dlg_cancel, null) 428cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .create(); 429cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk case DLG_CANNOT_CLEAR_DATA: 430cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return new AlertDialog.Builder(getActivity()) 431cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .setTitle(getActivity().getText(R.string.clear_failed_dlg_title)) 432cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .setMessage(getActivity().getText(R.string.clear_failed_dlg_text)) 433cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .setNeutralButton(R.string.dlg_ok, new DialogInterface.OnClickListener() { 434cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void onClick(DialogInterface dialog, int which) { 435cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mClearDataButton.setEnabled(false); 436cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk //force to recompute changed value 437cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk setIntentAndFinish(false, false); 438cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 439cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk }) 440cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk .create(); 441cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 442cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return null; 443cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 444cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 445cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk @Override 446cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void onPackageSizeChanged(String packageName) { 447cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (packageName.equals(mAppEntry.info.packageName)) { 448cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk refreshSizeInfo(); 449cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 450cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 451cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 452cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private final Handler mHandler = new Handler() { 453cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void handleMessage(Message msg) { 454cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (getView() == null) { 455cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return; 456cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 457cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk switch (msg.what) { 458cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk case MSG_CLEAR_USER_DATA: 459cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk processClearMsg(msg); 460cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk break; 461cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk case MSG_CLEAR_CACHE: 462cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk // Refresh size info 46307025891683aef83d850b0a91b37aa75b11ce33cJason Monk mState.requestSize(mPackageName, mUserId); 464cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk break; 465cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 466cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 467cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk }; 468cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 469cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public static CharSequence getSummary(AppEntry appEntry, Context context) { 470cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (appEntry.size == ApplicationsState.SIZE_INVALID 471cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk || appEntry.size == ApplicationsState.SIZE_UNKNOWN) { 472cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return context.getText(R.string.computing_size); 473cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } else { 474cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk CharSequence storageType = context.getString( 475cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk (appEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 476cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk ? R.string.storage_type_external 477cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk : R.string.storage_type_internal); 478cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return context.getString(R.string.storage_summary_format, 479cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk getSize(appEntry, context), storageType); 480cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 481cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 482cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 483cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk private static CharSequence getSize(AppEntry appEntry, Context context) { 484cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk long size = appEntry.size; 485cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk if (size == SIZE_INVALID) { 486cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return context.getText(R.string.invalid_size_value); 487cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 488cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk return Formatter.formatFileSize(context, size); 489cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 490cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 4918a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren @Override 4928a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren protected int getMetricsCategory() { 4938a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren return MetricsLogger.APPLICATIONS_APP_STORAGE; 4948a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren } 4958a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren 496cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk class ClearCacheObserver extends IPackageDataObserver.Stub { 497cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void onRemoveCompleted(final String packageName, final boolean succeeded) { 498cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk final Message msg = mHandler.obtainMessage(MSG_CLEAR_CACHE); 499cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED; 500cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mHandler.sendMessage(msg); 501cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 502cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 503cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk 504cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk class ClearUserDataObserver extends IPackageDataObserver.Stub { 505cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk public void onRemoveCompleted(final String packageName, final boolean succeeded) { 506cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk final Message msg = mHandler.obtainMessage(MSG_CLEAR_USER_DATA); 50760a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED; 508cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk mHandler.sendMessage(msg); 509cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 510cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk } 511cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk} 512