• 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.telephony;
18 
19 import static androidx.lifecycle.Lifecycle.Event.ON_START;
20 import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
21 
22 import android.content.Context;
23 import android.os.PersistableBundle;
24 import android.telephony.CarrierConfigManager;
25 import android.telephony.SubscriptionManager;
26 import android.telephony.TelephonyManager;
27 import android.util.Log;
28 
29 import androidx.lifecycle.Lifecycle;
30 import androidx.lifecycle.LifecycleObserver;
31 import androidx.lifecycle.OnLifecycleEvent;
32 import androidx.preference.ListPreference;
33 import androidx.preference.Preference;
34 import androidx.preference.PreferenceScreen;
35 
36 import com.android.settings.R;
37 import com.android.settings.network.AllowedNetworkTypesListener;
38 import com.android.settings.network.SubscriptionsChangeListener;
39 import com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants;
40 
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.List;
44 import java.util.stream.Stream;
45 
46 /**
47  * Preference controller for "Enabled network mode"
48  */
49 public class EnabledNetworkModePreferenceController extends
50         TelephonyBasePreferenceController implements
51         ListPreference.OnPreferenceChangeListener, LifecycleObserver,
52         SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
53 
54     private static final String LOG_TAG = "EnabledNetworkMode";
55     private AllowedNetworkTypesListener mAllowedNetworkTypesListener;
56     private Preference mPreference;
57     private PreferenceScreen mPreferenceScreen;
58     private TelephonyManager mTelephonyManager;
59     private CarrierConfigManager mCarrierConfigManager;
60     private PreferenceEntriesBuilder mBuilder;
61     private SubscriptionsChangeListener mSubscriptionsListener;
62 
EnabledNetworkModePreferenceController(Context context, String key)63     public EnabledNetworkModePreferenceController(Context context, String key) {
64         super(context, key);
65         mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
66         mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
67     }
68 
69     @Override
getAvailabilityStatus(int subId)70     public int getAvailabilityStatus(int subId) {
71         boolean visible;
72         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
73         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
74             visible = false;
75         } else if (carrierConfig == null) {
76             visible = false;
77         } else if (carrierConfig.getBoolean(
78                 CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
79                 || carrierConfig.getBoolean(
80                 CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)) {
81             visible = false;
82         } else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
83             visible = false;
84         } else {
85             visible = true;
86         }
87 
88         return visible ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
89     }
90 
91     @OnLifecycleEvent(ON_START)
onStart()92     public void onStart() {
93         mSubscriptionsListener.start();
94         if (mAllowedNetworkTypesListener == null) {
95             return;
96         }
97         mAllowedNetworkTypesListener.register(mContext, mSubId);
98     }
99 
100     @OnLifecycleEvent(ON_STOP)
onStop()101     public void onStop() {
102         mSubscriptionsListener.stop();
103         if (mAllowedNetworkTypesListener == null) {
104             return;
105         }
106         mAllowedNetworkTypesListener.unregister(mContext, mSubId);
107     }
108 
109     @Override
displayPreference(PreferenceScreen screen)110     public void displayPreference(PreferenceScreen screen) {
111         super.displayPreference(screen);
112         mPreferenceScreen = screen;
113         mPreference = screen.findPreference(getPreferenceKey());
114     }
115 
116     @Override
updateState(Preference preference)117     public void updateState(Preference preference) {
118         super.updateState(preference);
119         final ListPreference listPreference = (ListPreference) preference;
120 
121         mBuilder.setPreferenceEntries();
122         mBuilder.setPreferenceValueAndSummary();
123 
124         listPreference.setEntries(mBuilder.getEntries());
125         listPreference.setEntryValues(mBuilder.getEntryValues());
126         listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue()));
127         listPreference.setSummary(mBuilder.getSummary());
128     }
129 
130     @Override
onPreferenceChange(Preference preference, Object object)131     public boolean onPreferenceChange(Preference preference, Object object) {
132         final int newPreferredNetworkMode = Integer.parseInt((String) object);
133         final ListPreference listPreference = (ListPreference) preference;
134 
135         if (mTelephonyManager.setPreferredNetworkTypeBitmask(
136                 MobileNetworkUtils.getRafFromNetworkType(newPreferredNetworkMode))) {
137             mBuilder.setPreferenceValueAndSummary(newPreferredNetworkMode);
138             listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue()));
139             listPreference.setSummary(mBuilder.getSummary());
140             return true;
141         }
142         return false;
143     }
144 
init(Lifecycle lifecycle, int subId)145     public void init(Lifecycle lifecycle, int subId) {
146         mSubId = subId;
147         mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
148                 .createForSubscriptionId(mSubId);
149         mBuilder = new PreferenceEntriesBuilder(mContext, mSubId);
150 
151         if (mAllowedNetworkTypesListener == null) {
152             mAllowedNetworkTypesListener = new AllowedNetworkTypesListener(
153                     mContext.getMainExecutor());
154             mAllowedNetworkTypesListener.setAllowedNetworkTypesListener(
155                     () -> {
156                         mBuilder.updateConfig();
157                         updatePreference();
158                     });
159         }
160 
161         lifecycle.addObserver(this);
162     }
163 
updatePreference()164     private void updatePreference() {
165         if (mPreferenceScreen != null) {
166             displayPreference(mPreferenceScreen);
167         }
168         if (mPreference != null) {
169             updateState(mPreference);
170         }
171     }
172 
173     enum EnabledNetworks {
174         ENABLED_NETWORKS_UNKNOWN,
175         ENABLED_NETWORKS_CDMA_CHOICES,
176         ENABLED_NETWORKS_CDMA_NO_LTE_CHOICES,
177         ENABLED_NETWORKS_CDMA_ONLY_LTE_CHOICES,
178         ENABLED_NETWORKS_TDSCDMA_CHOICES,
179         ENABLED_NETWORKS_EXCEPT_GSM_LTE_CHOICES,
180         ENABLED_NETWORKS_EXCEPT_GSM_4G_CHOICES,
181         ENABLED_NETWORKS_EXCEPT_GSM_CHOICES,
182         ENABLED_NETWORKS_EXCEPT_LTE_CHOICES,
183         ENABLED_NETWORKS_4G_CHOICES,
184         ENABLED_NETWORKS_CHOICES,
185         PREFERRED_NETWORK_MODE_CHOICES_WORLD_MODE
186     }
187 
188     private final class PreferenceEntriesBuilder {
189         private CarrierConfigManager mCarrierConfigManager;
190         private Context mContext;
191         private TelephonyManager mTelephonyManager;
192 
193         private boolean mAllowed5gNetworkType;
194         private boolean mIsGlobalCdma;
195         private boolean mIs5gEntryDisplayed;
196         private boolean mShow4gForLTE;
197         private boolean mSupported5gRadioAccessFamily;
198         private int mSelectedEntry;
199         private int mSubId;
200         private String mSummary;
201 
202         private List<String> mEntries = new ArrayList<>();
203         private List<Integer> mEntriesValue = new ArrayList<>();
204 
PreferenceEntriesBuilder(Context context, int subId)205         PreferenceEntriesBuilder(Context context, int subId) {
206             this.mContext = context;
207             this.mSubId = subId;
208             mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
209             mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
210                     .createForSubscriptionId(mSubId);
211             updateConfig();
212         }
213 
updateConfig()214         public void updateConfig() {
215             mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
216             final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
217             mAllowed5gNetworkType = checkSupportedRadioBitmask(
218                     mTelephonyManager.getAllowedNetworkTypesForReason(
219                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER),
220                     TelephonyManager.NETWORK_TYPE_BITMASK_NR);
221             mSupported5gRadioAccessFamily = checkSupportedRadioBitmask(
222                     mTelephonyManager.getSupportedRadioAccessFamily(),
223                     TelephonyManager.NETWORK_TYPE_BITMASK_NR);
224             mIsGlobalCdma = mTelephonyManager.isLteCdmaEvdoGsmWcdmaEnabled()
225                     && carrierConfig != null
226                     && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
227             mShow4gForLTE = carrierConfig != null && carrierConfig.getBoolean(
228                     CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
229             Log.d(LOG_TAG, "PreferenceEntriesBuilder: subId" + mSubId
230                     + ",Supported5gRadioAccessFamily :" + mSupported5gRadioAccessFamily
231                     + ",mAllowed5gNetworkType :" + mAllowed5gNetworkType
232                     + ",IsGlobalCdma :" + mIsGlobalCdma
233                     + ",Show4gForLTE :" + mShow4gForLTE);
234         }
235 
setPreferenceEntries()236         void setPreferenceEntries() {
237             clearAllEntries();
238             String[] entryValues;
239             int[] entryValuesInt;
240             switch (getEnabledNetworkType()) {
241                 case ENABLED_NETWORKS_CDMA_CHOICES:
242                     entryValues = getResourcesForSubId().getStringArray(
243                             R.array.enabled_networks_cdma_values);
244                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
245                     if (entryValuesInt.length < 4) {
246                         throw new IllegalArgumentException(
247                                 "ENABLED_NETWORKS_CDMA_CHOICES index error.");
248                     }
249                     add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
250                     addLteEntry(entryValuesInt[0]);
251                     add3gEntry(entryValuesInt[1]);
252                     add1xEntry(entryValuesInt[2]);
253                     addGlobalEntry(entryValuesInt[3]);
254                     break;
255                 case ENABLED_NETWORKS_CDMA_NO_LTE_CHOICES:
256                     entryValues = getResourcesForSubId().getStringArray(
257                             R.array.enabled_networks_cdma_no_lte_values);
258                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
259                     if (entryValuesInt.length < 2) {
260                         throw new IllegalArgumentException(
261                                 "ENABLED_NETWORKS_CDMA_NO_LTE_CHOICES index error.");
262                     }
263                     add3gEntry(entryValuesInt[0]);
264                     add1xEntry(entryValuesInt[1]);
265                     break;
266                 case ENABLED_NETWORKS_CDMA_ONLY_LTE_CHOICES:
267                     entryValues = getResourcesForSubId().getStringArray(
268                             R.array.enabled_networks_cdma_only_lte_values);
269                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
270                     if (entryValuesInt.length < 2) {
271                         throw new IllegalArgumentException(
272                                 "ENABLED_NETWORKS_CDMA_ONLY_LTE_CHOICES index error.");
273                     }
274                     addLteEntry(entryValuesInt[0]);
275                     addGlobalEntry(entryValuesInt[1]);
276                     break;
277                 case ENABLED_NETWORKS_TDSCDMA_CHOICES:
278                     entryValues = getResourcesForSubId().getStringArray(
279                             R.array.enabled_networks_tdscdma_values);
280                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
281                     if (entryValuesInt.length < 3) {
282                         throw new IllegalArgumentException(
283                                 "ENABLED_NETWORKS_TDSCDMA_CHOICES index error.");
284                     }
285                     add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
286                     addLteEntry(entryValuesInt[0]);
287                     add3gEntry(entryValuesInt[1]);
288                     add2gEntry(entryValuesInt[2]);
289                     break;
290                 case ENABLED_NETWORKS_EXCEPT_GSM_LTE_CHOICES:
291                     entryValues = getResourcesForSubId().getStringArray(
292                             R.array.enabled_networks_except_gsm_lte_values);
293                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
294                     if (entryValuesInt.length < 1) {
295                         throw new IllegalArgumentException(
296                                 "ENABLED_NETWORKS_EXCEPT_GSM_LTE_CHOICES index error.");
297                     }
298                     add3gEntry(entryValuesInt[0]);
299                     break;
300                 case ENABLED_NETWORKS_EXCEPT_GSM_4G_CHOICES:
301                     entryValues = getResourcesForSubId().getStringArray(
302                             R.array.enabled_networks_except_gsm_values);
303                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
304                     if (entryValuesInt.length < 2) {
305                         throw new IllegalArgumentException(
306                                 "ENABLED_NETWORKS_EXCEPT_GSM_4G_CHOICES index error.");
307                     }
308                     add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
309                     add4gEntry(entryValuesInt[0]);
310                     add3gEntry(entryValuesInt[1]);
311                     break;
312                 case ENABLED_NETWORKS_EXCEPT_GSM_CHOICES:
313                     entryValues = getResourcesForSubId().getStringArray(
314                             R.array.enabled_networks_except_gsm_values);
315                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
316                     if (entryValuesInt.length < 2) {
317                         throw new IllegalArgumentException(
318                                 "ENABLED_NETWORKS_EXCEPT_GSM_CHOICES index error.");
319                     }
320                     add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
321                     addLteEntry(entryValuesInt[0]);
322                     add3gEntry(entryValuesInt[1]);
323                     break;
324                 case ENABLED_NETWORKS_EXCEPT_LTE_CHOICES:
325                     entryValues = getResourcesForSubId().getStringArray(
326                             R.array.enabled_networks_except_lte_values);
327                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
328                     if (entryValuesInt.length < 2) {
329                         throw new IllegalArgumentException(
330                                 "ENABLED_NETWORKS_EXCEPT_LTE_CHOICES index error.");
331                     }
332                     add3gEntry(entryValuesInt[0]);
333                     add2gEntry(entryValuesInt[1]);
334                     break;
335                 case ENABLED_NETWORKS_4G_CHOICES:
336                     entryValues = getResourcesForSubId().getStringArray(
337                             R.array.enabled_networks_values);
338                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
339                     if (entryValuesInt.length < 3) {
340                         throw new IllegalArgumentException(
341                                 "ENABLED_NETWORKS_4G_CHOICES index error.");
342                     }
343                     add5gEntry(addNrToLteNetworkType(
344                             entryValuesInt[0]));
345                     add4gEntry(entryValuesInt[0]);
346                     add3gEntry(entryValuesInt[1]);
347                     add2gEntry(entryValuesInt[2]);
348                     break;
349                 case ENABLED_NETWORKS_CHOICES:
350                     entryValues = getResourcesForSubId().getStringArray(
351                             R.array.enabled_networks_values);
352                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
353                     if (entryValuesInt.length < 3) {
354                         throw new IllegalArgumentException("ENABLED_NETWORKS_CHOICES index error.");
355                     }
356                     add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
357                     addLteEntry(entryValuesInt[0]);
358                     add3gEntry(entryValuesInt[1]);
359                     add2gEntry(entryValuesInt[2]);
360                     break;
361                 case PREFERRED_NETWORK_MODE_CHOICES_WORLD_MODE:
362                     entryValues = getResourcesForSubId().getStringArray(
363                             R.array.preferred_network_mode_values_world_mode);
364                     entryValuesInt = Stream.of(entryValues).mapToInt(Integer::parseInt).toArray();
365                     if (entryValuesInt.length < 3) {
366                         throw new IllegalArgumentException(
367                                 "PREFERRED_NETWORK_MODE_CHOICES_WORLD_MODE index error.");
368                     }
369                     addGlobalEntry(entryValuesInt[0]);
370 
371                     addCustomEntry(
372                             getResourcesForSubId().getString(
373                                     R.string.network_world_mode_cdma_lte),
374                             entryValuesInt[1]);
375                     addCustomEntry(
376                             getResourcesForSubId().getString(
377                                     R.string.network_world_mode_gsm_lte),
378                             entryValuesInt[2]);
379                     break;
380                 default:
381                     throw new IllegalArgumentException("Not supported enabled network types.");
382             }
383         }
384 
getPreferredNetworkMode()385         private int getPreferredNetworkMode() {
386             int networkMode = MobileNetworkUtils.getNetworkTypeFromRaf(
387                     (int) mTelephonyManager.getAllowedNetworkTypesForReason(
388                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
389             if (!showNrList()) {
390                 Log.d(LOG_TAG, "Network mode :" + networkMode + " reduce NR");
391                 networkMode = reduceNrToLteNetworkType(networkMode);
392             }
393             Log.d(LOG_TAG, "getPreferredNetworkMode: " + networkMode);
394             return networkMode;
395         }
396 
getEnabledNetworkType()397         private EnabledNetworks getEnabledNetworkType() {
398             EnabledNetworks enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_UNKNOWN;
399             final int phoneType = mTelephonyManager.getPhoneType();
400             final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
401 
402             if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
403                 final int lteForced = android.provider.Settings.Global.getInt(
404                         mContext.getContentResolver(),
405                         android.provider.Settings.Global.LTE_SERVICE_FORCED + mSubId,
406                         0);
407                 final int settingsNetworkMode = getPreferredNetworkMode();
408                 if (mTelephonyManager.isLteCdmaEvdoGsmWcdmaEnabled()) {
409                     if (lteForced == 0) {
410                         enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_CDMA_CHOICES;
411                     } else {
412                         switch (settingsNetworkMode) {
413                             case TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO:
414                             case TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO:
415                             case TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA:
416                                 enabledNetworkType =
417                                         EnabledNetworks.ENABLED_NETWORKS_CDMA_NO_LTE_CHOICES;
418                                 break;
419                             case TelephonyManagerConstants.NETWORK_MODE_GLOBAL:
420                             case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
421                             case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
422                             case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
423                                 enabledNetworkType =
424                                         EnabledNetworks.ENABLED_NETWORKS_CDMA_ONLY_LTE_CHOICES;
425                                 break;
426                             default:
427                                 enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_CDMA_CHOICES;
428                                 break;
429                         }
430                     }
431                 }
432             } else if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
433                 if (MobileNetworkUtils.isTdscdmaSupported(mContext, mSubId)) {
434                     enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_TDSCDMA_CHOICES;
435                 } else if (carrierConfig != null
436                         && !carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
437                         && !carrierConfig.getBoolean(CarrierConfigManager.KEY_LTE_ENABLED_BOOL)) {
438                     enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_EXCEPT_GSM_LTE_CHOICES;
439                 } else if (carrierConfig != null
440                         && !carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
441                     enabledNetworkType = mShow4gForLTE
442                             ? EnabledNetworks.ENABLED_NETWORKS_EXCEPT_GSM_4G_CHOICES
443                             : EnabledNetworks.ENABLED_NETWORKS_EXCEPT_GSM_CHOICES;
444                 } else if (carrierConfig != null
445                         && !carrierConfig.getBoolean(CarrierConfigManager.KEY_LTE_ENABLED_BOOL)) {
446                     enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_EXCEPT_LTE_CHOICES;
447                 } else if (mIsGlobalCdma) {
448                     enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_CDMA_CHOICES;
449                 } else {
450                     enabledNetworkType = mShow4gForLTE ? EnabledNetworks.ENABLED_NETWORKS_4G_CHOICES
451                             : EnabledNetworks.ENABLED_NETWORKS_CHOICES;
452                 }
453             }
454             //TODO(b/117881708): figure out what world mode is, then we can optimize code. Otherwise
455             // I prefer to keep this old code
456             if (MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
457                 enabledNetworkType = EnabledNetworks.PREFERRED_NETWORK_MODE_CHOICES_WORLD_MODE;
458             }
459 
460             Log.d(LOG_TAG, "enabledNetworkType: " + enabledNetworkType);
461             return enabledNetworkType;
462         }
463 
464         /**
465          * Sets the display string for the network mode choice and selects the corresponding item
466          *
467          * @param networkMode the current network mode. The current mode might not be an option in
468          *                    the choice list. The nearest choice is selected instead
469          */
setPreferenceValueAndSummary(int networkMode)470         void setPreferenceValueAndSummary(int networkMode) {
471             setSelectedEntry(networkMode);
472             switch (networkMode) {
473                 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_WCDMA:
474                 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
475                 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM:
476                     setSelectedEntry(
477                             TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
478                     setSummary(R.string.network_3G);
479                     break;
480                 case TelephonyManagerConstants.NETWORK_MODE_WCDMA_ONLY:
481                 case TelephonyManagerConstants.NETWORK_MODE_GSM_UMTS:
482                 case TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF:
483                     if (!mIsGlobalCdma) {
484                         setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF);
485                         setSummary(R.string.network_3G);
486                     } else {
487                         setSelectedEntry(
488                                 TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
489                         setSummary(R.string.network_global);
490                     }
491                     break;
492                 case TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY:
493                     if (!mIsGlobalCdma) {
494                         setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY);
495                         setSummary(R.string.network_2G);
496                     } else {
497                         setSelectedEntry(
498                                 TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
499                         setSummary(R.string.network_global);
500                     }
501                     break;
502                 case TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA:
503                     if (MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
504                         setSummary(
505                                 R.string.preferred_network_mode_lte_gsm_umts_summary);
506                         break;
507                     }
508                 case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
509                 case TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA:
510                     if (!mIsGlobalCdma) {
511                         setSelectedEntry(
512                                 TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA);
513                         if (is5gEntryDisplayed()) {
514                             setSummary(mShow4gForLTE
515                                     ? R.string.network_4G_pure : R.string.network_lte_pure);
516                         } else {
517                             setSummary(mShow4gForLTE
518                                     ? R.string.network_4G : R.string.network_lte);
519                         }
520                     } else {
521                         setSelectedEntry(
522                                 TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
523                         setSummary(R.string.network_global);
524                     }
525                     break;
526                 case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
527                     if (MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
528                         setSummary(
529                                 R.string.preferred_network_mode_lte_cdma_summary);
530                     } else {
531                         setSelectedEntry(
532                                 TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO);
533                         setSummary(is5gEntryDisplayed()
534                                 ? R.string.network_lte_pure : R.string.network_lte);
535                     }
536                     break;
537                 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
538                     setSelectedEntry(
539                             TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
540                     setSummary(R.string.network_3G);
541                     break;
542                 case TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO:
543                 case TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA:
544                 case TelephonyManagerConstants.NETWORK_MODE_GLOBAL:
545                     setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO);
546                     setSummary(R.string.network_3G);
547                     break;
548                 case TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO:
549                     setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO);
550                     setSummary(R.string.network_1x);
551                     break;
552                 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY:
553                     setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY);
554                     setSummary(R.string.network_3G);
555                     break;
556                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
557                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
558                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA:
559                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
560                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
561                 case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
562                     if (MobileNetworkUtils.isTdscdmaSupported(mContext, mSubId)) {
563                         setSelectedEntry(TelephonyManagerConstants
564                                 .NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
565                         setSummary(is5gEntryDisplayed()
566                                 ? R.string.network_lte_pure : R.string.network_lte);
567                     } else {
568                         setSelectedEntry(
569                                 TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
570                         if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA
571                                 || mIsGlobalCdma
572                                 || MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
573                             setSummary(R.string.network_global);
574                         } else {
575                             if (is5gEntryDisplayed()) {
576                                 setSummary(mShow4gForLTE
577                                         ? R.string.network_4G_pure : R.string.network_lte_pure);
578                             } else {
579                                 setSummary(mShow4gForLTE
580                                         ? R.string.network_4G : R.string.network_lte);
581                             }
582                         }
583                     }
584                     break;
585 
586                 case TelephonyManagerConstants.NETWORK_MODE_NR_ONLY:
587                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE:
588                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
589                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA:
590                     setSelectedEntry(
591                             TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA);
592                     setSummary(getResourcesForSubId().getString(R.string.network_5G_recommended));
593                     break;
594                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
595                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
596                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
597                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
598                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
599                     setSelectedEntry(TelephonyManagerConstants
600                             .NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
601                     setSummary(getResourcesForSubId().getString(R.string.network_5G_recommended));
602                     break;
603                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
604                     setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO);
605                     setSummary(getResourcesForSubId().getString(R.string.network_5G_recommended));
606                     break;
607                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
608                     setSelectedEntry(
609                             TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
610                     if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA
611                             || mIsGlobalCdma
612                             || MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
613                         setSummary(R.string.network_global);
614                     } else {
615                         setSummary(getResourcesForSubId().getString(
616                                 R.string.network_5G_recommended));
617                     }
618                     break;
619                 default:
620                     setSummary(
621                             getResourcesForSubId().getString(
622                                     R.string.mobile_network_mode_error, networkMode));
623             }
624         }
625 
626         /**
627          * Transform LTE network mode to 5G network mode.
628          *
629          * @param networkType an LTE network mode without 5G.
630          * @return the corresponding network mode with 5G.
631          */
addNrToLteNetworkType(int networkType)632         private int addNrToLteNetworkType(int networkType) {
633             switch (networkType) {
634                 case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
635                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE;
636                 case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
637                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
638                 case TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA:
639                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
640                 case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
641                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA;
642                 case TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA:
643                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA;
644                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA:
645                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA;
646                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
647                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM;
648                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
649                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA;
650                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
651                     return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA;
652                 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
653                     return TelephonyManagerConstants
654                             .NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
655                 default:
656                     return networkType; // not LTE
657             }
658         }
659 
660         /**
661          * Transform NR5G network mode to LTE network mode.
662          *
663          * @param networkType an 5G network mode.
664          * @return the corresponding network mode without 5G.
665          */
reduceNrToLteNetworkType(int networkType)666         private int reduceNrToLteNetworkType(int networkType) {
667             switch (networkType) {
668                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE:
669                     return TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY;
670                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
671                     return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO;
672                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
673                     return TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
674                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
675                     return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
676                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA:
677                     return TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA;
678                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
679                     return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA;
680                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
681                     return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
682                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
683                     return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
684                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
685                     return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
686                 case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
687                     return TelephonyManagerConstants
688                             .NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
689                 default:
690                     return networkType; // do nothing
691             }
692         }
693 
setPreferenceValueAndSummary()694         private void setPreferenceValueAndSummary() {
695             setPreferenceValueAndSummary(getPreferredNetworkMode());
696         }
697 
checkSupportedRadioBitmask(long supportedRadioBitmask, long targetBitmask)698         private boolean checkSupportedRadioBitmask(long supportedRadioBitmask, long targetBitmask) {
699             return (targetBitmask & supportedRadioBitmask) > 0;
700         }
701 
702         /**
703          * Add 5G option. Only show the UI when device supported 5G and allowed 5G.
704          */
add5gEntry(int value)705         private void add5gEntry(int value) {
706             boolean isNRValue = value >= TelephonyManagerConstants.NETWORK_MODE_NR_ONLY;
707             if (showNrList() && isNRValue) {
708                 mEntries.add(getResourcesForSubId().getString(R.string.network_5G_recommended));
709                 mEntriesValue.add(value);
710                 mIs5gEntryDisplayed = true;
711             } else {
712                 mIs5gEntryDisplayed = false;
713                 Log.d(LOG_TAG, "Hide 5G option. "
714                         + " supported5GRadioAccessFamily: " + mSupported5gRadioAccessFamily
715                         + " allowed5GNetworkType: " + mAllowed5gNetworkType
716                         + " isNRValue: " + isNRValue);
717             }
718         }
719 
addGlobalEntry(int value)720         private void addGlobalEntry(int value) {
721             Log.d(LOG_TAG, "addGlobalEntry. "
722                     + " supported5GRadioAccessFamily: " + mSupported5gRadioAccessFamily
723                     + " allowed5GNetworkType: " + mAllowed5gNetworkType);
724             mEntries.add(getResourcesForSubId().getString(R.string.network_global));
725             if (showNrList()) {
726                 value = addNrToLteNetworkType(value);
727             }
728             mEntriesValue.add(value);
729         }
730 
showNrList()731         private boolean showNrList() {
732             return mSupported5gRadioAccessFamily && mAllowed5gNetworkType;
733         }
734 
735         /**
736          * Add LTE entry. If device supported 5G, show "LTE" instead of "LTE (recommended)".
737          */
addLteEntry(int value)738         private void addLteEntry(int value) {
739             if (showNrList()) {
740                 mEntries.add(getResourcesForSubId().getString(R.string.network_lte_pure));
741             } else {
742                 mEntries.add(getResourcesForSubId().getString(R.string.network_lte));
743             }
744             mEntriesValue.add(value);
745         }
746 
747         /**
748          * Add 4G entry. If device supported 5G, show "4G" instead of "4G (recommended)".
749          */
add4gEntry(int value)750         private void add4gEntry(int value) {
751             if (showNrList()) {
752                 mEntries.add(getResourcesForSubId().getString(R.string.network_4G_pure));
753             } else {
754                 mEntries.add(getResourcesForSubId().getString(R.string.network_4G));
755             }
756             mEntriesValue.add(value);
757         }
758 
add3gEntry(int value)759         private void add3gEntry(int value) {
760             mEntries.add(getResourcesForSubId().getString(R.string.network_3G));
761             mEntriesValue.add(value);
762         }
763 
add2gEntry(int value)764         private void add2gEntry(int value) {
765             mEntries.add(getResourcesForSubId().getString(R.string.network_2G));
766             mEntriesValue.add(value);
767         }
768 
add1xEntry(int value)769         private void add1xEntry(int value) {
770             mEntries.add(getResourcesForSubId().getString(R.string.network_1x));
771             mEntriesValue.add(value);
772         }
773 
addCustomEntry(String name, int value)774         private void addCustomEntry(String name, int value) {
775             mEntries.add(name);
776             mEntriesValue.add(value);
777         }
778 
getEntries()779         private String[] getEntries() {
780             return mEntries.toArray(new String[0]);
781         }
782 
clearAllEntries()783         private void clearAllEntries() {
784             mEntries.clear();
785             mEntriesValue.clear();
786         }
787 
getEntryValues()788         private String[] getEntryValues() {
789             final Integer[] intArr = mEntriesValue.toArray(new Integer[0]);
790             return Arrays.stream(intArr)
791                     .map(String::valueOf)
792                     .toArray(String[]::new);
793         }
794 
getSelectedEntryValue()795         private int getSelectedEntryValue() {
796             return mSelectedEntry;
797         }
798 
setSelectedEntry(int value)799         private void setSelectedEntry(int value) {
800             boolean isInEntriesValue = mEntriesValue.stream()
801                     .anyMatch(v -> v == value);
802 
803             if (isInEntriesValue) {
804                 mSelectedEntry = value;
805             } else if (mEntriesValue.size() > 0) {
806                 // if the value isn't in entriesValue, select on the first one.
807                 mSelectedEntry = mEntriesValue.get(0);
808             } else {
809                 Log.e(LOG_TAG, "entriesValue is empty");
810             }
811         }
812 
getSummary()813         private String getSummary() {
814             return mSummary;
815         }
816 
setSummary(int summaryResId)817         private void setSummary(int summaryResId) {
818             setSummary(getResourcesForSubId().getString(summaryResId));
819         }
820 
setSummary(String summary)821         private void setSummary(String summary) {
822             this.mSummary = summary;
823         }
824 
is5gEntryDisplayed()825         private boolean is5gEntryDisplayed() {
826             return mIs5gEntryDisplayed;
827         }
828 
829     }
830 
831     @Override
onAirplaneModeChanged(boolean airplaneModeEnabled)832     public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
833     }
834 
835     @Override
onSubscriptionsChanged()836     public void onSubscriptionsChanged() {
837         mBuilder.updateConfig();
838     }
839 }
840