1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License.
6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at
7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and
14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License.
15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings.deviceinfo;
18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1929d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapuimport android.app.AlertDialog;
2029d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapuimport android.app.Dialog;
210e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkeyimport android.app.DialogFragment;
22c778bc560dea3e3112a60f373bc62a35a67c8d4aAmith Yamasaniimport android.content.ActivityNotFoundException;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.BroadcastReceiver;
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
2529d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapuimport android.content.DialogInterface;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.IntentFilter;
280e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkeyimport android.content.pm.IPackageDataObserver;
290e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkeyimport android.content.pm.PackageInfo;
300e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkeyimport android.content.pm.PackageManager;
318218d3ba180505a52998caa1fd9f6a1647984e7fLi Gangimport android.hardware.usb.UsbManager;
32511c8cf103193fb41c915941b1b1d2a442a1ae12Kenny Rootimport android.os.Bundle;
33d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.os.Environment;
34afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.IBinder;
35afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.RemoteException;
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.ServiceManager;
376ad2e323f7733f39c6757a19a9ae9f5020cf9225Maggie Benthallimport android.os.UserManager;
38d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.os.storage.IMountService;
391e60c9603e02f95158d21b4a2089dc45dffb41c1San Mehatimport android.os.storage.StorageEventListener;
40d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.os.storage.StorageManager;
41104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunneimport android.os.storage.StorageVolume;
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.Preference;
43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.PreferenceScreen;
44afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log;
4502900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwoodimport android.view.Menu;
4602900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwoodimport android.view.MenuInflater;
4702900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwoodimport android.view.MenuItem;
4829d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapuimport android.widget.Toast;
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
50104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunneimport com.android.settings.R;
51263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglioimport com.android.settings.SettingsActivity;
52104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunneimport com.android.settings.SettingsPreferenceFragment;
533fd8051a89c5fbcd52b83566a05f0edb919414a5Amith Yamasaniimport com.android.settings.Utils;
5445f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglioimport com.android.settings.search.BaseSearchIndexProvider;
55f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglioimport com.android.settings.search.Indexable;
56f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglioimport com.android.settings.search.SearchIndexableRaw;
57e6c5003278184c202833209164ddf1ae8c083f12Jeff Sharkeyimport com.google.android.collect.Lists;
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
5996c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkeyimport java.util.ArrayList;
600e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkeyimport java.util.List;
6196c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey
6296c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey/**
6396c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey * Panel showing storage usage on disk for known {@link StorageVolume} returned
6496c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey * by {@link StorageManager}. Calculates and displays usage of data types.
6596c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey */
669a60d7b5697873a41810fe87a89e60824e3548daFabrice Di Megliopublic class Memory extends SettingsPreferenceFragment implements Indexable {
6721809740f2fd8fe8df4e300e5d1d15f0ccedbb5fVasu Nori    private static final String TAG = "MemorySettings";
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
690e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    private static final String TAG_CONFIRM_CLEAR_CACHE = "confirmClearCache";
700e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
7129d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    private static final int DLG_CONFIRM_UNMOUNT = 1;
7229d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    private static final int DLG_ERROR_UNMOUNT = 2;
7329d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu
748f1bd8a7526edf49196430be214acb54e66a63eeGilles Debunne    // The mountToggle Preference that has last been clicked.
758f1bd8a7526edf49196430be214acb54e66a63eeGilles Debunne    // Assumes no two successive unmount event on 2 different volumes are performed before the first
768f1bd8a7526edf49196430be214acb54e66a63eeGilles Debunne    // one's preference is disabled
7796c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey    private static Preference sLastClickedMountToggle;
7896c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey    private static String sClickedMountPoint;
792a32192329ac47da1e64f7085f4317212e99a3bfBen Komalo
80afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Access using getMountService()
81da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey    private IMountService mMountService;
82da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey    private StorageManager mStorageManager;
83da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey    private UsbManager mUsbManager;
848218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang
8596c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey    private ArrayList<StorageVolumePreferenceCategory> mCategories = Lists.newArrayList();
86511c8cf103193fb41c915941b1b1d2a442a1ae12Kenny Root
87afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
88d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onCreate(Bundle icicle) {
89afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onCreate(icicle);
904a3d713f3aa1cb3b43343dd8af95ee858c8c6d8bSan Mehat
91da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey        final Context context = getActivity();
928218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang
93da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
94da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey
95da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey        mStorageManager = StorageManager.from(context);
96da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey        mStorageManager.registerListener(mStorageListener);
974a3d713f3aa1cb3b43343dd8af95ee858c8c6d8bSan Mehat
98afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        addPreferencesFromResource(R.xml.device_info_memory);
99511c8cf103193fb41c915941b1b1d2a442a1ae12Kenny Root
100da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey        addCategory(StorageVolumePreferenceCategory.buildForInternal(context));
101bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn
10296c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        final StorageVolume[] storageVolumes = mStorageManager.getVolumeList();
10396c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        for (StorageVolume volume : storageVolumes) {
104da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey            if (!volume.isEmulated()) {
105da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey                addCategory(StorageVolumePreferenceCategory.buildForPhysical(context, volume));
106da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey            }
10721809740f2fd8fe8df4e300e5d1d15f0ccedbb5fVasu Nori        }
10802900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood
10911d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey        setHasOptionsMenu(true);
11011d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey    }
11111d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey
112da13ec0cb454f1aadada2acf12291cfaf0a7b176Jeff Sharkey    private void addCategory(StorageVolumePreferenceCategory category) {
11396c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        mCategories.add(category);
11496c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        getPreferenceScreen().addPreference(category);
11596c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        category.init();
11696c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey    }
11796c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey
11811d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey    private boolean isMassStorageEnabled() {
119fc76a78c458ac90d7e050ffc233cf9e32a2d9c0bJeff Sharkey        // Mass storage is enabled if primary volume supports it
120fc76a78c458ac90d7e050ffc233cf9e32a2d9c0bJeff Sharkey        final StorageVolume[] volumes = mStorageManager.getVolumeList();
121fc76a78c458ac90d7e050ffc233cf9e32a2d9c0bJeff Sharkey        final StorageVolume primary = StorageManager.getPrimaryVolume(volumes);
122fc76a78c458ac90d7e050ffc233cf9e32a2d9c0bJeff Sharkey        return primary != null && primary.allowMassStorage();
123340e85d1d029ddd96b368da27a8e36bc41da19a7Vasu Nori    }
124340e85d1d029ddd96b368da27a8e36bc41da19a7Vasu Nori
125afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
126d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onResume() {
127afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onResume();
1284a3d713f3aa1cb3b43343dd8af95ee858c8c6d8bSan Mehat        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
129afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
130afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        intentFilter.addDataScheme("file");
131104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        getActivity().registerReceiver(mMediaScannerReceiver, intentFilter);
132afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1338218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang        intentFilter = new IntentFilter();
1348218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang        intentFilter.addAction(UsbManager.ACTION_USB_STATE);
1358218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang        getActivity().registerReceiver(mMediaScannerReceiver, intentFilter);
1368218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang
13796c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        for (StorageVolumePreferenceCategory category : mCategories) {
13896c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            category.onResume();
139511c8cf103193fb41c915941b1b1d2a442a1ae12Kenny Root        }
140afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1414a3d713f3aa1cb3b43343dd8af95ee858c8c6d8bSan Mehat
1424a3d713f3aa1cb3b43343dd8af95ee858c8c6d8bSan Mehat    StorageEventListener mStorageListener = new StorageEventListener() {
143a2175d1df2d0c6efd49c124be4d04eb962a28c5aSan Mehat        @Override
144a2175d1df2d0c6efd49c124be4d04eb962a28c5aSan Mehat        public void onStorageStateChanged(String path, String oldState, String newState) {
145b7609ff9990e583d62c9af0080d741884a9c5a06Gilles Debunne            Log.i(TAG, "Received storage state changed notification that " + path +
146b7609ff9990e583d62c9af0080d741884a9c5a06Gilles Debunne                    " changed state from " + oldState + " to " + newState);
14796c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            for (StorageVolumePreferenceCategory category : mCategories) {
14896c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                final StorageVolume volume = category.getStorageVolume();
14996c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                if (volume != null && path.equals(volume.getPath())) {
15096c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                    category.onStorageStateChanged();
151104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                    break;
152104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                }
153e4330890d6996bd1ad65bc6c5ab1dfb39f224ea4Kenny Root            }
1544a3d713f3aa1cb3b43343dd8af95ee858c8c6d8bSan Mehat        }
1554a3d713f3aa1cb3b43343dd8af95ee858c8c6d8bSan Mehat    };
156511c8cf103193fb41c915941b1b1d2a442a1ae12Kenny Root
157afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
158d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onPause() {
159afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onPause();
160104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        getActivity().unregisterReceiver(mMediaScannerReceiver);
16196c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        for (StorageVolumePreferenceCategory category : mCategories) {
16296c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            category.onPause();
163104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        }
164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
16529d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu
16629d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    @Override
167d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onDestroy() {
16829d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        if (mStorageManager != null && mStorageListener != null) {
16929d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            mStorageManager.unregisterListener(mStorageListener);
17029d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        }
17129d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        super.onDestroy();
17229d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    }
17329d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu
17402900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood    @Override
17502900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
17611d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey        inflater.inflate(R.menu.storage, menu);
17711d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey    }
17811d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey
17911d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey    @Override
18011d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey    public void onPrepareOptionsMenu(Menu menu) {
18111d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey        final MenuItem usb = menu.findItem(R.id.storage_usb);
1826ad2e323f7733f39c6757a19a9ae9f5020cf9225Maggie Benthall        UserManager um = (UserManager)getActivity().getSystemService(Context.USER_SERVICE);
1836ad2e323f7733f39c6757a19a9ae9f5020cf9225Maggie Benthall        boolean usbItemVisible = !isMassStorageEnabled()
1846ad2e323f7733f39c6757a19a9ae9f5020cf9225Maggie Benthall                && !um.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
1856ad2e323f7733f39c6757a19a9ae9f5020cf9225Maggie Benthall        usb.setVisible(usbItemVisible);
18602900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood    }
18702900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood
18802900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood    @Override
18902900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood    public boolean onOptionsItemSelected(MenuItem item) {
19002900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood        switch (item.getItemId()) {
19111d3012c78fcd23d2dfc7830e03db191af7ba476Jeff Sharkey            case R.id.storage_usb:
192263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio                if (getActivity() instanceof SettingsActivity) {
193263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio                    ((SettingsActivity) getActivity()).startPreferencePanel(
19402900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood                            UsbSettings.class.getCanonicalName(),
1955bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio                            null, R.string.storage_title_usb, null, this, 0);
19602900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood                } else {
1975bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio                    startFragment(this, UsbSettings.class.getCanonicalName(),
1985bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio                            R.string.storage_title_usb, -1, null);
19902900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood                }
20002900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood                return true;
20102900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood        }
20202900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood        return super.onOptionsItemSelected(item);
20302900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood    }
20402900a12b11efc89057fc5d0a19c08d20ff8d2c1Mike Lockwood
205afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private synchronized IMountService getMountService() {
206afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project       if (mMountService == null) {
207afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           IBinder service = ServiceManager.getService("mount");
208afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           if (service != null) {
209afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project               mMountService = IMountService.Stub.asInterface(service);
210afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           } else {
211afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project               Log.e(TAG, "Can't get mount service");
212afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           }
213afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project       }
214afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project       return mMountService;
215afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
2162a32192329ac47da1e64f7085f4317212e99a3bfBen Komalo
217afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
218afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
2190e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        if (StorageVolumePreferenceCategory.KEY_CACHE.equals(preference.getKey())) {
2200e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            ConfirmClearCacheFragment.show(this);
2210e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            return true;
2220e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        }
2230e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
22496c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        for (StorageVolumePreferenceCategory category : mCategories) {
22596c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            Intent intent = category.intentForClick(preference);
226104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne            if (intent != null) {
2273fd8051a89c5fbcd52b83566a05f0edb919414a5Amith Yamasani                // Don't go across app boundary if monkey is running
2283fd8051a89c5fbcd52b83566a05f0edb919414a5Amith Yamasani                if (!Utils.isMonkeyRunning()) {
229c778bc560dea3e3112a60f373bc62a35a67c8d4aAmith Yamasani                    try {
230c778bc560dea3e3112a60f373bc62a35a67c8d4aAmith Yamasani                        startActivity(intent);
231c778bc560dea3e3112a60f373bc62a35a67c8d4aAmith Yamasani                    } catch (ActivityNotFoundException anfe) {
232c778bc560dea3e3112a60f373bc62a35a67c8d4aAmith Yamasani                        Log.w(TAG, "No activity found for intent " + intent);
233c778bc560dea3e3112a60f373bc62a35a67c8d4aAmith Yamasani                    }
2343fd8051a89c5fbcd52b83566a05f0edb919414a5Amith Yamasani                }
235104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                return true;
23635351faed3589813524f8951ab46c36cef9b505dSan Mehat            }
237104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne
23896c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            final StorageVolume volume = category.getStorageVolume();
23996c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            if (volume != null && category.mountToggleClicked(preference)) {
24096c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                sLastClickedMountToggle = preference;
24196c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                sClickedMountPoint = volume.getPath();
24296c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                String state = mStorageManager.getVolumeState(volume.getPath());
2436d36fd3a03299b9b1bdaaceef2bfaa8714c3fa72Gilles Debunne                if (Environment.MEDIA_MOUNTED.equals(state) ||
2446d36fd3a03299b9b1bdaaceef2bfaa8714c3fa72Gilles Debunne                        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
245104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                    unmount();
246104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                } else {
247104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                    mount();
248104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                }
249104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                return true;
25021809740f2fd8fe8df4e300e5d1d15f0ccedbb5fVasu Nori            }
251afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
2523d713b162ee13f49b2cbe95beafbabb109f859ffMike Lockwood
253afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
2552a32192329ac47da1e64f7085f4317212e99a3bfBen Komalo
256104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne    private final BroadcastReceiver mMediaScannerReceiver = new BroadcastReceiver() {
257afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        @Override
258afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void onReceive(Context context, Intent intent) {
2598218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang            String action = intent.getAction();
2608218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang            if (action.equals(UsbManager.ACTION_USB_STATE)) {
2618218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang               boolean isUsbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
2628218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang               String usbFunction = mUsbManager.getDefaultFunction();
26396c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey               for (StorageVolumePreferenceCategory category : mCategories) {
26496c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                   category.onUsbStateChanged(isUsbConnected, usbFunction);
2658218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang               }
2668218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
26796c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                for (StorageVolumePreferenceCategory category : mCategories) {
26896c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                    category.onMediaScannerFinished();
2698218d3ba180505a52998caa1fd9f6a1647984e7fLi Gang                }
270e4330890d6996bd1ad65bc6c5ab1dfb39f224ea4Kenny Root            }
271afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
272afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    };
273afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
27429d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    @Override
275d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public Dialog onCreateDialog(int id) {
27629d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        switch (id) {
27729d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        case DLG_CONFIRM_UNMOUNT:
278d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani                return new AlertDialog.Builder(getActivity())
27929d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu                    .setTitle(R.string.dlg_confirm_unmount_title)
28029d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu                    .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
28129d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu                        public void onClick(DialogInterface dialog, int which) {
282104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne                            doUnmount();
28329d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu                        }})
28429d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu                    .setNegativeButton(R.string.cancel, null)
28529d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu                    .setMessage(R.string.dlg_confirm_unmount_text)
28629d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu                    .create();
28729d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        case DLG_ERROR_UNMOUNT:
288d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani                return new AlertDialog.Builder(getActivity())
28929d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            .setTitle(R.string.dlg_error_unmount_title)
29029d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            .setNeutralButton(R.string.dlg_ok, null)
29129d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            .setMessage(R.string.dlg_error_unmount_text)
29229d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            .create();
29329d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        }
29429d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        return null;
29529d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    }
29629d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu
297104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne    private void doUnmount() {
29829d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        // Present a toast here
299d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        Toast.makeText(getActivity(), R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
30029d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        IMountService mountService = getMountService();
30129d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        try {
30296c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            sLastClickedMountToggle.setEnabled(false);
30396c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            sLastClickedMountToggle.setTitle(getString(R.string.sd_ejecting_title));
30496c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            sLastClickedMountToggle.setSummary(getString(R.string.sd_ejecting_summary));
30596c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey            mountService.unmountVolume(sClickedMountPoint, true, false);
30629d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        } catch (RemoteException e) {
307104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne            // Informative dialog to user that unmount failed.
30829d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            showDialogInner(DLG_ERROR_UNMOUNT);
30929d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        }
31029d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    }
31129d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu
31229d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    private void showDialogInner(int id) {
31329d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        removeDialog(id);
31429d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        showDialog(id);
31529d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu    }
31629d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu
3176f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu    private boolean hasAppsAccessingStorage() throws RemoteException {
318afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        IMountService mountService = getMountService();
31996c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey        int stUsers[] = mountService.getStorageUsers(sClickedMountPoint);
3206f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu        if (stUsers != null && stUsers.length > 0) {
3216f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu            return true;
3226f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu        }
323104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        // TODO FIXME Parameterize with mountPoint and uncomment.
324104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        // On HC-MR2, no apps can be installed on sd and the emulated internal storage is not
325104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        // removable: application cannot interfere with unmount
326104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        /*
3276f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
3283d503e356f2a4ca6b5baaceec9ea0f04cf038609Suchi Amalapurapu        List<ApplicationInfo> list = am.getRunningExternalApplications();
3293d503e356f2a4ca6b5baaceec9ea0f04cf038609Suchi Amalapurapu        if (list != null && list.size() > 0) {
3303d503e356f2a4ca6b5baaceec9ea0f04cf038609Suchi Amalapurapu            return true;
3316f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu        }
332104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne        */
33399da1a22a35eed631a757ccbf1bac1d7af74124dGilles Debunne        // Better safe than sorry. Assume the storage is used to ask for confirmation.
33499da1a22a35eed631a757ccbf1bac1d7af74124dGilles Debunne        return true;
3356f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu    }
3366f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu
3376f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu    private void unmount() {
3386f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu        // Check if external media is in use.
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        try {
3406f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu           if (hasAppsAccessingStorage()) {
3416f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu               // Present dialog to user
3426f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu               showDialogInner(DLG_CONFIRM_UNMOUNT);
3436f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu           } else {
344104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne               doUnmount();
3456f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu           }
34629d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        } catch (RemoteException e) {
34729d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            // Very unlikely. But present an error dialog anyway
34829d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            Log.e(TAG, "Is MountService running?");
34929d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu            showDialogInner(DLG_ERROR_UNMOUNT);
35029d587fa1826d9f3411b650b4da030650ac686e0Suchi Amalapurapu        }
3516f58b1b426b8c466881ad038f40b57e2f8dcca9dSuchi Amalapurapu    }
352afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
35335351faed3589813524f8951ab46c36cef9b505dSan Mehat    private void mount() {
35435351faed3589813524f8951ab46c36cef9b505dSan Mehat        IMountService mountService = getMountService();
35535351faed3589813524f8951ab46c36cef9b505dSan Mehat        try {
35635351faed3589813524f8951ab46c36cef9b505dSan Mehat            if (mountService != null) {
35796c2f8c50865e823e710be4d92f1589f978f03c2Jeff Sharkey                mountService.mountVolume(sClickedMountPoint);
35835351faed3589813524f8951ab46c36cef9b505dSan Mehat            } else {
35935351faed3589813524f8951ab46c36cef9b505dSan Mehat                Log.e(TAG, "Mount service is null, can't mount");
36035351faed3589813524f8951ab46c36cef9b505dSan Mehat            }
36135351faed3589813524f8951ab46c36cef9b505dSan Mehat        } catch (RemoteException ex) {
362104ea2873dff5fa3a5f6bd4cfdb893bac3527fdfGilles Debunne            // Not much can be done
36335351faed3589813524f8951ab46c36cef9b505dSan Mehat        }
364e4330890d6996bd1ad65bc6c5ab1dfb39f224ea4Kenny Root    }
3650e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
3660e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    private void onCacheCleared() {
3670e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        for (StorageVolumePreferenceCategory category : mCategories) {
3680e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            category.onCacheCleared();
3690e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        }
3700e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    }
3710e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
3720e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    private static class ClearCacheObserver extends IPackageDataObserver.Stub {
3730e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        private final Memory mTarget;
3740e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        private int mRemaining;
3750e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
3760e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        public ClearCacheObserver(Memory target, int remaining) {
3770e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            mTarget = target;
3780e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            mRemaining = remaining;
3790e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        }
3800e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
3810e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        @Override
3820e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
3830e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            synchronized (this) {
3840e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                if (--mRemaining == 0) {
3850e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                    mTarget.onCacheCleared();
3860e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                }
3870e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            }
3880e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        }
3890e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    }
3900e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
3910e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    /**
3920e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey     * Dialog to request user confirmation before clearing all cache data.
3930e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey     */
3940e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    public static class ConfirmClearCacheFragment extends DialogFragment {
3950e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        public static void show(Memory parent) {
3960e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            if (!parent.isAdded()) return;
3970e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
3980e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            final ConfirmClearCacheFragment dialog = new ConfirmClearCacheFragment();
3990e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            dialog.setTargetFragment(parent, 0);
4000e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_CLEAR_CACHE);
4010e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        }
4020e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
4030e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        @Override
4040e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        public Dialog onCreateDialog(Bundle savedInstanceState) {
4050e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            final Context context = getActivity();
4060e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
4070e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
4080e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            builder.setTitle(R.string.memory_clear_cache_title);
4090e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            builder.setMessage(getString(R.string.memory_clear_cache_message));
4100e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
4110e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
4120e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                @Override
4130e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                public void onClick(DialogInterface dialog, int which) {
4140e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                    final Memory target = (Memory) getTargetFragment();
4150e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                    final PackageManager pm = context.getPackageManager();
4160e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                    final List<PackageInfo> infos = pm.getInstalledPackages(0);
4170e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                    final ClearCacheObserver observer = new ClearCacheObserver(
4180e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                            target, infos.size());
4190e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                    for (PackageInfo info : infos) {
4200e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                        pm.deleteApplicationCacheFiles(info.packageName, observer);
4210e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                    }
4220e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey                }
4230e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            });
4240e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            builder.setNegativeButton(android.R.string.cancel, null);
4250e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey
4260e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey            return builder.create();
4270e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey        }
4280e9cf8a723c3e03207e905e8e03303ec4b5526dcJeff Sharkey    }
429f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
430f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio    /**
431f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio     * Enable indexing of searchable data
432f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio     */
433f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
43445f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio        new BaseSearchIndexProvider() {
435f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio            @Override
436f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio            public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
437f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
438f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
439f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                SearchIndexableRaw data = new SearchIndexableRaw(context);
440f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.storage_settings);
441f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
442f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
443f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
444f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
445f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.internal_storage);
446f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
447f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
448f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
449f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
450f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                final StorageVolume[] storageVolumes = StorageManager.from(context).getVolumeList();
451f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                for (StorageVolume volume : storageVolumes) {
452f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                    if (!volume.isEmulated()) {
453f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                        data.title = volume.getDescription(context);
454f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                        data.screenTitle = context.getString(R.string.storage_settings);
455f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                        result.add(data);
456f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                    }
457f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                }
458f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
459f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
460f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_size);
461f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
462f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
463f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
464f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
465f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_available);
466f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
467f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
468f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
469f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
470f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_apps_usage);
471f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
472f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
473f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
474f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
475f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_dcim_usage);
476f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
477f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
478f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
479f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
480f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_music_usage);
481f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
482f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
483f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
484f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
485f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_downloads_usage);
486f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
487f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
488f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
489f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
490f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_media_cache_usage);
491f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
492f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
493f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
494f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data = new SearchIndexableRaw(context);
495f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.title = context.getString(R.string.memory_media_misc_usage);
496f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                data.screenTitle = context.getString(R.string.storage_settings);
497f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                result.add(data);
498f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
499f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio                return result;
500f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio            }
501f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio        };
502f66eb7a8c8aa65c704dad4e565ce919ec121705fFabrice Di Meglio
503afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
504