AppStorageSettings.java revision 9a1c0dce7a496f51087cf0497b931a31c64b0a65
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;
32c27f9e179adef2061e0000385f350874a7772c4eJason Monkimport android.preference.Preference;
33c27f9e179adef2061e0000385f350874a7772c4eJason Monkimport android.preference.PreferenceCategory;
34cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.text.format.Formatter;
35cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.util.Log;
36cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.view.View;
37cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.view.View.OnClickListener;
38cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport android.widget.Button;
39cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
408a963babe2e36b7a41f77b8d2598c97658196e58Chris Wrenimport com.android.internal.logging.MetricsLogger;
41cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.R;
42cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monkimport com.android.settings.Utils;
431f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport com.android.settings.deviceinfo.StorageWizardMoveConfirm;
4467cd6ab93a526fe65877743e458590f4e6f187eeTony Mantlerimport com.android.settingslib.applications.ApplicationsState;
4567cd6ab93a526fe65877743e458590f4e6f187eeTony Mantlerimport com.android.settingslib.applications.ApplicationsState.AppEntry;
4667cd6ab93a526fe65877743e458590f4e6f187eeTony Mantlerimport com.android.settingslib.applications.ApplicationsState.Callbacks;
471f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
481f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.Collections;
491f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.List;
501f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkeyimport java.util.Objects;
51cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
5260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monkpublic class AppStorageSettings extends AppInfoWithHeader
53e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        implements OnClickListener, Callbacks, DialogInterface.OnClickListener {
54588a0881c13d8ed63ba67b3145254c22211a2019Jason Monk    private static final String TAG = AppStorageSettings.class.getSimpleName();
55cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
56cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    //internal constants used in Handler
57cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int OP_SUCCESSFUL = 1;
58cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int OP_FAILED = 2;
59cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int MSG_CLEAR_USER_DATA = 1;
60cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int MSG_CLEAR_CACHE = 3;
61cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
62cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // invalid size value used initially and also when size retrieval through PackageManager
63cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // fails for whatever reason
64cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int SIZE_INVALID = -1;
65cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
66cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // Result code identifiers
67cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public static final int REQUEST_MANAGE_SPACE = 2;
68cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
69cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int DLG_CLEAR_DATA = DLG_BASE + 1;
70cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static final int DLG_CANNOT_CLEAR_DATA = DLG_BASE + 2;
71cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
72e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    private static final String KEY_STORAGE_USED = "storage_used";
73e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    private static final String KEY_CHANGE_STORAGE = "change_storage_button";
74bd45c3cbe0ccb9d5a1ebeabccda1e803d613e729Jason Monk    private static final String KEY_STORAGE_SPACE = "storage_space";
75c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_STORAGE_CATEGORY = "storage_category";
7660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk
77c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_TOTAL_SIZE = "total_size";
78c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_APP_SIZE = "app_size";
79c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_EXTERNAL_CODE_SIZE = "external_code_size";
80c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_DATA_SIZE = "data_size";
81c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_EXTERNAL_DATA_SIZE = "external_data_size";
82c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_CACHE_SIZE = "cache_size";
83c27f9e179adef2061e0000385f350874a7772c4eJason Monk
84c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_CLEAR_DATA = "clear_data_button";
85c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private static final String KEY_CLEAR_CACHE = "clear_cache_button";
86c27f9e179adef2061e0000385f350874a7772c4eJason Monk
87c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private Preference mTotalSize;
88c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private Preference mAppSize;
89c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private Preference mDataSize;
90c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private Preference mExternalCodeSize;
91c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private Preference mExternalDataSize;
92cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
93cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // Views related to cache info
94c27f9e179adef2061e0000385f350874a7772c4eJason Monk    private Preference mCacheSize;
95cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private Button mClearDataButton;
96cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private Button mClearCacheButton;
9760a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk
98e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    private Preference mStorageUsed;
99e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    private Button mChangeStorageButton;
100cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
101cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private boolean mCanClearData = true;
102cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private boolean mHaveSizes = false;
103cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
104cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastCodeSize = -1;
105cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastDataSize = -1;
106cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastExternalCodeSize = -1;
107cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastExternalDataSize = -1;
108cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastCacheSize = -1;
109cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private long mLastTotalSize = -1;
110cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
111cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private ClearCacheObserver mClearCacheObserver;
112cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private ClearUserDataObserver mClearDataObserver;
113cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
114cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    // Resource strings
115cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private CharSequence mInvalidSizeStr;
116cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private CharSequence mComputingStr;
117cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
118e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    private VolumeInfo[] mCandidates;
119e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    private AlertDialog.Builder mDialogBuilder;
120e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk
121cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
122cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public void onCreate(Bundle savedInstanceState) {
123cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        super.onCreate(savedInstanceState);
124cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
12560a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        addPreferencesFromResource(R.xml.app_storage_settings);
12660a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        setupViews();
127cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
128cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
129ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk    @Override
130ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk    public void onResume() {
131ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk        super.onResume();
132ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk        mState.requestSize(mPackageName, mUserId);
133ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk    }
134ece9d5145f38ec077be9d7f3a2e145500b296a29Jason Monk
13560a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    private void setupViews() {
136cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mComputingStr = getActivity().getText(R.string.computing_size);
137cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
138cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
139cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Set default values on sizes
140c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mTotalSize = findPreference(KEY_TOTAL_SIZE);
141c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mAppSize =  findPreference(KEY_APP_SIZE);
142c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mDataSize =  findPreference(KEY_DATA_SIZE);
143c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mExternalCodeSize = findPreference(KEY_EXTERNAL_CODE_SIZE);
144c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mExternalDataSize = findPreference(KEY_EXTERNAL_DATA_SIZE);
145cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
146cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (Environment.isExternalStorageEmulated()) {
147c27f9e179adef2061e0000385f350874a7772c4eJason Monk            PreferenceCategory category = (PreferenceCategory) findPreference(KEY_STORAGE_CATEGORY);
148c27f9e179adef2061e0000385f350874a7772c4eJason Monk            category.removePreference(mExternalCodeSize);
149c27f9e179adef2061e0000385f350874a7772c4eJason Monk            category.removePreference(mExternalDataSize);
150cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
151c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_DATA))
15260a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk                .findViewById(R.id.button);
153cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
154e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        mStorageUsed = findPreference(KEY_STORAGE_USED);
155e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        mChangeStorageButton = (Button) ((LayoutPreference) findPreference(KEY_CHANGE_STORAGE))
156e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                .findViewById(R.id.button);
157e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        mChangeStorageButton.setText(R.string.change);
158e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        mChangeStorageButton.setOnClickListener(this);
159cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
160cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Cache section
161c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mCacheSize = findPreference(KEY_CACHE_SIZE);
162c27f9e179adef2061e0000385f350874a7772c4eJason Monk        mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_CACHE))
16360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk                .findViewById(R.id.button);
16460a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        mClearCacheButton.setText(R.string.clear_cache_btn_text);
165cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
166cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
167cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
168cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public void onClick(View v) {
169cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (v == mClearCacheButton) {
170cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            // Lazy initialization of observer
171cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mClearCacheObserver == null) {
172cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheObserver = new ClearCacheObserver();
173cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
174cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mPm.deleteApplicationCacheFiles(mPackageName, mClearCacheObserver);
175e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        } else if (v == mClearDataButton) {
176cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mAppEntry.info.manageSpaceActivityName != null) {
177cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                if (!Utils.isMonkeyRunning()) {
178cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    Intent intent = new Intent(Intent.ACTION_DEFAULT);
179cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    intent.setClassName(mAppEntry.info.packageName,
180cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            mAppEntry.info.manageSpaceActivityName);
181cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    startActivityForResult(intent, REQUEST_MANAGE_SPACE);
182cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                }
183cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
184cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                showDialogInner(DLG_CLEAR_DATA, 0);
185cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
186bd45c3cbe0ccb9d5a1ebeabccda1e803d613e729Jason Monk        } else if (v == mChangeStorageButton && mDialogBuilder != null) {
187e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            mDialogBuilder.show();
18860a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        }
18960a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    }
19060a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk
19160a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk    @Override
192e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    public void onClick(DialogInterface dialog, int which) {
1931f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final Context context = getActivity();
1941f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
1951f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        // If not current volume, kick off move wizard
196e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        final VolumeInfo targetVol = mCandidates[which];
197954d8dad5e395544f95ca211466bcc7195d31877Jeff Sharkey        final VolumeInfo currentVol = context.getPackageManager().getPackageCurrentVolume(
1981f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey                mAppEntry.info);
1991f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        if (!Objects.equals(targetVol, currentVol)) {
2001f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            final Intent intent = new Intent(context, StorageWizardMoveConfirm.class);
2011f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, targetVol.getId());
2021f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
2031f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey            startActivity(intent);
204cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
205e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        dialog.dismiss();
206cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
207cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
208cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private String getSizeStr(long size) {
209cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (size == SIZE_INVALID) {
210cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return mInvalidSizeStr.toString();
211cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
212cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return Formatter.formatFileSize(getActivity(), size);
213cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
214cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
215cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void refreshSizeInfo() {
216cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppEntry.size == ApplicationsState.SIZE_INVALID
217cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                || mAppEntry.size == ApplicationsState.SIZE_UNKNOWN) {
218cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mLastCodeSize = mLastDataSize = mLastCacheSize = mLastTotalSize = -1;
219cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (!mHaveSizes) {
220c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mAppSize.setSummary(mComputingStr);
221c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mDataSize.setSummary(mComputingStr);
222c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mCacheSize.setSummary(mComputingStr);
223c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mTotalSize.setSummary(mComputingStr);
224cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
225cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
226cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearCacheButton.setEnabled(false);
227cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
228cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
229cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mHaveSizes = true;
230cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            long codeSize = mAppEntry.codeSize;
231cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            long dataSize = mAppEntry.dataSize;
232cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (Environment.isExternalStorageEmulated()) {
233cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                codeSize += mAppEntry.externalCodeSize;
234cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                dataSize +=  mAppEntry.externalDataSize;
235cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
236cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                if (mLastExternalCodeSize != mAppEntry.externalCodeSize) {
237cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    mLastExternalCodeSize = mAppEntry.externalCodeSize;
238c27f9e179adef2061e0000385f350874a7772c4eJason Monk                    mExternalCodeSize.setSummary(getSizeStr(mAppEntry.externalCodeSize));
239cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                }
240cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                if (mLastExternalDataSize !=  mAppEntry.externalDataSize) {
241cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    mLastExternalDataSize =  mAppEntry.externalDataSize;
242c27f9e179adef2061e0000385f350874a7772c4eJason Monk                    mExternalDataSize.setSummary(getSizeStr( mAppEntry.externalDataSize));
243cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                }
244cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
245cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastCodeSize != codeSize) {
246cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastCodeSize = codeSize;
247c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mAppSize.setSummary(getSizeStr(codeSize));
248cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
249cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastDataSize != dataSize) {
250cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastDataSize = dataSize;
251c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mDataSize.setSummary(getSizeStr(dataSize));
252cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
253cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            long cacheSize = mAppEntry.cacheSize + mAppEntry.externalCacheSize;
254cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastCacheSize != cacheSize) {
255cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastCacheSize = cacheSize;
256c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mCacheSize.setSummary(getSizeStr(cacheSize));
257cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
258cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mLastTotalSize != mAppEntry.size) {
259cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mLastTotalSize = mAppEntry.size;
260c27f9e179adef2061e0000385f350874a7772c4eJason Monk                mTotalSize.setSummary(getSizeStr(mAppEntry.size));
261cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
262cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
263cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if ((mAppEntry.dataSize+ mAppEntry.externalDataSize) <= 0 || !mCanClearData) {
264cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setEnabled(false);
265cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
266cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setEnabled(true);
267cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setOnClickListener(this);
268cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
269cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (cacheSize <= 0) {
270cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheButton.setEnabled(false);
271cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
272cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheButton.setEnabled(true);
273cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearCacheButton.setOnClickListener(this);
274cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
275cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
276cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppControlRestricted) {
277cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearCacheButton.setEnabled(false);
278cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
279cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
280cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
281cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
282cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
283cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    protected boolean refreshUi() {
284cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        retrieveAppEntry();
2859a1c0dce7a496f51087cf0497b931a31c64b0a65Julia Reynolds        if (mAppEntry == null) {
2869a1c0dce7a496f51087cf0497b931a31c64b0a65Julia Reynolds            return false;
2879a1c0dce7a496f51087cf0497b931a31c64b0a65Julia Reynolds        }
288cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        refreshSizeInfo();
2891f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
2901f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final VolumeInfo currentVol = getActivity().getPackageManager()
291954d8dad5e395544f95ca211466bcc7195d31877Jeff Sharkey                .getPackageCurrentVolume(mAppEntry.info);
292e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        final StorageManager storage = getContext().getSystemService(StorageManager.class);
293e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        mStorageUsed.setSummary(storage.getBestVolumeDescription(currentVol));
294e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk
295e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        refreshButtons();
2961f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
297cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return true;
298cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
299cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
300cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void refreshButtons() {
301e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk        initMoveDialog();
3021f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        initDataButtons();
303cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
304cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
305cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void initDataButtons() {
306cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // If the app doesn't have its own space management UI
307cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // And it's a system app that doesn't allow clearing user data or is an active admin
308cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Then disable the Clear Data button.
309cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppEntry.info.manageSpaceActivityName == null
310cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                && ((mAppEntry.info.flags&(ApplicationInfo.FLAG_SYSTEM
311cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        | ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA))
312cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        == ApplicationInfo.FLAG_SYSTEM
313cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        || mDpm.packageHasActiveAdmins(mPackageName))) {
314cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setText(R.string.clear_user_data_text);
315cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
316cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mCanClearData = false;
317cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
318cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (mAppEntry.info.manageSpaceActivityName != null) {
319cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setText(R.string.manage_space_text);
320cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            } else {
321cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                mClearDataButton.setText(R.string.clear_user_data_text);
322cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
323cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setOnClickListener(this);
324cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
325cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
326cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mAppControlRestricted) {
327cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(false);
328cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
329cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
330cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
331e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk    private void initMoveDialog() {
3321f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final Context context = getActivity();
3331f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final StorageManager storage = context.getSystemService(StorageManager.class);
3341f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
3351f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey        final List<VolumeInfo> candidates = context.getPackageManager()
336954d8dad5e395544f95ca211466bcc7195d31877Jeff Sharkey                .getPackageCandidateVolumes(mAppEntry.info);
337c27f9e179adef2061e0000385f350874a7772c4eJason Monk        if (candidates.size() > 1) {
338c27f9e179adef2061e0000385f350874a7772c4eJason Monk            Collections.sort(candidates, VolumeInfo.getDescriptionComparator());
3391f4efd7360dea3038fe2096b1d4bccaae8e2a09fJeff Sharkey
340e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            CharSequence[] labels = new CharSequence[candidates.size()];
341e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            int current = -1;
342e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            for (int i = 0; i < candidates.size(); i++) {
343e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                final String volDescrip = storage.getBestVolumeDescription(candidates.get(i));
344e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                if (Objects.equals(volDescrip, mStorageUsed.getSummary())) {
345e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                    current = i;
346e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                }
347e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                labels[i] = volDescrip;
348c27f9e179adef2061e0000385f350874a7772c4eJason Monk            }
349e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            mCandidates = candidates.toArray(new VolumeInfo[candidates.size()]);
350e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            mDialogBuilder = new AlertDialog.Builder(getContext())
351e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                    .setTitle(R.string.change_storage)
352e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                    .setSingleChoiceItems(labels, current, this)
353e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk                    .setNegativeButton(R.string.cancel, null);
354c27f9e179adef2061e0000385f350874a7772c4eJason Monk        } else {
355e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            removePreference(KEY_STORAGE_USED);
356e8400c2fb78e80979b5190d4abc9685442cdfc25Jason Monk            removePreference(KEY_CHANGE_STORAGE);
357bd45c3cbe0ccb9d5a1ebeabccda1e803d613e729Jason Monk            removePreference(KEY_STORAGE_SPACE);
358cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
359cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
360cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
361cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    /*
362cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * Private method to initiate clearing user data when the user clicks the clear data
363cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * button for a system package
364cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     */
365cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void initiateClearUserData() {
366cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mClearDataButton.setEnabled(false);
367cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        // Invoke uninstall or clear user data based on sysPackage
368cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        String packageName = mAppEntry.info.packageName;
369cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        Log.i(TAG, "Clearing user data for package : " + packageName);
370cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (mClearDataObserver == null) {
371cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataObserver = new ClearUserDataObserver();
372cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
373cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        ActivityManager am = (ActivityManager)
374cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                getActivity().getSystemService(Context.ACTIVITY_SERVICE);
375cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
376cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (!res) {
377cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            // Clearing data failed for some obscure reason. Just log error for now
378cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            Log.i(TAG, "Couldnt clear application user data for package:"+packageName);
379cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
380cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
381cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setText(R.string.recompute_size);
382cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
383cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
384cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
385cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    /*
386cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * Private method to handle clear message notification from observer when
387cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     * the async operation from PackageManager is complete
388cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk     */
389cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private void processClearMsg(Message msg) {
390cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        int result = msg.arg1;
391cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        String packageName = mAppEntry.info.packageName;
392cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        mClearDataButton.setText(R.string.clear_user_data_text);
39360a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk        if (result == OP_SUCCESSFUL) {
394cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            Log.i(TAG, "Cleared user data for package : "+packageName);
39507025891683aef83d850b0a91b37aa75b11ce33cJason Monk            mState.requestSize(mPackageName, mUserId);
396cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
397cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mClearDataButton.setEnabled(true);
398cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
399cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
400cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
401cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
402cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    protected AlertDialog createDialog(int id, int errorCode) {
403cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        switch (id) {
404cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            case DLG_CLEAR_DATA:
405cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                return new AlertDialog.Builder(getActivity())
406cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setTitle(getActivity().getText(R.string.clear_data_dlg_title))
407cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setMessage(getActivity().getText(R.string.clear_data_dlg_text))
408cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
409cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            public void onClick(DialogInterface dialog, int which) {
410cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                // Clear user data here
411cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                initiateClearUserData();
412cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            }
413cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        })
414cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setNegativeButton(R.string.dlg_cancel, null)
415cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .create();
416cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            case DLG_CANNOT_CLEAR_DATA:
417cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                return new AlertDialog.Builder(getActivity())
418cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setTitle(getActivity().getText(R.string.clear_failed_dlg_title))
419cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setMessage(getActivity().getText(R.string.clear_failed_dlg_text))
420cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .setNeutralButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
421cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            public void onClick(DialogInterface dialog, int which) {
422cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                mClearDataButton.setEnabled(false);
423cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                //force to recompute changed value
424cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                                setIntentAndFinish(false, false);
425cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                            }
426cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        })
427cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                        .create();
428cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
429cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return null;
430cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
431cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
432cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    @Override
433cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public void onPackageSizeChanged(String packageName) {
434cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (packageName.equals(mAppEntry.info.packageName)) {
435cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            refreshSizeInfo();
436cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
437cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
438cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
439cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private final Handler mHandler = new Handler() {
440cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        public void handleMessage(Message msg) {
441cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            if (getView() == null) {
442cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                return;
443cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
444cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            switch (msg.what) {
445cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                case MSG_CLEAR_USER_DATA:
446cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    processClearMsg(msg);
447cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    break;
448cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                case MSG_CLEAR_CACHE:
449cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    // Refresh size info
45007025891683aef83d850b0a91b37aa75b11ce33cJason Monk                    mState.requestSize(mPackageName, mUserId);
451cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    break;
452cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            }
453cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
454cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    };
455cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
456cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    public static CharSequence getSummary(AppEntry appEntry, Context context) {
457cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (appEntry.size == ApplicationsState.SIZE_INVALID
458cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                || appEntry.size == ApplicationsState.SIZE_UNKNOWN) {
459cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return context.getText(R.string.computing_size);
460cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        } else {
461cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            CharSequence storageType = context.getString(
462cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    (appEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0
463cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    ? R.string.storage_type_external
464cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    : R.string.storage_type_internal);
465cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return context.getString(R.string.storage_summary_format,
466cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk                    getSize(appEntry, context), storageType);
467cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
468cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
469cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
470cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    private static CharSequence getSize(AppEntry appEntry, Context context) {
471cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        long size = appEntry.size;
472cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        if (size == SIZE_INVALID) {
473cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            return context.getText(R.string.invalid_size_value);
474cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
475cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        return Formatter.formatFileSize(context, size);
476cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
477cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
4788a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    @Override
4798a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    protected int getMetricsCategory() {
4808a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren        return MetricsLogger.APPLICATIONS_APP_STORAGE;
4818a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    }
4828a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren
483cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    class ClearCacheObserver extends IPackageDataObserver.Stub {
484cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
485cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            final Message msg = mHandler.obtainMessage(MSG_CLEAR_CACHE);
486cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED;
487cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk            mHandler.sendMessage(msg);
488cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
489cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
490cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk
491cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    class ClearUserDataObserver extends IPackageDataObserver.Stub {
492cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk       public void onRemoveCompleted(final String packageName, final boolean succeeded) {
493cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk           final Message msg = mHandler.obtainMessage(MSG_CLEAR_USER_DATA);
49460a09ea2388db01a661beeb9995a7ecf770a4200Jason Monk           msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED;
495cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk           mHandler.sendMessage(msg);
496cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk        }
497cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk    }
498cd91128a2de5d111c59fe442c72b764d9a9acb3aJason Monk}
499