1 /* 2 * Copyright (C) 2014 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 android.telephony; 18 19 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED; 20 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED; 21 22 import android.Manifest; 23 import android.annotation.CallbackExecutor; 24 import android.annotation.ColorInt; 25 import android.annotation.DurationMillisLong; 26 import android.annotation.IntDef; 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.annotation.RequiresFeature; 30 import android.annotation.RequiresPermission; 31 import android.annotation.SdkConstant; 32 import android.annotation.SdkConstant.SdkConstantType; 33 import android.annotation.SuppressAutoDoc; 34 import android.annotation.SystemApi; 35 import android.annotation.SystemService; 36 import android.app.PendingIntent; 37 import android.app.PropertyInvalidatedCache; 38 import android.compat.annotation.UnsupportedAppUsage; 39 import android.content.Context; 40 import android.content.Intent; 41 import android.content.pm.PackageInfo; 42 import android.content.pm.PackageManager; 43 import android.content.res.Configuration; 44 import android.content.res.Resources; 45 import android.database.ContentObserver; 46 import android.net.NetworkCapabilities; 47 import android.net.NetworkPolicyManager; 48 import android.net.Uri; 49 import android.os.Binder; 50 import android.os.Build; 51 import android.os.Bundle; 52 import android.os.Handler; 53 import android.os.Looper; 54 import android.os.ParcelUuid; 55 import android.os.Process; 56 import android.os.RemoteException; 57 import android.os.UserHandle; 58 import android.provider.Telephony.SimInfo; 59 import android.telephony.euicc.EuiccManager; 60 import android.telephony.ims.ImsMmTelManager; 61 import android.text.TextUtils; 62 import android.util.Base64; 63 import android.util.Log; 64 import android.util.Pair; 65 66 import com.android.internal.telephony.ISetOpportunisticDataCallback; 67 import com.android.internal.telephony.ISub; 68 import com.android.internal.telephony.PhoneConstants; 69 import com.android.internal.telephony.util.HandlerExecutor; 70 import com.android.internal.util.FunctionalUtils; 71 import com.android.internal.util.Preconditions; 72 import com.android.telephony.Rlog; 73 74 import java.io.ByteArrayInputStream; 75 import java.io.ByteArrayOutputStream; 76 import java.io.IOException; 77 import java.io.ObjectInputStream; 78 import java.io.ObjectOutputStream; 79 import java.lang.annotation.Retention; 80 import java.lang.annotation.RetentionPolicy; 81 import java.util.ArrayList; 82 import java.util.Arrays; 83 import java.util.Collections; 84 import java.util.HashMap; 85 import java.util.List; 86 import java.util.Locale; 87 import java.util.Map; 88 import java.util.concurrent.ConcurrentHashMap; 89 import java.util.concurrent.Executor; 90 import java.util.function.Consumer; 91 import java.util.stream.Collectors; 92 93 /** 94 * Subscription manager provides the mobile subscription information. 95 */ 96 @SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) 97 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION) 98 public class SubscriptionManager { 99 private static final String LOG_TAG = "SubscriptionManager"; 100 private static final boolean DBG = false; 101 private static final boolean VDBG = false; 102 103 /** An invalid subscription identifier */ 104 public static final int INVALID_SUBSCRIPTION_ID = -1; 105 106 /** Base value for placeholder SUBSCRIPTION_ID's. */ 107 /** @hide */ 108 public static final int PLACEHOLDER_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1; 109 110 /** An invalid phone identifier */ 111 /** @hide */ 112 public static final int INVALID_PHONE_INDEX = -1; 113 114 /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */ 115 public static final int INVALID_SIM_SLOT_INDEX = -1; 116 117 /** Indicates the default subscription ID in Telephony. */ 118 public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE; 119 120 /** 121 * Indicates the default phone id. 122 * @hide 123 */ 124 public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE; 125 126 /** Indicates the default slot index. */ 127 /** @hide */ 128 public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE; 129 130 /** Minimum possible subid that represents a subscription */ 131 /** @hide */ 132 public static final int MIN_SUBSCRIPTION_ID_VALUE = 0; 133 134 /** Maximum possible subid that represents a subscription */ 135 /** @hide */ 136 public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1; 137 138 /** @hide */ 139 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 140 public static final Uri CONTENT_URI = SimInfo.CONTENT_URI; 141 142 /** The IPC cache key shared by all subscription manager service cacheable properties. */ 143 private static final String CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY = 144 "cache_key.telephony.subscription_manager_service"; 145 146 /** @hide */ 147 public static final String GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME = "getSimSpecificSettings"; 148 149 /** @hide */ 150 public static final String RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME = 151 "restoreSimSpecificSettings"; 152 153 /** 154 * The key of the boolean flag indicating whether restoring subscriptions actually changes 155 * the subscription database or not. 156 * 157 * @hide 158 */ 159 public static final String RESTORE_SIM_SPECIFIC_SETTINGS_DATABASE_UPDATED = 160 "restoreSimSpecificSettingsDatabaseUpdated"; 161 162 /** 163 * Key to the backup & restore data byte array in the Bundle that is returned by {@link 164 * #getAllSimSpecificSettingsForBackup()} or to be pass in to {@link 165 * #restoreAllSimSpecificSettingsFromBackup(byte[])}. 166 * 167 * @hide 168 */ 169 public static final String KEY_SIM_SPECIFIC_SETTINGS_DATA = "KEY_SIM_SPECIFIC_SETTINGS_DATA"; 170 171 private static final int MAX_CACHE_SIZE = 4; 172 173 private static class VoidPropertyInvalidatedCache<T> 174 extends PropertyInvalidatedCache<Void, T> { 175 private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod; 176 private final String mCacheKeyProperty; 177 private final T mDefaultValue; 178 VoidPropertyInvalidatedCache( FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod, String cacheKeyProperty, T defaultValue)179 VoidPropertyInvalidatedCache( 180 FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod, 181 String cacheKeyProperty, 182 T defaultValue) { 183 super(MAX_CACHE_SIZE, cacheKeyProperty); 184 mInterfaceMethod = subscriptionInterfaceMethod; 185 mCacheKeyProperty = cacheKeyProperty; 186 mDefaultValue = defaultValue; 187 } 188 189 @Override recompute(Void query)190 public T recompute(Void query) { 191 // This always throws on any error. The exceptions must be handled outside 192 // the cache. 193 try { 194 return mInterfaceMethod.applyOrThrow(TelephonyManager.getSubscriptionService()); 195 } catch (Exception re) { 196 throw new RuntimeException(re); 197 } 198 } 199 200 @Override query(Void query)201 public T query(Void query) { 202 T result = mDefaultValue; 203 204 try { 205 ISub iSub = TelephonyManager.getSubscriptionService(); 206 if (iSub != null) { 207 result = super.query(query); 208 } 209 } catch (Exception ex) { 210 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty); 211 } 212 213 if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result); 214 return result; 215 } 216 } 217 218 private static class IntegerPropertyInvalidatedCache<T> 219 extends PropertyInvalidatedCache<Integer, T> { 220 private final FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> mInterfaceMethod; 221 private final String mCacheKeyProperty; 222 private final T mDefaultValue; 223 IntegerPropertyInvalidatedCache( FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod, String cacheKeyProperty, T defaultValue)224 IntegerPropertyInvalidatedCache( 225 FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod, 226 String cacheKeyProperty, 227 T defaultValue) { 228 super(MAX_CACHE_SIZE, cacheKeyProperty); 229 mInterfaceMethod = subscriptionInterfaceMethod; 230 mCacheKeyProperty = cacheKeyProperty; 231 mDefaultValue = defaultValue; 232 } 233 234 @Override recompute(Integer query)235 public T recompute(Integer query) { 236 // This always throws on any error. The exceptions must be handled outside 237 // the cache. 238 try { 239 return mInterfaceMethod.applyOrThrow( 240 TelephonyManager.getSubscriptionService(), query); 241 } catch (Exception re) { 242 throw new RuntimeException(re); 243 } 244 } 245 246 @Override query(Integer query)247 public T query(Integer query) { 248 T result = mDefaultValue; 249 250 try { 251 ISub iSub = TelephonyManager.getSubscriptionService(); 252 if (iSub != null) { 253 result = super.query(query); 254 } 255 } catch (Exception ex) { 256 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty); 257 } 258 259 if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result); 260 return result; 261 } 262 } 263 264 private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSubIdCache = 265 new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId, 266 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, 267 INVALID_SUBSCRIPTION_ID); 268 269 private static VoidPropertyInvalidatedCache<Integer> sGetDefaultDataSubIdCache = 270 new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId, 271 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, 272 INVALID_SUBSCRIPTION_ID); 273 274 private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSmsSubIdCache = 275 new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId, 276 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, 277 INVALID_SUBSCRIPTION_ID); 278 279 private static VoidPropertyInvalidatedCache<Integer> sGetActiveDataSubscriptionIdCache = 280 new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId, 281 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, 282 INVALID_SUBSCRIPTION_ID); 283 284 private static IntegerPropertyInvalidatedCache<Integer> sGetSlotIndexCache = 285 new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex, 286 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, 287 INVALID_SIM_SLOT_INDEX); 288 289 private static IntegerPropertyInvalidatedCache<Integer> sGetSubIdCache = 290 new IntegerPropertyInvalidatedCache<>(ISub::getSubId, 291 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, 292 INVALID_SUBSCRIPTION_ID); 293 294 private static IntegerPropertyInvalidatedCache<Integer> sGetPhoneIdCache = 295 new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId, 296 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, 297 INVALID_PHONE_INDEX); 298 299 /** 300 * Generates a content {@link Uri} used to receive updates on simInfo change 301 * on the given subscriptionId 302 * @param subscriptionId the subscriptionId to receive updates on 303 * @return the Uri used to observe carrier identity changes 304 * @hide 305 */ getUriForSubscriptionId(int subscriptionId)306 public static Uri getUriForSubscriptionId(int subscriptionId) { 307 return Uri.withAppendedPath(CONTENT_URI, String.valueOf(subscriptionId)); 308 } 309 310 /** 311 * A content {@link Uri} used to receive updates on wfc enabled user setting. 312 * <p> 313 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the 314 * subscription wfc enabled {@link ImsMmTelManager#isVoWiFiSettingEnabled()} 315 * while your app is running. You can also use a {@link android.app.job.JobService} 316 * to ensure your app 317 * is notified of changes to the {@link Uri} even when it is not running. 318 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely 319 * delivery of updates to the {@link Uri}. 320 * To be notified of changes to a specific subId, append subId to the URI 321 * {@link Uri#withAppendedPath(Uri, String)}. 322 * @hide 323 */ 324 @NonNull 325 @SystemApi 326 public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc"); 327 328 /** 329 * A content {@link Uri} used to receive updates on advanced calling user setting 330 * 331 * <p> 332 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the 333 * subscription advanced calling enabled 334 * {@link ImsMmTelManager#isAdvancedCallingSettingEnabled()} while your app is running. 335 * You can also use a {@link android.app.job.JobService} to ensure your app is notified of 336 * changes to the {@link Uri} even when it is not running. 337 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely 338 * delivery of updates to the {@link Uri}. 339 * To be notified of changes to a specific subId, append subId to the URI 340 * {@link Uri#withAppendedPath(Uri, String)}. 341 * 342 * @see ImsMmTelManager#isAdvancedCallingSettingEnabled() 343 * 344 * @hide 345 */ 346 @NonNull 347 @SystemApi 348 public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath( 349 CONTENT_URI, "advanced_calling"); 350 351 /** 352 * A content {@link Uri} used to receive updates on wfc mode setting. 353 * <p> 354 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the 355 * subscription wfc mode {@link ImsMmTelManager#getVoWiFiModeSetting()} 356 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure 357 * your app is notified of changes to the {@link Uri} even when it is not running. 358 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely 359 * delivery of updates to the {@link Uri}. 360 * To be notified of changes to a specific subId, append subId to the URI 361 * {@link Uri#withAppendedPath(Uri, String)}. 362 * @hide 363 */ 364 @NonNull 365 @SystemApi 366 public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode"); 367 368 /** 369 * A content {@link Uri} used to receive updates on wfc roaming mode setting. 370 * <p> 371 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the 372 * subscription wfc roaming mode {@link ImsMmTelManager#getVoWiFiRoamingModeSetting()} 373 * while your app is running. You can also use a {@link android.app.job.JobService} 374 * to ensure your app is notified of changes to the {@link Uri} even when it is not running. 375 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely 376 * delivery of updates to the {@link Uri}. 377 * To be notified of changes to a specific subId, append subId to the URI 378 * {@link Uri#withAppendedPath(Uri, String)}. 379 * @hide 380 */ 381 @NonNull 382 @SystemApi 383 public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath( 384 CONTENT_URI, "wfc_roaming_mode"); 385 386 /** 387 * A content {@link Uri} used to receive updates on vt(video telephony over IMS) enabled 388 * setting. 389 * <p> 390 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the 391 * subscription vt enabled {@link ImsMmTelManager#isVtSettingEnabled()} 392 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure 393 * your app is notified of changes to the {@link Uri} even when it is not running. 394 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely 395 * delivery of updates to the {@link Uri}. 396 * To be notified of changes to a specific subId, append subId to the URI 397 * {@link Uri#withAppendedPath(Uri, String)}. 398 * @hide 399 */ 400 @NonNull 401 @SystemApi 402 public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath( 403 CONTENT_URI, "vt_enabled"); 404 405 /** 406 * A content {@link Uri} used to receive updates on wfc roaming enabled setting. 407 * <p> 408 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the 409 * subscription wfc roaming enabled {@link ImsMmTelManager#isVoWiFiRoamingSettingEnabled()} 410 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure 411 * your app is notified of changes to the {@link Uri} even when it is not running. 412 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely 413 * delivery of updates to the {@link Uri}. 414 * To be notified of changes to a specific subId, append subId to the URI 415 * {@link Uri#withAppendedPath(Uri, String)}. 416 * @hide 417 */ 418 @NonNull 419 @SystemApi 420 public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath( 421 CONTENT_URI, "wfc_roaming_enabled"); 422 423 424 /** 425 * A content {@link uri} used to call the appropriate backup or restore method for sim-specific 426 * settings 427 * <p> 428 * See {@link #GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME} and {@link 429 * #RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME} for information on what method to call. 430 * @hide 431 */ 432 @NonNull 433 public static final Uri SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI = Uri.withAppendedPath( 434 CONTENT_URI, "backup_and_restore"); 435 436 /** 437 * A content {@link uri} used to notify contentobservers listening to siminfo restore during 438 * SuW. 439 * @hide 440 */ 441 @NonNull 442 public static final Uri SIM_INFO_SUW_RESTORE_CONTENT_URI = Uri.withAppendedPath( 443 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, "suw_restore"); 444 445 /** 446 * A content {@link Uri} used to receive updates on cross sim enabled user setting. 447 * <p> 448 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the 449 * subscription cross sim calling enabled 450 * {@link ImsMmTelManager#isCrossSimCallingEnabled()} 451 * while your app is running. You can also use a {@link android.app.job.JobService} 452 * to ensure your app 453 * is notified of changes to the {@link Uri} even when it is not running. 454 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely 455 * delivery of updates to the {@link Uri}. 456 * To be notified of changes to a specific subId, append subId to the URI 457 * {@link Uri#withAppendedPath(Uri, String)}. 458 * @hide 459 */ 460 @NonNull 461 @SystemApi 462 public static final Uri CROSS_SIM_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, 463 SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED); 464 465 /** 466 * TelephonyProvider unique key column name is the subscription id. 467 * <P>Type: TEXT (String)</P> 468 */ 469 /** @hide */ 470 public static final String UNIQUE_KEY_SUBSCRIPTION_ID = 471 SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID; 472 473 /** 474 * TelephonyProvider column name for a unique identifier for the subscription within the 475 * specific subscription type. For example, it contains SIM ICC Identifier subscriptions 476 * on Local SIMs. and Mac-address for Remote-SIM Subscriptions for Bluetooth devices. 477 * <P>Type: TEXT (String)</P> 478 */ 479 /** @hide */ 480 public static final String ICC_ID = SimInfo.COLUMN_ICC_ID; 481 482 /** 483 * TelephonyProvider column name for user SIM_SlOT_INDEX 484 * <P>Type: INTEGER (int)</P> 485 */ 486 /** @hide */ 487 public static final String SIM_SLOT_INDEX = SimInfo.COLUMN_SIM_SLOT_INDEX; 488 489 /** SIM is not inserted */ 490 /** @hide */ 491 public static final int SIM_NOT_INSERTED = SimInfo.SIM_NOT_INSERTED; 492 493 /** 494 * The slot-index for Bluetooth Remote-SIM subscriptions 495 * @hide 496 */ 497 public static final int SLOT_INDEX_FOR_REMOTE_SIM_SUB = INVALID_SIM_SLOT_INDEX; 498 499 /** 500 * TelephonyProvider column name Subscription-type. 501 * <P>Type: INTEGER (int)</P> {@link #SUBSCRIPTION_TYPE_LOCAL_SIM} for Local-SIM Subscriptions, 502 * {@link #SUBSCRIPTION_TYPE_REMOTE_SIM} for Remote-SIM Subscriptions. 503 * Default value is 0. 504 */ 505 /** @hide */ 506 public static final String SUBSCRIPTION_TYPE = SimInfo.COLUMN_SUBSCRIPTION_TYPE; 507 508 /** 509 * TelephonyProvider column name for last used TP - message Reference 510 * <P>Type: INTEGER (int)</P> with -1 as default value 511 * TP - Message Reference valid range [0 - 255] 512 * @hide 513 */ 514 public static final String TP_MESSAGE_REF = SimInfo.COLUMN_TP_MESSAGE_REF; 515 516 /** 517 * TelephonyProvider column name enabled_mobile_data_policies. 518 * A list of mobile data policies, each of which represented by an integer and joint by ",". 519 * 520 * Default value is empty string. 521 * @hide 522 */ 523 public static final String ENABLED_MOBILE_DATA_POLICIES = 524 SimInfo.COLUMN_ENABLED_MOBILE_DATA_POLICIES; 525 526 /** @hide */ 527 @Retention(RetentionPolicy.SOURCE) 528 @IntDef(prefix = {"SUBSCRIPTION_TYPE_"}, 529 value = { 530 SUBSCRIPTION_TYPE_LOCAL_SIM, 531 SUBSCRIPTION_TYPE_REMOTE_SIM}) 532 public @interface SubscriptionType {} 533 534 /** 535 * This constant is to designate a subscription as a Local-SIM Subscription. 536 * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the 537 * device. 538 * </p> 539 */ 540 public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = SimInfo.SUBSCRIPTION_TYPE_LOCAL_SIM; 541 542 /** 543 * This constant is to designate a subscription as a Remote-SIM Subscription. 544 * <p> 545 * A Remote-SIM subscription is for a SIM on a phone connected to this device via some 546 * connectivity mechanism, for example bluetooth. Similar to Local SIM, this subscription can 547 * be used for SMS, Voice and data by proxying data through the connected device. 548 * Certain data of the SIM, such as IMEI, are not accessible for Remote SIMs. 549 * </p> 550 * 551 * <p> 552 * A Remote-SIM is available only as long the phone stays connected to this device. 553 * When the phone disconnects, Remote-SIM subscription is removed from this device and is 554 * no longer known. All data associated with the subscription, such as stored SMS, call logs, 555 * contacts etc, are removed from this device. 556 * </p> 557 * 558 * <p> 559 * If the phone re-connects to this device, a new Remote-SIM subscription is created for 560 * the phone. The Subscription Id associated with the new subscription is different from 561 * the Subscription Id of the previous Remote-SIM subscription created (and removed) for the 562 * phone; i.e., new Remote-SIM subscription treats the reconnected phone as a Remote-SIM that 563 * was never seen before. 564 * </p> 565 */ 566 public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = SimInfo.SUBSCRIPTION_TYPE_REMOTE_SIM; 567 568 /** 569 * TelephonyProvider column name for user displayed name. 570 * <P>Type: TEXT (String)</P> 571 */ 572 /** @hide */ 573 public static final String DISPLAY_NAME = SimInfo.COLUMN_DISPLAY_NAME; 574 575 /** 576 * TelephonyProvider column name for the service provider name for the SIM. 577 * <P>Type: TEXT (String)</P> 578 */ 579 /** @hide */ 580 public static final String CARRIER_NAME = SimInfo.COLUMN_CARRIER_NAME; 581 582 /** 583 * Default name resource 584 * @hide 585 */ 586 public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName; 587 588 /** 589 * TelephonyProvider column name for source of the user displayed name. 590 * <P>Type: INT (int)</P> with one of the NAME_SOURCE_XXXX values below 591 * 592 * @hide 593 */ 594 public static final String NAME_SOURCE = SimInfo.COLUMN_NAME_SOURCE; 595 596 /** 597 * The name_source is unknown. (for initialization) 598 * @hide 599 */ 600 public static final int NAME_SOURCE_UNKNOWN = SimInfo.NAME_SOURCE_UNKNOWN; 601 602 /** 603 * The name_source is from the carrier id. 604 * @hide 605 */ 606 public static final int NAME_SOURCE_CARRIER_ID = SimInfo.NAME_SOURCE_CARRIER_ID; 607 608 /** 609 * The name_source is from SIM EF_SPN. 610 * @hide 611 */ 612 public static final int NAME_SOURCE_SIM_SPN = SimInfo.NAME_SOURCE_SIM_SPN; 613 614 /** 615 * The name_source is from user input 616 * @hide 617 */ 618 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 619 public static final int NAME_SOURCE_USER_INPUT = SimInfo.NAME_SOURCE_USER_INPUT; 620 621 /** 622 * The name_source is carrier (carrier app, carrier config, etc.) 623 * @hide 624 */ 625 public static final int NAME_SOURCE_CARRIER = SimInfo.NAME_SOURCE_CARRIER; 626 627 /** 628 * The name_source is from SIM EF_PNN. 629 * @hide 630 */ 631 public static final int NAME_SOURCE_SIM_PNN = SimInfo.NAME_SOURCE_SIM_PNN; 632 633 /** @hide */ 634 @Retention(RetentionPolicy.SOURCE) 635 @IntDef(prefix = {"NAME_SOURCE_"}, 636 value = { 637 NAME_SOURCE_UNKNOWN, 638 NAME_SOURCE_CARRIER_ID, 639 NAME_SOURCE_SIM_SPN, 640 NAME_SOURCE_USER_INPUT, 641 NAME_SOURCE_CARRIER, 642 NAME_SOURCE_SIM_PNN 643 }) 644 public @interface SimDisplayNameSource {} 645 646 /** 647 * Device status is not shared to a remote party. 648 */ 649 public static final int D2D_SHARING_DISABLED = 0; 650 651 /** 652 * Device status is shared with all numbers in the user's contacts. 653 */ 654 public static final int D2D_SHARING_ALL_CONTACTS = 1; 655 656 /** 657 * Device status is shared with all selected contacts. 658 */ 659 public static final int D2D_SHARING_SELECTED_CONTACTS = 2; 660 661 /** 662 * Device status is shared whenever possible. 663 */ 664 public static final int D2D_SHARING_ALL = 3; 665 666 /** @hide */ 667 @Retention(RetentionPolicy.SOURCE) 668 @IntDef(prefix = {"D2D_SHARING_"}, 669 value = { 670 D2D_SHARING_DISABLED, 671 D2D_SHARING_ALL_CONTACTS, 672 D2D_SHARING_SELECTED_CONTACTS, 673 D2D_SHARING_ALL 674 }) 675 public @interface DeviceToDeviceStatusSharingPreference {} 676 677 /** 678 * TelephonyProvider column name for device to device sharing status. 679 * <P>Type: INTEGER (int)</P> 680 */ 681 public static final String D2D_STATUS_SHARING = SimInfo.COLUMN_D2D_STATUS_SHARING; 682 683 /** 684 * TelephonyProvider column name for contacts information that allow device to device sharing. 685 * <P>Type: TEXT (String)</P> 686 */ 687 public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS = 688 SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS; 689 690 /** 691 * TelephonyProvider column name for the color of a SIM. 692 * <P>Type: INTEGER (int)</P> 693 */ 694 /** @hide */ 695 public static final String HUE = SimInfo.COLUMN_COLOR; 696 697 /** 698 * TelephonyProvider column name for the phone number of a SIM. 699 * <P>Type: TEXT (String)</P> 700 */ 701 /** @hide */ 702 public static final String NUMBER = SimInfo.COLUMN_NUMBER; 703 704 /** 705 * TelephonyProvider column name for whether data roaming is enabled. 706 * <P>Type: INTEGER (int)</P> 707 */ 708 /** @hide */ 709 public static final String DATA_ROAMING = SimInfo.COLUMN_DATA_ROAMING; 710 711 /** Indicates that data roaming is enabled for a subscription */ 712 public static final int DATA_ROAMING_ENABLE = SimInfo.DATA_ROAMING_ENABLE; 713 714 /** Indicates that data roaming is disabled for a subscription */ 715 public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE; 716 717 /** @hide */ 718 @Retention(RetentionPolicy.SOURCE) 719 @IntDef(prefix = {"DATA_ROAMING_"}, 720 value = { 721 DATA_ROAMING_ENABLE, 722 DATA_ROAMING_DISABLE 723 }) 724 public @interface DataRoamingMode {} 725 726 /** 727 * TelephonyProvider column name for subscription carrier id. 728 * @see TelephonyManager#getSimCarrierId() 729 * <p>Type: INTEGER (int) </p> 730 * @hide 731 */ 732 public static final String CARRIER_ID = SimInfo.COLUMN_CARRIER_ID; 733 734 /** 735 * @hide A comma-separated list of EHPLMNs associated with the subscription 736 * <P>Type: TEXT (String)</P> 737 */ 738 public static final String EHPLMNS = SimInfo.COLUMN_EHPLMNS; 739 740 /** 741 * @hide A comma-separated list of HPLMNs associated with the subscription 742 * <P>Type: TEXT (String)</P> 743 */ 744 public static final String HPLMNS = SimInfo.COLUMN_HPLMNS; 745 746 /** 747 * TelephonyProvider column name for the MCC associated with a SIM, stored as a string. 748 * <P>Type: TEXT (String)</P> 749 * @hide 750 */ 751 public static final String MCC_STRING = SimInfo.COLUMN_MCC_STRING; 752 753 /** 754 * TelephonyProvider column name for the MNC associated with a SIM, stored as a string. 755 * <P>Type: TEXT (String)</P> 756 * @hide 757 */ 758 public static final String MNC_STRING = SimInfo.COLUMN_MNC_STRING; 759 760 /** 761 * TelephonyProvider column name for the MCC associated with a SIM. 762 * <P>Type: INTEGER (int)</P> 763 * @hide 764 */ 765 public static final String MCC = SimInfo.COLUMN_MCC; 766 767 /** 768 * TelephonyProvider column name for the MNC associated with a SIM. 769 * <P>Type: INTEGER (int)</P> 770 * @hide 771 */ 772 public static final String MNC = SimInfo.COLUMN_MNC; 773 774 /** 775 * TelephonyProvider column name for the iso country code associated with a SIM. 776 * <P>Type: TEXT (String)</P> 777 * @hide 778 */ 779 public static final String ISO_COUNTRY_CODE = SimInfo.COLUMN_ISO_COUNTRY_CODE; 780 781 /** 782 * TelephonyProvider column name for whether a subscription is embedded (that is, present on an 783 * eSIM). 784 * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded. 785 * @hide 786 */ 787 public static final String IS_EMBEDDED = SimInfo.COLUMN_IS_EMBEDDED; 788 789 /** 790 * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of the 791 * current enabled profile on the card, while for eUICC card it is the EID of the card. 792 * <P>Type: TEXT (String)</P> 793 * @hide 794 */ 795 public static final String CARD_ID = SimInfo.COLUMN_CARD_ID; 796 797 /** 798 * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from 799 * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1. 800 * <p>TYPE: BLOB 801 * @hide 802 */ 803 public static final String ACCESS_RULES = SimInfo.COLUMN_ACCESS_RULES; 804 805 /** 806 * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from 807 * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs. 808 * Only present if there are access rules in CarrierConfigs 809 * <p>TYPE: BLOB 810 * @hide 811 */ 812 public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS = 813 SimInfo.COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS; 814 815 /** 816 * TelephonyProvider column name identifying whether an embedded subscription is on a removable 817 * card. Such subscriptions are marked inaccessible as soon as the current card is removed. 818 * Otherwise, they will remain accessible unless explicitly deleted. Only present if 819 * {@link #IS_EMBEDDED} is 1. 820 * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable. 821 * @hide 822 */ 823 public static final String IS_REMOVABLE = SimInfo.COLUMN_IS_REMOVABLE; 824 825 /** 826 * TelephonyProvider column name for extreme threat in CB settings 827 * @hide 828 */ 829 public static final String CB_EXTREME_THREAT_ALERT = 830 SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT; 831 832 /** 833 * TelephonyProvider column name for severe threat in CB settings 834 *@hide 835 */ 836 public static final String CB_SEVERE_THREAT_ALERT = SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT; 837 838 /** 839 * TelephonyProvider column name for amber alert in CB settings 840 *@hide 841 */ 842 public static final String CB_AMBER_ALERT = SimInfo.COLUMN_CB_AMBER_ALERT; 843 844 /** 845 * TelephonyProvider column name for emergency alert in CB settings 846 *@hide 847 */ 848 public static final String CB_EMERGENCY_ALERT = SimInfo.COLUMN_CB_EMERGENCY_ALERT; 849 850 /** 851 * TelephonyProvider column name for alert sound duration in CB settings 852 *@hide 853 */ 854 public static final String CB_ALERT_SOUND_DURATION = 855 SimInfo.COLUMN_CB_ALERT_SOUND_DURATION; 856 857 /** 858 * TelephonyProvider column name for alert reminder interval in CB settings 859 *@hide 860 */ 861 public static final String CB_ALERT_REMINDER_INTERVAL = 862 SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL; 863 864 /** 865 * TelephonyProvider column name for enabling vibrate in CB settings 866 *@hide 867 */ 868 public static final String CB_ALERT_VIBRATE = SimInfo.COLUMN_CB_ALERT_VIBRATE; 869 870 /** 871 * TelephonyProvider column name for enabling alert speech in CB settings 872 *@hide 873 */ 874 public static final String CB_ALERT_SPEECH = SimInfo.COLUMN_CB_ALERT_SPEECH; 875 876 /** 877 * TelephonyProvider column name for ETWS test alert in CB settings 878 *@hide 879 */ 880 public static final String CB_ETWS_TEST_ALERT = SimInfo.COLUMN_CB_ETWS_TEST_ALERT; 881 882 /** 883 * TelephonyProvider column name for enable channel50 alert in CB settings 884 *@hide 885 */ 886 public static final String CB_CHANNEL_50_ALERT = SimInfo.COLUMN_CB_CHANNEL_50_ALERT; 887 888 /** 889 * TelephonyProvider column name for CMAS test alert in CB settings 890 *@hide 891 */ 892 public static final String CB_CMAS_TEST_ALERT = SimInfo.COLUMN_CB_CMAS_TEST_ALERT; 893 894 /** 895 * TelephonyProvider column name for Opt out dialog in CB settings 896 *@hide 897 */ 898 public static final String CB_OPT_OUT_DIALOG = SimInfo.COLUMN_CB_OPT_OUT_DIALOG; 899 900 /** 901 * TelephonyProvider column name for enable Volte. 902 * 903 * If this setting is not initialized (set to -1) then we use the Carrier Config value 904 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}. 905 *@hide 906 */ 907 public static final String ENHANCED_4G_MODE_ENABLED = 908 SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED; 909 910 /** 911 * TelephonyProvider column name for enable VT (Video Telephony over IMS) 912 *@hide 913 */ 914 public static final String VT_IMS_ENABLED = SimInfo.COLUMN_VT_IMS_ENABLED; 915 916 /** 917 * TelephonyProvider column name for enable Wifi calling 918 *@hide 919 */ 920 public static final String WFC_IMS_ENABLED = SimInfo.COLUMN_WFC_IMS_ENABLED; 921 922 /** 923 * TelephonyProvider column name for Wifi calling mode 924 *@hide 925 */ 926 public static final String WFC_IMS_MODE = SimInfo.COLUMN_WFC_IMS_MODE; 927 928 /** 929 * TelephonyProvider column name for Wifi calling mode in roaming 930 *@hide 931 */ 932 public static final String WFC_IMS_ROAMING_MODE = SimInfo.COLUMN_WFC_IMS_ROAMING_MODE; 933 934 /** 935 * TelephonyProvider column name for enable Wifi calling in roaming 936 *@hide 937 */ 938 public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED; 939 940 /** 941 * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this 942 * subscription. 943 * @hide 944 */ 945 public static final String IMS_RCS_UCE_ENABLED = SimInfo.COLUMN_IMS_RCS_UCE_ENABLED; 946 947 /** 948 * Determines if the user has enabled cross SIM calling for this subscription. 949 * 950 * @hide 951 */ 952 public static final String CROSS_SIM_CALLING_ENABLED = SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED; 953 954 /** 955 * TelephonyProvider column name for whether a subscription is opportunistic, that is, 956 * whether the network it connects to is limited in functionality or coverage. 957 * For example, CBRS. 958 * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic. 959 * @hide 960 */ 961 public static final String IS_OPPORTUNISTIC = SimInfo.COLUMN_IS_OPPORTUNISTIC; 962 963 /** 964 * TelephonyProvider column name for group ID. Subscriptions with same group ID 965 * are considered bundled together, and should behave as a single subscription at 966 * certain scenarios. 967 * 968 * @hide 969 */ 970 public static final String GROUP_UUID = SimInfo.COLUMN_GROUP_UUID; 971 972 /** 973 * TelephonyProvider column name for group owner. It's the package name who created 974 * the subscription group. 975 * 976 * @hide 977 */ 978 public static final String GROUP_OWNER = SimInfo.COLUMN_GROUP_OWNER; 979 980 /** 981 * TelephonyProvider column name for the profile class of a subscription 982 * Only present if {@link #IS_EMBEDDED} is 1. 983 * <P>Type: INTEGER (int)</P> 984 * @hide 985 */ 986 public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS; 987 988 /** 989 * TelephonyProvider column name for the port index of the active UICC port. 990 * <P>Type: INTEGER (int)</P> 991 * @hide 992 */ 993 public static final String PORT_INDEX = SimInfo.COLUMN_PORT_INDEX; 994 995 /** 996 * TelephonyProvider column name for VoIMS opt-in status. 997 * 998 * <P>Type: INTEGER (int)</P> 999 * @hide 1000 */ 1001 public static final String VOIMS_OPT_IN_STATUS = SimInfo.COLUMN_VOIMS_OPT_IN_STATUS; 1002 1003 /** 1004 * TelephonyProvider column name for NR Advanced calling 1005 * Determines if the user has enabled VoNR settings for this subscription. 1006 * 1007 * @hide 1008 */ 1009 public static final String NR_ADVANCED_CALLING_ENABLED = 1010 SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED; 1011 1012 /** 1013 * Profile class of the subscription 1014 * @hide 1015 */ 1016 @Retention(RetentionPolicy.SOURCE) 1017 @IntDef(prefix = { "PROFILE_CLASS_" }, value = { 1018 SimInfo.PROFILE_CLASS_TESTING, 1019 SimInfo.PROFILE_CLASS_PROVISIONING, 1020 SimInfo.PROFILE_CLASS_OPERATIONAL, 1021 SimInfo.PROFILE_CLASS_UNSET, 1022 }) 1023 public @interface ProfileClass {} 1024 1025 /** 1026 * A testing profile can be pre-loaded or downloaded onto 1027 * the eUICC and provides connectivity to test equipment 1028 * for the purpose of testing the device and the eUICC. It 1029 * is not intended to store any operator credentials. 1030 * @hide 1031 */ 1032 @SystemApi 1033 public static final int PROFILE_CLASS_TESTING = SimInfo.PROFILE_CLASS_TESTING; 1034 1035 /** 1036 * A provisioning profile is pre-loaded onto the eUICC and 1037 * provides connectivity to a mobile network solely for the 1038 * purpose of provisioning profiles. 1039 * @hide 1040 */ 1041 @SystemApi 1042 public static final int PROFILE_CLASS_PROVISIONING = SimInfo.PROFILE_CLASS_PROVISIONING; 1043 1044 /** 1045 * An operational profile can be pre-loaded or downloaded 1046 * onto the eUICC and provides services provided by the 1047 * operator. 1048 * @hide 1049 */ 1050 @SystemApi 1051 public static final int PROFILE_CLASS_OPERATIONAL = SimInfo.PROFILE_CLASS_OPERATIONAL; 1052 1053 /** 1054 * The profile class is unset. This occurs when profile class 1055 * info is not available. The subscription either has no profile 1056 * metadata or the profile metadata did not encode profile class. 1057 * @hide 1058 */ 1059 @SystemApi 1060 public static final int PROFILE_CLASS_UNSET = SimInfo.PROFILE_CLASS_UNSET; 1061 1062 /** 1063 * Default profile class 1064 * @hide 1065 */ 1066 @SystemApi 1067 @Deprecated 1068 public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_UNSET; 1069 1070 /** 1071 * IMSI (International Mobile Subscriber Identity). 1072 * <P>Type: TEXT </P> 1073 * @hide 1074 */ 1075 //TODO: add @SystemApi 1076 public static final String IMSI = SimInfo.COLUMN_IMSI; 1077 1078 /** 1079 * Whether uicc applications is set to be enabled or disabled. By default it's enabled. 1080 * @hide 1081 */ 1082 public static final String UICC_APPLICATIONS_ENABLED = SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED; 1083 1084 /** 1085 * Indicate which network type is allowed. 1086 * @hide 1087 */ 1088 public static final String ALLOWED_NETWORK_TYPES = 1089 SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS; 1090 1091 /** 1092 * TelephonyProvider column name for user handle associated with a sim. 1093 * <P>Type: INTEGER (int)</P> 1094 * @hide 1095 */ 1096 public static final String USER_HANDLE = SimInfo.COLUMN_USER_HANDLE; 1097 1098 /** 1099 * TelephonyProvider column name for satellite enabled. 1100 * By default, it's disabled. 1101 * <P>Type: INTEGER (int)</P> 1102 * @hide 1103 */ 1104 public static final String SATELLITE_ENABLED = SimInfo.COLUMN_SATELLITE_ENABLED; 1105 1106 /** @hide */ 1107 @Retention(RetentionPolicy.SOURCE) 1108 @IntDef(prefix = {"USAGE_SETTING_"}, 1109 value = { 1110 USAGE_SETTING_UNKNOWN, 1111 USAGE_SETTING_DEFAULT, 1112 USAGE_SETTING_VOICE_CENTRIC, 1113 USAGE_SETTING_DATA_CENTRIC}) 1114 public @interface UsageSetting {} 1115 1116 /** 1117 * The usage setting is unknown. 1118 * 1119 * This will be the usage setting returned on devices that do not support querying the 1120 * or setting the usage setting. 1121 * 1122 * It may also be provided by a carrier that wishes to provide a value to avoid making any 1123 * settings changes. 1124 */ 1125 public static final int USAGE_SETTING_UNKNOWN = -1; 1126 1127 /** 1128 * Subscription uses the default setting. 1129 * 1130 * The value is based upon device capability and the other properties of the subscription. 1131 * 1132 * Most subscriptions will default to voice-centric when in a phone. 1133 * 1134 * An opportunistic subscription will default to data-centric. 1135 * 1136 * @see SubscriptionInfo#isOpportunistic 1137 */ 1138 public static final int USAGE_SETTING_DEFAULT = 0; 1139 1140 /** 1141 * This subscription is forced to voice-centric mode 1142 * 1143 * <p>Refer to voice-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3. 1144 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221 1145 * Annex A. 1146 * 1147 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_CALLING} and support usage 1148 * setting configuration must support setting this value via 1149 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}. 1150 */ 1151 public static final int USAGE_SETTING_VOICE_CENTRIC = 1; 1152 1153 /** 1154 * This subscription is forced to data-centric mode 1155 * 1156 * <p>Refer to data-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3. 1157 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221 1158 * Annex A. 1159 * 1160 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_DATA} and support usage 1161 * setting configuration must support setting this value via. 1162 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}. 1163 */ 1164 public static final int USAGE_SETTING_DATA_CENTRIC = 2; 1165 1166 /** 1167 * Indicate the preferred usage setting for the subscription. 1168 * 1169 * 0 - Default - If the value has not been explicitly set, it will be "default" 1170 * 1 - Voice-centric 1171 * 2 - Data-centric 1172 * 1173 * @hide 1174 */ 1175 public static final String USAGE_SETTING = SimInfo.COLUMN_USAGE_SETTING; 1176 1177 /** 1178 * Broadcast Action: The user has changed one of the default subs related to 1179 * data, phone calls, or sms</p> 1180 * 1181 * TODO: Change to a listener 1182 * @hide 1183 */ 1184 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1185 public static final String SUB_DEFAULT_CHANGED_ACTION = 1186 "android.intent.action.SUB_DEFAULT_CHANGED"; 1187 1188 /** 1189 * Broadcast Action: The default subscription has changed. This has the following 1190 * extra values:</p> 1191 * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index 1192 */ 1193 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1194 public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED 1195 = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED"; 1196 1197 /** 1198 * Broadcast Action: The default sms subscription has changed. This has the following 1199 * extra values:</p> 1200 * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms 1201 * subscription index 1202 */ 1203 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1204 public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED 1205 = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED"; 1206 1207 /** 1208 * Activity Action: Display UI for managing the billing relationship plans 1209 * between a carrier and a specific subscriber. 1210 * <p> 1211 * Carrier apps are encouraged to implement this activity, and the OS will 1212 * provide an affordance to quickly enter this activity, typically via 1213 * Settings. This affordance will only be shown when the carrier app is 1214 * actively providing subscription plan information via 1215 * {@link #setSubscriptionPlans(int, List)}. 1216 * <p> 1217 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription 1218 * the user is interested in. 1219 */ 1220 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 1221 public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS 1222 = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS"; 1223 1224 /** 1225 * Broadcast Action: Request a refresh of the billing relationship plans 1226 * between a carrier and a specific subscriber. 1227 * <p> 1228 * Carrier apps are encouraged to implement this receiver, and the OS will 1229 * provide an affordance to request a refresh. This affordance will only be 1230 * shown when the carrier app is actively providing subscription plan 1231 * information via {@link #setSubscriptionPlans(int, List)}. 1232 * <p> 1233 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription 1234 * the user is interested in. 1235 * <p> 1236 * Receivers should protect themselves by checking that the sender holds the 1237 * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission. 1238 */ 1239 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1240 public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS 1241 = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS"; 1242 1243 /** 1244 * Broadcast Action: The billing relationship plans between a carrier and a 1245 * specific subscriber has changed. 1246 * <p> 1247 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription 1248 * changed. 1249 * @hide 1250 */ 1251 @SystemApi 1252 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1253 @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) 1254 public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED 1255 = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED"; 1256 1257 /** 1258 * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and 1259 * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription 1260 * which has changed. 1261 */ 1262 public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX"; 1263 1264 /** 1265 * Integer extra to specify SIM slot index. 1266 */ 1267 public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX"; 1268 1269 /** 1270 * A source of phone number: the EF-MSISDN (see 3GPP TS 31.102), 1271 * or EF-MDN for CDMA (see 3GPP2 C.P0065-B), from UICC application. 1272 * 1273 * <p>The availability and a of the number depends on the carrier. 1274 * The number may be updated by over-the-air update to UICC applications 1275 * from the carrier, or by other means with physical access to the SIM. 1276 */ 1277 public static final int PHONE_NUMBER_SOURCE_UICC = 1; 1278 1279 /** 1280 * A source of phone number: provided by an app that has carrier privilege. 1281 * 1282 * <p>The number is intended to be set by a carrier app knowing the correct number 1283 * which is, for example, different from the number in {@link #PHONE_NUMBER_SOURCE_UICC UICC} 1284 * for some reason. 1285 * The number is not available until a carrier app sets one via 1286 * {@link #setCarrierPhoneNumber(int, String)}. 1287 * The app can update the number with the same API should the number change. 1288 */ 1289 public static final int PHONE_NUMBER_SOURCE_CARRIER = 2; 1290 1291 /** 1292 * A source of phone number: provided by IMS (IP Multimedia Subsystem) implementation. 1293 * When IMS service is registered (as indicated by 1294 * {@link android.telephony.ims.RegistrationManager.RegistrationCallback#onRegistered(int)}) 1295 * the IMS implementation may return P-Associated-Uri SIP headers (RFC 3455). The URIs 1296 * are the user’s public user identities known to the network (see 3GPP TS 24.229 5.4.1.2), 1297 * and the phone number is typically one of them (see “global number” in 3GPP TS 23.003 13.4). 1298 * 1299 * <p>This source provides the phone number from the last IMS registration. 1300 * IMS registration may happen on every device reboot or other network condition changes. 1301 * The number will be updated should the associated URI change after an IMS registration. 1302 */ 1303 public static final int PHONE_NUMBER_SOURCE_IMS = 3; 1304 1305 /** @hide */ 1306 @Retention(RetentionPolicy.SOURCE) 1307 @IntDef(prefix = {"PHONE_NUMBER_SOURCE"}, 1308 value = { 1309 PHONE_NUMBER_SOURCE_UICC, 1310 PHONE_NUMBER_SOURCE_CARRIER, 1311 PHONE_NUMBER_SOURCE_IMS, 1312 }) 1313 public @interface PhoneNumberSource {} 1314 1315 private final Context mContext; 1316 1317 // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing 1318 // the Context and subId. 1319 private static final Map<Pair<Context, Integer>, Resources> sResourcesCache = 1320 new ConcurrentHashMap<>(); 1321 1322 /** 1323 * A listener class for monitoring changes to {@link SubscriptionInfo} records. 1324 * <p> 1325 * Override the onSubscriptionsChanged method in the object that extends this 1326 * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)} 1327 * to register your listener and to unregister invoke 1328 * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)} 1329 * <p> 1330 * Permissions android.Manifest.permission.READ_PHONE_STATE is required 1331 * for #onSubscriptionsChanged to be invoked. 1332 */ 1333 public static class OnSubscriptionsChangedListener { 1334 private class OnSubscriptionsChangedListenerHandler extends Handler { OnSubscriptionsChangedListenerHandler()1335 OnSubscriptionsChangedListenerHandler() { 1336 super(); 1337 } 1338 OnSubscriptionsChangedListenerHandler(Looper looper)1339 OnSubscriptionsChangedListenerHandler(Looper looper) { 1340 super(looper); 1341 } 1342 } 1343 1344 /** 1345 * Posted executor callback on the handler associated with a given looper. 1346 * The looper can be the calling thread's looper or the looper passed from the 1347 * constructor {@link #OnSubscriptionsChangedListener(Looper)}. 1348 */ 1349 private final HandlerExecutor mExecutor; 1350 1351 /** 1352 * @hide 1353 */ getHandlerExecutor()1354 public HandlerExecutor getHandlerExecutor() { 1355 return mExecutor; 1356 } 1357 OnSubscriptionsChangedListener()1358 public OnSubscriptionsChangedListener() { 1359 mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler()); 1360 } 1361 1362 /** 1363 * Allow a listener to be created with a custom looper 1364 * @param looper the looper that the underlining handler should run on 1365 * @hide 1366 */ OnSubscriptionsChangedListener(Looper looper)1367 public OnSubscriptionsChangedListener(Looper looper) { 1368 mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper)); 1369 } 1370 1371 /** 1372 * Callback invoked when there is any change to any SubscriptionInfo, as well as once on 1373 * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically 1374 * this method would invoke {@link #getActiveSubscriptionInfoList} 1375 */ onSubscriptionsChanged()1376 public void onSubscriptionsChanged() { 1377 if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN"); 1378 } 1379 1380 /** 1381 * Callback invoked when {@link SubscriptionManager#addOnSubscriptionsChangedListener( 1382 * Executor, OnSubscriptionsChangedListener)} or 1383 * {@link SubscriptionManager#addOnSubscriptionsChangedListener( 1384 * OnSubscriptionsChangedListener)} fails to complete due to the 1385 * {@link Context#TELEPHONY_REGISTRY_SERVICE} being unavailable. 1386 * @hide 1387 */ onAddListenerFailed()1388 public void onAddListenerFailed() { 1389 Rlog.w(LOG_TAG, "onAddListenerFailed not overridden"); 1390 } 1391 log(String s)1392 private void log(String s) { 1393 Rlog.d(LOG_TAG, s); 1394 } 1395 } 1396 1397 /** @hide */ 1398 @UnsupportedAppUsage SubscriptionManager(Context context)1399 public SubscriptionManager(Context context) { 1400 if (DBG) logd("SubscriptionManager created"); 1401 mContext = context; 1402 } 1403 getNetworkPolicyManager()1404 private NetworkPolicyManager getNetworkPolicyManager() { 1405 return (NetworkPolicyManager) mContext 1406 .getSystemService(Context.NETWORK_POLICY_SERVICE); 1407 } 1408 1409 /** 1410 * @deprecated developers should always obtain references directly from 1411 * {@link Context#getSystemService(Class)}. 1412 */ 1413 @Deprecated from(Context context)1414 public static SubscriptionManager from(Context context) { 1415 return (SubscriptionManager) context 1416 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 1417 } 1418 1419 /** 1420 * Register for changes to the list of active {@link SubscriptionInfo} records or to the 1421 * individual records themselves. When a change occurs the onSubscriptionsChanged method of 1422 * the listener will be invoked immediately if there has been a notification. The 1423 * onSubscriptionChanged method will also be triggered once initially when calling this 1424 * function. The callback will be invoked on the looper specified in the listener's constructor. 1425 * 1426 * @param listener an instance of {@link OnSubscriptionsChangedListener} with 1427 * onSubscriptionsChanged overridden. 1428 * 1429 * @deprecated Will get exception if the parameter listener is not initialized with a Looper. 1430 * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}. 1431 */ 1432 @Deprecated addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1433 public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { 1434 if (listener == null) return; 1435 addOnSubscriptionsChangedListener(listener.mExecutor, listener); 1436 } 1437 1438 /** 1439 * Register for changes to the list of active {@link SubscriptionInfo} records or to the 1440 * individual records themselves. When a change occurs the onSubscriptionsChanged method of 1441 * the listener will be invoked immediately if there has been a notification. The 1442 * onSubscriptionChanged method will also be triggered once initially when calling this 1443 * function. 1444 * 1445 * @param listener an instance of {@link OnSubscriptionsChangedListener} with 1446 * onSubscriptionsChanged overridden. 1447 * @param executor the executor that will execute callbacks. 1448 */ addOnSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnSubscriptionsChangedListener listener)1449 public void addOnSubscriptionsChangedListener( 1450 @NonNull @CallbackExecutor Executor executor, 1451 @NonNull OnSubscriptionsChangedListener listener) { 1452 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1453 if (DBG) { 1454 logd("register OnSubscriptionsChangedListener pkgName=" + pkgName 1455 + " listener=" + listener); 1456 } 1457 // We use the TelephonyRegistry as it runs in the system and thus is always 1458 // available. 1459 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1460 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1461 if (telephonyRegistryManager != null) { 1462 telephonyRegistryManager.addOnSubscriptionsChangedListener(listener, 1463 executor); 1464 } else { 1465 // If the telephony registry isn't available, we will inform the caller on their 1466 // listener that it failed so they can try to re-register. 1467 loge("addOnSubscriptionsChangedListener: pkgname=" + pkgName + " failed to be added " 1468 + " due to TELEPHONY_REGISTRY_SERVICE being unavailable."); 1469 executor.execute(() -> listener.onAddListenerFailed()); 1470 } 1471 } 1472 1473 /** 1474 * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary 1475 * as the listener will automatically be unregistered if an attempt to invoke the listener 1476 * fails. 1477 * 1478 * @param listener that is to be unregistered. 1479 */ removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1480 public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { 1481 if (listener == null) return; 1482 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1483 if (DBG) { 1484 logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug 1485 + " listener=" + listener); 1486 } 1487 // We use the TelephonyRegistry as it runs in the system and thus is always 1488 // available. 1489 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1490 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1491 if (telephonyRegistryManager != null) { 1492 telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener); 1493 } 1494 } 1495 1496 /** 1497 * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic 1498 * subscriptions. 1499 * <p> 1500 * Override the onOpportunisticSubscriptionsChanged method in the object that extends this 1501 * or {@link #addOnOpportunisticSubscriptionsChangedListener( 1502 * Executor, OnOpportunisticSubscriptionsChangedListener)} 1503 * to register your listener and to unregister invoke 1504 * {@link #removeOnOpportunisticSubscriptionsChangedListener( 1505 * OnOpportunisticSubscriptionsChangedListener)} 1506 * <p> 1507 * Permissions android.Manifest.permission.READ_PHONE_STATE is required 1508 * for #onOpportunisticSubscriptionsChanged to be invoked. 1509 */ 1510 public static class OnOpportunisticSubscriptionsChangedListener { 1511 /** 1512 * Callback invoked when there is any change to any SubscriptionInfo. Typically 1513 * this method would invoke {@link #getActiveSubscriptionInfoList} 1514 */ onOpportunisticSubscriptionsChanged()1515 public void onOpportunisticSubscriptionsChanged() { 1516 if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN"); 1517 } 1518 log(String s)1519 private void log(String s) { 1520 Rlog.d(LOG_TAG, s); 1521 } 1522 } 1523 1524 /** 1525 * Register for changes to the list of opportunistic subscription records or to the 1526 * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged 1527 * method of the listener will be invoked immediately if there has been a notification. 1528 * 1529 * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with 1530 * onOpportunisticSubscriptionsChanged overridden. 1531 */ addOnOpportunisticSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnOpportunisticSubscriptionsChangedListener listener)1532 public void addOnOpportunisticSubscriptionsChangedListener( 1533 @NonNull @CallbackExecutor Executor executor, 1534 @NonNull OnOpportunisticSubscriptionsChangedListener listener) { 1535 if (executor == null || listener == null) { 1536 return; 1537 } 1538 1539 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1540 if (DBG) { 1541 logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName 1542 + " listener=" + listener); 1543 } 1544 1545 // We use the TelephonyRegistry as it runs in the system and thus is always 1546 // available. 1547 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1548 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1549 if (telephonyRegistryManager != null) { 1550 telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener( 1551 listener, executor); 1552 } 1553 } 1554 1555 /** 1556 * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently 1557 * listening opportunistic subscriptions change. This is not strictly necessary 1558 * as the listener will automatically be unregistered if an attempt to invoke the listener 1559 * fails. 1560 * 1561 * @param listener that is to be unregistered. 1562 */ removeOnOpportunisticSubscriptionsChangedListener( @onNull OnOpportunisticSubscriptionsChangedListener listener)1563 public void removeOnOpportunisticSubscriptionsChangedListener( 1564 @NonNull OnOpportunisticSubscriptionsChangedListener listener) { 1565 Preconditions.checkNotNull(listener, "listener cannot be null"); 1566 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1567 if (DBG) { 1568 logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug=" 1569 + pkgForDebug + " listener=" + listener); 1570 } 1571 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1572 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1573 if (telephonyRegistryManager != null) { 1574 telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener); 1575 } 1576 } 1577 1578 /** 1579 * Get the active SubscriptionInfo with the input subId. 1580 * 1581 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 1582 * or that the calling app has carrier privileges (see 1583 * {@link TelephonyManager#hasCarrierPrivileges}). 1584 * 1585 * @param subId The unique SubscriptionInfo key in database. 1586 * @return SubscriptionInfo, maybe null if its not active. 1587 */ 1588 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 1589 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfo(int subId)1590 public SubscriptionInfo getActiveSubscriptionInfo(int subId) { 1591 if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId); 1592 if (!isValidSubscriptionId(subId)) { 1593 if (DBG) { 1594 logd("[getActiveSubscriptionInfo]- invalid subId"); 1595 } 1596 return null; 1597 } 1598 1599 SubscriptionInfo subInfo = null; 1600 1601 try { 1602 ISub iSub = TelephonyManager.getSubscriptionService(); 1603 if (iSub != null) { 1604 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(), 1605 mContext.getAttributionTag()); 1606 } 1607 } catch (RemoteException ex) { 1608 // ignore it 1609 } 1610 1611 return subInfo; 1612 } 1613 1614 /** 1615 * Gets an active SubscriptionInfo {@link SubscriptionInfo} associated with the Sim IccId. 1616 * 1617 * @param iccId the IccId of SIM card 1618 * @return SubscriptionInfo, maybe null if its not active 1619 * 1620 * @hide 1621 */ 1622 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) 1623 @Nullable 1624 @SystemApi getActiveSubscriptionInfoForIcc(@onNull String iccId)1625 public SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String iccId) { 1626 if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId); 1627 if (iccId == null) { 1628 logd("[getActiveSubscriptionInfoForIccIndex]- null iccid"); 1629 return null; 1630 } 1631 1632 SubscriptionInfo result = null; 1633 1634 try { 1635 ISub iSub = TelephonyManager.getSubscriptionService(); 1636 if (iSub != null) { 1637 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(), 1638 mContext.getAttributionTag()); 1639 } 1640 } catch (RemoteException ex) { 1641 // ignore it 1642 } 1643 1644 return result; 1645 } 1646 1647 /** 1648 * Get the active SubscriptionInfo associated with the slotIndex 1649 * 1650 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 1651 * or that the calling app has carrier privileges (see 1652 * {@link TelephonyManager#hasCarrierPrivileges}). 1653 * 1654 * @param slotIndex the slot which the subscription is inserted 1655 * @return SubscriptionInfo, maybe null if its not active 1656 */ 1657 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 1658 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfoForSimSlotIndex(int slotIndex)1659 public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) { 1660 if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex); 1661 if (!isValidSlotIndex(slotIndex)) { 1662 logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex"); 1663 return null; 1664 } 1665 1666 SubscriptionInfo result = null; 1667 1668 try { 1669 ISub iSub = TelephonyManager.getSubscriptionService(); 1670 if (iSub != null) { 1671 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex, 1672 mContext.getOpPackageName(), mContext.getAttributionTag()); 1673 } 1674 } catch (RemoteException ex) { 1675 // ignore it 1676 } 1677 1678 return result; 1679 } 1680 1681 /** 1682 * Get all subscription info records from SIMs that are inserted now or previously inserted. 1683 * 1684 * <p> 1685 * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission, 1686 * {@link SubscriptionInfo#getNumber()} will return empty string. 1687 * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER}, 1688 * {@link SubscriptionInfo#getIccId()} will return an empty string, and 1689 * {@link SubscriptionInfo#getGroupUuid()} will return {@code null}. 1690 * 1691 * <p> 1692 * The carrier app will only get the list of subscriptions that it has carrier privilege on, 1693 * but will have non-stripped {@link SubscriptionInfo} in the list. 1694 * 1695 * @return List of all {@link SubscriptionInfo} records from SIMs that are inserted or 1696 * previously inserted. Sorted by {@link SubscriptionInfo#getSimSlotIndex()}, then 1697 * {@link SubscriptionInfo#getSubscriptionId()}. 1698 * 1699 * @throws SecurityException if callers do not hold the required permission. 1700 */ 1701 @NonNull 1702 @RequiresPermission(anyOf = { 1703 Manifest.permission.READ_PHONE_STATE, 1704 "carrier privileges", 1705 }) getAllSubscriptionInfoList()1706 public List<SubscriptionInfo> getAllSubscriptionInfoList() { 1707 List<SubscriptionInfo> result = null; 1708 try { 1709 ISub iSub = TelephonyManager.getSubscriptionService(); 1710 if (iSub != null) { 1711 result = iSub.getAllSubInfoList(mContext.getOpPackageName(), 1712 mContext.getAttributionTag()); 1713 } 1714 } catch (RemoteException ex) { 1715 // ignore it 1716 } 1717 1718 if (result == null) { 1719 result = Collections.emptyList(); 1720 } 1721 return result; 1722 } 1723 1724 /** 1725 * Get the SubscriptionInfo(s) of the currently active SIM(s). The records will be sorted 1726 * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}. 1727 * 1728 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 1729 * or that the calling app has carrier privileges (see 1730 * {@link TelephonyManager#hasCarrierPrivileges}). 1731 * 1732 * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device. 1733 * <ul> 1734 * <li> 1735 * If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener} 1736 * has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be 1737 * invoked in the future. 1738 * </li> 1739 * <li> 1740 * If the list is empty then there are no {@link SubscriptionInfo} records currently available. 1741 * </li> 1742 * <li> 1743 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex} 1744 * then by {@link SubscriptionInfo#getSubscriptionId}. 1745 * </li> 1746 * </ul> 1747 */ 1748 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfoList()1749 public List<SubscriptionInfo> getActiveSubscriptionInfoList() { 1750 return getActiveSubscriptionInfoList(/* userVisibleonly */true); 1751 } 1752 1753 /** 1754 * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s). 1755 * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} 1756 * then by {@link SubscriptionInfo#getSubscriptionId}. 1757 * 1758 * Hidden subscriptions refer to those are not meant visible to the users. 1759 * For example, an opportunistic subscription that is grouped with other 1760 * subscriptions should remain invisible to users as they are only functionally 1761 * supplementary to primary ones. 1762 * 1763 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 1764 * or that the calling app has carrier privileges (see 1765 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible 1766 * to the calling app are returned. 1767 * 1768 * @return Sorted list of the currently available {@link SubscriptionInfo} 1769 * records on the device. 1770 * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return 1771 * both active and hidden SubscriptionInfos. 1772 * 1773 */ getCompleteActiveSubscriptionInfoList()1774 public @NonNull List<SubscriptionInfo> getCompleteActiveSubscriptionInfoList() { 1775 List<SubscriptionInfo> completeList = getActiveSubscriptionInfoList( 1776 /* userVisibleonly */false); 1777 if (completeList == null) { 1778 completeList = new ArrayList<>(); 1779 } 1780 return completeList; 1781 } 1782 1783 /** 1784 * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly 1785 * is true, it will filter out the hidden subscriptions. 1786 * 1787 * @hide 1788 */ getActiveSubscriptionInfoList(boolean userVisibleOnly)1789 public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) { 1790 List<SubscriptionInfo> activeList = null; 1791 1792 try { 1793 ISub iSub = TelephonyManager.getSubscriptionService(); 1794 if (iSub != null) { 1795 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(), 1796 mContext.getAttributionTag()); 1797 } 1798 } catch (RemoteException ex) { 1799 // ignore it 1800 } 1801 1802 if (!userVisibleOnly || activeList == null) { 1803 return activeList; 1804 } else { 1805 return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo)) 1806 .collect(Collectors.toList()); 1807 } 1808 } 1809 1810 /** 1811 * Gets the SubscriptionInfo(s) of all available subscriptions, if any. 1812 * 1813 * <p>Available subscriptions include active ones (those with a non-negative 1814 * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded 1815 * subscriptions. 1816 * 1817 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by 1818 * {@link SubscriptionInfo#getSubscriptionId}. 1819 * 1820 * @return Sorted list of the current {@link SubscriptionInfo} records available on the 1821 * device. 1822 * <ul> 1823 * <li> 1824 * If null is returned the current state is unknown but if a 1825 * {@link OnSubscriptionsChangedListener} has been registered 1826 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future. 1827 * <li> 1828 * If the list is empty then there are no {@link SubscriptionInfo} records currently available. 1829 * <li> 1830 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex} 1831 * then by {@link SubscriptionInfo#getSubscriptionId}. 1832 * </ul> 1833 * 1834 * <p> 1835 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required 1836 * for #getAvailableSubscriptionInfoList to be invoked. 1837 * @hide 1838 */ 1839 @SystemApi getAvailableSubscriptionInfoList()1840 public List<SubscriptionInfo> getAvailableSubscriptionInfoList() { 1841 List<SubscriptionInfo> result = null; 1842 1843 try { 1844 ISub iSub = TelephonyManager.getSubscriptionService(); 1845 if (iSub != null) { 1846 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(), 1847 mContext.getAttributionTag()); 1848 } 1849 } catch (RemoteException ex) { 1850 // ignore it 1851 } 1852 return result; 1853 } 1854 1855 /** 1856 * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if 1857 * any. 1858 * 1859 * <p>Only those subscriptions for which the calling app has carrier privileges per the 1860 * subscription metadata, if any, will be included in the returned list. 1861 * 1862 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by 1863 * {@link SubscriptionInfo#getSubscriptionId}. 1864 * 1865 * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the 1866 * device which are accessible to the caller. 1867 * <ul> 1868 * <li> 1869 * If null is returned the current state is unknown but if a 1870 * {@link OnSubscriptionsChangedListener} has been registered 1871 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future. 1872 * <li> 1873 * If the list is empty then there are no {@link SubscriptionInfo} records currently available. 1874 * <li> 1875 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex} 1876 * then by {@link SubscriptionInfo#getSubscriptionId}. 1877 * </ul> 1878 */ getAccessibleSubscriptionInfoList()1879 public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() { 1880 List<SubscriptionInfo> result = null; 1881 1882 try { 1883 ISub iSub = TelephonyManager.getSubscriptionService(); 1884 if (iSub != null) { 1885 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName()); 1886 } 1887 } catch (RemoteException ex) { 1888 // ignore it 1889 } 1890 return result; 1891 } 1892 1893 /** 1894 * Request a refresh of the platform cache of profile information for the eUICC which 1895 * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}. 1896 * 1897 * <p>Should be called by the EuiccService implementation whenever this information changes due 1898 * to an operation done outside the scope of a request initiated by the platform to the 1899 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that 1900 * were made through the EuiccService. 1901 * 1902 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 1903 * 1904 * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID. 1905 * 1906 * @hide 1907 */ 1908 @SystemApi requestEmbeddedSubscriptionInfoListRefresh()1909 public void requestEmbeddedSubscriptionInfoListRefresh() { 1910 int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc(); 1911 try { 1912 ISub iSub = TelephonyManager.getSubscriptionService(); 1913 if (iSub != null) { 1914 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId); 1915 } 1916 } catch (RemoteException ex) { 1917 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed."); 1918 } 1919 } 1920 1921 /** 1922 * Request a refresh of the platform cache of profile information for the eUICC with the given 1923 * {@code cardId}. 1924 * 1925 * <p>Should be called by the EuiccService implementation whenever this information changes due 1926 * to an operation done outside the scope of a request initiated by the platform to the 1927 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that 1928 * were made through the EuiccService. 1929 * 1930 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 1931 * 1932 * @param cardId the card ID of the eUICC. 1933 * 1934 * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID. 1935 * 1936 * @hide 1937 */ 1938 @SystemApi requestEmbeddedSubscriptionInfoListRefresh(int cardId)1939 public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) { 1940 try { 1941 ISub iSub = TelephonyManager.getSubscriptionService(); 1942 if (iSub != null) { 1943 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId); 1944 } 1945 } catch (RemoteException ex) { 1946 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed."); 1947 } 1948 } 1949 1950 /** 1951 * Get the active subscription count. 1952 * 1953 * @return The current number of active subscriptions. 1954 * 1955 * @see #getActiveSubscriptionInfoList() 1956 */ 1957 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfoCount()1958 public int getActiveSubscriptionInfoCount() { 1959 int result = 0; 1960 1961 try { 1962 ISub iSub = TelephonyManager.getSubscriptionService(); 1963 if (iSub != null) { 1964 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(), 1965 mContext.getAttributionTag()); 1966 } 1967 } catch (RemoteException ex) { 1968 // ignore it 1969 } 1970 1971 return result; 1972 } 1973 1974 /** 1975 * @return the maximum number of active subscriptions that will be returned by 1976 * {@link #getActiveSubscriptionInfoList} and the value returned by 1977 * {@link #getActiveSubscriptionInfoCount}. 1978 */ getActiveSubscriptionInfoCountMax()1979 public int getActiveSubscriptionInfoCountMax() { 1980 int result = 0; 1981 1982 try { 1983 ISub iSub = TelephonyManager.getSubscriptionService(); 1984 if (iSub != null) { 1985 result = iSub.getActiveSubInfoCountMax(); 1986 } 1987 } catch (RemoteException ex) { 1988 // ignore it 1989 } 1990 1991 return result; 1992 } 1993 1994 /** 1995 * Add a new SubscriptionInfo to SubscriptionInfo database if needed 1996 * @param iccId the IccId of the SIM card 1997 * @param slotIndex the slot which the SIM is inserted 1998 * @return the URL of the newly created row or the updated row 1999 * @hide 2000 */ addSubscriptionInfoRecord(String iccId, int slotIndex)2001 public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) { 2002 if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex); 2003 if (iccId == null) { 2004 logd("[addSubscriptionInfoRecord]- null iccId"); 2005 } 2006 if (!isValidSlotIndex(slotIndex)) { 2007 logd("[addSubscriptionInfoRecord]- invalid slotIndex"); 2008 } 2009 2010 addSubscriptionInfoRecord(iccId, null, slotIndex, SUBSCRIPTION_TYPE_LOCAL_SIM); 2011 2012 // FIXME: Always returns null? 2013 return null; 2014 2015 } 2016 2017 /** 2018 * Add a new SubscriptionInfo to SubscriptionInfo database if needed 2019 * @param uniqueId This is the unique identifier for the subscription within the 2020 * specific subscription type. 2021 * @param displayName human-readable name of the device the subscription corresponds to. 2022 * @param slotIndex the slot assigned to this subscription. It is ignored for subscriptionType 2023 * of {@link #SUBSCRIPTION_TYPE_REMOTE_SIM}. 2024 * @param subscriptionType the {@link #SUBSCRIPTION_TYPE} 2025 * @hide 2026 */ 2027 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) addSubscriptionInfoRecord(@onNull String uniqueId, @Nullable String displayName, int slotIndex, @SubscriptionType int subscriptionType)2028 public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName, 2029 int slotIndex, @SubscriptionType int subscriptionType) { 2030 if (VDBG) { 2031 logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId 2032 + ", displayName:" + displayName + ", slotIndex:" + slotIndex 2033 + ", subscriptionType: " + subscriptionType); 2034 } 2035 if (uniqueId == null) { 2036 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null"); 2037 return; 2038 } 2039 2040 try { 2041 ISub iSub = TelephonyManager.getSubscriptionService(); 2042 if (iSub == null) { 2043 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- ISub service is null"); 2044 return; 2045 } 2046 int result = iSub.addSubInfo(uniqueId, displayName, slotIndex, subscriptionType); 2047 if (result < 0) { 2048 Log.e(LOG_TAG, "Adding of subscription didn't succeed: error = " + result); 2049 } else { 2050 logd("successfully added new subscription"); 2051 } 2052 } catch (RemoteException ex) { 2053 // ignore it 2054 } 2055 } 2056 2057 /** 2058 * Remove subscription info record from the subscription database. 2059 * 2060 * @param uniqueId This is the unique identifier for the subscription within the specific 2061 * subscription type. 2062 * @param subscriptionType the type of subscription to be removed. 2063 * 2064 * @throws NullPointerException if {@code uniqueId} is {@code null}. 2065 * @throws SecurityException if callers do not hold the required permission. 2066 * 2067 * @hide 2068 */ 2069 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) removeSubscriptionInfoRecord(@onNull String uniqueId, @SubscriptionType int subscriptionType)2070 public void removeSubscriptionInfoRecord(@NonNull String uniqueId, 2071 @SubscriptionType int subscriptionType) { 2072 if (VDBG) { 2073 logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId 2074 + ", subscriptionType: " + subscriptionType); 2075 } 2076 if (uniqueId == null) { 2077 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null"); 2078 return; 2079 } 2080 2081 try { 2082 ISub iSub = TelephonyManager.getSubscriptionService(); 2083 if (iSub == null) { 2084 Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null"); 2085 return; 2086 } 2087 boolean result = iSub.removeSubInfo(uniqueId, subscriptionType); 2088 if (!result) { 2089 Log.e(LOG_TAG, "Removal of subscription didn't succeed"); 2090 } else { 2091 logd("successfully removed subscription"); 2092 } 2093 } catch (RemoteException ex) { 2094 // ignore it 2095 } 2096 } 2097 2098 /** 2099 * Set SIM icon tint color for subscription ID 2100 * @param tint the RGB value of icon tint color of the SIM 2101 * @param subId the unique subscription ID in database 2102 * @return the number of records updated 2103 * @hide 2104 */ 2105 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setIconTint(@olorInt int tint, int subId)2106 public int setIconTint(@ColorInt int tint, int subId) { 2107 if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId); 2108 return setSubscriptionPropertyHelper(subId, "setIconTint", 2109 (iSub)-> iSub.setIconTint(subId, tint) 2110 ); 2111 } 2112 2113 /** 2114 * Set the display name for a subscription ID 2115 * @param displayName the display name of SIM card 2116 * @param subId the unique Subscritpion ID in database 2117 * @param nameSource SIM display name source 2118 * @return the number of records updated or < 0 if invalid subId 2119 * @hide 2120 */ 2121 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDisplayName(@ullable String displayName, int subId, @SimDisplayNameSource int nameSource)2122 public int setDisplayName(@Nullable String displayName, int subId, 2123 @SimDisplayNameSource int nameSource) { 2124 if (VDBG) { 2125 logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId 2126 + " nameSource:" + nameSource); 2127 } 2128 return setSubscriptionPropertyHelper(subId, "setDisplayName", 2129 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource) 2130 ); 2131 } 2132 2133 /** 2134 * Set phone number by subId 2135 * @param number the phone number of the SIM 2136 * @param subId the unique SubscriptionInfo index in database 2137 * @return the number of records updated 2138 * @hide 2139 */ 2140 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setDisplayNumber(String number, int subId)2141 public int setDisplayNumber(String number, int subId) { 2142 if (number == null) { 2143 logd("[setDisplayNumber]- fail"); 2144 return -1; 2145 } 2146 return setSubscriptionPropertyHelper(subId, "setDisplayNumber", 2147 (iSub)-> iSub.setDisplayNumber(number, subId) 2148 ); 2149 } 2150 2151 /** 2152 * Set data roaming by simInfo index 2153 * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming 2154 * @param subId the unique SubscriptionInfo index in database 2155 * @return the number of records updated 2156 * @hide 2157 */ 2158 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setDataRoaming(int roaming, int subId)2159 public int setDataRoaming(int roaming, int subId) { 2160 if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId); 2161 return setSubscriptionPropertyHelper(subId, "setDataRoaming", 2162 (iSub)->iSub.setDataRoaming(roaming, subId) 2163 ); 2164 } 2165 2166 /** 2167 * Get slotIndex associated with the subscription. 2168 * 2169 * @param subscriptionId the unique SubscriptionInfo index in database 2170 * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied 2171 * subscriptionId doesn't have an associated slot index. 2172 */ getSlotIndex(int subscriptionId)2173 public static int getSlotIndex(int subscriptionId) { 2174 return sGetSlotIndexCache.query(subscriptionId); 2175 } 2176 2177 /** 2178 * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size 2179 * of the array is 1. This API was mistakenly designed to return multiple subscription ids, 2180 * which is not possible in the current Android telephony architecture. 2181 * 2182 * @param slotIndex The logical SIM slot index. 2183 * 2184 * @return Subscription id of the active subscription on the specified logical SIM slot index. 2185 * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will 2186 * be returned. {@code null} if the provided {@code slotIndex} is not valid. 2187 * 2188 * @deprecated Use {@link #getSubscriptionId(int)} instead. 2189 */ 2190 @Deprecated 2191 @Nullable getSubscriptionIds(int slotIndex)2192 public int[] getSubscriptionIds(int slotIndex) { 2193 if (!isValidSlotIndex(slotIndex)) { 2194 return null; 2195 } 2196 return new int[]{getSubscriptionId(slotIndex)}; 2197 } 2198 2199 /** 2200 * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size 2201 * of the array is 1. This API was mistakenly designed to return multiple subscription ids, 2202 * which is not possible in the current Android telephony architecture. 2203 * 2204 * @param slotIndex The logical SIM slot index. 2205 * 2206 * @return Subscription id of the active subscription on the specified logical SIM slot index. 2207 * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will 2208 * be returned. {@code null} if the provided {@code slotIndex} is not valid. 2209 * 2210 * @deprecated Use {@link #getSubscriptionId(int)} instead. 2211 * @hide 2212 */ getSubId(int slotIndex)2213 public static int[] getSubId(int slotIndex) { 2214 if (!isValidSlotIndex(slotIndex)) { 2215 return null; 2216 } 2217 return new int[]{getSubscriptionId(slotIndex)}; 2218 } 2219 2220 /** 2221 * Get the subscription id for specified logical SIM slot index. 2222 * 2223 * @param slotIndex The logical SIM slot index. 2224 * @return The subscription id. {@link #INVALID_SUBSCRIPTION_ID} if SIM is absent. 2225 */ getSubscriptionId(int slotIndex)2226 public static int getSubscriptionId(int slotIndex) { 2227 if (!isValidSlotIndex(slotIndex)) { 2228 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2229 } 2230 2231 return sGetSubIdCache.query(slotIndex); 2232 } 2233 2234 /** @hide */ 2235 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) getPhoneId(int subId)2236 public static int getPhoneId(int subId) { 2237 return sGetPhoneIdCache.query(subId); 2238 } 2239 logd(String msg)2240 private static void logd(String msg) { 2241 Rlog.d(LOG_TAG, msg); 2242 } 2243 loge(String msg)2244 private static void loge(String msg) { 2245 Rlog.e(LOG_TAG, msg); 2246 } 2247 2248 /** 2249 * Returns the system's default subscription id. 2250 * 2251 * For a voice capable device, it will return getDefaultVoiceSubscriptionId. 2252 * For a data only device, it will return the getDefaultDataSubscriptionId. 2253 * May return an INVALID_SUBSCRIPTION_ID on error. 2254 * 2255 * @return the "system" default subscription id. 2256 */ getDefaultSubscriptionId()2257 public static int getDefaultSubscriptionId() { 2258 return sGetDefaultSubIdCache.query(null); 2259 } 2260 2261 /** 2262 * Returns the system's default voice subscription id. 2263 * 2264 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID. 2265 * 2266 * @return the default voice subscription Id. 2267 */ getDefaultVoiceSubscriptionId()2268 public static int getDefaultVoiceSubscriptionId() { 2269 int subId = INVALID_SUBSCRIPTION_ID; 2270 2271 try { 2272 ISub iSub = TelephonyManager.getSubscriptionService(); 2273 if (iSub != null) { 2274 subId = iSub.getDefaultVoiceSubId(); 2275 } 2276 } catch (RemoteException ex) { 2277 // ignore it 2278 } 2279 2280 if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId); 2281 return subId; 2282 } 2283 2284 /** 2285 * Sets the system's default voice subscription id. 2286 * 2287 * On a data-only device, this is a no-op. 2288 * 2289 * May throw a {@link RuntimeException} if the provided subscription id is equal to 2290 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} 2291 * 2292 * @param subscriptionId A valid subscription ID to set as the system default, or 2293 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} 2294 * @hide 2295 */ 2296 @SystemApi 2297 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDefaultVoiceSubscriptionId(int subscriptionId)2298 public void setDefaultVoiceSubscriptionId(int subscriptionId) { 2299 if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId); 2300 try { 2301 ISub iSub = TelephonyManager.getSubscriptionService(); 2302 if (iSub != null) { 2303 iSub.setDefaultVoiceSubId(subscriptionId); 2304 } 2305 } catch (RemoteException ex) { 2306 // ignore it 2307 } 2308 } 2309 2310 /** 2311 * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards 2312 * compatibility. 2313 * @hide 2314 */ setDefaultVoiceSubId(int subId)2315 public void setDefaultVoiceSubId(int subId) { 2316 setDefaultVoiceSubscriptionId(subId); 2317 } 2318 2319 /** 2320 * Return the SubscriptionInfo for default voice subscription. 2321 * 2322 * Will return null on data only devices, or on error. 2323 * 2324 * @return the SubscriptionInfo for the default voice subscription. 2325 * @hide 2326 */ 2327 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getDefaultVoiceSubscriptionInfo()2328 public SubscriptionInfo getDefaultVoiceSubscriptionInfo() { 2329 return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId()); 2330 } 2331 2332 /** @hide */ 2333 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getDefaultVoicePhoneId()2334 public static int getDefaultVoicePhoneId() { 2335 return getPhoneId(getDefaultVoiceSubscriptionId()); 2336 } 2337 2338 /** 2339 * Returns the system's default SMS subscription id. 2340 * 2341 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID. 2342 * 2343 * @return the default SMS subscription Id. 2344 */ getDefaultSmsSubscriptionId()2345 public static int getDefaultSmsSubscriptionId() { 2346 return sGetDefaultSmsSubIdCache.query(null); 2347 } 2348 2349 /** 2350 * Set the subscription which will be used by default for SMS, with the subscription which 2351 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied 2352 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}). 2353 * 2354 * @param subscriptionId the supplied subscription ID 2355 * 2356 * @hide 2357 */ 2358 @SystemApi 2359 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setDefaultSmsSubId(int subscriptionId)2360 public void setDefaultSmsSubId(int subscriptionId) { 2361 if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId); 2362 try { 2363 ISub iSub = TelephonyManager.getSubscriptionService(); 2364 if (iSub != null) { 2365 iSub.setDefaultSmsSubId(subscriptionId); 2366 } 2367 } catch (RemoteException ex) { 2368 ex.rethrowFromSystemServer(); 2369 } 2370 } 2371 2372 /** 2373 * Returns the system's default data subscription id. 2374 * 2375 * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID. 2376 * 2377 * @return the default data subscription Id. 2378 */ getDefaultDataSubscriptionId()2379 public static int getDefaultDataSubscriptionId() { 2380 return sGetDefaultDataSubIdCache.query(null); 2381 } 2382 2383 /** 2384 * Set the subscription which will be used by default for data, with the subscription which 2385 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied 2386 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}). 2387 * 2388 * @param subscriptionId the supplied subscription ID 2389 * 2390 * @hide 2391 */ 2392 @SystemApi 2393 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setDefaultDataSubId(int subscriptionId)2394 public void setDefaultDataSubId(int subscriptionId) { 2395 if (VDBG) logd("setDataSubscription sub id = " + subscriptionId); 2396 try { 2397 ISub iSub = TelephonyManager.getSubscriptionService(); 2398 if (iSub != null) { 2399 iSub.setDefaultDataSubId(subscriptionId); 2400 } 2401 } catch (RemoteException ex) { 2402 // ignore it 2403 } 2404 } 2405 2406 /** 2407 * Return the SubscriptionInfo for default data subscription. 2408 * 2409 * Will return null on voice only devices, or on error. 2410 * 2411 * @return the SubscriptionInfo for the default data subscription. 2412 * @hide 2413 */ 2414 @UnsupportedAppUsage getDefaultDataSubscriptionInfo()2415 public SubscriptionInfo getDefaultDataSubscriptionInfo() { 2416 return getActiveSubscriptionInfo(getDefaultDataSubscriptionId()); 2417 } 2418 2419 /** 2420 * Check if the supplied subscription ID is valid. 2421 * 2422 * <p>A valid subscription ID is not necessarily an active subscription ID 2423 * (see {@link #isActiveSubscriptionId(int)}) or an usable subscription ID 2424 * (see {@link #isUsableSubscriptionId(int)}). Unless specifically noted, subscription 2425 * APIs work with a valid subscription ID. 2426 * 2427 * @param subscriptionId The subscription ID. 2428 * @return {@code true} if the supplied subscriptionId is valid; {@code false} otherwise. 2429 */ isValidSubscriptionId(int subscriptionId)2430 public static boolean isValidSubscriptionId(int subscriptionId) { 2431 return subscriptionId > INVALID_SUBSCRIPTION_ID; 2432 } 2433 2434 /** 2435 * Check if the supplied subscription ID is usable. 2436 * 2437 * <p>A usable subscription ID is a valid subscription ID, but not necessarily an active 2438 * subscription ID (see {@link #isActiveSubscriptionId(int)}). Some subscription APIs 2439 * require a usable subscription ID, and this is noted in their documentation; otherwise, a 2440 * subscription ID does not need to be usable for subscription functions, only valid. 2441 * 2442 * @param subscriptionId the subscription ID 2443 * @return {@code true} if the subscription ID is usable; {@code false} otherwise. 2444 */ isUsableSubscriptionId(int subscriptionId)2445 public static boolean isUsableSubscriptionId(int subscriptionId) { 2446 return isUsableSubIdValue(subscriptionId); 2447 } 2448 2449 /** 2450 * @return true if subId is an usable subId value else false. A 2451 * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID. 2452 * @hide 2453 */ 2454 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) isUsableSubIdValue(int subId)2455 public static boolean isUsableSubIdValue(int subId) { 2456 return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE; 2457 } 2458 2459 /** @hide */ 2460 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) isValidSlotIndex(int slotIndex)2461 public static boolean isValidSlotIndex(int slotIndex) { 2462 return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount(); 2463 } 2464 2465 /** @hide */ 2466 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isValidPhoneId(int phoneId)2467 public static boolean isValidPhoneId(int phoneId) { 2468 return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount(); 2469 } 2470 2471 /** @hide */ 2472 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) putPhoneIdAndSubIdExtra(Intent intent, int phoneId)2473 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) { 2474 int subId = SubscriptionManager.getSubscriptionId(phoneId); 2475 if (isValidSubscriptionId(subId)) { 2476 putPhoneIdAndSubIdExtra(intent, phoneId, subId); 2477 } else { 2478 logd("putPhoneIdAndSubIdExtra: no valid subs"); 2479 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); 2480 intent.putExtra(EXTRA_SLOT_INDEX, phoneId); 2481 } 2482 } 2483 2484 /** @hide */ 2485 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId)2486 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) { 2487 if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId); 2488 intent.putExtra(EXTRA_SLOT_INDEX, phoneId); 2489 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); 2490 putSubscriptionIdExtra(intent, subId); 2491 } 2492 2493 /** 2494 * Get visible subscription Id(s) of the currently active SIM(s). 2495 * 2496 * @return the list of subId's that are active, 2497 * is never null but the length may be 0. 2498 * @hide 2499 */ 2500 @SystemApi 2501 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getActiveSubscriptionIdList()2502 public @NonNull int[] getActiveSubscriptionIdList() { 2503 return getActiveSubscriptionIdList(/* visibleOnly */ true); 2504 } 2505 2506 /** 2507 * Get both hidden and visible subscription Id(s) of the currently active SIM(s). 2508 * 2509 * Hidden subscriptions refer to those are not meant visible to the users. 2510 * For example, an opportunistic subscription that is grouped with other 2511 * subscriptions should remain invisible to users as they are only functionally 2512 * supplementary to primary ones. 2513 * 2514 * @return the list of subId's that are active, 2515 * is never null but the length may be 0. 2516 * @hide 2517 */ 2518 @SystemApi 2519 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getCompleteActiveSubscriptionIdList()2520 public @NonNull int[] getCompleteActiveSubscriptionIdList() { 2521 return getActiveSubscriptionIdList(/* visibleOnly */false); 2522 } 2523 2524 /** 2525 * @return a non-null list of subId's that are active. 2526 * 2527 * @hide 2528 */ getActiveSubscriptionIdList(boolean visibleOnly)2529 public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) { 2530 try { 2531 ISub iSub = TelephonyManager.getSubscriptionService(); 2532 if (iSub != null) { 2533 int[] subId = iSub.getActiveSubIdList(visibleOnly); 2534 if (subId != null) return subId; 2535 } 2536 } catch (RemoteException ex) { 2537 // ignore it 2538 } 2539 2540 return new int[0]; 2541 } 2542 2543 /** 2544 * Returns true if the device is considered roaming on the current 2545 * network for a subscription. 2546 * <p> 2547 * Availability: Only when user registered to a network. 2548 * 2549 * @param subId The subscription ID 2550 * @return true if the network for the subscription is roaming, false otherwise 2551 */ isNetworkRoaming(int subId)2552 public boolean isNetworkRoaming(int subId) { 2553 final int phoneId = getPhoneId(subId); 2554 if (phoneId < 0) { 2555 // What else can we do? 2556 return false; 2557 } 2558 return TelephonyManager.getDefault().isNetworkRoaming(subId); 2559 } 2560 2561 /** 2562 * Set a field in the subscription database. Note not all fields are supported. 2563 * 2564 * @param subscriptionId Subscription Id of Subscription. 2565 * @param columnName Column name in the database. Note not all fields are supported. 2566 * @param value Value to store in the database. 2567 * 2568 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 2569 * exposed. 2570 * @throws SecurityException if callers do not hold the required permission. 2571 * 2572 * @see android.provider.Telephony.SimInfo for all the columns. 2573 * 2574 * @hide 2575 */ 2576 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setSubscriptionProperty(int subscriptionId, @NonNull String columnName, @NonNull String value)2577 public static void setSubscriptionProperty(int subscriptionId, @NonNull String columnName, 2578 @NonNull String value) { 2579 try { 2580 ISub iSub = TelephonyManager.getSubscriptionService(); 2581 if (iSub != null) { 2582 iSub.setSubscriptionProperty(subscriptionId, columnName, value); 2583 } 2584 } catch (RemoteException ex) { 2585 // ignore it 2586 } 2587 } 2588 2589 /** 2590 * Serialize list of contacts uri to string 2591 * @hide 2592 */ serializeUriLists(List<Uri> uris)2593 public static String serializeUriLists(List<Uri> uris) { 2594 List<String> contacts = new ArrayList<>(); 2595 for (Uri uri : uris) { 2596 contacts.add(uri.toString()); 2597 } 2598 try { 2599 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 2600 ObjectOutputStream oos = new ObjectOutputStream(bos); 2601 oos.writeObject(contacts); 2602 oos.flush(); 2603 return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT); 2604 } catch (IOException e) { 2605 logd("serializeUriLists IO exception"); 2606 } 2607 return ""; 2608 } 2609 2610 /** 2611 * Get specific field in string format from the subscription info database. 2612 * 2613 * @param context The calling context. 2614 * @param subscriptionId Subscription id of the subscription. 2615 * @param columnName Column name in subscription database. 2616 * 2617 * @return Value in string format associated with {@code subscriptionId} and {@code columnName} 2618 * from the database. Empty string if the {@code subscriptionId} is invalid (for backward 2619 * compatible). 2620 * 2621 * @throws IllegalArgumentException if the field is not exposed. 2622 * 2623 * @see android.provider.Telephony.SimInfo for all the columns. 2624 * 2625 * @hide 2626 */ 2627 @NonNull 2628 @RequiresPermission(anyOf = { 2629 Manifest.permission.READ_PHONE_STATE, 2630 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 2631 "carrier privileges", 2632 }) getStringSubscriptionProperty(@onNull Context context, int subscriptionId, @NonNull String columnName)2633 private static String getStringSubscriptionProperty(@NonNull Context context, 2634 int subscriptionId, @NonNull String columnName) { 2635 String resultValue = null; 2636 try { 2637 ISub iSub = TelephonyManager.getSubscriptionService(); 2638 if (iSub != null) { 2639 resultValue = iSub.getSubscriptionProperty(subscriptionId, columnName, 2640 context.getOpPackageName(), context.getAttributionTag()); 2641 } 2642 } catch (RemoteException ex) { 2643 // ignore it 2644 } 2645 return TextUtils.emptyIfNull(resultValue); 2646 } 2647 2648 /** 2649 * Get specific field in {@code boolean} format from the subscription info database. 2650 * 2651 * @param subscriptionId Subscription id of the subscription. 2652 * @param columnName Column name in subscription database. 2653 * @param defaultValue Default value in case not found or error. 2654 * @param context The calling context. 2655 * 2656 * @return Value in {@code boolean} format associated with {@code subscriptionId} and 2657 * {@code columnName} from the database, or {@code defaultValue} if not found or error. 2658 * 2659 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 2660 * exposed. 2661 * 2662 * @see android.provider.Telephony.SimInfo for all the columns. 2663 * 2664 * @hide 2665 */ 2666 @RequiresPermission(anyOf = { 2667 Manifest.permission.READ_PHONE_STATE, 2668 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 2669 "carrier privileges", 2670 }) getBooleanSubscriptionProperty(int subscriptionId, @NonNull String columnName, boolean defaultValue, @NonNull Context context)2671 public static boolean getBooleanSubscriptionProperty(int subscriptionId, 2672 @NonNull String columnName, boolean defaultValue, @NonNull Context context) { 2673 String result = getStringSubscriptionProperty(context, subscriptionId, columnName); 2674 if (!result.isEmpty()) { 2675 try { 2676 return Integer.parseInt(result) == 1; 2677 } catch (NumberFormatException err) { 2678 logd("getBooleanSubscriptionProperty NumberFormat exception"); 2679 } 2680 } 2681 return defaultValue; 2682 } 2683 2684 /** 2685 * Get specific field in {@code integer} format from the subscription info database. 2686 * 2687 * @param subscriptionId Subscription id of the subscription. 2688 * @param columnName Column name in subscription database. 2689 * @param defaultValue Default value in case not found or error. 2690 * @param context The calling context. 2691 * 2692 * @return Value in {@code integer} format associated with {@code subscriptionId} and 2693 * {@code columnName} from the database, or {@code defaultValue} if not found or error. 2694 * 2695 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 2696 * exposed. 2697 * 2698 * @see android.provider.Telephony.SimInfo for all the columns. 2699 * 2700 * @hide 2701 */ 2702 @RequiresPermission(anyOf = { 2703 Manifest.permission.READ_PHONE_STATE, 2704 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 2705 "carrier privileges", 2706 }) getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName, int defaultValue, @NonNull Context context)2707 public static int getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName, 2708 int defaultValue, @NonNull Context context) { 2709 String result = getStringSubscriptionProperty(context, subscriptionId, columnName); 2710 if (!result.isEmpty()) { 2711 try { 2712 return Integer.parseInt(result); 2713 } catch (NumberFormatException err) { 2714 logd("getIntegerSubscriptionProperty NumberFormat exception"); 2715 } 2716 } 2717 return defaultValue; 2718 } 2719 2720 /** 2721 * Get specific field in {@code long} format from the subscription info database. 2722 * 2723 * @param subscriptionId Subscription id of the subscription. 2724 * @param columnName Column name in subscription database. 2725 * @param defaultValue Default value in case not found or error. 2726 * @param context The calling context. 2727 * 2728 * @return Value in {@code long} format associated with {@code subscriptionId} and 2729 * {@code columnName} from the database, or {@code defaultValue} if not found or error. 2730 * 2731 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 2732 * exposed. 2733 * 2734 * @see android.provider.Telephony.SimInfo for all the columns. 2735 * 2736 * @hide 2737 */ 2738 @RequiresPermission(anyOf = { 2739 Manifest.permission.READ_PHONE_STATE, 2740 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 2741 "carrier privileges", 2742 }) getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName, long defaultValue, @NonNull Context context)2743 public static long getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName, 2744 long defaultValue, @NonNull Context context) { 2745 String result = getStringSubscriptionProperty(context, subscriptionId, columnName); 2746 if (!result.isEmpty()) { 2747 try { 2748 return Long.parseLong(result); 2749 } catch (NumberFormatException err) { 2750 logd("getLongSubscriptionProperty NumberFormat exception"); 2751 } 2752 } 2753 return defaultValue; 2754 } 2755 2756 /** 2757 * Returns the {@link Resources} from the given {@link Context} for the MCC/MNC associated with 2758 * the subscription. If the subscription ID is invalid, the base resources are returned instead. 2759 * 2760 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 2761 * 2762 * @param context Context object 2763 * @param subId Subscription Id of Subscription whose resources are required 2764 * @return Resources associated with Subscription. 2765 * @hide 2766 */ 2767 @NonNull 2768 @SystemApi getResourcesForSubId(@onNull Context context, int subId)2769 public static Resources getResourcesForSubId(@NonNull Context context, int subId) { 2770 return getResourcesForSubId(context, subId, false); 2771 } 2772 2773 /** 2774 * Returns the resources associated with Subscription. 2775 * @param context Context object 2776 * @param subId Subscription Id of Subscription who's resources are required 2777 * @param useRootLocale if root locale should be used. Localized locale is used if false. 2778 * @return Resources associated with Subscription. 2779 * @hide 2780 */ 2781 @NonNull getResourcesForSubId(Context context, int subId, boolean useRootLocale)2782 public static Resources getResourcesForSubId(Context context, int subId, 2783 boolean useRootLocale) { 2784 // Check if resources for this context and subId already exist in the resource cache. 2785 // Resources that use the root locale are not cached. 2786 Pair<Context, Integer> cacheKey = null; 2787 if (isValidSubscriptionId(subId) && !useRootLocale) { 2788 cacheKey = Pair.create(context, subId); 2789 if (sResourcesCache.containsKey(cacheKey)) { 2790 // Cache hit. Use cached Resources. 2791 return sResourcesCache.get(cacheKey); 2792 } 2793 } 2794 2795 final SubscriptionInfo subInfo = 2796 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId); 2797 2798 Configuration overrideConfig = new Configuration(); 2799 if (subInfo != null) { 2800 overrideConfig.mcc = subInfo.getMcc(); 2801 overrideConfig.mnc = subInfo.getMnc(); 2802 if (overrideConfig.mnc == 0) { 2803 overrideConfig.mnc = Configuration.MNC_ZERO; 2804 cacheKey = null; 2805 } 2806 } else { 2807 cacheKey = null; 2808 } 2809 2810 if (useRootLocale) { 2811 overrideConfig.setLocale(Locale.ROOT); 2812 } 2813 2814 // Create new context with new configuration so that we can avoid modifying the passed in 2815 // context. 2816 // Note that if the original context configuration changes, the resources here will also 2817 // change for all values except those overridden by newConfig (e.g. if the device has an 2818 // orientation change). 2819 Context newContext = context.createConfigurationContext(overrideConfig); 2820 Resources res = newContext.getResources(); 2821 2822 if (cacheKey != null) { 2823 // Save the newly created Resources in the resource cache. 2824 sResourcesCache.put(cacheKey, res); 2825 } 2826 return res; 2827 } 2828 2829 /** 2830 * Checks if the supplied subscription ID corresponds to a subscription which is actively in 2831 * use on the device. An active subscription ID is a valid and usable subscription ID. 2832 * 2833 * @param subscriptionId the subscription ID. 2834 * @return {@code true} if the supplied subscription ID corresponds to an active subscription; 2835 * {@code false} if it does not correspond to an active subscription; or throw a 2836 * SecurityException if the caller hasn't got the right permission. 2837 */ 2838 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) isActiveSubscriptionId(int subscriptionId)2839 public boolean isActiveSubscriptionId(int subscriptionId) { 2840 return isActiveSubId(subscriptionId); 2841 } 2842 2843 /** 2844 * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription 2845 * and the SIM providing the subscription is present in a slot and in "LOADED" state. 2846 * @hide 2847 */ 2848 @UnsupportedAppUsage isActiveSubId(int subId)2849 public boolean isActiveSubId(int subId) { 2850 try { 2851 ISub iSub = TelephonyManager.getSubscriptionService(); 2852 if (iSub != null) { 2853 return iSub.isActiveSubId(subId, mContext.getOpPackageName(), 2854 mContext.getAttributionTag()); 2855 } 2856 } catch (RemoteException ex) { 2857 } 2858 return false; 2859 } 2860 2861 /** 2862 * Get the description of the billing relationship plan between a carrier 2863 * and a specific subscriber. 2864 * <p> 2865 * This method is only accessible to the following narrow set of apps: 2866 * <ul> 2867 * <li>The carrier app for this subscriberId, as determined by 2868 * {@link TelephonyManager#hasCarrierPrivileges()}. 2869 * <li>The carrier app explicitly delegated access through 2870 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 2871 * </ul> 2872 * 2873 * @param subId the subscriber this relationship applies to 2874 * @throws SecurityException if the caller doesn't meet the requirements 2875 * outlined above. 2876 */ getSubscriptionPlans(int subId)2877 public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) { 2878 SubscriptionPlan[] subscriptionPlans = 2879 getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName()); 2880 return subscriptionPlans == null 2881 ? Collections.emptyList() : Arrays.asList(subscriptionPlans); 2882 } 2883 2884 /** 2885 * Set the description of the billing relationship plan between a carrier 2886 * and a specific subscriber. 2887 * <p> 2888 * This method is only accessible to the following narrow set of apps: 2889 * <ul> 2890 * <li>The carrier app for this subscriberId, as determined by 2891 * {@link TelephonyManager#hasCarrierPrivileges()}. 2892 * <li>The carrier app explicitly delegated access through 2893 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 2894 * </ul> 2895 * 2896 * @param subId the subscriber this relationship applies to. An empty list 2897 * may be sent to clear any existing plans. 2898 * @param plans the list of plans. The first plan is always the primary and 2899 * most important plan. Any additional plans are secondary and 2900 * may not be displayed or used by decision making logic. 2901 * @throws SecurityException if the caller doesn't meet the requirements 2902 * outlined above. 2903 * @throws IllegalArgumentException if plans don't meet the requirements 2904 * defined in {@link SubscriptionPlan}. 2905 * @deprecated use {@link #setSubscriptionPlans(int, List, long)} instead. 2906 */ 2907 @Deprecated setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans)2908 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) { 2909 setSubscriptionPlans(subId, plans, 0); 2910 } 2911 2912 /** 2913 * Set the description of the billing relationship plan between a carrier 2914 * and a specific subscriber. 2915 * <p> 2916 * This method is only accessible to the following narrow set of apps: 2917 * <ul> 2918 * <li>The carrier app for this subscriberId, as determined by 2919 * {@link TelephonyManager#hasCarrierPrivileges()}. 2920 * <li>The carrier app explicitly delegated access through 2921 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 2922 * </ul> 2923 * 2924 * @param subId the subscriber this relationship applies to. An empty list 2925 * may be sent to clear any existing plans. 2926 * @param plans the list of plans. The first plan is always the primary and 2927 * most important plan. Any additional plans are secondary and 2928 * may not be displayed or used by decision making logic. 2929 * @param expirationDurationMillis the duration after which the subscription plans 2930 * will be automatically cleared, or {@code 0} to leave the plans until 2931 * explicitly cleared, or the next reboot, whichever happens first. 2932 * @throws SecurityException if the caller doesn't meet the requirements 2933 * outlined above. 2934 * @throws IllegalArgumentException if plans don't meet the requirements 2935 * defined in {@link SubscriptionPlan}. 2936 */ setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans, @DurationMillisLong long expirationDurationMillis)2937 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans, 2938 @DurationMillisLong long expirationDurationMillis) { 2939 getNetworkPolicyManager().setSubscriptionPlans(subId, 2940 plans.toArray(new SubscriptionPlan[0]), expirationDurationMillis, 2941 mContext.getOpPackageName()); 2942 } 2943 2944 /** 2945 * Temporarily override the billing relationship plan between a carrier and 2946 * a specific subscriber to be considered unmetered. This will be reflected 2947 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}. 2948 * <p> 2949 * This method is only accessible to the following narrow set of apps: 2950 * <ul> 2951 * <li>The carrier app for this subscriberId, as determined by 2952 * {@link TelephonyManager#hasCarrierPrivileges()}. 2953 * <li>The carrier app explicitly delegated access through 2954 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 2955 * </ul> 2956 * 2957 * @param subId the subscriber this override applies to. 2958 * @param overrideUnmetered set if the billing relationship should be 2959 * considered unmetered. 2960 * @param expirationDurationMillis the duration after which the requested override 2961 * will be automatically cleared, or {@code 0} to leave in the 2962 * requested state until explicitly cleared, or the next reboot, 2963 * whichever happens first. 2964 * @throws SecurityException if the caller doesn't meet the requirements 2965 * outlined above. 2966 */ setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long expirationDurationMillis)2967 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, 2968 @DurationMillisLong long expirationDurationMillis) { 2969 setSubscriptionOverrideUnmetered(subId, overrideUnmetered, 2970 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis); 2971 } 2972 2973 /** 2974 * Temporarily override the billing relationship plan between a carrier and 2975 * a specific subscriber to be considered unmetered. This will be reflected 2976 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}. 2977 * <p> 2978 * This method is only accessible to the following narrow set of apps: 2979 * <ul> 2980 * <li>The carrier app for this subscriberId, as determined by 2981 * {@link TelephonyManager#hasCarrierPrivileges()}. 2982 * <li>The carrier app explicitly delegated access through 2983 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 2984 * </ul> 2985 * 2986 * @param subId the subscriber this override applies to. 2987 * @param overrideUnmetered set if the billing relationship should be 2988 * considered unmetered. 2989 * @param networkTypes the network types this override applies to. If no 2990 * network types are specified, override values will be ignored. 2991 * @param expirationDurationMillis the duration after which the requested override 2992 * will be automatically cleared, or {@code 0} to leave in the 2993 * requested state until explicitly cleared, or the next reboot, 2994 * whichever happens first. 2995 * @throws SecurityException if the caller doesn't meet the requirements 2996 * outlined above. 2997 */ setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)2998 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, 2999 @NonNull @Annotation.NetworkType int[] networkTypes, 3000 @DurationMillisLong long expirationDurationMillis) { 3001 final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0; 3002 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED, 3003 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName()); 3004 } 3005 3006 /** 3007 * Temporarily override the billing relationship plan between a carrier and 3008 * a specific subscriber to be considered congested. This will cause the 3009 * device to delay certain network requests when possible, such as developer 3010 * jobs that are willing to run in a flexible time window. 3011 * <p> 3012 * This method is only accessible to the following narrow set of apps: 3013 * <ul> 3014 * <li>The carrier app for this subscriberId, as determined by 3015 * {@link TelephonyManager#hasCarrierPrivileges()}. 3016 * <li>The carrier app explicitly delegated access through 3017 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3018 * </ul> 3019 * 3020 * @param subId the subscriber this override applies to. 3021 * @param overrideCongested set if the subscription should be considered 3022 * congested. 3023 * @param expirationDurationMillis the duration after which the requested override 3024 * will be automatically cleared, or {@code 0} to leave in the 3025 * requested state until explicitly cleared, or the next reboot, 3026 * whichever happens first. 3027 * @throws SecurityException if the caller doesn't meet the requirements 3028 * outlined above. 3029 */ setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long expirationDurationMillis)3030 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, 3031 @DurationMillisLong long expirationDurationMillis) { 3032 setSubscriptionOverrideCongested(subId, overrideCongested, 3033 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis); 3034 } 3035 3036 /** 3037 * Temporarily override the billing relationship plan between a carrier and 3038 * a specific subscriber to be considered congested. This will cause the 3039 * device to delay certain network requests when possible, such as developer 3040 * jobs that are willing to run in a flexible time window. 3041 * <p> 3042 * This method is only accessible to the following narrow set of apps: 3043 * <ul> 3044 * <li>The carrier app for this subscriberId, as determined by 3045 * {@link TelephonyManager#hasCarrierPrivileges()}. 3046 * <li>The carrier app explicitly delegated access through 3047 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3048 * </ul> 3049 * 3050 * @param subId the subscriber this override applies to. 3051 * @param overrideCongested set if the subscription should be considered congested. 3052 * @param networkTypes the network types this override applies to. If no network types are 3053 * specified, override values will be ignored. 3054 * @param expirationDurationMillis the duration after which the requested override 3055 * will be automatically cleared, or {@code 0} to leave in the requested state until explicitly 3056 * cleared, or the next reboot, whichever happens first. 3057 * 3058 * @throws SecurityException if the caller doesn't meet the requirements outlined above. 3059 */ setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)3060 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, 3061 @NonNull @Annotation.NetworkType int[] networkTypes, 3062 @DurationMillisLong long expirationDurationMillis) { 3063 final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0; 3064 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED, 3065 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName()); 3066 } 3067 3068 /** 3069 * Checks whether the app with the given context is authorized to manage the given subscription 3070 * according to its metadata. 3071 * 3072 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns 3073 * true). To check for permissions for non-embedded subscription as well, 3074 * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}. 3075 * 3076 * @param info The subscription to check. 3077 * @return whether the app is authorized to manage this subscription per its metadata. 3078 * @see android.telephony.TelephonyManager#hasCarrierPrivileges 3079 */ canManageSubscription(SubscriptionInfo info)3080 public boolean canManageSubscription(SubscriptionInfo info) { 3081 return canManageSubscription(info, mContext.getPackageName()); 3082 } 3083 3084 /** 3085 * Checks whether the given app is authorized to manage the given subscription. An app can only 3086 * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the 3087 * {@link android.telephony.SubscriptionInfo} with the access status. 3088 * 3089 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns 3090 * true). To check for permissions for non-embedded subscription as well, 3091 * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}. 3092 * 3093 * @param info The subscription to check. 3094 * @param packageName Package name of the app to check. 3095 * 3096 * @return whether the app is authorized to manage this subscription per its access rules. 3097 * @see android.telephony.TelephonyManager#hasCarrierPrivileges 3098 * @hide 3099 */ 3100 @SystemApi canManageSubscription(@onNull SubscriptionInfo info, @NonNull String packageName)3101 public boolean canManageSubscription(@NonNull SubscriptionInfo info, 3102 @NonNull String packageName) { 3103 if (info == null || info.getAccessRules() == null || packageName == null) { 3104 return false; 3105 } 3106 PackageManager packageManager = mContext.getPackageManager(); 3107 PackageInfo packageInfo; 3108 try { 3109 packageInfo = packageManager.getPackageInfo(packageName, 3110 PackageManager.GET_SIGNING_CERTIFICATES); 3111 } catch (PackageManager.NameNotFoundException e) { 3112 logd("Unknown package: " + packageName); 3113 return false; 3114 } 3115 for (UiccAccessRule rule : info.getAccessRules()) { 3116 if (rule.getCarrierPrivilegeStatus(packageInfo) 3117 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 3118 return true; 3119 } 3120 } 3121 return false; 3122 } 3123 3124 /** 3125 * Set which subscription is preferred for cellular data. 3126 * It's also usually the subscription we set up internet connection on. 3127 * 3128 * PreferredData overwrites user setting of default data subscription. And it's used 3129 * by AlternativeNetworkService or carrier apps to switch primary and CBRS 3130 * subscription dynamically in multi-SIM devices. 3131 * 3132 * @param subId which subscription is preferred to for cellular data. If it's 3133 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}, it means 3134 * it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()} 3135 * is used to determine which modem is preferred. 3136 * @param needValidation whether Telephony will wait until the network is validated by 3137 * connectivity service before switching data to it. More details see 3138 * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}. 3139 * @param executor The executor of where the callback will execute. 3140 * @param callback Callback will be triggered once it succeeds or failed. 3141 * Pass null if don't care about the result. 3142 * 3143 * @throws IllegalStateException when subscription manager service is not available. 3144 * @throws SecurityException when clients do not have MODIFY_PHONE_STATE permission. 3145 * @hide 3146 */ 3147 @SystemApi 3148 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setPreferredDataSubscriptionId(int subId, boolean needValidation, @Nullable @CallbackExecutor Executor executor, @Nullable @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback)3149 public void setPreferredDataSubscriptionId(int subId, boolean needValidation, 3150 @Nullable @CallbackExecutor Executor executor, @Nullable 3151 @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) { 3152 if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId); 3153 try { 3154 ISub iSub = TelephonyManager.getSubscriptionService(); 3155 if (iSub == null) { 3156 throw new IllegalStateException("subscription manager service is null."); 3157 } 3158 3159 ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() { 3160 @Override 3161 public void onComplete(int result) { 3162 if (executor == null || callback == null) { 3163 return; 3164 } 3165 final long identity = Binder.clearCallingIdentity(); 3166 try { 3167 executor.execute(() -> { 3168 callback.accept(result); 3169 }); 3170 } finally { 3171 Binder.restoreCallingIdentity(identity); 3172 } 3173 } 3174 }; 3175 iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub); 3176 } catch (RemoteException ex) { 3177 loge("setPreferredDataSubscriptionId RemoteException=" + ex); 3178 ex.rethrowFromSystemServer(); 3179 } 3180 } 3181 3182 /** 3183 * Get which subscription is preferred for cellular data. 3184 * It's also usually the subscription we set up internet connection on. 3185 * 3186 * PreferredData overwrites user setting of default data subscription. And it's used 3187 * by AlternativeNetworkService or carrier apps to switch primary and CBRS 3188 * subscription dynamically in multi-SIM devices. 3189 * 3190 * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if 3191 * there's no prefered subscription. 3192 * 3193 * @hide 3194 * 3195 */ 3196 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getPreferredDataSubscriptionId()3197 public int getPreferredDataSubscriptionId() { 3198 int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 3199 try { 3200 ISub iSub = TelephonyManager.getSubscriptionService(); 3201 if (iSub != null) { 3202 preferredSubId = iSub.getPreferredDataSubscriptionId(); 3203 } 3204 } catch (RemoteException ex) { 3205 // ignore it 3206 } 3207 3208 return preferredSubId; 3209 } 3210 3211 /** 3212 * Return opportunistic subscriptions that can be visible to the caller. 3213 * Opportunistic subscriptions are for opportunistic networks, which are cellular 3214 * networks with limited capabilities and coverage, for example, CBRS. 3215 * 3216 * <p>Requires Permission: 3217 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 3218 * or that the calling app has carrier privileges (see 3219 * {@link TelephonyManager#hasCarrierPrivileges}). 3220 * 3221 * @return the list of opportunistic subscription info. If none exists, an empty list. 3222 */ 3223 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3224 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getOpportunisticSubscriptions()3225 public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() { 3226 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3227 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null; 3228 List<SubscriptionInfo> subInfoList = null; 3229 3230 try { 3231 ISub iSub = TelephonyManager.getSubscriptionService(); 3232 if (iSub != null) { 3233 subInfoList = iSub.getOpportunisticSubscriptions(contextPkg, 3234 contextAttributionTag); 3235 } 3236 } catch (RemoteException ex) { 3237 // ignore it 3238 } 3239 3240 if (subInfoList == null) { 3241 subInfoList = new ArrayList<>(); 3242 } 3243 3244 return subInfoList; 3245 } 3246 3247 /** 3248 * Switch to a certain subscription 3249 * 3250 * @param subId sub id 3251 * @param callbackIntent pending intent that will be sent after operation is done. 3252 * 3253 * @deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int, 3254 * PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use 3255 * {@link EuiccManager#switchToSubscription(int, PendingIntent)} or 3256 * {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead. 3257 */ 3258 @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) 3259 @Deprecated switchToSubscription(int subId, @NonNull PendingIntent callbackIntent)3260 public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) { 3261 Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null"); 3262 EuiccManager euiccManager = new EuiccManager(mContext); 3263 euiccManager.switchToSubscription(subId, callbackIntent); 3264 } 3265 3266 /** 3267 * Set whether a subscription is opportunistic, that is, whether the network it connects 3268 * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has 3269 * following impacts: 3270 * 1) Even if it's active, it will be dormant most of the time. The modem will not try 3271 * to scan or camp until it knows an available network is nearby to save power. 3272 * 2) Telephony relies on system app or carrier input to notify nearby available networks. 3273 * See {@link TelephonyManager#updateAvailableNetworks(List, Executor, Consumer)} 3274 * for more information. 3275 * 3) In multi-SIM devices, when the network is nearby and camped, system may automatically 3276 * switch internet data between it and default data subscription, based on carrier 3277 * recommendation and its signal strength and metered-ness, etc. 3278 * 3279 * 3280 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier 3281 * privilege permission of the subscription. 3282 * 3283 * @param opportunistic whether it’s opportunistic subscription. 3284 * @param subId the unique SubscriptionInfo index in database 3285 * @return {@code true} if the operation is succeed, {@code false} otherwise. 3286 */ 3287 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3288 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setOpportunistic(boolean opportunistic, int subId)3289 public boolean setOpportunistic(boolean opportunistic, int subId) { 3290 if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId); 3291 return setSubscriptionPropertyHelper(subId, "setOpportunistic", 3292 (iSub)-> iSub.setOpportunistic( 3293 opportunistic, subId, mContext.getOpPackageName())) == 1; 3294 } 3295 3296 /** 3297 * Inform SubscriptionManager that subscriptions in the list are bundled 3298 * as a group. It can be multiple primary (non-opportunistic) subscriptions, 3299 * or one or more primary plus one or more opportunistic subscriptions. 3300 * 3301 * This API will always create a new immutable group and assign group UUID to all the 3302 * subscriptions, regardless whether they are in a group already or not. 3303 * 3304 * Grouped subscriptions will have below behaviors: 3305 * 1) They will share the same user settings. 3306 * 2) The opportunistic subscriptions in the group is considered invisible and will not 3307 * return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier 3308 * privilege permission of the subscriptions. 3309 * 3) The opportunistic subscriptions in the group can't be active by itself. If all other 3310 * non-opportunistic ones are deactivated (unplugged or disabled in Settings), 3311 * the opportunistic ones will be deactivated automatically. 3312 * 3313 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} 3314 * permission or had carrier privilege permission on the subscriptions: 3315 * {@link TelephonyManager#hasCarrierPrivileges()} or 3316 * {@link #canManageSubscription(SubscriptionInfo)} 3317 * 3318 * @throws SecurityException if the caller doesn't meet the requirements 3319 * outlined above. 3320 * @throws IllegalArgumentException if any of the subscriptions in the list doesn't exist. 3321 * @throws IllegalStateException if Telephony service is in bad state. 3322 * 3323 * @param subIdList list of subId that will be in the same group 3324 * @return groupUUID a UUID assigned to the subscription group. 3325 * 3326 */ 3327 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3328 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) createSubscriptionGroup(@onNull List<Integer> subIdList)3329 public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) { 3330 Preconditions.checkNotNull(subIdList, "can't create group for null subId list"); 3331 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3332 if (VDBG) { 3333 logd("[createSubscriptionGroup]"); 3334 } 3335 3336 ParcelUuid groupUuid = null; 3337 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); 3338 try { 3339 ISub iSub = TelephonyManager.getSubscriptionService(); 3340 if (iSub != null) { 3341 groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug); 3342 } else { 3343 if (!isSystemProcess()) { 3344 throw new IllegalStateException("telephony service is null."); 3345 } 3346 } 3347 } catch (RemoteException ex) { 3348 loge("createSubscriptionGroup RemoteException " + ex); 3349 if (!isSystemProcess()) { 3350 ex.rethrowAsRuntimeException(); 3351 } 3352 } 3353 3354 return groupUuid; 3355 } 3356 3357 /** 3358 * Add a list of subscriptions into a group. 3359 * See {@link #createSubscriptionGroup(List)} for more details. 3360 * 3361 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} 3362 * permission or had carrier privilege permission on the subscriptions: 3363 * {@link TelephonyManager#hasCarrierPrivileges()} or 3364 * {@link #canManageSubscription(SubscriptionInfo)} 3365 * 3366 * @throws SecurityException if the caller doesn't meet the requirements 3367 * outlined above. 3368 * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist. 3369 * @throws IllegalStateException if Telephony service is in bad state. 3370 * 3371 * @param subIdList list of subId that need adding into the group 3372 * @param groupUuid the groupUuid the subscriptions are being added to. 3373 * 3374 */ 3375 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3376 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) addSubscriptionsIntoGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3377 public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList, 3378 @NonNull ParcelUuid groupUuid) { 3379 Preconditions.checkNotNull(subIdList, "subIdList can't be null."); 3380 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null."); 3381 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3382 if (VDBG) { 3383 logd("[addSubscriptionsIntoGroup]"); 3384 } 3385 3386 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); 3387 3388 try { 3389 ISub iSub = TelephonyManager.getSubscriptionService(); 3390 if (iSub != null) { 3391 iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug); 3392 } else { 3393 if (!isSystemProcess()) { 3394 throw new IllegalStateException("telephony service is null."); 3395 } 3396 } 3397 } catch (RemoteException ex) { 3398 loge("addSubscriptionsIntoGroup RemoteException " + ex); 3399 if (!isSystemProcess()) { 3400 ex.rethrowAsRuntimeException(); 3401 } 3402 } 3403 } 3404 isSystemProcess()3405 private boolean isSystemProcess() { 3406 return Process.myUid() == Process.SYSTEM_UID; 3407 } 3408 3409 /** 3410 * Remove a list of subscriptions from their subscription group. 3411 * 3412 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} 3413 * permission or has carrier privilege permission on all of the subscriptions provided in 3414 * {@code subIdList}. 3415 * 3416 * @param subIdList list of subId that need removing from their groups. 3417 * @param groupUuid The UUID of the subscription group. 3418 * 3419 * @throws SecurityException if the caller doesn't meet the requirements outlined above. 3420 * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong the 3421 * specified group. 3422 * @throws IllegalStateException if Telephony service is in bad state. 3423 * 3424 * @see #createSubscriptionGroup(List) 3425 */ 3426 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3427 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) removeSubscriptionsFromGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3428 public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList, 3429 @NonNull ParcelUuid groupUuid) { 3430 Preconditions.checkNotNull(subIdList, "subIdList can't be null."); 3431 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null."); 3432 String callingPackage = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3433 if (VDBG) { 3434 logd("[removeSubscriptionsFromGroup]"); 3435 } 3436 3437 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); 3438 3439 try { 3440 ISub iSub = TelephonyManager.getSubscriptionService(); 3441 if (iSub != null) { 3442 iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, callingPackage); 3443 } else { 3444 if (!isSystemProcess()) { 3445 throw new IllegalStateException("telephony service is null."); 3446 } 3447 } 3448 } catch (RemoteException ex) { 3449 loge("removeSubscriptionsFromGroup RemoteException " + ex); 3450 if (!isSystemProcess()) { 3451 ex.rethrowAsRuntimeException(); 3452 } 3453 } 3454 } 3455 3456 /** 3457 * Get subscriptionInfo list of subscriptions that are in the same group of given subId. 3458 * 3459 * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE} 3460 * or carrier privilege permission on the subscription. 3461 * {@link TelephonyManager#hasCarrierPrivileges()} 3462 * 3463 * <p>Starting with API level 33, the caller also needs permission to access device identifiers 3464 * to get the list of subscriptions associated with a group UUID. 3465 * This method can be invoked if one of the following requirements is met: 3466 * <ul> 3467 * <li>If the app has carrier privilege permission. 3468 * {@link TelephonyManager#hasCarrierPrivileges()} 3469 * <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} permission and 3470 * access to device identifiers. 3471 * </ul> 3472 * 3473 * @throws IllegalStateException if Telephony service is in bad state. 3474 * @throws SecurityException if the caller doesn't meet the requirements 3475 * outlined above. 3476 * 3477 * @param groupUuid of which list of subInfo will be returned. 3478 * @return list of subscriptionInfo that belong to the same group, including the given 3479 * subscription itself. It will return an empty list if no subscription belongs to the group. 3480 */ 3481 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3482 @RequiresPermission(Manifest.permission.READ_PHONE_STATE) getSubscriptionsInGroup(@onNull ParcelUuid groupUuid)3483 public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) { 3484 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null"); 3485 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3486 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null; 3487 if (VDBG) { 3488 logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid); 3489 } 3490 3491 List<SubscriptionInfo> result = null; 3492 try { 3493 ISub iSub = TelephonyManager.getSubscriptionService(); 3494 if (iSub != null) { 3495 result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg, 3496 contextAttributionTag); 3497 } else { 3498 if (!isSystemProcess()) { 3499 throw new IllegalStateException("telephony service is null."); 3500 } 3501 } 3502 } catch (RemoteException ex) { 3503 loge("removeSubscriptionsFromGroup RemoteException " + ex); 3504 if (!isSystemProcess()) { 3505 ex.rethrowAsRuntimeException(); 3506 } 3507 } 3508 3509 return result; 3510 } 3511 3512 /** 3513 * Whether a subscription is visible to API caller. If it's a bundled opportunistic 3514 * subscription, it should be hidden anywhere in Settings, dialer, status bar etc. 3515 * Exception is if caller owns carrier privilege, in which case they will 3516 * want to see their own hidden subscriptions. 3517 * 3518 * @param info the subscriptionInfo to check against. 3519 * 3520 * @return {@code true} if this subscription should be visible to the API caller. 3521 * 3522 * @hide 3523 */ isSubscriptionVisible(SubscriptionInfo info)3524 public boolean isSubscriptionVisible(SubscriptionInfo info) { 3525 if (info == null) return false; 3526 // If subscription is NOT grouped opportunistic subscription, it's visible. 3527 if (info.getGroupUuid() == null || !info.isOpportunistic()) return true; 3528 3529 // If the caller is the carrier app and owns the subscription, it should be visible 3530 // to the caller. 3531 boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext) 3532 .hasCarrierPrivileges(info.getSubscriptionId()) 3533 || canManageSubscription(info); 3534 return hasCarrierPrivilegePermission; 3535 } 3536 3537 /** 3538 * Return a list of subscriptions that are available and visible to the user. 3539 * Used by Settings app to show a list of subscriptions for user to pick. 3540 * 3541 * <p> 3542 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required 3543 * for getSelectableSubscriptionInfoList to be invoked. 3544 * @return list of user selectable subscriptions. 3545 * 3546 * @hide 3547 */ getSelectableSubscriptionInfoList()3548 public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() { 3549 List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList(); 3550 if (availableList == null) { 3551 return null; 3552 } else { 3553 // Multiple subscriptions in a group should only have one representative. 3554 // It should be the current active primary subscription if any, or any 3555 // primary subscription. 3556 List<SubscriptionInfo> selectableList = new ArrayList<>(); 3557 Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>(); 3558 3559 for (SubscriptionInfo info : availableList) { 3560 // Opportunistic subscriptions are considered invisible 3561 // to users so they should never be returned. 3562 if (!isSubscriptionVisible(info)) continue; 3563 3564 ParcelUuid groupUuid = info.getGroupUuid(); 3565 if (groupUuid == null) { 3566 // Doesn't belong to any group. Add in the list. 3567 selectableList.add(info); 3568 } else if (!groupMap.containsKey(groupUuid) 3569 || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX 3570 && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) { 3571 // If it belongs to a group that has never been recorded or it's the current 3572 // active subscription, add it in the list. 3573 selectableList.remove(groupMap.get(groupUuid)); 3574 selectableList.add(info); 3575 groupMap.put(groupUuid, info); 3576 } 3577 3578 } 3579 return selectableList; 3580 } 3581 } 3582 3583 /** 3584 * Enable or disable a subscription. This method is same as 3585 * {@link #setUiccApplicationsEnabled(int, boolean)}. 3586 * 3587 * @param subscriptionId Subscription to be enabled or disabled. 3588 * @param enable whether user is turning it on or off. 3589 * 3590 * @return whether the operation is successful. 3591 * 3592 * @hide 3593 */ 3594 @SystemApi 3595 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setSubscriptionEnabled(int subscriptionId, boolean enable)3596 public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) { 3597 try { 3598 ISub iSub = TelephonyManager.getSubscriptionService(); 3599 if (iSub != null) { 3600 iSub.setUiccApplicationsEnabled(enable, subscriptionId); 3601 } 3602 } catch (RemoteException ex) { 3603 return false; 3604 } 3605 return true; 3606 } 3607 3608 /** 3609 * Set uicc applications being enabled or disabled. 3610 * The value will be remembered on the subscription and will be applied whenever it's present. 3611 * If the subscription in currently present, it will also apply the setting to modem 3612 * immediately (the setting in the modem will not change until the modem receives and responds 3613 * to the request, but typically this should only take a few seconds. The user visible setting 3614 * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated 3615 * immediately.) 3616 * 3617 * @param subscriptionId which subscription to operate on. 3618 * @param enabled whether uicc applications are enabled or disabled. 3619 * @hide 3620 */ 3621 @SystemApi 3622 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setUiccApplicationsEnabled(int subscriptionId, boolean enabled)3623 public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) { 3624 if (VDBG) { 3625 logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled); 3626 } 3627 try { 3628 ISub iSub = TelephonyManager.getSubscriptionService(); 3629 if (iSub != null) { 3630 iSub.setUiccApplicationsEnabled(enabled, subscriptionId); 3631 } 3632 } catch (RemoteException ex) { 3633 // ignore it 3634 } 3635 } 3636 3637 /** 3638 * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM. 3639 * 3640 * Physical SIM refers non-euicc, or aka non-programmable SIM. 3641 * 3642 * It provides whether a physical SIM card can be disabled without taking it out, which is done 3643 * via {@link #setSubscriptionEnabled(int, boolean)} API. 3644 * 3645 * @return whether can disable subscriptions on physical SIMs. 3646 * 3647 * @hide 3648 */ 3649 @SystemApi 3650 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) canDisablePhysicalSubscription()3651 public boolean canDisablePhysicalSubscription() { 3652 if (VDBG) { 3653 logd("canDisablePhysicalSubscription"); 3654 } 3655 try { 3656 ISub iSub = TelephonyManager.getSubscriptionService(); 3657 if (iSub != null) { 3658 return iSub.canDisablePhysicalSubscription(); 3659 } 3660 } catch (RemoteException ex) { 3661 // ignore it 3662 } 3663 3664 return false; 3665 } 3666 3667 /** 3668 * Check if the subscription is currently active in any slot. 3669 * 3670 * @param subscriptionId The subscription id. 3671 * 3672 * @hide 3673 */ 3674 @SystemApi 3675 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) isSubscriptionEnabled(int subscriptionId)3676 public boolean isSubscriptionEnabled(int subscriptionId) { 3677 try { 3678 ISub iSub = TelephonyManager.getSubscriptionService(); 3679 if (iSub != null) { 3680 return iSub.isSubscriptionEnabled(subscriptionId); 3681 } 3682 } catch (RemoteException ex) { 3683 // ignore it 3684 } 3685 3686 return false; 3687 } 3688 3689 /** 3690 * Set the device to device status sharing user preference for a subscription id. The setting 3691 * app uses this method to indicate with whom they wish to share device to device status 3692 * information. 3693 * 3694 * @param subscriptionId The subscription id. 3695 * @param sharing The status sharing preference. 3696 * 3697 * @throws SecurityException if the caller doesn't have permissions required. 3698 */ 3699 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDeviceToDeviceStatusSharingPreference(int subscriptionId, @DeviceToDeviceStatusSharingPreference int sharing)3700 public void setDeviceToDeviceStatusSharingPreference(int subscriptionId, 3701 @DeviceToDeviceStatusSharingPreference int sharing) { 3702 if (VDBG) { 3703 logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: " 3704 + subscriptionId); 3705 } 3706 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus", 3707 (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId)); 3708 } 3709 3710 /** 3711 * Returns the user-chosen device to device status sharing preference 3712 * @param subscriptionId Subscription id of subscription 3713 * @return The device to device status sharing preference 3714 * 3715 * @throws SecurityException if the caller doesn't have permissions required. 3716 */ getDeviceToDeviceStatusSharingPreference( int subscriptionId)3717 public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference( 3718 int subscriptionId) { 3719 if (VDBG) { 3720 logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId); 3721 } 3722 return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING, 3723 D2D_SHARING_DISABLED, mContext); 3724 } 3725 3726 /** 3727 * Set the list of contacts that allow device to device status sharing for a subscription id. 3728 * The setting app uses this method to indicate with whom they wish to share device to device 3729 * status information. 3730 * 3731 * @param subscriptionId The subscription id. 3732 * @param contacts The list of contacts that allow device to device status sharing. 3733 * 3734 * @throws SecurityException if the caller doesn't have permissions required. 3735 */ 3736 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDeviceToDeviceStatusSharingContacts(int subscriptionId, @NonNull List<Uri> contacts)3737 public void setDeviceToDeviceStatusSharingContacts(int subscriptionId, 3738 @NonNull List<Uri> contacts) { 3739 String contactString = serializeUriLists(contacts); 3740 if (VDBG) { 3741 logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString 3742 + " subId: " + subscriptionId); 3743 } 3744 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus", 3745 (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts), 3746 subscriptionId)); 3747 } 3748 3749 /** 3750 * Get the list of contacts that allow device to device status sharing. 3751 * 3752 * @param subscriptionId Subscription id. 3753 * 3754 * @return The list of contacts that allow device to device status sharing. 3755 */ getDeviceToDeviceStatusSharingContacts(int subscriptionId)3756 public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(int subscriptionId) { 3757 String result = getStringSubscriptionProperty(mContext, subscriptionId, 3758 D2D_STATUS_SHARING_SELECTED_CONTACTS); 3759 if (result != null) { 3760 try { 3761 byte[] b = Base64.decode(result, Base64.DEFAULT); 3762 ByteArrayInputStream bis = new ByteArrayInputStream(b); 3763 ObjectInputStream ois = new ObjectInputStream(bis); 3764 List<String> contacts = ArrayList.class.cast(ois.readObject()); 3765 List<Uri> uris = new ArrayList<>(); 3766 for (String contact : contacts) { 3767 uris.add(Uri.parse(contact)); 3768 } 3769 return uris; 3770 } catch (IOException e) { 3771 logd("getDeviceToDeviceStatusSharingContacts IO exception"); 3772 } catch (ClassNotFoundException e) { 3773 logd("getDeviceToDeviceStatusSharingContacts ClassNotFound exception"); 3774 } 3775 } 3776 return new ArrayList<>(); 3777 } 3778 3779 /** 3780 * Get the active subscription id by logical SIM slot index. 3781 * 3782 * @param slotIndex The logical SIM slot index. 3783 * @return The active subscription id. 3784 * 3785 * @throws IllegalArgumentException if the provided slot index is invalid. 3786 * @throws SecurityException if callers do not hold the required permission. 3787 * 3788 * @hide 3789 */ 3790 @SystemApi 3791 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getEnabledSubscriptionId(int slotIndex)3792 public int getEnabledSubscriptionId(int slotIndex) { 3793 int subId = INVALID_SUBSCRIPTION_ID; 3794 3795 try { 3796 ISub iSub = TelephonyManager.getSubscriptionService(); 3797 if (iSub != null) { 3798 subId = iSub.getEnabledSubscriptionId(slotIndex); 3799 } 3800 } catch (RemoteException ex) { 3801 // ignore it 3802 } 3803 3804 if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId); 3805 return subId; 3806 } 3807 3808 private interface CallISubMethodHelper { callMethod(ISub iSub)3809 int callMethod(ISub iSub) throws RemoteException; 3810 } 3811 setSubscriptionPropertyHelper(int subId, String methodName, CallISubMethodHelper helper)3812 private int setSubscriptionPropertyHelper(int subId, String methodName, 3813 CallISubMethodHelper helper) { 3814 if (!isValidSubscriptionId(subId)) { 3815 logd("[" + methodName + "]" + "- fail"); 3816 return -1; 3817 } 3818 3819 int result = 0; 3820 3821 try { 3822 ISub iSub = TelephonyManager.getSubscriptionService(); 3823 if (iSub != null) { 3824 result = helper.callMethod(iSub); 3825 } 3826 } catch (RemoteException ex) { 3827 // ignore it 3828 } 3829 3830 return result; 3831 } 3832 3833 /** 3834 * Get active data subscription id. Active data subscription refers to the subscription 3835 * currently chosen to provide cellular internet connection to the user. This may be 3836 * different from {@link #getDefaultDataSubscriptionId()}. 3837 * 3838 * @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if 3839 * not. 3840 * 3841 * @see TelephonyCallback.ActiveDataSubscriptionIdListener 3842 */ getActiveDataSubscriptionId()3843 public static int getActiveDataSubscriptionId() { 3844 return sGetActiveDataSubscriptionIdCache.query(null); 3845 } 3846 3847 /** 3848 * Helper method that puts a subscription id on an intent with the constants: 3849 * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX. 3850 * Both constants are used to support backwards compatibility. Once we know we got all places, 3851 * we can remove PhoneConstants.SUBSCRIPTION_KEY. 3852 * @param intent Intent to put sub id on. 3853 * @param subId SubscriptionId to put on intent. 3854 * 3855 * @hide 3856 */ putSubscriptionIdExtra(Intent intent, int subId)3857 public static void putSubscriptionIdExtra(Intent intent, int subId) { 3858 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); 3859 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 3860 } 3861 3862 /** @hide */ invalidateSubscriptionManagerServiceCaches()3863 public static void invalidateSubscriptionManagerServiceCaches() { 3864 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY); 3865 } 3866 3867 /** 3868 * Allows a test process to disable client-side caching operations. 3869 * 3870 * @hide 3871 */ disableCaching()3872 public static void disableCaching() { 3873 sGetDefaultSubIdCache.disableLocal(); 3874 sGetDefaultDataSubIdCache.disableLocal(); 3875 sGetActiveDataSubscriptionIdCache.disableLocal(); 3876 sGetDefaultSmsSubIdCache.disableLocal(); 3877 sGetSlotIndexCache.disableLocal(); 3878 sGetSubIdCache.disableLocal(); 3879 sGetPhoneIdCache.disableLocal(); 3880 } 3881 3882 /** 3883 * Clears all process-local binder caches. 3884 * 3885 * @hide */ clearCaches()3886 public static void clearCaches() { 3887 sGetDefaultSubIdCache.clear(); 3888 sGetDefaultDataSubIdCache.clear(); 3889 sGetActiveDataSubscriptionIdCache.clear(); 3890 sGetDefaultSmsSubIdCache.clear(); 3891 sGetSlotIndexCache.clear(); 3892 sGetSubIdCache.clear(); 3893 sGetPhoneIdCache.clear(); 3894 } 3895 3896 /** 3897 * Called to retrieve SIM-specific settings data to be backed up. 3898 * 3899 * @return data in byte[] to be backed up. 3900 * 3901 * @hide 3902 */ 3903 @NonNull 3904 @SystemApi 3905 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getAllSimSpecificSettingsForBackup()3906 public byte[] getAllSimSpecificSettingsForBackup() { 3907 Bundle bundle = mContext.getContentResolver().call( 3908 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, 3909 GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null); 3910 return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA); 3911 } 3912 3913 /** 3914 * Called during setup wizard restore flow to attempt to restore the backed up sim-specific 3915 * configs to device for all existing SIMs in the subscription database {@link SimInfo}. 3916 * Internally, it will store the backup data in an internal file. This file will persist on 3917 * device for device's lifetime and will be used later on when a SIM is inserted to restore that 3918 * specific SIM's settings. End result is subscription database is modified to match any backed 3919 * up configs for the appropriate inserted SIMs. 3920 * 3921 * <p> 3922 * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any 3923 * {@link SimInfo} entry is updated as the result of this method call. 3924 * 3925 * @param data with the sim specific configs to be backed up. 3926 * 3927 * @hide 3928 */ 3929 @SystemApi 3930 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) restoreAllSimSpecificSettingsFromBackup(@onNull byte[] data)3931 public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) { 3932 try { 3933 ISub iSub = TelephonyManager.getSubscriptionService(); 3934 if (iSub != null) { 3935 iSub.restoreAllSimSpecificSettingsFromBackup(data); 3936 } else { 3937 throw new IllegalStateException("subscription service unavailable."); 3938 } 3939 } catch (RemoteException ex) { 3940 if (!isSystemProcess()) { 3941 ex.rethrowAsRuntimeException(); 3942 } 3943 } 3944 } 3945 3946 /** 3947 * Returns the phone number for the given {@code subscriptionId} and {@code source}, 3948 * or an empty string if not available. 3949 * 3950 * <p>General apps that need to know the phone number should use {@link #getPhoneNumber(int)} 3951 * instead. This API may be suitable specific apps that needs to know the phone number from 3952 * a specific source. For example, a carrier app needs to know exactly what's on 3953 * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number 3954 * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated. 3955 * 3956 * <p>The API provides no guarantees of what format the number is in: the format can vary 3957 * depending on the {@code source} and the network etc. Programmatic parsing should be done 3958 * cautiously, for example, after formatting the number to a consistent format with 3959 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}. 3960 * 3961 * <p>Note the assumption is that one subscription (which usually means one SIM) has 3962 * only one phone number. The multiple sources backup each other so hopefully at least one 3963 * is availavle. For example, for a carrier that doesn't typically set phone numbers 3964 * on {@link #PHONE_NUMBER_SOURCE_UICC UICC}, the source {@link #PHONE_NUMBER_SOURCE_IMS IMS} 3965 * may provide one. Or, a carrier may decide to provide the phone number via source 3966 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} if neither source UICC nor IMS is available. 3967 * 3968 * <p>The availability and correctness of the phone number depends on the underlying source 3969 * and the network etc. Additional verification is needed to use this number for 3970 * security-related or other sensitive scenarios. 3971 * 3972 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} 3973 * for the default one. 3974 * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants. 3975 * 3976 * @return the phone number, or an empty string if not available. 3977 * 3978 * @throws IllegalArgumentException if {@code source} is invalid. 3979 * @throws IllegalStateException if the telephony process is not currently available. 3980 * @throws SecurityException if the caller doesn't have permissions required. 3981 * 3982 * @see #PHONE_NUMBER_SOURCE_UICC 3983 * @see #PHONE_NUMBER_SOURCE_CARRIER 3984 * @see #PHONE_NUMBER_SOURCE_IMS 3985 */ 3986 @RequiresPermission(anyOf = { 3987 android.Manifest.permission.READ_PHONE_NUMBERS, 3988 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3989 "carrier privileges", 3990 }) 3991 @NonNull getPhoneNumber(int subscriptionId, @PhoneNumberSource int source)3992 public String getPhoneNumber(int subscriptionId, @PhoneNumberSource int source) { 3993 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) { 3994 subscriptionId = getDefaultSubscriptionId(); 3995 } 3996 if (source != PHONE_NUMBER_SOURCE_UICC 3997 && source != PHONE_NUMBER_SOURCE_CARRIER 3998 && source != PHONE_NUMBER_SOURCE_IMS) { 3999 throw new IllegalArgumentException("invalid source " + source); 4000 } 4001 try { 4002 ISub iSub = TelephonyManager.getSubscriptionService(); 4003 if (iSub != null) { 4004 return iSub.getPhoneNumber(subscriptionId, source, 4005 mContext.getOpPackageName(), mContext.getAttributionTag()); 4006 } else { 4007 throw new IllegalStateException("subscription service unavailable."); 4008 } 4009 } catch (RemoteException ex) { 4010 throw ex.rethrowAsRuntimeException(); 4011 } 4012 } 4013 4014 /** 4015 * Returns the phone number for the given {@code subId}, or an empty string if 4016 * not available. 4017 * 4018 * <p>This API is suitable for general apps that needs to know the phone number. 4019 * For specific apps that needs to know the phone number provided by a specific source, 4020 * {@link #getPhoneNumber(int, int)} may be suitable. 4021 * 4022 * <p>This API is built up on {@link #getPhoneNumber(int, int)}, but picks 4023 * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER} 4024 * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}. 4025 * 4026 * <p>The API provides no guarantees of what format the number is in: the format can vary 4027 * depending on the underlying source and the network etc. Programmatic parsing should be done 4028 * cautiously, for example, after formatting the number to a consistent format with 4029 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}. 4030 * 4031 * <p>The availability and correctness of the phone number depends on the underlying source 4032 * and the network etc. Additional verification is needed to use this number for 4033 * security-related or other sensitive scenarios. 4034 * 4035 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} 4036 * for the default one. 4037 * @return the phone number, or an empty string if not available. 4038 * 4039 * @throws IllegalStateException if the telephony process is not currently available. 4040 * @throws SecurityException if the caller doesn't have permissions required. 4041 * 4042 * @see #getPhoneNumber(int, int) 4043 */ 4044 @RequiresPermission(anyOf = { 4045 android.Manifest.permission.READ_PHONE_NUMBERS, 4046 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 4047 "carrier privileges", 4048 }) 4049 @NonNull getPhoneNumber(int subscriptionId)4050 public String getPhoneNumber(int subscriptionId) { 4051 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) { 4052 subscriptionId = getDefaultSubscriptionId(); 4053 } 4054 try { 4055 ISub iSub = TelephonyManager.getSubscriptionService(); 4056 if (iSub != null) { 4057 return iSub.getPhoneNumberFromFirstAvailableSource(subscriptionId, 4058 mContext.getOpPackageName(), mContext.getAttributionTag()); 4059 } else { 4060 throw new IllegalStateException("subscription service unavailable."); 4061 } 4062 } catch (RemoteException ex) { 4063 throw ex.rethrowAsRuntimeException(); 4064 } 4065 } 4066 4067 /** 4068 * Sets the phone number for the given {@code subId} for source 4069 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier}. 4070 * Sets an empty string to remove the previously set phone number. 4071 * 4072 * <p>The API is suitable for carrier apps to provide a phone number, for example when 4073 * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly. 4074 * 4075 * <p>It's recommended that the phone number is formatted to well-known formats, 4076 * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods. 4077 * 4078 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} 4079 * for the default one. 4080 * @param number the phone number, or an empty string to remove the previously set number. 4081 * @throws IllegalStateException if the telephony process is not currently available. 4082 * @throws NullPointerException if {@code number} is {@code null}. 4083 * @throws SecurityException if the caller doesn't have permissions required. 4084 */ 4085 @RequiresPermission("carrier privileges") setCarrierPhoneNumber(int subscriptionId, @NonNull String number)4086 public void setCarrierPhoneNumber(int subscriptionId, @NonNull String number) { 4087 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) { 4088 subscriptionId = getDefaultSubscriptionId(); 4089 } 4090 if (number == null) { 4091 throw new NullPointerException("invalid number null"); 4092 } 4093 try { 4094 ISub iSub = TelephonyManager.getSubscriptionService(); 4095 if (iSub != null) { 4096 iSub.setPhoneNumber(subscriptionId, PHONE_NUMBER_SOURCE_CARRIER, number, 4097 mContext.getOpPackageName(), mContext.getAttributionTag()); 4098 } else { 4099 throw new IllegalStateException("subscription service unavailable."); 4100 } 4101 } catch (RemoteException ex) { 4102 throw ex.rethrowAsRuntimeException(); 4103 } 4104 } 4105 4106 /** 4107 * Set the preferred usage setting. 4108 * 4109 * The cellular usage setting is a switch which controls the mode of operation for the cellular 4110 * radio to either require or not require voice service. It is not managed via Android’s 4111 * Settings. 4112 * 4113 * @param subscriptionId the subId of the subscription. 4114 * @param usageSetting the requested usage setting. 4115 * 4116 * @throws IllegalStateException if a specific mode or setting the mode is not supported on a 4117 * particular device. 4118 * 4119 * <p>Requires {@link android.Manifest.permission#MODIFY_PHONE_STATE} 4120 * or that the calling app has CarrierPrivileges for the given subscription. 4121 * 4122 * Note: This method will not allow the setting of USAGE_SETTING_UNKNOWN. 4123 * 4124 * @hide 4125 */ 4126 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setUsageSetting(int subscriptionId, @UsageSetting int usageSetting)4127 void setUsageSetting(int subscriptionId, @UsageSetting int usageSetting) { 4128 if (VDBG) logd("[setUsageSetting]+ setting:" + usageSetting + " subId:" + subscriptionId); 4129 setSubscriptionPropertyHelper(subscriptionId, "setUsageSetting", 4130 (iSub)-> iSub.setUsageSetting( 4131 usageSetting, subscriptionId, mContext.getOpPackageName())); 4132 } 4133 4134 /** 4135 * Convert phone number source to string. 4136 * 4137 * @param source The phone name source. 4138 * 4139 * @return The phone name source in string format. 4140 * 4141 * @hide 4142 */ 4143 @NonNull phoneNumberSourceToString(@honeNumberSource int source)4144 public static String phoneNumberSourceToString(@PhoneNumberSource int source) { 4145 switch (source) { 4146 case SubscriptionManager.PHONE_NUMBER_SOURCE_UICC: return "UICC"; 4147 case SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER: return "CARRIER"; 4148 case SubscriptionManager.PHONE_NUMBER_SOURCE_IMS: return "IMS"; 4149 default: 4150 return "UNKNOWN(" + source + ")"; 4151 } 4152 } 4153 4154 /** 4155 * Convert display name source to string. 4156 * 4157 * @param source The display name source. 4158 * @return The display name source in string format. 4159 * 4160 * @hide 4161 */ 4162 @NonNull displayNameSourceToString( @ubscriptionManager.SimDisplayNameSource int source)4163 public static String displayNameSourceToString( 4164 @SubscriptionManager.SimDisplayNameSource int source) { 4165 switch (source) { 4166 case SubscriptionManager.NAME_SOURCE_UNKNOWN: return "UNKNOWN"; 4167 case SubscriptionManager.NAME_SOURCE_CARRIER_ID: return "CARRIER_ID"; 4168 case SubscriptionManager.NAME_SOURCE_SIM_SPN: return "SIM_SPN"; 4169 case SubscriptionManager.NAME_SOURCE_USER_INPUT: return "USER_INPUT"; 4170 case SubscriptionManager.NAME_SOURCE_CARRIER: return "CARRIER"; 4171 case SubscriptionManager.NAME_SOURCE_SIM_PNN: return "SIM_PNN"; 4172 default: 4173 return "UNKNOWN(" + source + ")"; 4174 } 4175 } 4176 4177 /** 4178 * Convert subscription type to string. 4179 * 4180 * @param type The subscription type. 4181 * @return The subscription type in string format. 4182 * 4183 * @hide 4184 */ 4185 @NonNull subscriptionTypeToString(@ubscriptionManager.SubscriptionType int type)4186 public static String subscriptionTypeToString(@SubscriptionManager.SubscriptionType int type) { 4187 switch (type) { 4188 case SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM: return "LOCAL_SIM"; 4189 case SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM: return "REMOTE_SIM"; 4190 default: 4191 return "UNKNOWN(" + type + ")"; 4192 } 4193 } 4194 4195 /** 4196 * Convert usage setting to string. 4197 * 4198 * @param usageSetting Usage setting. 4199 * @return The usage setting in string format. 4200 * 4201 * @hide 4202 */ 4203 @NonNull usageSettingToString(@ubscriptionManager.UsageSetting int usageSetting)4204 public static String usageSettingToString(@SubscriptionManager.UsageSetting int usageSetting) { 4205 switch (usageSetting) { 4206 case SubscriptionManager.USAGE_SETTING_UNKNOWN: return "UNKNOWN"; 4207 case SubscriptionManager.USAGE_SETTING_DEFAULT: return "DEFAULT"; 4208 case SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC: return "VOICE_CENTRIC"; 4209 case SubscriptionManager.USAGE_SETTING_DATA_CENTRIC: return "DATA_CENTRIC"; 4210 default: 4211 return "UNKNOWN(" + usageSetting + ")"; 4212 } 4213 } 4214 4215 /** 4216 * Set userHandle for a subscription. 4217 * 4218 * Used to set an association between a subscription and a user on the device so that voice 4219 * calling and SMS from that subscription can be associated with that user. 4220 * Data services are always shared between users on the device. 4221 * 4222 * @param subscriptionId the subId of the subscription. 4223 * @param userHandle the userHandle associated with the subscription. 4224 * Pass {@code null} user handle to clear the association. 4225 * 4226 * @throws IllegalArgumentException if subscription is invalid. 4227 * @throws SecurityException if the caller doesn't have permissions required. 4228 * @throws IllegalStateException if subscription service is not available. 4229 * 4230 * @hide 4231 */ 4232 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle)4233 public void setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle) { 4234 if (!isValidSubscriptionId(subscriptionId)) { 4235 throw new IllegalArgumentException("[setSubscriptionUserHandle]: " 4236 + "Invalid subscriptionId: " + subscriptionId); 4237 } 4238 4239 try { 4240 ISub iSub = TelephonyManager.getSubscriptionService(); 4241 if (iSub != null) { 4242 iSub.setSubscriptionUserHandle(userHandle, subscriptionId); 4243 } else { 4244 throw new IllegalStateException("[setSubscriptionUserHandle]: " 4245 + "subscription service unavailable"); 4246 } 4247 } catch (RemoteException ex) { 4248 ex.rethrowAsRuntimeException(); 4249 } 4250 } 4251 4252 /** 4253 * Get UserHandle of this subscription. 4254 * 4255 * Used to get user handle associated with this subscription. 4256 * 4257 * @param subscriptionId the subId of the subscription. 4258 * @return userHandle associated with this subscription 4259 * or {@code null} if subscription is not associated with any user. 4260 * 4261 * @throws IllegalArgumentException if subscription is invalid. 4262 * @throws SecurityException if the caller doesn't have permissions required. 4263 * 4264 * @hide 4265 */ 4266 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) getSubscriptionUserHandle(int subscriptionId)4267 public @Nullable UserHandle getSubscriptionUserHandle(int subscriptionId) { 4268 if (!isValidSubscriptionId(subscriptionId)) { 4269 throw new IllegalArgumentException("[getSubscriptionUserHandle]: " 4270 + "Invalid subscriptionId: " + subscriptionId); 4271 } 4272 4273 try { 4274 ISub iSub = TelephonyManager.getSubscriptionService(); 4275 if (iSub != null) { 4276 return iSub.getSubscriptionUserHandle(subscriptionId); 4277 } else { 4278 Log.e(LOG_TAG, "[getSubscriptionUserHandle]: subscription service unavailable"); 4279 } 4280 } catch (RemoteException ex) { 4281 ex.rethrowAsRuntimeException(); 4282 } 4283 return null; 4284 } 4285 4286 /** 4287 * Check if subscription and user are associated with each other. 4288 * 4289 * @param subscriptionId the subId of the subscription 4290 * @param userHandle user handle of the user 4291 * @return {@code true} if subscription is associated with user 4292 * {code true} if there are no subscriptions on device 4293 * else {@code false} if subscription is not associated with user. 4294 * 4295 * @throws IllegalArgumentException if subscription is invalid. 4296 * @throws SecurityException if the caller doesn't have permissions required. 4297 * 4298 * @hide 4299 */ 4300 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) isSubscriptionAssociatedWithUser(int subscriptionId, @NonNull UserHandle userHandle)4301 public boolean isSubscriptionAssociatedWithUser(int subscriptionId, 4302 @NonNull UserHandle userHandle) { 4303 if (!isValidSubscriptionId(subscriptionId)) { 4304 throw new IllegalArgumentException("[isSubscriptionAssociatedWithUser]: " 4305 + "Invalid subscriptionId: " + subscriptionId); 4306 } 4307 4308 try { 4309 ISub iSub = TelephonyManager.getSubscriptionService(); 4310 if (iSub != null) { 4311 return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle); 4312 } else { 4313 Log.e(LOG_TAG, "[isSubscriptionAssociatedWithUser]: subscription service " 4314 + "unavailable"); 4315 } 4316 } catch (RemoteException ex) { 4317 ex.rethrowAsRuntimeException(); 4318 } 4319 return false; 4320 } 4321 4322 /** 4323 * Get list of subscriptions associated with user. 4324 * 4325 * @param userHandle user handle of the user 4326 * @return list of subscriptionInfo associated with the user. 4327 * 4328 * @throws SecurityException if the caller doesn't have permissions required. 4329 * @throws IllegalStateException if subscription service is not available. 4330 * 4331 * @hide 4332 */ 4333 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) getSubscriptionInfoListAssociatedWithUser( @onNull UserHandle userHandle)4334 public @NonNull List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser( 4335 @NonNull UserHandle userHandle) { 4336 try { 4337 ISub iSub = TelephonyManager.getSubscriptionService(); 4338 if (iSub != null) { 4339 return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle); 4340 } else { 4341 Log.e(LOG_TAG, "[getSubscriptionInfoListAssociatedWithUser]: " 4342 + "subscription service unavailable"); 4343 } 4344 } catch (RemoteException ex) { 4345 ex.rethrowAsRuntimeException(); 4346 } 4347 return new ArrayList<>(); 4348 } 4349 } 4350