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.Activity; 18 import android.app.settings.SettingsEnums; 19 import android.content.Context; 20 import android.net.NetworkTemplate; 21 import android.os.Bundle; 22 import android.os.UserManager; 23 import android.telephony.SubscriptionInfo; 24 import android.telephony.SubscriptionManager; 25 import android.text.TextUtils; 26 import android.util.EventLog; 27 import android.util.Log; 28 29 import androidx.annotation.VisibleForTesting; 30 import androidx.preference.Preference; 31 import androidx.preference.PreferenceScreen; 32 33 import com.android.settings.R; 34 import com.android.settings.dashboard.DashboardFragment; 35 import com.android.settings.datausage.lib.DataUsageLib; 36 import com.android.settings.network.ProxySubscriptionManager; 37 import com.android.settings.network.SubscriptionUtil; 38 import com.android.settings.network.telephony.MobileNetworkUtils; 39 import com.android.settingslib.core.AbstractPreferenceController; 40 41 import java.util.ArrayList; 42 import java.util.List; 43 44 /** 45 * Settings preference fragment that displays data usage summary. 46 */ 47 public class DataUsageSummary extends DashboardFragment { 48 49 private static final String TAG = "DataUsageSummary"; 50 51 static final boolean LOGD = false; 52 53 public static final String KEY_RESTRICT_BACKGROUND = "restrict_background"; 54 55 // Mobile data keys 56 public static final String KEY_MOBILE_USAGE_TITLE = "mobile_category"; 57 58 private ProxySubscriptionManager mProxySubscriptionMgr; 59 60 @Override getHelpResource()61 public int getHelpResource() { 62 return R.string.help_url_data_usage; 63 } 64 isSimHardwareVisible(Context context)65 public boolean isSimHardwareVisible(Context context) { 66 return SubscriptionUtil.isSimHardwareVisible(context); 67 } 68 69 @Override onCreate(Bundle icicle)70 public void onCreate(Bundle icicle) { 71 super.onCreate(icicle); 72 Context context = getContext(); 73 if (isGuestUser(context)) { 74 Log.e(TAG, "This setting isn't available due to user restriction."); 75 EventLog.writeEvent(0x534e4554, "262243574", -1 /* UID */, "Guest user"); 76 finish(); 77 return; 78 } 79 80 if (!isSimHardwareVisible(context) || 81 MobileNetworkUtils.isMobileNetworkUserRestricted(context)) { 82 finish(); 83 return; 84 } 85 enableProxySubscriptionManager(context); 86 87 boolean hasMobileData = DataUsageUtils.hasMobileData(context); 88 89 final int defaultSubId = SubscriptionManager.getDefaultDataSubscriptionId(); 90 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 91 hasMobileData = false; 92 } 93 94 if (!hasMobileData || !UserManager.get(context).isAdminUser()) { 95 removePreference(KEY_RESTRICT_BACKGROUND); 96 } 97 boolean hasWifiRadio = DataUsageUtils.hasWifiRadio(context); 98 if (hasMobileData) { 99 addMobileSection(defaultSubId); 100 if (hasActiveSubscription() && hasWifiRadio) { 101 // If the device has active SIM, the data usage section shows usage for mobile, 102 // and the WiFi section is added if there is a WiFi radio - legacy behavior. 103 addWifiSection(); 104 } 105 // Do not add the WiFi section if either there is no WiFi radio (obviously) or if no 106 // SIM is installed. In the latter case the data usage section will show WiFi usage and 107 // there should be no explicit WiFi section added. 108 } else if (hasWifiRadio) { 109 addWifiSection(); 110 } 111 if (DataUsageUtils.hasEthernet(context)) { 112 addEthernetSection(); 113 } 114 setHasOptionsMenu(true); 115 } 116 117 @Override getPreferenceScreenResId()118 protected int getPreferenceScreenResId() { 119 return R.xml.data_usage; 120 } 121 122 @Override getLogTag()123 protected String getLogTag() { 124 return TAG; 125 } 126 127 @Override createPreferenceControllers(Context context)128 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) { 129 final Activity activity = getActivity(); 130 final ArrayList<AbstractPreferenceController> controllers = new ArrayList<>(); 131 if (!isSimHardwareVisible(context) || 132 MobileNetworkUtils.isMobileNetworkUserRestricted(context)) { 133 return controllers; 134 } 135 final var mSummaryController = new DataUsageSummaryPreferenceController(activity, 136 DataUsageUtils.getDefaultSubscriptionId(activity)); 137 controllers.add(mSummaryController); 138 return controllers; 139 } 140 141 @VisibleForTesting addMobileSection(int subId)142 void addMobileSection(int subId) { 143 addMobileSection(subId, null); 144 } 145 146 @VisibleForTesting enableProxySubscriptionManager(Context context)147 void enableProxySubscriptionManager(Context context) { 148 // Enable ProxySubscriptionMgr with Lifecycle support for all controllers 149 // live within this fragment 150 mProxySubscriptionMgr = ProxySubscriptionManager.getInstance(context); 151 mProxySubscriptionMgr.setLifecycle(getLifecycle()); 152 } 153 154 @VisibleForTesting hasActiveSubscription()155 boolean hasActiveSubscription() { 156 final List<SubscriptionInfo> subInfoList = 157 mProxySubscriptionMgr.getActiveSubscriptionsInfo(); 158 return ((subInfoList != null) && (subInfoList.size() > 0)); 159 } 160 addMobileSection(int subId, SubscriptionInfo subInfo)161 private void addMobileSection(int subId, SubscriptionInfo subInfo) { 162 TemplatePreferenceCategory category = (TemplatePreferenceCategory) 163 inflatePreferences(R.xml.data_usage_cellular); 164 category.setTemplate(DataUsageLib.getMobileTemplate(getContext(), subId), subId); 165 category.pushTemplates(); 166 final CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName( 167 subInfo, getContext()); 168 if (subInfo != null && !TextUtils.isEmpty(displayName)) { 169 Preference title = category.findPreference(KEY_MOBILE_USAGE_TITLE); 170 title.setTitle(displayName); 171 } 172 } 173 174 @VisibleForTesting addWifiSection()175 void addWifiSection() { 176 TemplatePreferenceCategory category = (TemplatePreferenceCategory) 177 inflatePreferences(R.xml.data_usage_wifi); 178 category.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build(), 179 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 180 } 181 addEthernetSection()182 private void addEthernetSection() { 183 TemplatePreferenceCategory category = (TemplatePreferenceCategory) 184 inflatePreferences(R.xml.data_usage_ethernet); 185 category.setTemplate( 186 new NetworkTemplate.Builder(NetworkTemplate.MATCH_ETHERNET).build(), 187 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 188 } 189 inflatePreferences(int resId)190 private Preference inflatePreferences(int resId) { 191 PreferenceScreen rootPreferences = getPreferenceManager().inflateFromResource( 192 getPrefContext(), resId, null); 193 Preference pref = rootPreferences.getPreference(0); 194 rootPreferences.removeAll(); 195 196 PreferenceScreen screen = getPreferenceScreen(); 197 pref.setOrder(screen.getPreferenceCount()); 198 screen.addPreference(pref); 199 200 return pref; 201 } 202 203 @Override onResume()204 public void onResume() { 205 super.onResume(); 206 updateState(); 207 } 208 updateState()209 private void updateState() { 210 PreferenceScreen screen = getPreferenceScreen(); 211 for (int i = 1; i < screen.getPreferenceCount(); i++) { 212 Preference currentPreference = screen.getPreference(i); 213 if (currentPreference instanceof TemplatePreferenceCategory) { 214 ((TemplatePreferenceCategory) currentPreference).pushTemplates(); 215 } 216 } 217 } 218 219 @Override getMetricsCategory()220 public int getMetricsCategory() { 221 return SettingsEnums.DATA_USAGE_SUMMARY; 222 } 223 isGuestUser(Context context)224 private static boolean isGuestUser(Context context) { 225 if (context == null) return false; 226 final UserManager userManager = context.getSystemService(UserManager.class); 227 if (userManager == null) return false; 228 return userManager.isGuestUser(); 229 } 230 } 231