Home | History | Annotate | Download | only in deletionhelper
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.storagemanager.deletionhelper;
     18 
     19 import android.content.Context;
     20 import android.support.v7.preference.Preference;
     21 import android.text.format.DateUtils;
     22 import android.text.format.Formatter;
     23 import android.util.AttributeSet;
     24 import android.view.View;
     25 import com.android.internal.logging.MetricsLogger;
     26 import com.android.internal.logging.MetricsProto.MetricsEvent;
     27 import com.android.storagemanager.PreferenceListCache;
     28 import com.android.storagemanager.R;
     29 
     30 import java.io.File;
     31 import java.util.Set;
     32 
     33 /**
     34  * DownloadsDeletionPreferenceGroup defines a checkable preference group which contains
     35  * downloads file deletion preferences.
     36  */
     37 public class DownloadsDeletionPreferenceGroup extends CollapsibleCheckboxPreferenceGroup
     38         implements DeletionType.FreeableChangedListener, Preference.OnPreferenceChangeListener {
     39     private DownloadsDeletionType mDeletionType;
     40     private DeletionType.FreeableChangedListener mListener;
     41 
     42     public DownloadsDeletionPreferenceGroup(Context context) {
     43         this(context, null);
     44     }
     45 
     46     public DownloadsDeletionPreferenceGroup(Context context, AttributeSet attrs) {
     47         super(context, attrs);
     48         setChecked(true);
     49         setOrderingAsAdded(false);
     50         setOnPreferenceChangeListener(this);
     51     }
     52 
     53     /**
     54      * Set up a deletion type to get info for the preference group.
     55      * @param type A {@link DownloadsDeletionType}.
     56      */
     57     public void registerDeletionService(DownloadsDeletionType type) {
     58         mDeletionType = type;
     59         mDeletionType.registerFreeableChangedListener(this);
     60     }
     61 
     62     /**
     63      * Registers a callback to be called when the amount of freeable space updates.
     64      * @param listener The callback listener.
     65      */
     66     public void registerFreeableChangedListener(DeletionType.FreeableChangedListener listener) {
     67         mListener = listener;
     68     }
     69 
     70     @Override
     71     public void onFreeableChanged(int numItems, long freeableBytes) {
     72         updatePreferenceText(numItems, freeableBytes, mDeletionType.getMostRecentLastModified());
     73         maybeUpdateListener(numItems, freeableBytes);
     74         updateFiles();
     75     }
     76 
     77     @Override
     78     public boolean onPreferenceChange(Preference preference, Object newValue) {
     79         boolean checked = (boolean) newValue;
     80         if (!checked) {
     81             // Temporarily stop listening to avoid propagating the checked change to children.
     82             setOnPreferenceChangeListener(null);
     83             setChecked(false);
     84             setOnPreferenceChangeListener(this);
     85         }
     86 
     87         // If we have no deletion type, we have no files to toggle.
     88         if (mDeletionType == null) {
     89             return true;
     90         }
     91 
     92         // If the group checkbox changed, we need to toggle every child preference.
     93         if (preference == this) {
     94             for (int i = 0; i < getPreferenceCount(); i++) {
     95                 DownloadsFilePreference p = (DownloadsFilePreference) getPreference(i);
     96                 p.setOnPreferenceChangeListener(null);
     97                 mDeletionType.toggleFile(p.getFile(), checked);
     98                 p.setChecked(checked);
     99                 p.setOnPreferenceChangeListener(this);
    100             }
    101             maybeUpdateListener(mDeletionType.getFiles().size(), mDeletionType.getFreeableBytes());
    102             MetricsLogger.action(getContext(), MetricsEvent.ACTION_DELETION_SELECTION_DOWNLOADS,
    103                     checked);
    104             return true;
    105         }
    106 
    107         // If a single DownloadFilePreference changed, we need to toggle just itself.
    108         DownloadsFilePreference p = (DownloadsFilePreference) preference;
    109         mDeletionType.toggleFile(p.getFile(), checked);
    110         maybeUpdateListener(mDeletionType.getFiles().size(), mDeletionType.getFreeableBytes());
    111         return true;
    112     }
    113 
    114     @Override
    115     public void onClick() {
    116         super.onClick();
    117         MetricsLogger.action(getContext(), MetricsEvent.ACTION_DELETION_DOWNLOADS_COLLAPSED,
    118                 isCollapsed());
    119     }
    120 
    121     private void updatePreferenceText(int itemCount, long bytes, long mostRecent) {
    122         Context context = getContext();
    123         setTitle(context.getString(R.string.deletion_helper_downloads_title, itemCount));
    124         // If there are no files to clear, show the empty text instead.
    125         if (itemCount != 0) {
    126             setSummary(context.getString(R.string.deletion_helper_downloads_category_summary,
    127                     Formatter.formatFileSize(context, bytes)));
    128         } else {
    129             setSummary(context.getString(R.string.deletion_helper_downloads_summary_empty,
    130                     Formatter.formatFileSize(context, bytes)));
    131         }
    132     }
    133 
    134     private void maybeUpdateListener(int numItems, long bytesFreeable) {
    135         if (mListener != null) {
    136             mListener.onFreeableChanged(numItems, bytesFreeable);
    137         }
    138     }
    139 
    140     private void updateFiles() {
    141         PreferenceListCache cache = new PreferenceListCache(this);
    142         Set<File> files = mDeletionType.getFiles();
    143         for (File file : files) {
    144             DownloadsFilePreference filePreference =
    145                     (DownloadsFilePreference) cache.getCachedPreference(file.getPath());
    146             if (filePreference == null) {
    147                 filePreference = new DownloadsFilePreference(getContext(), file);
    148                 filePreference.setChecked(mDeletionType.isChecked(file));
    149                 filePreference.setOnPreferenceChangeListener(this);
    150             }
    151             addPreference(filePreference);
    152         }
    153         cache.removeCachedPrefs();
    154     }
    155 }
    156