AppStorageSettings.java revision 1f4efd7360dea3038fe2096b1d4bccaae8e2a09f
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;
21cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.Context;
22cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.DialogInterface;
23cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.Intent;
24cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.pm.ApplicationInfo;
25cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.content.pm.IPackageDataObserver;
26cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Bundle;
27cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Environment;
28cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Handler;
29cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.os.Message;
301f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport android.os.storage.StorageManager;
311f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport android.os.storage.VolumeInfo;
32cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.text.format.Formatter;
33cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.util.Log;
34cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.view.View;
35cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.view.View.OnClickListener;
36cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.widget.Button;
37cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.widget.TextView;
38cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
398a963babe2e36b7a41f77b8d2598c97658196e58Chris Wrenimport com.android.internal.logging.MetricsLogger;
401f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport com.android.settings.DropDownPreference;
41cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.R;
42cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.Utils;
43cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.applications.ApplicationsState.AppEntry;
44cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.applications.ApplicationsState.Callbacks;
451f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport com.android.settings.deviceinfo.StorageWizardMoveConfirm;
461f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
471f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.Collections;
481f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.List;
491f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.Objects;
50cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
5160a09ea2388db01a661beeb9995a7ecf770a4200Jason Monkpublic class AppStorageSettings extends AppInfoWithHeader
5260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        implements OnClickListener, Callbacks, DropDownPreference.Callback {
53588a0881c13d8ed63ba67b3145254c22211a2019Jason Monk    private static final String TAG = AppStorageSettings.class.getSimpleName();
54cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
55cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    //internal constants used in Handler
56cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int OP_SUCCESSFUL = 1;
57cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int OP_FAILED = 2;
58cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int MSG_CLEAR_USER_DATA = 1;
59cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int MSG_CLEAR_CACHE = 3;
60cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
61cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // invalid size value used initially and also when size retrieval through PackageManager
62cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // fails for whatever reason
63cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int SIZE_INVALID = -1;
64cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
65cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // Result code identifiers
66cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public static final int REQUEST_MANAGE_SPACE = 2;
67cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
68cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int DLG_CLEAR_DATA = DLG_BASE + 1;
69cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int DLG_CANNOT_CLEAR_DATA = DLG_BASE + 2;
70cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
7160a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    private static final String KEY_MOVE_PREFERENCE = "app_location_setting";
7260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    private static final String KEY_STORAGE_SETTINGS = "storage_settings";
7360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    private static final String KEY_CACHE_SETTINGS = "cache_settings";
7460a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk
75cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private TextView mTotalSize;
76cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private TextView mAppSize;
77cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private TextView mDataSize;
78cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private TextView mExternalCodeSize;
79cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private TextView mExternalDataSize;
80cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
81cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // Views related to cache info
82cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private TextView mCacheSize;
83cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private Button mClearDataButton;
84cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private Button mClearCacheButton;
8560a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk
8660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    private DropDownPreference mMoveDropDown;
87cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
88cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private boolean mCanClearData = true;
89cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private boolean mHaveSizes = false;
90cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
91cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastCodeSize = -1;
92cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastDataSize = -1;
93cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastExternalCodeSize = -1;
94cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastExternalDataSize = -1;
95cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastCacheSize = -1;
96cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastTotalSize = -1;
97cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
98cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private ClearCacheObserver mClearCacheObserver;
99cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private ClearUserDataObserver mClearDataObserver;
100cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
101cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // Resource strings
102cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private CharSequence mInvalidSizeStr;
103cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private CharSequence mComputingStr;
104cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
105cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
106cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public void onCreate(Bundle savedInstanceState) {
107cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        super.onCreate(savedInstanceState);
108cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
10960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        addPreferencesFromResource(R.xml.app_storage_settings);
11060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        setupViews();
111cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
112cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
11360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    private void setupViews() {
114cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mComputingStr = getActivity().getText(R.string.computing_size);
115cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
11660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        LayoutPreference view = (LayoutPreference) findPreference(KEY_STORAGE_SETTINGS);
117cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
118cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Set default values on sizes
11960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mTotalSize = (TextView) view.findViewById(R.id.total_size_text);
12060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mAppSize = (TextView) view.findViewById(R.id.application_size_text);
12160a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mDataSize = (TextView) view.findViewById(R.id.data_size_text);
12260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mExternalCodeSize = (TextView) view.findViewById(R.id.external_code_size_text);
12360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mExternalDataSize = (TextView) view.findViewById(R.id.external_data_size_text);
124cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
125cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (Environment.isExternalStorageEmulated()) {
12660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk            ((View) mExternalCodeSize.getParent()).setVisibility(View.GONE);
12760a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk            ((View) mExternalDataSize.getParent()).setVisibility(View.GONE);
128cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
12960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mClearDataButton = (Button) view.findViewById(R.id.clear_data_button)
13060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk                .findViewById(R.id.button);
131cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
13260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mMoveDropDown = (DropDownPreference) findPreference(KEY_MOVE_PREFERENCE);
13360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mMoveDropDown.setCallback(this);
134cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
13560a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        view = (LayoutPreference) findPreference(KEY_CACHE_SETTINGS);
136cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Cache section
13760a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mCacheSize = (TextView) view.findViewById(R.id.cache_size_text);
13860a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mClearCacheButton = (Button) view.findViewById(R.id.clear_cache_button)
13960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk                .findViewById(R.id.button);
14060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mClearCacheButton.setText(R.string.clear_cache_btn_text);
141cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
142cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
143cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
144cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public void onClick(View v) {
145cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (v == mClearCacheButton) {
146cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            // Lazy initialization of observer
147cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mClearCacheObserver == null) {
148cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheObserver = new ClearCacheObserver();
149cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
150cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mPm.deleteApplicationCacheFiles(mPackageName, mClearCacheObserver);
151cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else if(v == mClearDataButton) {
152cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mAppEntry.info.manageSpaceActivityName != null) {
153cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                if (!Utils.isMonkeyRunning()) {
154cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    Intent intent = new Intent(Intent.ACTION_DEFAULT);
155cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    intent.setClassName(mAppEntry.info.packageName,
156cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            mAppEntry.info.manageSpaceActivityName);
157cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    startActivityForResult(intent, REQUEST_MANAGE_SPACE);
158cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                }
159cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
160cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                showDialogInner(DLG_CLEAR_DATA, 0);
161cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
16260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        }
16360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    }
16460a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk
16560a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    @Override
16660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    public boolean onItemSelected(int pos, Object value) {
1671f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final Context context = getActivity();
1681f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
1691f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        // If not current volume, kick off move wizard
1701f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final VolumeInfo targetVol = (VolumeInfo) value;
1711f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final VolumeInfo currentVol = context.getPackageManager().getApplicationCurrentVolume(
1721f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey                mAppEntry.info);
1731f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        if (!Objects.equals(targetVol, currentVol)) {
1741f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            final Intent intent = new Intent(context, StorageWizardMoveConfirm.class);
1751f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, targetVol.getId());
1761f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
1771f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            startActivity(intent);
178cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
1791f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
18060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        return true;
181cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
182cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
183cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private String getSizeStr(long size) {
184cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (size == SIZE_INVALID) {
185cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return mInvalidSizeStr.toString();
186cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
187cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return Formatter.formatFileSize(getActivity(), size);
188cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
189cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
190cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void refreshSizeInfo() {
191cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppEntry.size == ApplicationsState.SIZE_INVALID
192cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                || mAppEntry.size == ApplicationsState.SIZE_UNKNOWN) {
193cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mLastCodeSize = mLastDataSize = mLastCacheSize = mLastTotalSize = -1;
194cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (!mHaveSizes) {
195cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mAppSize.setText(mComputingStr);
196cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mDataSize.setText(mComputingStr);
197cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mCacheSize.setText(mComputingStr);
198cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mTotalSize.setText(mComputingStr);
199cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
200cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
201cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearCacheButton.setEnabled(false);
202cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
203cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
204cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mHaveSizes = true;
205cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            long codeSize = mAppEntry.codeSize;
206cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            long dataSize = mAppEntry.dataSize;
207cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (Environment.isExternalStorageEmulated()) {
208cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                codeSize += mAppEntry.externalCodeSize;
209cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                dataSize +=  mAppEntry.externalDataSize;
210cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
211cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                if (mLastExternalCodeSize != mAppEntry.externalCodeSize) {
212cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    mLastExternalCodeSize = mAppEntry.externalCodeSize;
213cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    mExternalCodeSize.setText(getSizeStr(mAppEntry.externalCodeSize));
214cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                }
215cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                if (mLastExternalDataSize !=  mAppEntry.externalDataSize) {
216cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    mLastExternalDataSize =  mAppEntry.externalDataSize;
217cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    mExternalDataSize.setText(getSizeStr( mAppEntry.externalDataSize));
218cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                }
219cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
220cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastCodeSize != codeSize) {
221cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastCodeSize = codeSize;
222cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mAppSize.setText(getSizeStr(codeSize));
223cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
224cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastDataSize != dataSize) {
225cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastDataSize = dataSize;
226cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mDataSize.setText(getSizeStr(dataSize));
227cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
228cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            long cacheSize = mAppEntry.cacheSize + mAppEntry.externalCacheSize;
229cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastCacheSize != cacheSize) {
230cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastCacheSize = cacheSize;
231cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mCacheSize.setText(getSizeStr(cacheSize));
232cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
233cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastTotalSize != mAppEntry.size) {
234cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastTotalSize = mAppEntry.size;
235cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mTotalSize.setText(getSizeStr(mAppEntry.size));
236cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
237cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
238cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if ((mAppEntry.dataSize+ mAppEntry.externalDataSize) <= 0 || !mCanClearData) {
239cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setEnabled(false);
240cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
241cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setEnabled(true);
242cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setOnClickListener(this);
243cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
244cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (cacheSize <= 0) {
245cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheButton.setEnabled(false);
246cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
247cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheButton.setEnabled(true);
248cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheButton.setOnClickListener(this);
249cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
250cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
251cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppControlRestricted) {
252cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearCacheButton.setEnabled(false);
253cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
254cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
255cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
256cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
257cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
258cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    protected boolean refreshUi() {
259cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        retrieveAppEntry();
260cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        refreshButtons();
261cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        refreshSizeInfo();
2621f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
2631f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final VolumeInfo currentVol = getActivity().getPackageManager()
2641f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey                .getApplicationCurrentVolume(mAppEntry.info);
2651f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        mMoveDropDown.setSelectedValue(currentVol);
2661f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
267cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return true;
268cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
269cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
270cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void refreshButtons() {
2711f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        initMoveDropDown();
2721f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        initDataButtons();
273cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
274cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
275cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void initDataButtons() {
276cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // If the app doesn't have its own space management UI
277cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // And it's a system app that doesn't allow clearing user data or is an active admin
278cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Then disable the Clear Data button.
279cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppEntry.info.manageSpaceActivityName == null
280cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                && ((mAppEntry.info.flags&(ApplicationInfo.FLAG_SYSTEM
281cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        | ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA))
282cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        == ApplicationInfo.FLAG_SYSTEM
283cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        || mDpm.packageHasActiveAdmins(mPackageName))) {
284cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setText(R.string.clear_user_data_text);
285cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
286cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mCanClearData = false;
287cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
288cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mAppEntry.info.manageSpaceActivityName != null) {
289cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setText(R.string.manage_space_text);
290cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
291cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setText(R.string.clear_user_data_text);
292cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
293cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setOnClickListener(this);
294cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
295cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
296cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppControlRestricted) {
297cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
298cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
299cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
300cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
30160a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    private void initMoveDropDown() {
3021f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final Context context = getActivity();
3031f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final StorageManager storage = context.getSystemService(StorageManager.class);
3041f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
3051f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final List<VolumeInfo> candidates = context.getPackageManager()
3061f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey                .getApplicationCandidateVolumes(mAppEntry.info);
3071f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        Collections.sort(candidates, VolumeInfo.getDescriptionComparator());
3081f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
3091f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        mMoveDropDown.clearItems();
3101f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        for (VolumeInfo vol : candidates) {
3111f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            final String volDescrip = storage.getBestVolumeDescription(vol);
3121f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            mMoveDropDown.addItem(volDescrip, vol);
313cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
31460a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mMoveDropDown.setSelectable(!mAppControlRestricted);
315cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
316cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
317cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    /*
318cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * Private method to initiate clearing user data when the user clicks the clear data
319cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * button for a system package
320cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     */
321cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void initiateClearUserData() {
322cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mClearDataButton.setEnabled(false);
323cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Invoke uninstall or clear user data based on sysPackage
324cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        String packageName = mAppEntry.info.packageName;
325cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        Log.i(TAG, "Clearing user data for package : " + packageName);
326cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mClearDataObserver == null) {
327cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataObserver = new ClearUserDataObserver();
328cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
329cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        ActivityManager am = (ActivityManager)
330cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                getActivity().getSystemService(Context.ACTIVITY_SERVICE);
331cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
332cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (!res) {
333cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            // Clearing data failed for some obscure reason. Just log error for now
334cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            Log.i(TAG, "Couldnt clear application user data for package:"+packageName);
335cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
336cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
337cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setText(R.string.recompute_size);
338cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
339cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
340cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
341cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    /*
342cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * Private method to handle clear message notification from observer when
343cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * the async operation from PackageManager is complete
344cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     */
345cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void processClearMsg(Message msg) {
346cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        int result = msg.arg1;
347cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        String packageName = mAppEntry.info.packageName;
348cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mClearDataButton.setText(R.string.clear_user_data_text);
34960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        if (result == OP_SUCCESSFUL) {
350cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            Log.i(TAG, "Cleared user data for package : "+packageName);
35107025891683aef83d850b0a91b37aa75b11ce33cJason Monk            mState.requestSize(mPackageName, mUserId);
352cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
353cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(true);
354cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
355cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
356cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
357cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
358cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    protected AlertDialog createDialog(int id, int errorCode) {
359cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        switch (id) {
360cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            case DLG_CLEAR_DATA:
361cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                return new AlertDialog.Builder(getActivity())
362cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setTitle(getActivity().getText(R.string.clear_data_dlg_title))
363cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setMessage(getActivity().getText(R.string.clear_data_dlg_text))
364cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
365cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            public void onClick(DialogInterface dialog, int which) {
366cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                // Clear user data here
367cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                initiateClearUserData();
368cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            }
369cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        })
370cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setNegativeButton(R.string.dlg_cancel, null)
371cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .create();
372cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            case DLG_CANNOT_CLEAR_DATA:
373cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                return new AlertDialog.Builder(getActivity())
374cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setTitle(getActivity().getText(R.string.clear_failed_dlg_title))
375cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setMessage(getActivity().getText(R.string.clear_failed_dlg_text))
376cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setNeutralButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
377cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            public void onClick(DialogInterface dialog, int which) {
378cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                mClearDataButton.setEnabled(false);
379cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                //force to recompute changed value
380cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                setIntentAndFinish(false, false);
381cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            }
382cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        })
383cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .create();
384cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
385cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return null;
386cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
387cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
388cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
389cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public void onPackageSizeChanged(String packageName) {
390cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (packageName.equals(mAppEntry.info.packageName)) {
391cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            refreshSizeInfo();
392cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
393cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
394cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
395cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private final Handler mHandler = new Handler() {
396cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        public void handleMessage(Message msg) {
397cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (getView() == null) {
398cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                return;
399cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
400cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            switch (msg.what) {
401cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                case MSG_CLEAR_USER_DATA:
402cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    processClearMsg(msg);
403cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    break;
404cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                case MSG_CLEAR_CACHE:
405cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    // Refresh size info
40607025891683aef83d850b0a91b37aa75b11ce33cJason Monk                    mState.requestSize(mPackageName, mUserId);
407cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    break;
408cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
409cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
410cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    };
411cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
412cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public static CharSequence getSummary(AppEntry appEntry, Context context) {
413cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (appEntry.size == ApplicationsState.SIZE_INVALID
414cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                || appEntry.size == ApplicationsState.SIZE_UNKNOWN) {
415cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return context.getText(R.string.computing_size);
416cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
417cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            CharSequence storageType = context.getString(
418cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    (appEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0
419cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    ? R.string.storage_type_external
420cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    : R.string.storage_type_internal);
421cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return context.getString(R.string.storage_summary_format,
422cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    getSize(appEntry, context), storageType);
423cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
424cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
425cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
426cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static CharSequence getSize(AppEntry appEntry, Context context) {
427cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        long size = appEntry.size;
428cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (size == SIZE_INVALID) {
429cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return context.getText(R.string.invalid_size_value);
430cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
431cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return Formatter.formatFileSize(context, size);
432cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
433cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
4348a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    @Override
4358a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    protected int getMetricsCategory() {
4368a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren        return MetricsLogger.APPLICATIONS_APP_STORAGE;
4378a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    }
4388a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren
439cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    class ClearCacheObserver extends IPackageDataObserver.Stub {
440cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
441cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            final Message msg = mHandler.obtainMessage(MSG_CLEAR_CACHE);
442cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED;
443cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mHandler.sendMessage(msg);
444cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
445cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
446cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
447cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    class ClearUserDataObserver extends IPackageDataObserver.Stub {
448cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk       public void onRemoveCompleted(final String packageName, final boolean succeeded) {
449cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk           final Message msg = mHandler.obtainMessage(MSG_CLEAR_USER_DATA);
45060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk           msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED;
451cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk           mHandler.sendMessage(msg);
452cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
453cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
454cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk}
455