• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DownloadsDeletionPreferenceGroup(Context context)42     public DownloadsDeletionPreferenceGroup(Context context) {
43         this(context, null);
44     }
45 
DownloadsDeletionPreferenceGroup(Context context, AttributeSet attrs)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      */
registerDeletionService(DownloadsDeletionType type)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      */
registerFreeableChangedListener(DeletionType.FreeableChangedListener listener)66     public void registerFreeableChangedListener(DeletionType.FreeableChangedListener listener) {
67         mListener = listener;
68     }
69 
70     @Override
onFreeableChanged(int numItems, long freeableBytes)71     public void onFreeableChanged(int numItems, long freeableBytes) {
72         updatePreferenceText(numItems, freeableBytes, mDeletionType.getMostRecentLastModified());
73         maybeUpdateListener(numItems, freeableBytes);
74         updateFiles();
75     }
76 
77     @Override
onPreferenceChange(Preference preference, Object newValue)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
onClick()115     public void onClick() {
116         super.onClick();
117         MetricsLogger.action(getContext(), MetricsEvent.ACTION_DELETION_DOWNLOADS_COLLAPSED,
118                 isCollapsed());
119     }
120 
updatePreferenceText(int itemCount, long bytes, long mostRecent)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 
maybeUpdateListener(int numItems, long bytesFreeable)134     private void maybeUpdateListener(int numItems, long bytesFreeable) {
135         if (mListener != null) {
136             mListener.onFreeableChanged(numItems, bytesFreeable);
137         }
138     }
139 
updateFiles()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