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.app.settings.SettingsEnums;
19 import android.content.Context;
20 import android.os.Bundle;
21 import android.provider.SearchIndexableResource;
22 import android.telephony.SubscriptionManager;
23 import android.widget.Switch;
24 
25 import androidx.preference.Preference;
26 
27 import com.android.settings.R;
28 import com.android.settings.SettingsActivity;
29 import com.android.settings.SettingsPreferenceFragment;
30 import com.android.settings.applications.AppStateBaseBridge.Callback;
31 import com.android.settings.datausage.DataSaverBackend.Listener;
32 import com.android.settings.search.BaseSearchIndexProvider;
33 import com.android.settings.search.Indexable;
34 import com.android.settings.widget.SwitchBar;
35 import com.android.settings.widget.SwitchBar.OnSwitchChangeListener;
36 import com.android.settingslib.applications.ApplicationsState;
37 import com.android.settingslib.applications.ApplicationsState.AppEntry;
38 import com.android.settingslib.applications.ApplicationsState.Callbacks;
39 import com.android.settingslib.applications.ApplicationsState.Session;
40 import com.android.settingslib.search.SearchIndexable;
41 
42 import java.util.ArrayList;
43 import java.util.List;
44 
45 @SearchIndexable
46 public class DataSaverSummary extends SettingsPreferenceFragment
47         implements OnSwitchChangeListener, Listener, Callback, Callbacks {
48 
49     private static final String KEY_UNRESTRICTED_ACCESS = "unrestricted_access";
50 
51     private SwitchBar mSwitchBar;
52     private DataSaverBackend mDataSaverBackend;
53     private Preference mUnrestrictedAccess;
54     private ApplicationsState mApplicationsState;
55     private AppStateDataUsageBridge mDataUsageBridge;
56     private Session mSession;
57 
58     // Flag used to avoid infinite loop due if user switch it on/off too quicky.
59     private boolean mSwitching;
60 
61     @Override
onCreate(Bundle icicle)62     public void onCreate(Bundle icicle) {
63         super.onCreate(icicle);
64 
65         addPreferencesFromResource(R.xml.data_saver);
66         mFooterPreferenceMixin.createFooterPreference()
67                 .setTitle(com.android.internal.R.string.data_saver_description);
68         mUnrestrictedAccess = findPreference(KEY_UNRESTRICTED_ACCESS);
69         mApplicationsState = ApplicationsState.getInstance(
70                 (Application) getContext().getApplicationContext());
71         mDataSaverBackend = new DataSaverBackend(getContext());
72         mDataUsageBridge = new AppStateDataUsageBridge(mApplicationsState, this, mDataSaverBackend);
73         mSession = mApplicationsState.newSession(this, getSettingsLifecycle());
74     }
75 
76     @Override
onActivityCreated(Bundle savedInstanceState)77     public void onActivityCreated(Bundle savedInstanceState) {
78         super.onActivityCreated(savedInstanceState);
79         mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar();
80         mSwitchBar.setSwitchBarText(
81                 R.string.data_saver_switch_title,
82                 R.string.data_saver_switch_title);
83         mSwitchBar.show();
84         mSwitchBar.addOnSwitchChangeListener(this);
85     }
86 
87     @Override
onResume()88     public void onResume() {
89         super.onResume();
90         mDataSaverBackend.refreshWhitelist();
91         mDataSaverBackend.refreshBlacklist();
92         mDataSaverBackend.addListener(this);
93         mDataUsageBridge.resume();
94     }
95 
96     @Override
onPause()97     public void onPause() {
98         super.onPause();
99         mDataSaverBackend.remListener(this);
100         mDataUsageBridge.pause();
101     }
102 
103     @Override
onSwitchChanged(Switch switchView, boolean isChecked)104     public void onSwitchChanged(Switch switchView, boolean isChecked) {
105         synchronized (this) {
106             if (mSwitching) {
107                 return;
108             }
109             mSwitching = true;
110             mDataSaverBackend.setDataSaverEnabled(isChecked);
111         }
112     }
113 
114     @Override
getMetricsCategory()115     public int getMetricsCategory() {
116         return SettingsEnums.DATA_SAVER_SUMMARY;
117     }
118 
119     @Override
getHelpResource()120     public int getHelpResource() {
121         return R.string.help_url_data_saver;
122     }
123 
124     @Override
onDataSaverChanged(boolean isDataSaving)125     public void onDataSaverChanged(boolean isDataSaving) {
126         synchronized (this) {
127             mSwitchBar.setChecked(isDataSaving);
128             mSwitching = false;
129         }
130     }
131 
132     @Override
onWhitelistStatusChanged(int uid, boolean isWhitelisted)133     public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) {
134     }
135 
136     @Override
onBlacklistStatusChanged(int uid, boolean isBlacklisted)137     public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) {
138     }
139 
140     @Override
onExtraInfoUpdated()141     public void onExtraInfoUpdated() {
142         if (!isAdded()) {
143             return;
144         }
145         int count = 0;
146         final ArrayList<AppEntry> allApps = mSession.getAllApps();
147         final int N = allApps.size();
148         for (int i = 0; i < N; i++) {
149             final AppEntry entry = allApps.get(i);
150             if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(entry)) {
151                 continue;
152             }
153             if (entry.extraInfo != null && ((AppStateDataUsageBridge.DataUsageState)
154                     entry.extraInfo).isDataSaverWhitelisted) {
155                 count++;
156             }
157         }
158         mUnrestrictedAccess.setSummary(getResources().getQuantityString(
159                 R.plurals.data_saver_unrestricted_summary, count, count));
160     }
161 
162     @Override
onRunningStateChanged(boolean running)163     public void onRunningStateChanged(boolean running) {
164 
165     }
166 
167     @Override
onPackageListChanged()168     public void onPackageListChanged() {
169 
170     }
171 
172     @Override
onRebuildComplete(ArrayList<AppEntry> apps)173     public void onRebuildComplete(ArrayList<AppEntry> apps) {
174 
175     }
176 
177     @Override
onPackageIconChanged()178     public void onPackageIconChanged() {
179 
180     }
181 
182     @Override
onPackageSizeChanged(String packageName)183     public void onPackageSizeChanged(String packageName) {
184 
185     }
186 
187     @Override
onAllSizesComputed()188     public void onAllSizesComputed() {
189 
190     }
191 
192     @Override
onLauncherInfoChanged()193     public void onLauncherInfoChanged() {
194 
195     }
196 
197     @Override
onLoadEntriesCompleted()198     public void onLoadEntriesCompleted() {
199 
200     }
201 
202     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
203             new BaseSearchIndexProvider() {
204                 @Override
205                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
206                         boolean enabled) {
207                     final ArrayList<SearchIndexableResource> result = new ArrayList<>();
208 
209                     final SearchIndexableResource sir = new SearchIndexableResource(context);
210                     sir.xmlResId = R.xml.data_saver;
211                     result.add(sir);
212                     return result;
213                 }
214 
215                 @Override
216                 protected boolean isPageSearchEnabled(Context context) {
217                     return DataUsageUtils.hasMobileData(context)
218                             && DataUsageUtils.getDefaultSubscriptionId(context)
219                             != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
220                 }
221             };
222 }
223