DeletionHelperSettings.java revision 2a508e16fa21573aa2fcb2f985136566b8301f35
109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi/* 209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * Copyright (C) 2016 The Android Open Source Project 309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * 409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * Licensed under the Apache License, Version 2.0 (the "License"); 509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * you may not use this file except in compliance with the License. 609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * You may obtain a copy of the License at 709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * 809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * http://www.apache.org/licenses/LICENSE-2.0 909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * 1009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * Unless required by applicable law or agreed to in writing, software 1109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * distributed under the License is distributed on an "AS IS" BASIS, 1209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * See the License for the specific language governing permissions and 1409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * limitations under the License. 1509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi */ 1609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 1709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishipackage com.android.storagemanager.deletionhelper; 1809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 1909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.Manifest; 2009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.app.Activity; 2109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.content.pm.PackageManager; 2209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.os.Bundle; 2309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.support.v14.preference.PreferenceFragment; 2409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.text.format.Formatter; 2509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.view.View; 2609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport android.widget.Button; 272ace931586ac5ee3d0633c051bc276690975f3eaDaniel Nishiimport com.android.internal.logging.MetricsLogger; 282ace931586ac5ee3d0633c051bc276690975f3eaDaniel Nishiimport com.android.internal.logging.MetricsProto.MetricsEvent; 2909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport com.android.storagemanager.ButtonBarProvider; 3009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport com.android.storagemanager.R; 3109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 32b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishiimport com.android.storagemanager.overlay.FeatureFactory; 33b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishiimport com.android.storagemanager.overlay.DeletionHelperFeatureProvider; 34b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi 3509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishiimport java.util.HashSet; 3609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 3709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi/** 3809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * Settings screen for the deletion helper, which manually removes data which is not recently used. 3909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi */ 4009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishipublic class DeletionHelperSettings extends PreferenceFragment implements 4109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi DeletionType.FreeableChangedListener, 4209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi View.OnClickListener { 4309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private static final String APPS_KEY = "apps_group"; 4409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private static final String KEY_DOWNLOADS_PREFERENCE = "delete_downloads"; 45b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi private static final String KEY_PHOTOS_VIDEOS_PREFERENCE = "delete_photos"; 4609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private static final int DOWNLOADS_LOADER_ID = 1; 4709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 4809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private AppDeletionPreferenceGroup mApps; 4909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private AppDeletionType mAppBackend; 5009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private DownloadsDeletionPreferenceGroup mDownloadsPreference; 5109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private DownloadsDeletionType mDownloadsDeletion; 52b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi private PhotosDeletionPreference mPhotoPreference; 53b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi private DeletionType mPhotoVideoDeletion; 5409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private Button mCancel, mFree; 55b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi private DeletionHelperFeatureProvider mProvider; 5609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 5709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public static DeletionHelperSettings newInstance() { 5809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi return new DeletionHelperSettings(); 5909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 6009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 6109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 6209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 6309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi addPreferencesFromResource(R.xml.deletion_helper_list); 6409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mApps = (AppDeletionPreferenceGroup) findPreference(APPS_KEY); 6509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 6609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi HashSet<String> checkedApplications = null; 6709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi if (savedInstanceState != null) { 6809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi checkedApplications = 6909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi (HashSet<String>) savedInstanceState.getSerializable( 7009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi AppDeletionType.EXTRA_CHECKED_SET); 7109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 7209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mAppBackend = new AppDeletionType(getActivity().getApplication(), checkedApplications); 7309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mAppBackend.registerView(mApps); 7409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mAppBackend.registerFreeableChangedListener(this); 7509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mApps.setDeletionType(mAppBackend); 76b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi 77b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoPreference = (PhotosDeletionPreference) findPreference(KEY_PHOTOS_VIDEOS_PREFERENCE); 78b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mProvider = FeatureFactory.getFactory(getActivity()).getDeletionHelperFeatureProvider(); 79b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi if (mProvider != null) { 80b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoVideoDeletion = mProvider.createPhotoVideoDeletionType(getContext()); 81b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi } 8209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 8309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 8409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 8509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onActivityCreated(Bundle savedInstanceState) { 8609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi super.onActivityCreated(savedInstanceState); 8709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi initializeButtons(); 8809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 8909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi Activity activity = getActivity(); 9009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi if (activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) 9109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi != PackageManager.PERMISSION_GRANTED) { 9209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi activity.requestPermissions( 9309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 9409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 0); 9509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 96b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi 971741bb654cca0989ff33df02536041adc0873405Daniel Nishi if (mProvider == null || mPhotoVideoDeletion == null) { 98b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi getPreferenceScreen().removePreference(mPhotoPreference); 99b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoPreference = null; 100b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi } else { 101b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoPreference.registerFreeableChangedListener(this); 102b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoPreference.registerDeletionService(mPhotoVideoDeletion); 103b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi } 10409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsPreference = 10509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi (DownloadsDeletionPreferenceGroup) findPreference(KEY_DOWNLOADS_PREFERENCE); 10609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsDeletion = new DownloadsDeletionType(getActivity()); 10709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsPreference.registerFreeableChangedListener(this); 10809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsPreference.registerDeletionService(mDownloadsDeletion); 10909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi updateFreeButtonText(); 11009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 11109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 11209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 11309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onResume() { 11409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi super.onResume(); 11509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mAppBackend.onResume(); 11609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsDeletion.onResume(); 11709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 11809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi if (getActivity().checkSelfPermission( 11909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 12009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi getLoaderManager().initLoader(DOWNLOADS_LOADER_ID, new Bundle(), mDownloadsDeletion); 12109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 122b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi 123b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi if (mPhotoVideoDeletion != null) { 124b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoVideoDeletion.onResume(); 125b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi } 12609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 12709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 12809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 12909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 13009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onPause() { 13109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi super.onPause(); 13209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mAppBackend.onPause(); 13309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsDeletion.onPause(); 134b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi 135b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi if (mPhotoVideoDeletion != null) { 136b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoVideoDeletion.onPause(); 137b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi } 13809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 13909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 14009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 14109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onSaveInstanceState(Bundle outState) { 14209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi super.onSaveInstanceState(outState); 14309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mAppBackend.onSaveInstanceStateBundle(outState); 14409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 14509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 14609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 14709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onFreeableChanged(int numItems, long bytesFreeable) { 1482a508e16fa21573aa2fcb2f985136566b8301f35Daniel Nishi // bytesFreeable is the number of bytes freed by a single deletion type. If it is non-zero, 1492a508e16fa21573aa2fcb2f985136566b8301f35Daniel Nishi // there is stuff to free and we can enable it. If it is zero, though, we still need to get 1502a508e16fa21573aa2fcb2f985136566b8301f35Daniel Nishi // getTotalFreeableSpace to check all deletion types. 1512a508e16fa21573aa2fcb2f985136566b8301f35Daniel Nishi mFree.setEnabled(bytesFreeable != 0 || getTotalFreeableSpace() != 0); 15209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi updateFreeButtonText(); 15309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 15409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 15509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi /** 15609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi * Clears out the selected apps and data from the device and closes the fragment. 15709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi */ 15809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi protected void clearData() { 159b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi // This should be fine as long as there is only one extra deletion feature. 160b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi // In the future, this should be done in an async queue in order to not 161b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi // interfere with the simultaneous PackageDeletionTask. 162b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi if (mPhotoPreference != null && mPhotoPreference.isChecked()) { 163b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi mPhotoVideoDeletion.clearFreeableData(getActivity()); 164b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi } 16509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsDeletion.clearFreeableData(getActivity()); 16609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mAppBackend.clearFreeableData(getActivity()); 16709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 16809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 16909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 17009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onClick(View v) { 171aff68018da784efc08b532597c2691465546957bDaniel Nishi if (v.getId() == R.id.next_button) { 17209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi ConfirmDeletionDialog dialog = 17309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi ConfirmDeletionDialog.newInstance(getTotalFreeableSpace()); 17409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi // The 0 is a placeholder for an optional result code. 17509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi dialog.setTargetFragment(this, 0); 17609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi dialog.show(getFragmentManager(), ConfirmDeletionDialog.TAG); 1772ace931586ac5ee3d0633c051bc276690975f3eaDaniel Nishi MetricsLogger.action(getContext(), MetricsEvent.ACTION_DELETION_HELPER_CLEAR); 17809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } else { 1792ace931586ac5ee3d0633c051bc276690975f3eaDaniel Nishi MetricsLogger.action(getContext(), MetricsEvent.ACTION_DELETION_HELPER_CANCEL); 180aff68018da784efc08b532597c2691465546957bDaniel Nishi getActivity().finish(); 18109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 18209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 18309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 18409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi @Override 18509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi public void onRequestPermissionsResult(int requestCode, String permissions[], 18609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi int[] grantResults) { 18709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi if (requestCode == 0) { 18809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 18909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsDeletion.onResume(); 19009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi getLoaderManager().initLoader(DOWNLOADS_LOADER_ID, new Bundle(), 19109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mDownloadsDeletion); 19209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 19309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 19409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 19509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 19609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private void initializeButtons() { 19709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi ButtonBarProvider activity = (ButtonBarProvider) getActivity(); 19809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi activity.getButtonBar().setVisibility(View.VISIBLE); 19909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 20009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mCancel = activity.getSkipButton(); 20109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mCancel.setText(R.string.cancel); 20209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mCancel.setOnClickListener(this); 20309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mCancel.setVisibility(View.VISIBLE); 20409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 20509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mFree = activity.getNextButton(); 20609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mFree.setText(R.string.storage_menu_free); 20709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mFree.setOnClickListener(this); 2082a508e16fa21573aa2fcb2f985136566b8301f35Daniel Nishi mFree.setEnabled(false); 20909fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 21009fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 21109fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private void updateFreeButtonText() { 21209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi mFree.setText(String.format(getActivity().getString(R.string.deletion_helper_free_button), 21309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi Formatter.formatFileSize(getActivity(), getTotalFreeableSpace()))); 21409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 21509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi 21609fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi private long getTotalFreeableSpace() { 21709fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi long freeableSpace = 0; 21809fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi freeableSpace += mAppBackend.getTotalAppsFreeableSpace(false); 219b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi if (mPhotoPreference != null) { 220b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi freeableSpace += mPhotoPreference.getFreeableBytes(); 221b26f457e30d6d444c873efaaf26181139bb92aedDaniel Nishi } 22209fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi freeableSpace += mDownloadsDeletion.getFreeableBytes(); 22309fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi return freeableSpace; 22409fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi } 22509fa1388d090666e631f9d764f935604a2c753e9Daniel Nishi}