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}