• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.network;
18 
19 import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
20 import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
21 
22 import static com.android.settings.network.MobileIconGroupExtKt.getSummaryForSub;
23 import static com.android.settings.network.MobileIconGroupExtKt.maybeToHtml;
24 import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
25 import static com.android.settingslib.mobile.MobileMappings.getIconKey;
26 import static com.android.settingslib.mobile.MobileMappings.mapIconSets;
27 
28 import android.content.BroadcastReceiver;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.IntentFilter;
32 import android.graphics.drawable.Drawable;
33 import android.net.wifi.WifiManager;
34 import android.os.UserManager;
35 import android.telephony.AccessNetworkConstants;
36 import android.telephony.NetworkRegistrationInfo;
37 import android.telephony.ServiceState;
38 import android.telephony.SignalStrength;
39 import android.telephony.SubscriptionInfo;
40 import android.telephony.SubscriptionManager;
41 import android.telephony.TelephonyCallback;
42 import android.telephony.TelephonyDisplayInfo;
43 import android.telephony.TelephonyManager;
44 import android.util.ArraySet;
45 import android.util.Log;
46 
47 import androidx.annotation.VisibleForTesting;
48 import androidx.collection.ArrayMap;
49 import androidx.lifecycle.Lifecycle;
50 import androidx.lifecycle.LifecycleObserver;
51 import androidx.lifecycle.OnLifecycleEvent;
52 import androidx.preference.Preference;
53 import androidx.preference.PreferenceGroup;
54 import androidx.preference.PreferenceScreen;
55 
56 import com.android.settings.R;
57 import com.android.settings.Utils;
58 import com.android.settings.network.telephony.DataConnectivityListener;
59 import com.android.settings.network.telephony.MobileNetworkUtils;
60 import com.android.settings.network.telephony.SignalStrengthListener;
61 import com.android.settings.network.telephony.TelephonyDisplayInfoListener;
62 import com.android.settings.widget.MutableGearPreference;
63 import com.android.settings.wifi.WifiPickerTrackerHelper;
64 import com.android.settingslib.SignalIcon.MobileIconGroup;
65 import com.android.settingslib.core.AbstractPreferenceController;
66 import com.android.settingslib.mobile.MobileMappings;
67 import com.android.settingslib.mobile.MobileMappings.Config;
68 import com.android.settingslib.mobile.TelephonyIcons;
69 import com.android.settingslib.net.SignalStrengthUtil;
70 import com.android.wifitrackerlib.WifiEntry;
71 import com.android.wifitrackerlib.WifiPickerTracker;
72 
73 import java.util.Collections;
74 import java.util.List;
75 import java.util.Map;
76 import java.util.Set;
77 
78 /**
79  * This controller manages preference with data subscription information and make its state
80  * display on preference.
81  */
82 public class SubscriptionsPreferenceController extends AbstractPreferenceController implements
83         LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient,
84         MobileDataEnabledListener.Client, DataConnectivityListener.Client,
85         SignalStrengthListener.Callback, TelephonyDisplayInfoListener.Callback,
86         TelephonyCallback.CarrierNetworkListener, WifiPickerTracker.WifiPickerTrackerCallback {
87     private static final String TAG = "SubscriptionsPrefCntrlr";
88 
89     private UpdateListener mUpdateListener;
90     private String mPreferenceGroupKey;
91     private PreferenceGroup mPreferenceGroup;
92     private TelephonyManager mTelephonyManager;
93     private SubscriptionManager mSubscriptionManager;
94     private SubscriptionsChangeListener mSubscriptionsListener;
95     private MobileDataEnabledListener mDataEnabledListener;
96     private DataConnectivityListener mConnectivityListener;
97     private SignalStrengthListener mSignalStrengthListener;
98     private TelephonyDisplayInfoListener mTelephonyDisplayInfoListener;
99     @VisibleForTesting
100     WifiPickerTrackerHelper mWifiPickerTrackerHelper;
101     private final WifiManager mWifiManager;
102     private boolean mCarrierNetworkChangeMode;
103 
104     @VisibleForTesting
105     final BroadcastReceiver mConnectionChangeReceiver = new BroadcastReceiver() {
106         @Override
107         public void onReceive(Context context, Intent intent) {
108             final String action = intent.getAction();
109             if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
110                 mConfig = mSubsPrefCtrlInjector.getConfig(mContext);
111                 update();
112             } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
113                 update();
114             }
115         }
116     };
117 
118     // Map of subscription id to Preference
119     private Map<Integer, Preference> mSubscriptionPreferences;
120     private int mStartOrder;
121     private MutableGearPreference mSubsGearPref;
122     private Config mConfig = null;
123     private SubsPrefCtrlInjector mSubsPrefCtrlInjector;
124     private TelephonyDisplayInfo mTelephonyDisplayInfo =
125             new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
126                     TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
127 
128     /**
129      * This interface lets a parent of this class know that some change happened - this could
130      * either be because overall availability changed, or because we've added/removed/updated some
131      * preferences.
132      */
133     public interface UpdateListener {
onChildrenUpdated()134         void onChildrenUpdated();
135     }
136 
137     /**
138      * @param context            the context for the UI where we're placing these preferences
139      * @param lifecycle          for listening to lifecycle events for the UI
140      * @param updateListener     called to let our parent controller know that our availability has
141      *                           changed, or that one or more of the preferences we've placed in the
142      *                           PreferenceGroup has changed
143      * @param preferenceGroupKey the key used to lookup the PreferenceGroup where Preferences will
144      *                           be placed
145      * @param startOrder         the order that should be given to the first Preference placed into
146      *                           the PreferenceGroup; the second will use startOrder+1, third will
147      *                           use startOrder+2, etc. - this is useful for when the parent wants
148      *                           to have other preferences in the same PreferenceGroup and wants
149      *                           a specific ordering relative to this controller's prefs.
150      */
SubscriptionsPreferenceController(Context context, Lifecycle lifecycle, UpdateListener updateListener, String preferenceGroupKey, int startOrder)151     public SubscriptionsPreferenceController(Context context, Lifecycle lifecycle,
152             UpdateListener updateListener, String preferenceGroupKey, int startOrder) {
153         super(context);
154         mUpdateListener = updateListener;
155         mPreferenceGroupKey = preferenceGroupKey;
156         mStartOrder = startOrder;
157         mTelephonyManager = context.getSystemService(TelephonyManager.class);
158         mSubscriptionManager = context.getSystemService(SubscriptionManager.class)
159                 .createForAllUserProfiles();
160         mWifiManager = context.getSystemService(WifiManager.class);
161         mSubscriptionPreferences = new ArrayMap<>();
162         mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
163         mDataEnabledListener = new MobileDataEnabledListener(context, this);
164         mConnectivityListener = new DataConnectivityListener(context, this);
165         mSignalStrengthListener = new SignalStrengthListener(context, this);
166         mTelephonyDisplayInfoListener = new TelephonyDisplayInfoListener(context, this);
167         lifecycle.addObserver(this);
168         mWifiPickerTrackerHelper = new WifiPickerTrackerHelper(lifecycle, context, this);
169         mSubsPrefCtrlInjector = createSubsPrefCtrlInjector();
170         mConfig = mSubsPrefCtrlInjector.getConfig(mContext);
171     }
172 
registerReceiver()173     private void registerReceiver() {
174         IntentFilter filter = new IntentFilter();
175         filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
176         filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
177         mContext.registerReceiver(mConnectionChangeReceiver, filter);
178     }
179 
unRegisterReceiver()180     private void unRegisterReceiver() {
181         if (mConnectionChangeReceiver != null) {
182             mContext.unregisterReceiver(mConnectionChangeReceiver);
183         }
184     }
185 
186     @OnLifecycleEvent(ON_RESUME)
onResume()187     public void onResume() {
188         mSubscriptionsListener.start();
189         mDataEnabledListener.start(mSubsPrefCtrlInjector.getDefaultDataSubscriptionId());
190         mConnectivityListener.start();
191         mSignalStrengthListener.resume();
192         mTelephonyDisplayInfoListener.resume();
193         registerReceiver();
194         update();
195     }
196 
197     @OnLifecycleEvent(ON_PAUSE)
onPause()198     public void onPause() {
199         mSubscriptionsListener.stop();
200         mDataEnabledListener.stop();
201         mConnectivityListener.stop();
202         mSignalStrengthListener.pause();
203         mTelephonyDisplayInfoListener.pause();
204         unRegisterReceiver();
205     }
206 
207     @Override
displayPreference(PreferenceScreen screen)208     public void displayPreference(PreferenceScreen screen) {
209         mPreferenceGroup = screen.findPreference(mPreferenceGroupKey);
210         update();
211     }
212 
update()213     private void update() {
214         if (mPreferenceGroup == null) {
215             return;
216         }
217         if (!isAvailable()) {
218             if (mSubsGearPref != null) {
219                 mPreferenceGroup.removePreference(mSubsGearPref);
220             }
221             for (Preference pref : mSubscriptionPreferences.values()) {
222                 mPreferenceGroup.removePreference(pref);
223             }
224 
225             mSubscriptionPreferences.clear();
226             mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet());
227             mTelephonyDisplayInfoListener.updateSubscriptionIds(Collections.emptySet());
228             mUpdateListener.onChildrenUpdated();
229             return;
230         }
231 
232         // Prefer using the currently active sub
233         SubscriptionInfo subInfoCandidate = mSubscriptionManager.getActiveSubscriptionInfo(
234                 SubscriptionManager.getActiveDataSubscriptionId());
235         SubscriptionInfo subInfo = mSubscriptionManager.isSubscriptionVisible(subInfoCandidate)
236                 ? subInfoCandidate : mSubscriptionManager.getDefaultDataSubscriptionInfo();
237         if (subInfo == null) {
238             mPreferenceGroup.removeAll();
239             return;
240         }
241         if (mSubsGearPref == null) {
242             mPreferenceGroup.removeAll();
243             mSubsGearPref = new MutableGearPreference(mContext, null);
244             mSubsGearPref
245                     .checkRestrictionAndSetDisabled(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
246             mSubsGearPref.setOnPreferenceClickListener(preference -> {
247                 connectCarrierNetwork();
248                 return true;
249             });
250         }
251 
252         mSubsGearPref.setOnGearClickListener(p ->
253                 MobileNetworkUtils.launchMobileNetworkSettings(mContext, subInfo));
254 
255         if (!(mContext.getSystemService(UserManager.class)).isAdminUser()) {
256             mSubsGearPref.setGearEnabled(false);
257         }
258 
259         mSubsGearPref.setTitle(SubscriptionUtil.getUniqueSubscriptionDisplayName(
260                 subInfo, mContext));
261         mSubsGearPref.setOrder(mStartOrder);
262         mSubsGearPref.setSummary(getMobilePreferenceSummary(subInfo.getSubscriptionId()));
263         mSubsGearPref.setIcon(getIcon(subInfo.getSubscriptionId()));
264         mPreferenceGroup.addPreference(mSubsGearPref);
265 
266         final Set<Integer> activeDataSubIds = new ArraySet<>();
267         activeDataSubIds.add(subInfo.getSubscriptionId());
268         mSignalStrengthListener.updateSubscriptionIds(activeDataSubIds);
269         mTelephonyDisplayInfoListener.updateSubscriptionIds(activeDataSubIds);
270         mUpdateListener.onChildrenUpdated();
271     }
272 
273     /**@return {@code true} if subId is the default data sub. **/
isDds(int subId)274     private boolean isDds(int subId) {
275         SubscriptionInfo info = mSubscriptionManager.getDefaultDataSubscriptionInfo();
276         return info != null && info.getSubscriptionId() == subId;
277     }
278 
getMobilePreferenceSummary(int subId)279     private CharSequence getMobilePreferenceSummary(int subId) {
280         final TelephonyManager tmForSubId = mTelephonyManager.createForSubscriptionId(subId);
281         boolean isDds = isDds(subId);
282         if (!tmForSubId.isDataEnabled() && isDds) {
283             return mContext.getString(R.string.mobile_data_off_summary);
284         }
285         final ServiceState serviceState = tmForSubId.getServiceState();
286         final NetworkRegistrationInfo regInfo = (serviceState == null)
287                 ? null
288                 : serviceState.getNetworkRegistrationInfo(
289                         NetworkRegistrationInfo.DOMAIN_PS,
290                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
291 
292         final boolean isDataInService = (regInfo == null)
293                 ? false
294                 : regInfo.isRegistered();
295         final boolean isCarrierNetworkActive = isCarrierNetworkActive();
296         String result = mSubsPrefCtrlInjector.getNetworkType(mContext, mConfig,
297                 mTelephonyDisplayInfo, subId, isCarrierNetworkActive, mCarrierNetworkChangeMode);
298         if (mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext) || isCarrierNetworkActive) {
299             String connectionState = mContext.getString(isDds
300                     ? R.string.mobile_data_connection_active
301                     : R.string.mobile_data_temp_connection_active);
302             if (result.isEmpty()) {
303                 return connectionState;
304             } else {
305                 result = mContext.getString(
306                         com.android.settingslib.R.string.preference_summary_default_combination,
307                         connectionState, result);
308             }
309         } else if (!isDataInService) {
310             return mContext.getString(R.string.mobile_data_no_connection);
311         }
312         return maybeToHtml(result);
313     }
314 
315     @VisibleForTesting
getIcon(int subId)316     Drawable getIcon(int subId) {
317         final TelephonyManager tmForSubId = mTelephonyManager.createForSubscriptionId(subId);
318         final SignalStrength strength = tmForSubId.getSignalStrength();
319         int level = (strength == null) ? 0 : strength.getLevel();
320         int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
321         boolean isCarrierNetworkActive = isCarrierNetworkActive();
322         if (isCarrierNetworkActive) {
323             level = getCarrierNetworkLevel();
324             numLevels = WifiEntry.WIFI_LEVEL_MAX + 1;
325         } else if (shouldInflateSignalStrength(subId)) {
326             level += 1;
327             numLevels += 1;
328         }
329 
330         Drawable icon = mContext.getDrawable(R.drawable.ic_signal_strength_zero_bar_no_internet);
331 
332         final ServiceState serviceState = tmForSubId.getServiceState();
333         final NetworkRegistrationInfo regInfo = (serviceState == null)
334                 ? null
335                 : serviceState.getNetworkRegistrationInfo(
336                         NetworkRegistrationInfo.DOMAIN_PS,
337                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
338 
339         final boolean isDataInService = (regInfo == null)
340                 ? false
341                 : regInfo.isRegistered();
342         final boolean isVoiceInService = (serviceState == null)
343                 ? false
344                 : (serviceState.getState() == ServiceState.STATE_IN_SERVICE);
345         final boolean isDataEnabled = tmForSubId.isDataEnabled()
346                 // non-Dds but auto data switch feature is enabled
347                 || (!isDds(subId) && tmForSubId.isMobileDataPolicyEnabled(
348                         TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH));
349         if (isDataInService || isVoiceInService || isCarrierNetworkActive) {
350             icon = mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, !isDataEnabled,
351                     mCarrierNetworkChangeMode);
352         }
353 
354         final boolean isActiveCellularNetwork =
355                 mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext);
356         if (isActiveCellularNetwork || isCarrierNetworkActive) {
357             icon.setTint(Utils.getColorAccentDefaultColor(mContext));
358         }
359 
360         return icon;
361     }
362 
363     @VisibleForTesting
shouldInflateSignalStrength(int subId)364     boolean shouldInflateSignalStrength(int subId) {
365         return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId);
366     }
367 
368     /**
369      * The summary can have either 1 or 2 lines depending on which services (calls, SMS, data) this
370      * subscription is the default for.
371      *
372      * If this subscription is the default for calls and/or SMS, we add a line to show that.
373      *
374      * If this subscription is the default for data, we add a line with detail about
375      * whether the data connection is active.
376      *
377      * If a subscription isn't the default for anything, we just say it is available.
378      */
getSummary(int subId, boolean isDefaultForData)379     protected String getSummary(int subId, boolean isDefaultForData) {
380         final int callsDefaultSubId = mSubsPrefCtrlInjector.getDefaultVoiceSubscriptionId();
381         final int smsDefaultSubId = mSubsPrefCtrlInjector.getDefaultSmsSubscriptionId();
382 
383         String line1 = null;
384         if (subId == callsDefaultSubId && subId == smsDefaultSubId) {
385             line1 = mContext.getString(R.string.default_for_calls_and_sms);
386         } else if (subId == callsDefaultSubId) {
387             line1 = mContext.getString(R.string.default_for_calls);
388         } else if (subId == smsDefaultSubId) {
389             line1 = mContext.getString(R.string.default_for_sms);
390         }
391 
392         String line2 = null;
393         if (isDefaultForData) {
394             final TelephonyManager telMgrForSub = mContext.getSystemService(
395                     TelephonyManager.class).createForSubscriptionId(subId);
396             final boolean dataEnabled = telMgrForSub.isDataEnabled();
397             if (dataEnabled && mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext)) {
398                 line2 = mContext.getString(R.string.mobile_data_active);
399             } else if (!dataEnabled) {
400                 line2 = mContext.getString(R.string.mobile_data_off);
401             } else {
402                 line2 = mContext.getString(R.string.default_for_mobile_data);
403             }
404         }
405 
406         if (line1 != null && line2 != null) {
407             return String.join(System.lineSeparator(), line1, line2);
408         } else if (line1 != null) {
409             return line1;
410         } else if (line2 != null) {
411             return line2;
412         } else {
413             return mContext.getString(R.string.subscription_available);
414         }
415     }
416 
417     /**
418      * @return true if there is at least 1 available subscription.
419      */
420     @Override
isAvailable()421     public boolean isAvailable() {
422         if (mSubscriptionsListener.isAirplaneModeOn()
423                 && (!mWifiManager.isWifiEnabled() || !isCarrierNetworkActive())) {
424             return false;
425         }
426         List<SubscriptionInfo> subInfoList =
427                 SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager);
428         if (subInfoList == null) {
429             return false;
430         }
431 
432         return subInfoList.stream()
433                 // Avoid from showing subscription(SIM)s which has been marked as hidden
434                 // For example, only one subscription will be shown when there're multiple
435                 // subscriptions with same group UUID.
436                 .filter(subInfo ->
437                         mSubsPrefCtrlInjector.canSubscriptionBeDisplayed(mContext,
438                                 subInfo.getSubscriptionId()))
439                 .count() >= 1;
440     }
441 
442     @Override
getPreferenceKey()443     public String getPreferenceKey() {
444         return null;
445     }
446 
447     @Override
onAirplaneModeChanged(boolean airplaneModeEnabled)448     public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
449         update();
450     }
451 
452     @Override
onSubscriptionsChanged()453     public void onSubscriptionsChanged() {
454         // See if we need to change which sub id we're using to listen for enabled/disabled changes.
455         int defaultDataSubId = mSubsPrefCtrlInjector.getDefaultDataSubscriptionId();
456         if (defaultDataSubId != mDataEnabledListener.getSubId()) {
457             mDataEnabledListener.stop();
458             mDataEnabledListener.start(defaultDataSubId);
459         }
460         update();
461     }
462 
463     @Override
onMobileDataEnabledChange()464     public void onMobileDataEnabledChange() {
465         update();
466     }
467 
468     @Override
onDataConnectivityChange()469     public void onDataConnectivityChange() {
470         update();
471     }
472 
473     @Override
onSignalStrengthChanged()474     public void onSignalStrengthChanged() {
475         update();
476     }
477 
478     @Override
onTelephonyDisplayInfoChanged(int subId, TelephonyDisplayInfo telephonyDisplayInfo)479     public void onTelephonyDisplayInfoChanged(int subId,
480             TelephonyDisplayInfo telephonyDisplayInfo) {
481         if (subId != mSubsPrefCtrlInjector.getDefaultDataSubscriptionId()) {
482             return;
483         }
484         mTelephonyDisplayInfo = telephonyDisplayInfo;
485         update();
486     }
487 
488     @Override
onCarrierNetworkChange(boolean active)489     public void onCarrierNetworkChange(boolean active) {
490         mCarrierNetworkChangeMode = active;
491         update();
492     }
493 
494     @Override
onNumSavedNetworksChanged()495     public void onNumSavedNetworksChanged() {
496         //Do nothing
497     }
498 
499     @Override
onNumSavedSubscriptionsChanged()500     public void onNumSavedSubscriptionsChanged() {
501         //Do nothing
502     }
503 
504     @Override
onWifiStateChanged()505     public void onWifiStateChanged() {
506         update();
507     }
508 
509     @Override
onWifiEntriesChanged()510     public void onWifiEntriesChanged() {
511         update();
512     }
513 
514     @VisibleForTesting
connectCarrierNetwork()515     public void connectCarrierNetwork() {
516         if (!MobileNetworkUtils.isMobileDataEnabled(mContext)) {
517             return;
518         }
519         if (mWifiPickerTrackerHelper != null) {
520             mWifiPickerTrackerHelper.connectCarrierNetwork(null /* ConnectCallback */);
521         }
522     }
523 
createSubsPrefCtrlInjector()524     SubsPrefCtrlInjector createSubsPrefCtrlInjector() {
525         return new SubsPrefCtrlInjector();
526     }
527 
isCarrierNetworkActive()528     boolean isCarrierNetworkActive() {
529         return mWifiPickerTrackerHelper != null
530                 && mWifiPickerTrackerHelper.isCarrierNetworkActive();
531     }
532 
getCarrierNetworkLevel()533     private int getCarrierNetworkLevel() {
534         if (mWifiPickerTrackerHelper == null) return WifiEntry.WIFI_LEVEL_MIN;
535         return mWifiPickerTrackerHelper.getCarrierNetworkLevel();
536     }
537 
538     /**
539      * To inject necessary data from each static api.
540      */
541     @VisibleForTesting
542     public static class SubsPrefCtrlInjector {
543         /**
544          * Uses to inject function and value for class and test class.
545          */
canSubscriptionBeDisplayed(Context context, int subId)546         public boolean canSubscriptionBeDisplayed(Context context, int subId) {
547             return (SubscriptionUtil.getAvailableSubscriptionBySubIdAndShowingForUser(context,
548                     ProxySubscriptionManager.getInstance(context), subId) != null);
549         }
550 
551         /**
552          * Check SIM be able to display on UI.
553          */
getDefaultSmsSubscriptionId()554         public int getDefaultSmsSubscriptionId() {
555             return SubscriptionManager.getDefaultSmsSubscriptionId();
556         }
557 
558         /**
559          * Gets default voice subscription ID.
560          */
getDefaultVoiceSubscriptionId()561         public int getDefaultVoiceSubscriptionId() {
562             return SubscriptionManager.getDefaultVoiceSubscriptionId();
563         }
564 
565         /**
566          * Gets default data subscription ID.
567          */
getDefaultDataSubscriptionId()568         public int getDefaultDataSubscriptionId() {
569             return SubscriptionManager.getDefaultDataSubscriptionId();
570         }
571 
572         /**
573          * Confirms the current network is cellular and active.
574          */
isActiveCellularNetwork(Context context)575         public boolean isActiveCellularNetwork(Context context) {
576             return MobileNetworkUtils.activeNetworkIsCellular(context);
577         }
578 
579         /**
580          * Gets config for carrier customization.
581          */
getConfig(Context context)582         public Config getConfig(Context context) {
583             return MobileMappings.Config.readConfig(context);
584         }
585 
586         /**
587          * Gets current network type of Carrier Wi-Fi Network or Cellular.
588          */
getNetworkType(Context context, Config config, TelephonyDisplayInfo telephonyDisplayInfo, int subId, boolean isCarrierWifiNetwork, boolean carrierNetworkChanged)589         public String getNetworkType(Context context, Config config,
590                 TelephonyDisplayInfo telephonyDisplayInfo, int subId, boolean isCarrierWifiNetwork,
591                 boolean carrierNetworkChanged) {
592             MobileIconGroup iconGroup = null;
593             if (isCarrierWifiNetwork) {
594                 iconGroup = TelephonyIcons.CARRIER_MERGED_WIFI;
595             } else if (carrierNetworkChanged) {
596                 iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
597             } else {
598                 String iconKey = getIconKey(telephonyDisplayInfo);
599                 iconGroup = mapIconSets(config).get(iconKey);
600             }
601 
602             if (iconGroup == null) {
603                 Log.d(TAG, "Can not get the network's icon and description.");
604                 return "";
605             }
606 
607             return getSummaryForSub(iconGroup, context, subId);
608         }
609 
610         /**
611          * Gets signal icon with different signal level.
612          */
getIcon(Context context, int level, int numLevels, boolean cutOut, boolean carrierNetworkChanged)613         public Drawable getIcon(Context context, int level, int numLevels, boolean cutOut,
614                 boolean carrierNetworkChanged) {
615             return MobileNetworkUtils.getSignalStrengthIcon(context, level, numLevels,
616                     NO_CELL_DATA_TYPE_ICON, cutOut, carrierNetworkChanged);
617         }
618     }
619 }
620