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