OSDN Git Service

42e4df8bae695fcc39715adec0385fd276c06334
[android-x86/packages-apps-Settings.git] / src / com / android / settings / datausage / UnrestrictedDataAccess.java
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14
15 package com.android.settings.datausage;
16
17 import android.app.Application;
18 import android.content.Context;
19 import android.os.Bundle;
20 import android.support.v14.preference.SwitchPreference;
21 import android.support.v7.preference.Preference;
22 import android.support.v7.preference.PreferenceViewHolder;
23 import android.view.Menu;
24 import android.view.MenuInflater;
25 import android.view.MenuItem;
26 import android.view.View;
27
28 import com.android.internal.logging.MetricsProto.MetricsEvent;
29 import com.android.settings.AppHeader;
30 import com.android.settings.R;
31 import com.android.settings.SettingsActivity;
32 import com.android.settings.SettingsPreferenceFragment;
33 import com.android.settings.applications.AppInfoBase;
34 import com.android.settings.applications.AppStateBaseBridge;
35 import com.android.settings.applications.InstalledAppDetails;
36 import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
37 import com.android.settingslib.applications.ApplicationsState;
38 import com.android.settingslib.applications.ApplicationsState.AppEntry;
39 import com.android.settingslib.applications.ApplicationsState.AppFilter;
40
41 import java.util.ArrayList;
42
43 public class UnrestrictedDataAccess extends SettingsPreferenceFragment
44         implements ApplicationsState.Callbacks, AppStateBaseBridge.Callback,
45         Preference.OnPreferenceChangeListener {
46
47     private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 42;
48     private static final String EXTRA_SHOW_SYSTEM = "show_system";
49
50     private ApplicationsState mApplicationsState;
51     private AppStateDataUsageBridge mDataUsageBridge;
52     private ApplicationsState.Session mSession;
53     private DataSaverBackend mDataSaverBackend;
54     private boolean mShowSystem;
55     private boolean mExtraLoaded;
56     private AppFilter mFilter;
57
58     @Override
59     public void onCreate(Bundle icicle) {
60         super.onCreate(icicle);
61         setAnimationAllowed(true);
62         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
63         mApplicationsState = ApplicationsState.getInstance(
64                 (Application) getContext().getApplicationContext());
65         mDataSaverBackend = new DataSaverBackend(getContext());
66         mDataUsageBridge = new AppStateDataUsageBridge(mApplicationsState, this, mDataSaverBackend);
67         mSession = mApplicationsState.newSession(this);
68         mShowSystem = icicle != null && icicle.getBoolean(EXTRA_SHOW_SYSTEM);
69         mFilter = mShowSystem ? ApplicationsState.FILTER_ALL_ENABLED
70                 : ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER;
71         setHasOptionsMenu(true);
72     }
73
74     @Override
75     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
76         menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE,
77                 mShowSystem ? R.string.menu_hide_system : R.string.menu_show_system);
78         super.onCreateOptionsMenu(menu, inflater);
79     }
80
81     @Override
82     public boolean onOptionsItemSelected(MenuItem item) {
83         switch (item.getItemId()) {
84             case MENU_SHOW_SYSTEM:
85                 mShowSystem = !mShowSystem;
86                 item.setTitle(mShowSystem ? R.string.menu_hide_system : R.string.menu_show_system);
87                 mFilter = mShowSystem ? ApplicationsState.FILTER_ALL_ENABLED
88                         : ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER;
89                 if (mExtraLoaded) {
90                     rebuild();
91                 }
92                 break;
93         }
94         return super.onOptionsItemSelected(item);
95     }
96
97     @Override
98     public void onSaveInstanceState(Bundle outState) {
99         super.onSaveInstanceState(outState);
100         outState.putBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
101     }
102
103     @Override
104     public void onViewCreated(View view, Bundle savedInstanceState) {
105         super.onViewCreated(view, savedInstanceState);
106         setLoading(true, false);
107     }
108
109     @Override
110     public void onResume() {
111         super.onResume();
112         mSession.resume();
113         mDataUsageBridge.resume();
114     }
115
116     @Override
117     public void onPause() {
118         super.onPause();
119         mDataUsageBridge.pause();
120         mSession.pause();
121     }
122
123     @Override
124     public void onDestroy() {
125         super.onDestroy();
126         mSession.release();
127         mDataUsageBridge.release();
128     }
129
130     @Override
131     public void onExtraInfoUpdated() {
132         mExtraLoaded = true;
133         rebuild();
134     }
135
136     @Override
137     protected int getHelpResource() {
138         return R.string.help_url_unrestricted_data_access;
139     }
140
141     private void rebuild() {
142         ArrayList<AppEntry> apps = mSession.rebuild(mFilter, ApplicationsState.ALPHA_COMPARATOR);
143         if (apps != null) {
144             onRebuildComplete(apps);
145         }
146     }
147
148     @Override
149     public void onRunningStateChanged(boolean running) {
150
151     }
152
153     @Override
154     public void onPackageListChanged() {
155
156     }
157
158     @Override
159     public void onRebuildComplete(ArrayList<AppEntry> apps) {
160         if (getContext() == null) return;
161         cacheRemoveAllPrefs(getPreferenceScreen());
162         final int N = apps.size();
163         for (int i = 0; i < N; i++) {
164             AppEntry entry = apps.get(i);
165             String key = entry.info.packageName + "|" + entry.info.uid;
166             AccessPreference preference = (AccessPreference) getCachedPreference(key);
167             if (preference == null) {
168                 preference = new AccessPreference(getPrefContext(), entry);
169                 preference.setKey(key);
170                 preference.setOnPreferenceChangeListener(this);
171                 getPreferenceScreen().addPreference(preference);
172             } else {
173                 preference.reuse();
174             }
175             preference.setOrder(i);
176         }
177         setLoading(false, true);
178         removeCachedPrefs(getPreferenceScreen());
179     }
180
181     @Override
182     public void onPackageIconChanged() {
183
184     }
185
186     @Override
187     public void onPackageSizeChanged(String packageName) {
188
189     }
190
191     @Override
192     public void onAllSizesComputed() {
193
194     }
195
196     @Override
197     public void onLauncherInfoChanged() {
198
199     }
200
201     @Override
202     public void onLoadEntriesCompleted() {
203
204     }
205
206     @Override
207     protected int getMetricsCategory() {
208         return MetricsEvent.DATA_USAGE_UNRESTRICTED_ACCESS;
209     }
210
211     @Override
212     public boolean onPreferenceChange(Preference preference, Object newValue) {
213         if (preference instanceof AccessPreference) {
214             AccessPreference accessPreference = (AccessPreference) preference;
215             boolean whitelisted = newValue == Boolean.TRUE;
216             mDataSaverBackend.setIsWhitelisted(accessPreference.mEntry.info.uid,
217                     accessPreference.mEntry.info.packageName, whitelisted);
218             accessPreference.mState.isDataSaverWhitelisted = whitelisted;
219             return true;
220         }
221         return false;
222     }
223
224     private class AccessPreference extends SwitchPreference implements DataSaverBackend.Listener {
225         private final AppEntry mEntry;
226         private final DataUsageState mState;
227
228         public AccessPreference(final Context context, AppEntry entry) {
229             super(context);
230             mEntry = entry;
231             mState = (DataUsageState) mEntry.extraInfo;
232             mEntry.ensureLabel(getContext());
233             setState();
234             if (mEntry.icon != null) {
235                 setIcon(mEntry.icon);
236             }
237         }
238
239         @Override
240         public void onAttached() {
241             super.onAttached();
242             mDataSaverBackend.addListener(this);
243         }
244
245         @Override
246         public void onDetached() {
247             mDataSaverBackend.remListener(this);
248             super.onDetached();
249         }
250
251         @Override
252         protected void onClick() {
253             if (mState != null && mState.isDataSaverBlacklisted) {
254                 // app is blacklisted, launch App Data Usage screen
255                 InstalledAppDetails.startAppInfoFragment(AppDataUsage.class,
256                         getContext().getString(R.string.app_data_usage),
257                         UnrestrictedDataAccess.this,
258                         mEntry);
259             } else {
260                 // app is not blacklisted, let superclass handle toggle switch
261                 super.onClick();
262             }
263         }
264
265         // Sets UI state based on whitelist/blacklist status.
266         private void setState() {
267             setTitle(mEntry.label);
268             if (mState != null) {
269                 setChecked(mState.isDataSaverWhitelisted);
270                 if (mState.isDataSaverBlacklisted) {
271                     setSummary(R.string.restrict_background_blacklisted);
272                 } else {
273                     setSummary("");
274                 }
275             }
276         }
277
278         public void reuse() {
279             setState();
280             notifyChanged();
281         }
282
283         @Override
284         public void onBindViewHolder(PreferenceViewHolder holder) {
285             if (mEntry.icon == null) {
286                 holder.itemView.post(new Runnable() {
287                     @Override
288                     public void run() {
289                         // Ensure we have an icon before binding.
290                         mApplicationsState.ensureIcon(mEntry);
291                         // This might trigger us to bind again, but it gives an easy way to only
292                         // load the icon once its needed, so its probably worth it.
293                         setIcon(mEntry.icon);
294                     }
295                 });
296             }
297             holder.findViewById(android.R.id.widget_frame)
298                     .setVisibility(mState != null && mState.isDataSaverBlacklisted
299                             ? View.INVISIBLE : View.VISIBLE);
300             super.onBindViewHolder(holder);
301         }
302
303         @Override
304         public void onDataSaverChanged(boolean isDataSaving) {
305         }
306
307         @Override
308         public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) {
309             if (mState != null && mEntry.info.uid == uid) {
310                 mState.isDataSaverWhitelisted = isWhitelisted;
311                 reuse();
312             }
313         }
314
315         @Override
316         public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) {
317             if (mState != null && mEntry.info.uid == uid) {
318                 mState.isDataSaverBlacklisted = isBlacklisted;
319                 reuse();
320             }
321         }
322     }
323
324 }