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