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