• 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"); 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