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