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 android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI; 20 21 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.CDMA; 22 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.EVDO; 23 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.GSM; 24 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.LTE; 25 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.NR; 26 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA; 27 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_UNKNOWN; 28 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA; 29 import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO; 30 import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA; 31 import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO; 32 import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA; 33 34 import android.annotation.Nullable; 35 import android.content.ContentResolver; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.pm.PackageManager; 39 import android.content.pm.ResolveInfo; 40 import android.database.Cursor; 41 import android.graphics.Color; 42 import android.graphics.drawable.ColorDrawable; 43 import android.graphics.drawable.Drawable; 44 import android.graphics.drawable.LayerDrawable; 45 import android.net.ConnectivityManager; 46 import android.net.Network; 47 import android.net.NetworkCapabilities; 48 import android.os.Bundle; 49 import android.os.PersistableBundle; 50 import android.os.SystemClock; 51 import android.os.SystemProperties; 52 import android.os.UserManager; 53 import android.provider.Settings; 54 import android.telecom.PhoneAccountHandle; 55 import android.telecom.TelecomManager; 56 import android.telephony.CarrierConfigManager; 57 import android.telephony.ServiceState; 58 import android.telephony.SubscriptionInfo; 59 import android.telephony.SubscriptionManager; 60 import android.telephony.TelephonyManager; 61 import android.telephony.euicc.EuiccManager; 62 import android.telephony.ims.ImsManager; 63 import android.telephony.ims.ImsRcsManager; 64 import android.telephony.ims.ProvisioningManager; 65 import android.telephony.ims.RcsUceAdapter; 66 import android.telephony.ims.feature.MmTelFeature; 67 import android.telephony.ims.stub.ImsRegistrationImplBase; 68 import android.text.TextUtils; 69 import android.util.Log; 70 import android.view.Gravity; 71 72 import androidx.annotation.VisibleForTesting; 73 74 import com.android.internal.util.ArrayUtils; 75 import com.android.settings.R; 76 import com.android.settings.Utils; 77 import com.android.settings.core.BasePreferenceController; 78 import com.android.settings.core.SubSettingLauncher; 79 import com.android.settings.network.CarrierConfigCache; 80 import com.android.settings.network.SubscriptionUtil; 81 import com.android.settings.network.ims.WifiCallingQueryImsState; 82 import com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants; 83 import com.android.settingslib.core.instrumentation.Instrumentable; 84 import com.android.settingslib.development.DevelopmentSettingsEnabler; 85 import com.android.settingslib.graph.SignalDrawable; 86 import com.android.settingslib.utils.ThreadUtils; 87 88 import java.util.Arrays; 89 import java.util.HashSet; 90 import java.util.List; 91 import java.util.Set; 92 import java.util.concurrent.ExecutionException; 93 import java.util.concurrent.Future; 94 import java.util.concurrent.TimeUnit; 95 import java.util.concurrent.TimeoutException; 96 97 public class MobileNetworkUtils { 98 99 private static final String TAG = "MobileNetworkUtils"; 100 101 // CID of the device. 102 private static final String KEY_CID = "ro.boot.cid"; 103 // CIDs of devices which should not show anything related to eSIM. 104 private static final String KEY_ESIM_CID_IGNORE = "ro.setupwizard.esim_cid_ignore"; 105 // System Property which is used to decide whether the default eSIM UI will be shown, 106 // the default value is false. 107 private static final String KEY_ENABLE_ESIM_UI_BY_DEFAULT = 108 "esim.enable_esim_system_ui_by_default"; 109 private static final String LEGACY_ACTION_CONFIGURE_PHONE_ACCOUNT = 110 "android.telecom.action.CONNECTION_SERVICE_CONFIGURE"; 111 private static final String RTL_MARK = "\u200F"; 112 113 // The following constants are used to draw signal icon. 114 public static final int NO_CELL_DATA_TYPE_ICON = 0; 115 public static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT); 116 117 /** 118 * Return true if current user limited by UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS. 119 * 120 * Note: Guest user should have this restriction through 121 * GuestTelephonyPreferenceController.java. 122 * However, it's not help with those devices upgraded their software. 123 */ isMobileNetworkUserRestricted(Context context)124 public static boolean isMobileNetworkUserRestricted(Context context) { 125 UserManager um = context.getSystemService(UserManager.class); 126 boolean disallow = false; 127 if (um != null) { 128 disallow = um.isGuestUser() || um.hasUserRestriction( 129 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS); 130 } 131 return disallow; 132 } 133 134 /** 135 * Returns if DPC APNs are enforced. 136 */ isDpcApnEnforced(Context context)137 public static boolean isDpcApnEnforced(Context context) { 138 try (Cursor enforceCursor = context.getContentResolver().query(ENFORCE_MANAGED_URI, 139 null, null, null, null)) { 140 if (enforceCursor == null || enforceCursor.getCount() != 1) { 141 return false; 142 } 143 enforceCursor.moveToFirst(); 144 return enforceCursor.getInt(0) > 0; 145 } 146 } 147 148 /** 149 * Returns true if Wifi calling is provisioned for the specific subscription with id 150 * {@code subId}. 151 */ 152 @VisibleForTesting isWfcProvisionedOnDevice(int subId)153 public static boolean isWfcProvisionedOnDevice(int subId) { 154 final ProvisioningManager provisioningMgr = 155 ProvisioningManager.createForSubscriptionId(subId); 156 if (provisioningMgr == null) { 157 return true; 158 } 159 return provisioningMgr.getProvisioningStatusForCapability( 160 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, 161 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN); 162 } 163 164 /** 165 * @return The current user setting for whether or not contact discovery is enabled for the 166 * subscription id specified. 167 * @see RcsUceAdapter#isUceSettingEnabled() 168 */ isContactDiscoveryEnabled(Context context, int subId)169 public static boolean isContactDiscoveryEnabled(Context context, int subId) { 170 ImsManager imsManager = 171 context.getSystemService(ImsManager.class); 172 return isContactDiscoveryEnabled(imsManager, subId); 173 } 174 175 /** 176 * @return The current user setting for whether or not contact discovery is enabled for the 177 * subscription id specified. 178 * @see RcsUceAdapter#isUceSettingEnabled() 179 */ isContactDiscoveryEnabled(ImsManager imsManager, int subId)180 public static boolean isContactDiscoveryEnabled(ImsManager imsManager, 181 int subId) { 182 ImsRcsManager manager = getImsRcsManager(imsManager, subId); 183 if (manager == null) return false; 184 RcsUceAdapter adapter = manager.getUceAdapter(); 185 try { 186 return adapter.isUceSettingEnabled(); 187 } catch (android.telephony.ims.ImsException e) { 188 Log.w(TAG, "UCE service is not available: " + e.getMessage()); 189 } 190 return false; 191 } 192 193 /** 194 * Set the new user setting to enable or disable contact discovery through RCS UCE. 195 * @see RcsUceAdapter#setUceSettingEnabled(boolean) 196 */ setContactDiscoveryEnabled(ImsManager imsManager, int subId, boolean isEnabled)197 public static void setContactDiscoveryEnabled(ImsManager imsManager, 198 int subId, boolean isEnabled) { 199 ImsRcsManager manager = getImsRcsManager(imsManager, subId); 200 if (manager == null) return; 201 RcsUceAdapter adapter = manager.getUceAdapter(); 202 try { 203 adapter.setUceSettingEnabled(isEnabled); 204 } catch (android.telephony.ims.ImsException e) { 205 Log.w(TAG, "UCE service is not available: " + e.getMessage()); 206 } 207 } 208 209 /** 210 * @return The ImsRcsManager associated with the subscription specified. 211 */ getImsRcsManager(ImsManager imsManager, int subId)212 private static ImsRcsManager getImsRcsManager(ImsManager imsManager, 213 int subId) { 214 if (imsManager == null) return null; 215 try { 216 return imsManager.getImsRcsManager(subId); 217 } catch (Exception e) { 218 Log.w(TAG, "Could not resolve ImsRcsManager: " + e.getMessage()); 219 } 220 return null; 221 } 222 223 /** 224 * @return true if contact discovery is available for the subscription specified and the option 225 * should be shown to the user, false if the option should be hidden. 226 */ isContactDiscoveryVisible(Context context, int subId)227 public static boolean isContactDiscoveryVisible(Context context, int subId) { 228 CarrierConfigCache carrierConfigCache = CarrierConfigCache.getInstance(context); 229 if (!carrierConfigCache.hasCarrierConfigManager()) { 230 Log.w(TAG, "isContactDiscoveryVisible: Could not resolve carrier config"); 231 return false; 232 } 233 PersistableBundle bundle = carrierConfigCache.getConfigForSubId(subId); 234 return bundle.getBoolean( 235 CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, false /*default*/) 236 || bundle.getBoolean(CarrierConfigManager.Ims.KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, 237 false /*default*/); 238 } 239 buildPhoneAccountConfigureIntent( Context context, PhoneAccountHandle accountHandle)240 public static Intent buildPhoneAccountConfigureIntent( 241 Context context, PhoneAccountHandle accountHandle) { 242 Intent intent = buildConfigureIntent( 243 context, accountHandle, TelecomManager.ACTION_CONFIGURE_PHONE_ACCOUNT); 244 245 if (intent == null) { 246 // If the new configuration didn't work, try the old configuration intent. 247 intent = buildConfigureIntent(context, accountHandle, 248 LEGACY_ACTION_CONFIGURE_PHONE_ACCOUNT); 249 } 250 return intent; 251 } 252 buildConfigureIntent( Context context, PhoneAccountHandle accountHandle, String actionStr)253 private static Intent buildConfigureIntent( 254 Context context, PhoneAccountHandle accountHandle, String actionStr) { 255 if (accountHandle == null || accountHandle.getComponentName() == null 256 || TextUtils.isEmpty(accountHandle.getComponentName().getPackageName())) { 257 return null; 258 } 259 260 // Build the settings intent. 261 Intent intent = new Intent(actionStr); 262 intent.setPackage(accountHandle.getComponentName().getPackageName()); 263 intent.addCategory(Intent.CATEGORY_DEFAULT); 264 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle); 265 266 // Check to see that the phone account package can handle the setting intent. 267 final PackageManager pm = context.getPackageManager(); 268 final List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0); 269 if (resolutions.size() == 0) { 270 intent = null; // set no intent if the package cannot handle it. 271 } 272 273 return intent; 274 } 275 276 /** 277 * Whether to show the entry point to eUICC settings. 278 * 279 * <p>We show the entry point on any device which supports eUICC as long as either the eUICC 280 * was ever provisioned (that is, at least one profile was ever downloaded onto it), or if 281 * the user has enabled development mode. 282 */ showEuiccSettings(Context context)283 public static boolean showEuiccSettings(Context context) { 284 if (!SubscriptionUtil.isSimHardwareVisible(context)) { 285 return false; 286 } 287 long timeForAccess = SystemClock.elapsedRealtime(); 288 try { 289 Boolean isShow = ((Future<Boolean>) ThreadUtils.postOnBackgroundThread(() -> { 290 try { 291 return showEuiccSettingsDetecting(context); 292 } catch (Exception threadException) { 293 Log.w(TAG, "Accessing Euicc failure", threadException); 294 } 295 return Boolean.FALSE; 296 })).get(3, TimeUnit.SECONDS); 297 return ((isShow != null) && isShow.booleanValue()); 298 } catch (ExecutionException | InterruptedException | TimeoutException exception) { 299 timeForAccess = SystemClock.elapsedRealtime() - timeForAccess; 300 Log.w(TAG, "Accessing Euicc takes too long: +" + timeForAccess + "ms"); 301 } 302 return false; 303 } 304 305 // The same as #showEuiccSettings(Context context) showEuiccSettingsDetecting(Context context)306 public static Boolean showEuiccSettingsDetecting(Context context) { 307 final EuiccManager euiccManager = 308 (EuiccManager) context.getSystemService(EuiccManager.class); 309 if (!euiccManager.isEnabled()) { 310 Log.w(TAG, "EuiccManager is not enabled."); 311 return false; 312 } 313 314 final ContentResolver cr = context.getContentResolver(); 315 final boolean esimIgnoredDevice = 316 Arrays.asList(TextUtils.split(SystemProperties.get(KEY_ESIM_CID_IGNORE, ""), ",")) 317 .contains(SystemProperties.get(KEY_CID)); 318 final boolean enabledEsimUiByDefault = 319 SystemProperties.getBoolean(KEY_ENABLE_ESIM_UI_BY_DEFAULT, true); 320 final boolean euiccProvisioned = 321 Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) != 0; 322 final boolean inDeveloperMode = 323 DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(context); 324 Log.i(TAG, 325 String.format("showEuiccSettings: esimIgnoredDevice: %b, enabledEsimUiByDefault: " 326 + "%b, euiccProvisioned: %b, inDeveloperMode: %b.", 327 esimIgnoredDevice, enabledEsimUiByDefault, euiccProvisioned, inDeveloperMode)); 328 return (euiccProvisioned 329 || (!esimIgnoredDevice && inDeveloperMode) 330 || (!esimIgnoredDevice && enabledEsimUiByDefault 331 && isCurrentCountrySupported(context))); 332 } 333 334 /** 335 * Return {@code true} if mobile data is enabled 336 */ isMobileDataEnabled(Context context)337 public static boolean isMobileDataEnabled(Context context) { 338 final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class); 339 if (!telephonyManager.isDataEnabled()) { 340 // Check if the data is enabled on the second SIM in the case of dual SIM. 341 final TelephonyManager tmDefaultData = telephonyManager.createForSubscriptionId( 342 SubscriptionManager.getDefaultDataSubscriptionId()); 343 if (tmDefaultData == null || !tmDefaultData.isDataEnabled()) { 344 return false; 345 } 346 } 347 return true; 348 } 349 350 /** 351 * Set whether to enable data for {@code subId}, also whether to disable data for other 352 * subscription 353 */ setMobileDataEnabled(Context context, int subId, boolean enabled, boolean disableOtherSubscriptions)354 public static void setMobileDataEnabled(Context context, int subId, boolean enabled, 355 boolean disableOtherSubscriptions) { 356 final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class) 357 .createForSubscriptionId(subId); 358 final SubscriptionManager subscriptionManager = context.getSystemService( 359 SubscriptionManager.class); 360 telephonyManager.setDataEnabled(enabled); 361 362 if (disableOtherSubscriptions) { 363 final List<SubscriptionInfo> subInfoList = 364 subscriptionManager.getActiveSubscriptionInfoList(); 365 if (subInfoList != null) { 366 for (SubscriptionInfo subInfo : subInfoList) { 367 // We never disable mobile data for opportunistic subscriptions. 368 if (subInfo.getSubscriptionId() != subId && !subInfo.isOpportunistic()) { 369 context.getSystemService(TelephonyManager.class).createForSubscriptionId( 370 subInfo.getSubscriptionId()).setDataEnabled(false); 371 } 372 } 373 } 374 } 375 } 376 377 /** 378 * Return {@code true} if show CDMA category 379 */ isCdmaOptions(Context context, int subId)380 public static boolean isCdmaOptions(Context context, int subId) { 381 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 382 return false; 383 } 384 final PersistableBundle carrierConfig = 385 CarrierConfigCache.getInstance(context).getConfigForSubId(subId); 386 if (carrierConfig != null 387 && !carrierConfig.getBoolean( 388 CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL) 389 && carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) { 390 return true; 391 } 392 393 final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class) 394 .createForSubscriptionId(subId); 395 if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 396 return true; 397 } 398 399 if (isWorldMode(context, subId)) { 400 final int settingsNetworkMode = getNetworkTypeFromRaf( 401 (int) telephonyManager.getAllowedNetworkTypesForReason( 402 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER)); 403 404 if (settingsNetworkMode == NETWORK_MODE_LTE_GSM_WCDMA 405 || settingsNetworkMode == NETWORK_MODE_LTE_CDMA_EVDO 406 || settingsNetworkMode == NETWORK_MODE_NR_LTE_GSM_WCDMA 407 || settingsNetworkMode == NETWORK_MODE_NR_LTE_CDMA_EVDO) { 408 return true; 409 } 410 411 if (shouldSpeciallyUpdateGsmCdma(context, subId)) { 412 return true; 413 } 414 } 415 416 return false; 417 } 418 419 /** 420 * return {@code true} if we need show Gsm related settings 421 */ isGsmOptions(Context context, int subId)422 public static boolean isGsmOptions(Context context, int subId) { 423 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 424 return false; 425 } 426 if (isGsmBasicOptions(context, subId)) { 427 return true; 428 } 429 final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class) 430 .createForSubscriptionId(subId); 431 final int networkMode = getNetworkTypeFromRaf( 432 (int) telephonyManager.getAllowedNetworkTypesForReason( 433 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER)); 434 if (isWorldMode(context, subId)) { 435 if (networkMode == NETWORK_MODE_LTE_CDMA_EVDO 436 || networkMode == NETWORK_MODE_LTE_GSM_WCDMA 437 || networkMode == NETWORK_MODE_NR_LTE_CDMA_EVDO 438 || networkMode == NETWORK_MODE_NR_LTE_GSM_WCDMA) { 439 return true; 440 } else if (shouldSpeciallyUpdateGsmCdma(context, subId)) { 441 return true; 442 } 443 } 444 445 return false; 446 } 447 isGsmBasicOptions(Context context, int subId)448 private static boolean isGsmBasicOptions(Context context, int subId) { 449 final PersistableBundle carrierConfig = 450 CarrierConfigCache.getInstance(context).getConfigForSubId(subId); 451 if (carrierConfig != null 452 && !carrierConfig.getBoolean( 453 CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL) 454 && carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) { 455 return true; 456 } 457 458 final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class) 459 .createForSubscriptionId(subId); 460 if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 461 return true; 462 } 463 464 return false; 465 } 466 467 /** 468 * Return {@code true} if it is world mode, and we may show advanced options in telephony 469 * settings 470 */ isWorldMode(Context context, int subId)471 public static boolean isWorldMode(Context context, int subId) { 472 final PersistableBundle carrierConfig = 473 CarrierConfigCache.getInstance(context).getConfigForSubId(subId); 474 return carrierConfig == null 475 ? false 476 : carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL); 477 } 478 479 /** 480 * Return {@code true} if we need show settings for network selection(i.e. Verizon) 481 */ shouldDisplayNetworkSelectOptions(Context context, int subId)482 public static boolean shouldDisplayNetworkSelectOptions(Context context, int subId) { 483 final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class) 484 .createForSubscriptionId(subId); 485 final PersistableBundle carrierConfig = 486 CarrierConfigCache.getInstance(context).getConfigForSubId(subId); 487 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID 488 || carrierConfig == null 489 || !carrierConfig.getBoolean( 490 CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL) 491 || carrierConfig.getBoolean( 492 CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL) 493 || (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL) 494 && !telephonyManager.isManualNetworkSelectionAllowed())) { 495 return false; 496 } 497 498 if (isWorldMode(context, subId)) { 499 final int networkMode = getNetworkTypeFromRaf( 500 (int) telephonyManager.getAllowedNetworkTypesForReason( 501 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER)); 502 if (networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO) { 503 return false; 504 } 505 if (shouldSpeciallyUpdateGsmCdma(context, subId)) { 506 return false; 507 } 508 509 if (networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA) { 510 return true; 511 } 512 } 513 514 return isGsmBasicOptions(context, subId); 515 } 516 517 /** 518 * Return {@code true} if Tdscdma is supported in current subscription 519 */ isTdscdmaSupported(Context context, int subId)520 public static boolean isTdscdmaSupported(Context context, int subId) { 521 return isTdscdmaSupported(context, 522 context.getSystemService(TelephonyManager.class).createForSubscriptionId(subId)); 523 } 524 525 //TODO(b/117651939): move it to telephony isTdscdmaSupported(Context context, TelephonyManager telephonyManager)526 private static boolean isTdscdmaSupported(Context context, TelephonyManager telephonyManager) { 527 final PersistableBundle carrierConfig = CarrierConfigCache.getInstance(context).getConfig(); 528 529 if (carrierConfig == null) { 530 return false; 531 } 532 533 if (carrierConfig.getBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL)) { 534 return true; 535 } 536 final String[] numericArray = carrierConfig.getStringArray( 537 CarrierConfigManager.KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY); 538 if (numericArray == null) { 539 return false; 540 } 541 final ServiceState serviceState = telephonyManager.getServiceState(); 542 final String operatorNumeric = 543 (serviceState != null) ? serviceState.getOperatorNumeric() : null; 544 if (operatorNumeric == null) { 545 return false; 546 } 547 for (String numeric : numericArray) { 548 if (operatorNumeric.equals(numeric)) { 549 return true; 550 } 551 } 552 return false; 553 } 554 555 /** 556 * Return subId that supported by search. If there are more than one, return first one, 557 * otherwise return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} 558 */ getSearchableSubscriptionId(Context context)559 public static int getSearchableSubscriptionId(Context context) { 560 final int[] subIds = getActiveSubscriptionIdList(context); 561 562 return subIds.length >= 1 ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID; 563 } 564 565 /** 566 * Return availability for a default subscription id. If subId already been set, use it to 567 * check, otherwise traverse all active subIds on device to check. 568 * @param context context 569 * @param defSubId Default subId get from telephony preference controller 570 * @param callback Callback to check availability for a specific subId 571 * @return Availability 572 * 573 * @see BasePreferenceController#getAvailabilityStatus() 574 */ getAvailability(Context context, int defSubId, TelephonyAvailabilityCallback callback)575 public static int getAvailability(Context context, int defSubId, 576 TelephonyAvailabilityCallback callback) { 577 if (defSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 578 // If subId has been set, return the corresponding status 579 return callback.getAvailabilityStatus(defSubId); 580 } else { 581 // Otherwise, search whether there is one subId in device that support this preference 582 final int[] subIds = getActiveSubscriptionIdList(context); 583 if (ArrayUtils.isEmpty(subIds)) { 584 return callback.getAvailabilityStatus( 585 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 586 } else { 587 for (final int subId : subIds) { 588 final int status = callback.getAvailabilityStatus(subId); 589 if (status == BasePreferenceController.AVAILABLE) { 590 return status; 591 } 592 } 593 return callback.getAvailabilityStatus(subIds[0]); 594 } 595 } 596 } 597 598 /** 599 * This method is migrated from {@link com.android.phone.MobileNetworkSettings} and we should 600 * use it carefully. This code snippet doesn't have very clear meaning however we should 601 * update GSM or CDMA differently based on what it returns. 602 * 603 * 1. For all CDMA settings, make them visible if it return {@code true} 604 * 2. For GSM settings, make them visible if it return {@code true} unless 3 605 * 3. For network select settings, make it invisible if it return {@code true} 606 */ 607 @VisibleForTesting shouldSpeciallyUpdateGsmCdma(Context context, int subId)608 static boolean shouldSpeciallyUpdateGsmCdma(Context context, int subId) { 609 if (!isWorldMode(context, subId)) { 610 return false; 611 } 612 final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class) 613 .createForSubscriptionId(subId); 614 final int networkMode = getNetworkTypeFromRaf( 615 (int) telephonyManager.getAllowedNetworkTypesForReason( 616 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER)); 617 if (networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM 618 || networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA 619 || networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA 620 || networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA 621 || networkMode 622 == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA 623 || networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) { 624 if (!isTdscdmaSupported(context, subId)) { 625 return true; 626 } 627 } 628 629 return false; 630 } 631 getSignalStrengthIcon(Context context, int level, int numLevels, int iconType, boolean cutOut, boolean carrierNetworkChanged)632 public static Drawable getSignalStrengthIcon(Context context, int level, int numLevels, 633 int iconType, boolean cutOut, boolean carrierNetworkChanged) { 634 final SignalDrawable signalDrawable = new SignalDrawable(context); 635 signalDrawable.setLevel( 636 carrierNetworkChanged ? SignalDrawable.getCarrierChangeState(numLevels) 637 : SignalDrawable.getState(level, numLevels, cutOut)); 638 639 // Make the network type drawable 640 final Drawable networkDrawable = 641 iconType == NO_CELL_DATA_TYPE_ICON 642 ? EMPTY_DRAWABLE 643 : context.getResources().getDrawable(iconType, context.getTheme()); 644 645 // Overlay the two drawables 646 final Drawable[] layers = {networkDrawable, signalDrawable}; 647 final int iconSize = 648 context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size); 649 650 final LayerDrawable icons = new LayerDrawable(layers); 651 // Set the network type icon at the top left 652 icons.setLayerGravity(0 /* index of networkDrawable */, Gravity.TOP | Gravity.LEFT); 653 // Set the signal strength icon at the bottom right 654 icons.setLayerGravity(1 /* index of SignalDrawable */, Gravity.BOTTOM | Gravity.RIGHT); 655 icons.setLayerSize(1 /* index of SignalDrawable */, iconSize, iconSize); 656 icons.setTintList(Utils.getColorAttr(context, android.R.attr.colorControlNormal)); 657 return icons; 658 } 659 660 /** 661 * This method is migrated from 662 * {@link android.telephony.TelephonyManager.getNetworkOperatorName}. Which provides 663 * 664 * 1. Better support under multi-SIM environment. 665 * 2. Similar design which aligned with operator name displayed in status bar 666 */ getCurrentCarrierNameForDisplay(Context context, int subId)667 public static CharSequence getCurrentCarrierNameForDisplay(Context context, int subId) { 668 final SubscriptionManager sm = context.getSystemService(SubscriptionManager.class); 669 if (sm != null) { 670 final SubscriptionInfo subInfo = getSubscriptionInfo(sm, subId); 671 if (subInfo != null) { 672 return subInfo.getCarrierName(); 673 } 674 } 675 return getOperatorNameFromTelephonyManager(context); 676 } 677 getCurrentCarrierNameForDisplay(Context context)678 public static CharSequence getCurrentCarrierNameForDisplay(Context context) { 679 final SubscriptionManager sm = context.getSystemService(SubscriptionManager.class); 680 if (sm != null) { 681 final int subId = sm.getDefaultSubscriptionId(); 682 final SubscriptionInfo subInfo = getSubscriptionInfo(sm, subId); 683 if (subInfo != null) { 684 return subInfo.getCarrierName(); 685 } 686 } 687 return getOperatorNameFromTelephonyManager(context); 688 } 689 getSubscriptionInfo(SubscriptionManager subManager, int subId)690 private static SubscriptionInfo getSubscriptionInfo(SubscriptionManager subManager, int subId) { 691 List<SubscriptionInfo> subInfos = subManager.getActiveSubscriptionInfoList(); 692 if (subInfos == null) { 693 return null; 694 } 695 for (SubscriptionInfo subInfo : subInfos) { 696 if (subInfo.getSubscriptionId() == subId) { 697 return subInfo; 698 } 699 } 700 return null; 701 } 702 getOperatorNameFromTelephonyManager(Context context)703 private static String getOperatorNameFromTelephonyManager(Context context) { 704 final TelephonyManager tm = 705 (TelephonyManager) context.getSystemService(TelephonyManager.class); 706 if (tm == null) { 707 return null; 708 } 709 return tm.getNetworkOperatorName(); 710 } 711 getActiveSubscriptionIdList(Context context)712 private static int[] getActiveSubscriptionIdList(Context context) { 713 final SubscriptionManager subscriptionManager = context.getSystemService( 714 SubscriptionManager.class); 715 final List<SubscriptionInfo> subInfoList = 716 subscriptionManager.getActiveSubscriptionInfoList(); 717 if (subInfoList == null) { 718 return new int[0]; 719 } 720 int[] activeSubIds = new int[subInfoList.size()]; 721 int i = 0; 722 for (SubscriptionInfo subInfo : subInfoList) { 723 activeSubIds[i] = subInfo.getSubscriptionId(); 724 i++; 725 } 726 return activeSubIds; 727 } 728 729 /** 730 * Loop through all the device logical slots to check whether the user's current country 731 * supports eSIM. 732 */ isCurrentCountrySupported(Context context)733 private static boolean isCurrentCountrySupported(Context context) { 734 final EuiccManager em = (EuiccManager) context.getSystemService(EuiccManager.class); 735 final TelephonyManager tm = 736 (TelephonyManager) context.getSystemService(TelephonyManager.class); 737 738 Set<String> countrySet = new HashSet<>(); 739 for (int i = 0; i < tm.getPhoneCount(); i++) { 740 String countryCode = tm.getNetworkCountryIso(i); 741 if (!TextUtils.isEmpty(countryCode)) { 742 countrySet.add(countryCode); 743 } 744 } 745 boolean isSupported = countrySet.stream().anyMatch(em::isSupportedCountry); 746 Log.i(TAG, "isCurrentCountrySupported countryCodes: " + countrySet 747 + " eSIMSupported: " + isSupported); 748 return isSupported; 749 } 750 751 /** 752 * Imported from {@link android.telephony.RadioAccessFamily} 753 */ getRafFromNetworkType(int type)754 public static long getRafFromNetworkType(int type) { 755 switch (type) { 756 case TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF: 757 return GSM | WCDMA; 758 case TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY: 759 return GSM; 760 case TelephonyManagerConstants.NETWORK_MODE_WCDMA_ONLY: 761 return WCDMA; 762 case TelephonyManagerConstants.NETWORK_MODE_GSM_UMTS: 763 return GSM | WCDMA; 764 case TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO: 765 return CDMA | EVDO; 766 case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO: 767 return LTE | CDMA | EVDO; 768 case TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA: 769 return LTE | GSM | WCDMA; 770 case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: 771 return LTE | CDMA | EVDO | GSM | WCDMA; 772 case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY: 773 return LTE; 774 case TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA: 775 return LTE | WCDMA; 776 case TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO: 777 return CDMA; 778 case TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA: 779 return EVDO; 780 case TelephonyManagerConstants.NETWORK_MODE_GLOBAL: 781 return GSM | WCDMA | CDMA | EVDO; 782 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY: 783 return RAF_TD_SCDMA; 784 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_WCDMA: 785 return RAF_TD_SCDMA | WCDMA; 786 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA: 787 return LTE | RAF_TD_SCDMA; 788 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM: 789 return RAF_TD_SCDMA | GSM; 790 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM: 791 return LTE | RAF_TD_SCDMA | GSM; 792 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA: 793 return RAF_TD_SCDMA | GSM | WCDMA; 794 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA: 795 return LTE | RAF_TD_SCDMA | WCDMA; 796 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: 797 return LTE | RAF_TD_SCDMA | GSM | WCDMA; 798 case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: 799 return RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; 800 case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: 801 return LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; 802 case (TelephonyManagerConstants.NETWORK_MODE_NR_ONLY): 803 return NR; 804 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE): 805 return NR | LTE; 806 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO): 807 return NR | LTE | CDMA | EVDO; 808 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA): 809 return NR | LTE | GSM | WCDMA; 810 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA): 811 return NR | LTE | CDMA | EVDO | GSM | WCDMA; 812 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA): 813 return NR | LTE | WCDMA; 814 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA): 815 return NR | LTE | RAF_TD_SCDMA; 816 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM): 817 return NR | LTE | RAF_TD_SCDMA | GSM; 818 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA): 819 return NR | LTE | RAF_TD_SCDMA | WCDMA; 820 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA): 821 return NR | LTE | RAF_TD_SCDMA | GSM | WCDMA; 822 case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA): 823 return NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; 824 default: 825 return RAF_UNKNOWN; 826 } 827 } 828 829 /** 830 * Imported from {@link android.telephony.RadioAccessFamily} 831 */ getNetworkTypeFromRaf(int raf)832 public static int getNetworkTypeFromRaf(int raf) { 833 raf = getAdjustedRaf(raf); 834 835 switch (raf) { 836 case (GSM | WCDMA): 837 return TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF; 838 case GSM: 839 return TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY; 840 case WCDMA: 841 return TelephonyManagerConstants.NETWORK_MODE_WCDMA_ONLY; 842 case (CDMA | EVDO): 843 return TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO; 844 case (LTE | CDMA | EVDO): 845 return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO; 846 case (LTE | GSM | WCDMA): 847 return TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA; 848 case (LTE | CDMA | EVDO | GSM | WCDMA): 849 return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; 850 case LTE: 851 return TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY; 852 case (LTE | WCDMA): 853 return TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA; 854 case CDMA: 855 return TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO; 856 case EVDO: 857 return TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA; 858 case (GSM | WCDMA | CDMA | EVDO): 859 return TelephonyManagerConstants.NETWORK_MODE_GLOBAL; 860 case RAF_TD_SCDMA: 861 return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY; 862 case (RAF_TD_SCDMA | WCDMA): 863 return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_WCDMA; 864 case (LTE | RAF_TD_SCDMA): 865 return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA; 866 case (RAF_TD_SCDMA | GSM): 867 return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM; 868 case (LTE | RAF_TD_SCDMA | GSM): 869 return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; 870 case (RAF_TD_SCDMA | GSM | WCDMA): 871 return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; 872 case (LTE | RAF_TD_SCDMA | WCDMA): 873 return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; 874 case (LTE | RAF_TD_SCDMA | GSM | WCDMA): 875 return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; 876 case (RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): 877 return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; 878 case (LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): 879 return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; 880 case (NR): 881 return TelephonyManagerConstants.NETWORK_MODE_NR_ONLY; 882 case (NR | LTE): 883 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE; 884 case (NR | LTE | CDMA | EVDO): 885 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO; 886 case (NR | LTE | GSM | WCDMA): 887 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA; 888 case (NR | LTE | CDMA | EVDO | GSM | WCDMA): 889 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA; 890 case (NR | LTE | WCDMA): 891 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA; 892 case (NR | LTE | RAF_TD_SCDMA): 893 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA; 894 case (NR | LTE | RAF_TD_SCDMA | GSM): 895 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM; 896 case (NR | LTE | RAF_TD_SCDMA | WCDMA): 897 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA; 898 case (NR | LTE | RAF_TD_SCDMA | GSM | WCDMA): 899 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA; 900 case (NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): 901 return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; 902 default: 903 return TelephonyManagerConstants.NETWORK_MODE_UNKNOWN; 904 } 905 } 906 907 /** 908 * Imported from {@link android.telephony.RadioAccessFamily} 909 */ getAdjustedRaf(int raf)910 private static int getAdjustedRaf(int raf) { 911 raf = ((GSM & raf) > 0) ? (GSM | raf) : raf; 912 raf = ((WCDMA & raf) > 0) ? (WCDMA | raf) : raf; 913 raf = ((CDMA & raf) > 0) ? (CDMA | raf) : raf; 914 raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf; 915 raf = ((LTE & raf) > 0) ? (LTE | raf) : raf; 916 raf = ((NR & raf) > 0) ? (NR | raf) : raf; 917 return raf; 918 } 919 920 /** 921 * Copied from SubscriptionsPreferenceController#activeNetworkIsCellular() 922 */ activeNetworkIsCellular(Context context)923 public static boolean activeNetworkIsCellular(Context context) { 924 final ConnectivityManager connectivityManager = 925 context.getSystemService(ConnectivityManager.class); 926 final Network activeNetwork = connectivityManager.getActiveNetwork(); 927 if (activeNetwork == null) { 928 return false; 929 } 930 final NetworkCapabilities networkCapabilities = 931 connectivityManager.getNetworkCapabilities(activeNetwork); 932 if (networkCapabilities == null) { 933 return false; 934 } 935 return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); 936 } 937 938 /** 939 * Copied from WifiCallingPreferenceController#isWifiCallingEnabled() 940 */ isWifiCallingEnabled(Context context, int subId, @Nullable WifiCallingQueryImsState queryImsState, @Nullable PhoneAccountHandle phoneAccountHandle)941 public static boolean isWifiCallingEnabled(Context context, int subId, 942 @Nullable WifiCallingQueryImsState queryImsState, 943 @Nullable PhoneAccountHandle phoneAccountHandle) { 944 if (phoneAccountHandle == null){ 945 phoneAccountHandle = context.getSystemService(TelecomManager.class) 946 .getSimCallManagerForSubscription(subId); 947 } 948 boolean isWifiCallingEnabled; 949 if (phoneAccountHandle != null) { 950 final Intent intent = buildPhoneAccountConfigureIntent(context, phoneAccountHandle); 951 isWifiCallingEnabled = intent != null; 952 } else { 953 if (queryImsState == null) { 954 queryImsState = new WifiCallingQueryImsState(context, subId); 955 } 956 isWifiCallingEnabled = queryImsState.isReadyToWifiCalling(); 957 } 958 return isWifiCallingEnabled; 959 } 960 961 962 /** 963 * Returns preferred status of Calls & SMS separately when Provider Model is enabled. 964 */ getPreferredStatus(boolean isRtlMode, Context context, SubscriptionManager subscriptionManager, boolean isPreferredCallStatus)965 public static CharSequence getPreferredStatus(boolean isRtlMode, Context context, 966 SubscriptionManager subscriptionManager, boolean isPreferredCallStatus) { 967 final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions( 968 subscriptionManager); 969 if (!subs.isEmpty()) { 970 final StringBuilder summary = new StringBuilder(); 971 for (SubscriptionInfo subInfo : subs) { 972 int subsSize = subs.size(); 973 final CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName( 974 subInfo, context); 975 976 // Set displayName as summary if there is only one valid SIM. 977 if (subsSize == 1 978 && SubscriptionManager.isValidSubscriptionId(subInfo.getSubscriptionId())) { 979 return displayName; 980 } 981 982 CharSequence status = isPreferredCallStatus 983 ? getPreferredCallStatus(context, subInfo) 984 : getPreferredSmsStatus(context, subInfo); 985 if (status.toString().isEmpty()) { 986 // If there are 2 or more SIMs and one of these has no preferred status, 987 // set only its displayName as summary. 988 summary.append(displayName); 989 } else { 990 summary.append(displayName) 991 .append(" (") 992 .append(status) 993 .append(")"); 994 } 995 // Do not add ", " for the last subscription. 996 if (subInfo != subs.get(subs.size() - 1)) { 997 summary.append(", "); 998 } 999 1000 if (isRtlMode) { 1001 summary.insert(0, RTL_MARK).insert(summary.length(), RTL_MARK); 1002 } 1003 } 1004 return summary; 1005 } else { 1006 return ""; 1007 } 1008 } 1009 getPreferredCallStatus(Context context, SubscriptionInfo subInfo)1010 private static CharSequence getPreferredCallStatus(Context context, SubscriptionInfo subInfo) { 1011 final int subId = subInfo.getSubscriptionId(); 1012 String status = ""; 1013 boolean isDataPreferred = subId == SubscriptionManager.getDefaultVoiceSubscriptionId(); 1014 1015 if (isDataPreferred) { 1016 status = setSummaryResId(context, R.string.calls_sms_preferred); 1017 } 1018 1019 return status; 1020 } 1021 getPreferredSmsStatus(Context context, SubscriptionInfo subInfo)1022 private static CharSequence getPreferredSmsStatus(Context context, SubscriptionInfo subInfo) { 1023 final int subId = subInfo.getSubscriptionId(); 1024 String status = ""; 1025 boolean isSmsPreferred = subId == SubscriptionManager.getDefaultSmsSubscriptionId(); 1026 1027 if (isSmsPreferred) { 1028 status = setSummaryResId(context, R.string.calls_sms_preferred); 1029 } 1030 1031 return status; 1032 } 1033 setSummaryResId(Context context, int resId)1034 private static String setSummaryResId(Context context, int resId) { 1035 return context.getResources().getString(resId); 1036 } 1037 launchMobileNetworkSettings(Context context, SubscriptionInfo info)1038 public static void launchMobileNetworkSettings(Context context, SubscriptionInfo info) { 1039 final int subId = info.getSubscriptionId(); 1040 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 1041 Log.d(TAG, "launchMobileNetworkSettings fail, subId is invalid."); 1042 return; 1043 } 1044 1045 Log.d(TAG, "launchMobileNetworkSettings for subId: " + subId); 1046 final Bundle extra = new Bundle(); 1047 extra.putInt(Settings.EXTRA_SUB_ID, subId); 1048 new SubSettingLauncher(context) 1049 .setTitleText(SubscriptionUtil.getUniqueSubscriptionDisplayName(info, context)) 1050 .setDestination(MobileNetworkSettings.class.getCanonicalName()) 1051 .setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN) 1052 .setArguments(extra) 1053 .launch(); 1054 } 1055 1056 } 1057