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_NTN = SimInfo.COLUMN_IS_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 /** @hide */ 1171 @Retention(RetentionPolicy.SOURCE) 1172 @IntDef(prefix = {"USAGE_SETTING_"}, 1173 value = { 1174 USAGE_SETTING_UNKNOWN, 1175 USAGE_SETTING_DEFAULT, 1176 USAGE_SETTING_VOICE_CENTRIC, 1177 USAGE_SETTING_DATA_CENTRIC}) 1178 public @interface UsageSetting {} 1179 1180 /** 1181 * The usage setting is unknown. 1182 * 1183 * This will be the usage setting returned on devices that do not support querying the 1184 * or setting the usage setting. 1185 * 1186 * It may also be provided by a carrier that wishes to provide a value to avoid making any 1187 * settings changes. 1188 */ 1189 public static final int USAGE_SETTING_UNKNOWN = -1; 1190 1191 /** 1192 * Subscription uses the default setting. 1193 * 1194 * The value is based upon device capability and the other properties of the subscription. 1195 * 1196 * Most subscriptions will default to voice-centric when in a phone. 1197 * 1198 * An opportunistic subscription will default to data-centric. 1199 * 1200 * @see SubscriptionInfo#isOpportunistic 1201 */ 1202 public static final int USAGE_SETTING_DEFAULT = 0; 1203 1204 /** 1205 * This subscription is forced to voice-centric mode 1206 * 1207 * <p>Refer to voice-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3. 1208 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221 1209 * Annex A. 1210 * 1211 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_CALLING} and support usage 1212 * setting configuration must support setting this value via 1213 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}. 1214 */ 1215 public static final int USAGE_SETTING_VOICE_CENTRIC = 1; 1216 1217 /** 1218 * This subscription is forced to data-centric mode 1219 * 1220 * <p>Refer to data-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3. 1221 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221 1222 * Annex A. 1223 * 1224 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_DATA} and support usage 1225 * setting configuration must support setting this value via. 1226 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}. 1227 */ 1228 public static final int USAGE_SETTING_DATA_CENTRIC = 2; 1229 1230 /** 1231 * Indicate the preferred usage setting for the subscription. 1232 * 1233 * 0 - Default - If the value has not been explicitly set, it will be "default" 1234 * 1 - Voice-centric 1235 * 2 - Data-centric 1236 * 1237 * @hide 1238 */ 1239 public static final String USAGE_SETTING = SimInfo.COLUMN_USAGE_SETTING; 1240 1241 /** 1242 * Broadcast Action: The user has changed one of the default subs related to 1243 * data, phone calls, or sms</p> 1244 * 1245 * TODO: Change to a listener 1246 * @hide 1247 */ 1248 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1249 public static final String SUB_DEFAULT_CHANGED_ACTION = 1250 "android.intent.action.SUB_DEFAULT_CHANGED"; 1251 1252 /** 1253 * Broadcast Action: The default subscription has changed. This has the following 1254 * extra values:</p> 1255 * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index 1256 */ 1257 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1258 public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED 1259 = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED"; 1260 1261 /** 1262 * Broadcast Action: The default sms subscription has changed. This has the following 1263 * extra values:</p> 1264 * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms 1265 * subscription index 1266 */ 1267 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1268 public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED 1269 = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED"; 1270 1271 /** 1272 * Activity Action: Display UI for managing the billing relationship plans 1273 * between a carrier and a specific subscriber. 1274 * <p> 1275 * Carrier apps are encouraged to implement this activity, and the OS will 1276 * provide an affordance to quickly enter this activity, typically via 1277 * Settings. This affordance will only be shown when the carrier app is 1278 * actively providing subscription plan information via 1279 * {@link #setSubscriptionPlans(int, List)}. 1280 * <p> 1281 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription 1282 * the user is interested in. 1283 */ 1284 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 1285 public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS 1286 = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS"; 1287 1288 /** 1289 * Broadcast Action: Request a refresh of the billing relationship plans 1290 * between a carrier and a specific subscriber. 1291 * <p> 1292 * Carrier apps are encouraged to implement this receiver, and the OS will 1293 * provide an affordance to request a refresh. This affordance will only be 1294 * shown when the carrier app is actively providing subscription plan 1295 * information via {@link #setSubscriptionPlans(int, List)}. 1296 * <p> 1297 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription 1298 * the user is interested in. 1299 * <p> 1300 * Receivers should protect themselves by checking that the sender holds the 1301 * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission. 1302 */ 1303 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1304 public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS 1305 = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS"; 1306 1307 /** 1308 * Broadcast Action: The billing relationship plans between a carrier and a 1309 * specific subscriber has changed. 1310 * <p> 1311 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription 1312 * changed. 1313 * @hide 1314 */ 1315 @SystemApi 1316 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1317 @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) 1318 public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED 1319 = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED"; 1320 1321 /** 1322 * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and 1323 * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription 1324 * which has changed. 1325 */ 1326 public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX"; 1327 1328 /** 1329 * Integer extra to specify SIM slot index. 1330 */ 1331 public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX"; 1332 1333 /** 1334 * A source of phone number: the EF-MSISDN (see 3GPP TS 31.102), 1335 * or EF-MDN for CDMA (see 3GPP2 C.P0065-B), from UICC application. 1336 * 1337 * <p>The availability and accuracy of the number depends on the carrier. 1338 * The number may be updated by over-the-air update to UICC applications 1339 * from the carrier, or by other means with physical access to the SIM. 1340 */ 1341 public static final int PHONE_NUMBER_SOURCE_UICC = 1; 1342 1343 /** 1344 * A source of phone number: provided by an app that has carrier privilege. 1345 * 1346 * <p>The number is intended to be set by a carrier app knowing the correct number 1347 * which is, for example, different from the number in {@link #PHONE_NUMBER_SOURCE_UICC UICC} 1348 * for some reason. 1349 * The number is not available until a carrier app sets one via 1350 * {@link #setCarrierPhoneNumber(int, String)}. 1351 * The app can update the number with the same API should the number change. 1352 */ 1353 public static final int PHONE_NUMBER_SOURCE_CARRIER = 2; 1354 1355 /** 1356 * A source of phone number: provided by IMS (IP Multimedia Subsystem) implementation. 1357 * When IMS service is registered (as indicated by 1358 * {@link android.telephony.ims.RegistrationManager.RegistrationCallback#onRegistered(int)}) 1359 * the IMS implementation may return P-Associated-Uri SIP headers (RFC 3455). The URIs 1360 * are the user’s public user identities known to the network (see 3GPP TS 24.229 5.4.1.2), 1361 * and the phone number is typically one of them (see “global number” in 3GPP TS 23.003 13.4). 1362 * 1363 * <p>This source provides the phone number from the last IMS registration. 1364 * IMS registration may happen on every device reboot or other network condition changes. 1365 * The number will be updated should the associated URI change after an IMS registration. 1366 */ 1367 public static final int PHONE_NUMBER_SOURCE_IMS = 3; 1368 1369 /** @hide */ 1370 @Retention(RetentionPolicy.SOURCE) 1371 @IntDef(prefix = {"PHONE_NUMBER_SOURCE"}, 1372 value = { 1373 PHONE_NUMBER_SOURCE_UICC, 1374 PHONE_NUMBER_SOURCE_CARRIER, 1375 PHONE_NUMBER_SOURCE_IMS, 1376 }) 1377 public @interface PhoneNumberSource {} 1378 1379 /** @hide */ 1380 @Retention(RetentionPolicy.SOURCE) 1381 @IntDef(prefix = {"SERVICE_CAPABILITY"}, 1382 value = { 1383 SERVICE_CAPABILITY_VOICE, 1384 SERVICE_CAPABILITY_SMS, 1385 SERVICE_CAPABILITY_DATA, 1386 }) 1387 public @interface ServiceCapability { 1388 } 1389 1390 /** 1391 * Represents a value indicating the voice calling capabilities of a subscription. 1392 * 1393 * <p>This value identifies whether the subscription supports various voice calling services. 1394 * These services can include circuit-switched (CS) calling, packet-switched (PS) IMS (IP 1395 * Multimedia Subsystem) calling, and over-the-top (OTT) calling options. 1396 * 1397 * <p>Note: The availability of emergency calling services is not solely dependent on this 1398 * voice capability. Emergency services may be accessible even if the subscription lacks 1399 * standard voice capabilities. However, the device's ability to support emergency calls 1400 * can be influenced by its inherent voice capabilities, as determined by 1401 * {@link TelephonyManager#isDeviceVoiceCapable()}. 1402 * 1403 * @see TelephonyManager#isDeviceVoiceCapable() 1404 */ 1405 @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) 1406 public static final int SERVICE_CAPABILITY_VOICE = 1; 1407 1408 /** 1409 * Represents a value indicating the SMS capabilities of a subscription. 1410 * 1411 * <p>This value identifies whether the subscription supports various sms services. 1412 * These services can include circuit-switched (CS) SMS, packet-switched (PS) IMS (IP 1413 * Multimedia Subsystem) SMS, and over-the-top (OTT) SMS options. 1414 * 1415 * <p>Note: The availability of emergency SMS services is not solely dependent on this 1416 * sms capability. Emergency services may be accessible even if the subscription lacks 1417 * standard sms capabilities. However, the device's ability to support emergency sms 1418 * can be influenced by its inherent sms capabilities, as determined by 1419 * {@link TelephonyManager#isDeviceSmsCapable()}. 1420 * 1421 * @see TelephonyManager#isDeviceSmsCapable() 1422 */ 1423 @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) 1424 public static final int SERVICE_CAPABILITY_SMS = 2; 1425 1426 /** 1427 * Represents a value indicating the data calling capabilities of a subscription. 1428 */ 1429 @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) 1430 public static final int SERVICE_CAPABILITY_DATA = 3; 1431 1432 /** 1433 * Maximum value of service capabilities supported so far. 1434 * @hide 1435 */ 1436 public static final int SERVICE_CAPABILITY_MAX = SERVICE_CAPABILITY_DATA; 1437 1438 /** 1439 * Bitmask for {@code SERVICE_CAPABILITY_VOICE}. 1440 * @hide 1441 */ 1442 public static final int SERVICE_CAPABILITY_VOICE_BITMASK = 1443 serviceCapabilityToBitmask(SERVICE_CAPABILITY_VOICE); 1444 1445 /** 1446 * Bitmask for {@code SERVICE_CAPABILITY_SMS}. 1447 * @hide 1448 */ 1449 public static final int SERVICE_CAPABILITY_SMS_BITMASK = 1450 serviceCapabilityToBitmask(SERVICE_CAPABILITY_SMS); 1451 1452 /** 1453 * Bitmask for {@code SERVICE_CAPABILITY_DATA}. 1454 * @hide 1455 */ 1456 public static final int SERVICE_CAPABILITY_DATA_BITMASK = 1457 serviceCapabilityToBitmask(SERVICE_CAPABILITY_DATA); 1458 1459 private final Context mContext; 1460 1461 /** 1462 * In order to prevent the overflow of the heap size due to an indiscriminate increase in the 1463 * cache, the heap size of the resource cache is set sufficiently large. 1464 */ 1465 private static final int MAX_RESOURCE_CACHE_ENTRY_COUNT = 1_000; 1466 1467 /** 1468 * Cache of Resources that has been created in getResourcesForSubId. Key contains package name, 1469 * and Configuration of Resources. If more than the maximum number of resources are stored in 1470 * this cache, the least recently used Resources will be removed to maintain the maximum size. 1471 */ 1472 private static final LruCache<Pair<String, Configuration>, Resources> sResourcesCache = 1473 new LruCache<>(MAX_RESOURCE_CACHE_ENTRY_COUNT); 1474 1475 1476 /** 1477 * The profile has not been transferred or converted to an eSIM. 1478 * @hide 1479 */ 1480 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION) 1481 @SystemApi 1482 public static final int TRANSFER_STATUS_NONE = 0; 1483 1484 /** 1485 * The existing profile of the old device has been transferred to an eSIM of the new device. 1486 * @hide 1487 */ 1488 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION) 1489 @SystemApi 1490 public static final int TRANSFER_STATUS_TRANSFERRED_OUT = 1; 1491 1492 /** 1493 * The existing profile of the same device has been converted to an eSIM of the same device 1494 * @hide 1495 */ 1496 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION) 1497 @SystemApi 1498 public static final int TRANSFER_STATUS_CONVERTED = 2; 1499 /** @hide */ 1500 @Retention(RetentionPolicy.SOURCE) 1501 @IntDef(prefix = {"TRANSFER_STATUS"}, 1502 value = { 1503 TRANSFER_STATUS_NONE, 1504 TRANSFER_STATUS_TRANSFERRED_OUT, 1505 TRANSFER_STATUS_CONVERTED, 1506 }) 1507 public @interface TransferStatus {} 1508 1509 1510 /** 1511 * A listener class for monitoring changes to {@link SubscriptionInfo} records. 1512 * <p> 1513 * Override the onSubscriptionsChanged method in the object that extends this 1514 * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)} 1515 * to register your listener and to unregister invoke 1516 * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)} 1517 * <p> 1518 * Permissions android.Manifest.permission.READ_PHONE_STATE is required 1519 * for #onSubscriptionsChanged to be invoked. 1520 */ 1521 public static class OnSubscriptionsChangedListener { 1522 1523 /** 1524 * After {@link Build.VERSION_CODES#Q}, it is no longer necessary to instantiate a 1525 * Handler inside of the OnSubscriptionsChangedListener in all cases, so it will only 1526 * be done for callers that do not supply an Executor. 1527 */ 1528 @ChangeId 1529 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) 1530 private static final long LAZY_INITIALIZE_SUBSCRIPTIONS_CHANGED_HANDLER = 278814050L; 1531 1532 /** 1533 * For backwards compatibility reasons, stashes the Looper associated with the thread 1534 * context in which this listener was created. 1535 */ 1536 private final Looper mCreatorLooper; 1537 1538 /** 1539 * @hide 1540 */ getCreatorLooper()1541 public Looper getCreatorLooper() { 1542 return mCreatorLooper; 1543 } 1544 1545 /** 1546 * Create an OnSubscriptionsChangedListener. 1547 * 1548 * For callers targeting {@link Build.VERSION_CODES#P} or earlier, this can only be called 1549 * on a thread that already has a prepared Looper. Callers targeting Q or later should 1550 * subsequently use {@link SubscriptionManager#addOnSubscriptionsChangedListener( 1551 * Executor, OnSubscriptionsChangedListener)}. 1552 * 1553 * On OS versions prior to {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} callers should 1554 * assume that this call will fail if invoked on a thread that does not already have a 1555 * prepared looper. 1556 */ OnSubscriptionsChangedListener()1557 public OnSubscriptionsChangedListener() { 1558 mCreatorLooper = Looper.myLooper(); 1559 if (mCreatorLooper == null 1560 && !Compatibility.isChangeEnabled( 1561 LAZY_INITIALIZE_SUBSCRIPTIONS_CHANGED_HANDLER)) { 1562 // matches the implementation of Handler 1563 throw new RuntimeException( 1564 "Can't create handler inside thread " 1565 + Thread.currentThread() 1566 + " that has not called Looper.prepare()"); 1567 } 1568 } 1569 1570 /** 1571 * Allow a listener to be created with a custom looper 1572 * @param looper the non-null Looper that the underlining handler should run on 1573 * @hide 1574 */ OnSubscriptionsChangedListener(@onNull Looper looper)1575 public OnSubscriptionsChangedListener(@NonNull Looper looper) { 1576 Objects.requireNonNull(looper); 1577 mCreatorLooper = looper; 1578 } 1579 1580 /** 1581 * Callback invoked when there is any change to any SubscriptionInfo, as well as once on 1582 * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically 1583 * this method would invoke {@link #getActiveSubscriptionInfoList} 1584 */ onSubscriptionsChanged()1585 public void onSubscriptionsChanged() { 1586 if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN"); 1587 } 1588 1589 /** 1590 * Callback invoked when {@link SubscriptionManager#addOnSubscriptionsChangedListener( 1591 * Executor, OnSubscriptionsChangedListener)} or 1592 * {@link SubscriptionManager#addOnSubscriptionsChangedListener( 1593 * OnSubscriptionsChangedListener)} fails to complete due to the 1594 * {@link Context#TELEPHONY_REGISTRY_SERVICE} being unavailable. 1595 * @hide 1596 */ onAddListenerFailed()1597 public void onAddListenerFailed() { 1598 Rlog.w(LOG_TAG, "onAddListenerFailed not overridden"); 1599 } 1600 log(String s)1601 private void log(String s) { 1602 Rlog.d(LOG_TAG, s); 1603 } 1604 } 1605 1606 /** 1607 * {@code true} if the SubscriptionManager instance should see all subscriptions regardless its 1608 * association with particular user profile. 1609 * 1610 * <p> It only applies to Android SDK 35(V) and above. For Android SDK 34(U) and below, the 1611 * caller can see all subscription across user profiles as it does today today even if it's 1612 * {@code false}. 1613 */ 1614 private final boolean mIsForAllUserProfiles; 1615 1616 /** @hide */ 1617 @UnsupportedAppUsage SubscriptionManager(Context context)1618 public SubscriptionManager(Context context) { 1619 this(context, false /*isForAllUserProfiles*/); 1620 } 1621 1622 /** Constructor */ SubscriptionManager(Context context, boolean isForAllUserProfiles)1623 private SubscriptionManager(Context context, boolean isForAllUserProfiles) { 1624 if (DBG) { 1625 logd("SubscriptionManager created " 1626 + (isForAllUserProfiles ? "for all user profile" : "")); 1627 } 1628 mIsForAllUserProfiles = isForAllUserProfiles; 1629 mContext = context; 1630 } 1631 getNetworkPolicyManager()1632 private NetworkPolicyManager getNetworkPolicyManager() { 1633 return (NetworkPolicyManager) mContext 1634 .getSystemService(Context.NETWORK_POLICY_SERVICE); 1635 } 1636 1637 /** 1638 * @deprecated developers should always obtain references directly from 1639 * {@link Context#getSystemService(Class)}. 1640 */ 1641 @Deprecated from(Context context)1642 public static SubscriptionManager from(Context context) { 1643 return (SubscriptionManager) context 1644 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 1645 } 1646 1647 /** 1648 * Register for changes to the list of active {@link SubscriptionInfo} records or to the 1649 * individual records themselves. When a change occurs the onSubscriptionsChanged method of 1650 * the listener will be invoked immediately if there has been a notification. The 1651 * onSubscriptionChanged method will also be triggered once initially when calling this 1652 * function. The callback will be invoked on the looper specified in the listener's constructor. 1653 * 1654 * @param listener an instance of {@link OnSubscriptionsChangedListener} with 1655 * onSubscriptionsChanged overridden. 1656 * 1657 * @deprecated Will get exception if the parameter listener is not initialized with a Looper. 1658 * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}. 1659 */ 1660 @Deprecated addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1661 public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { 1662 if (listener == null) return; 1663 1664 Looper looper = listener.getCreatorLooper(); 1665 if (looper == null) { 1666 throw new RuntimeException( 1667 "Can't create handler inside thread " + Thread.currentThread() 1668 + " that has not called Looper.prepare()"); 1669 } 1670 1671 addOnSubscriptionsChangedListener(new HandlerExecutor(new Handler(looper)), listener); 1672 } 1673 1674 /** 1675 * Register for changes to the list of {@link SubscriptionInfo} records or to the 1676 * individual records (active or inactive) themselves. When a change occurs, the 1677 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} method of 1678 * the listener will be invoked immediately. The 1679 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} method will also be invoked 1680 * once initially when calling this method. 1681 * 1682 * @param listener an instance of {@link OnSubscriptionsChangedListener} with 1683 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} overridden. 1684 * @param executor the executor that will execute callbacks. 1685 */ addOnSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnSubscriptionsChangedListener listener)1686 public void addOnSubscriptionsChangedListener( 1687 @NonNull @CallbackExecutor Executor executor, 1688 @NonNull OnSubscriptionsChangedListener listener) { 1689 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1690 if (DBG) { 1691 logd("register OnSubscriptionsChangedListener pkgName=" + pkgName 1692 + " listener=" + listener); 1693 } 1694 // We use the TelephonyRegistry as it runs in the system and thus is always 1695 // available. 1696 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1697 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1698 if (telephonyRegistryManager != null) { 1699 telephonyRegistryManager.addOnSubscriptionsChangedListener(listener, 1700 executor); 1701 } else { 1702 // If the telephony registry isn't available, we will inform the caller on their 1703 // listener that it failed so they can try to re-register. 1704 loge("addOnSubscriptionsChangedListener: pkgname=" + pkgName + " failed to be added " 1705 + " due to TELEPHONY_REGISTRY_SERVICE being unavailable."); 1706 executor.execute(() -> listener.onAddListenerFailed()); 1707 } 1708 } 1709 1710 /** 1711 * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary 1712 * as the listener will automatically be unregistered if an attempt to invoke the listener 1713 * fails. 1714 * 1715 * @param listener that is to be unregistered. 1716 */ removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1717 public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { 1718 if (listener == null) return; 1719 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1720 if (DBG) { 1721 logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug 1722 + " listener=" + listener); 1723 } 1724 // We use the TelephonyRegistry as it runs in the system and thus is always 1725 // available. 1726 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1727 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1728 if (telephonyRegistryManager != null) { 1729 telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener); 1730 } 1731 } 1732 1733 /** 1734 * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic 1735 * subscriptions. 1736 * <p> 1737 * Override the onOpportunisticSubscriptionsChanged method in the object that extends this 1738 * or {@link #addOnOpportunisticSubscriptionsChangedListener( 1739 * Executor, OnOpportunisticSubscriptionsChangedListener)} 1740 * to register your listener and to unregister invoke 1741 * {@link #removeOnOpportunisticSubscriptionsChangedListener( 1742 * OnOpportunisticSubscriptionsChangedListener)} 1743 * <p> 1744 * Permissions android.Manifest.permission.READ_PHONE_STATE is required 1745 * for #onOpportunisticSubscriptionsChanged to be invoked. 1746 */ 1747 public static class OnOpportunisticSubscriptionsChangedListener { 1748 /** 1749 * Callback invoked when there is any change to any SubscriptionInfo. Typically 1750 * this method would invoke {@link #getActiveSubscriptionInfoList} 1751 */ onOpportunisticSubscriptionsChanged()1752 public void onOpportunisticSubscriptionsChanged() { 1753 if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN"); 1754 } 1755 log(String s)1756 private void log(String s) { 1757 Rlog.d(LOG_TAG, s); 1758 } 1759 } 1760 1761 /** 1762 * Register for changes to the list of opportunistic subscription records or to the 1763 * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged 1764 * method of the listener will be invoked immediately if there has been a notification. 1765 * 1766 * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with 1767 * onOpportunisticSubscriptionsChanged overridden. 1768 */ addOnOpportunisticSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnOpportunisticSubscriptionsChangedListener listener)1769 public void addOnOpportunisticSubscriptionsChangedListener( 1770 @NonNull @CallbackExecutor Executor executor, 1771 @NonNull OnOpportunisticSubscriptionsChangedListener listener) { 1772 if (executor == null || listener == null) { 1773 return; 1774 } 1775 1776 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1777 if (DBG) { 1778 logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName 1779 + " listener=" + listener); 1780 } 1781 1782 // We use the TelephonyRegistry as it runs in the system and thus is always 1783 // available. 1784 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1785 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1786 if (telephonyRegistryManager != null) { 1787 telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener( 1788 listener, executor); 1789 } 1790 } 1791 1792 /** 1793 * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently 1794 * listening opportunistic subscriptions change. This is not strictly necessary 1795 * as the listener will automatically be unregistered if an attempt to invoke the listener 1796 * fails. 1797 * 1798 * @param listener that is to be unregistered. 1799 */ removeOnOpportunisticSubscriptionsChangedListener( @onNull OnOpportunisticSubscriptionsChangedListener listener)1800 public void removeOnOpportunisticSubscriptionsChangedListener( 1801 @NonNull OnOpportunisticSubscriptionsChangedListener listener) { 1802 Preconditions.checkNotNull(listener, "listener cannot be null"); 1803 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 1804 if (DBG) { 1805 logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug=" 1806 + pkgForDebug + " listener=" + listener); 1807 } 1808 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) 1809 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 1810 if (telephonyRegistryManager != null) { 1811 telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener); 1812 } 1813 } 1814 1815 /** 1816 * Get the active SubscriptionInfo with the input subId. 1817 * 1818 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 1819 * or that the calling app has carrier privileges (see 1820 * {@link TelephonyManager#hasCarrierPrivileges}). 1821 * 1822 * @param subId The unique SubscriptionInfo key in database. 1823 * @return SubscriptionInfo, maybe null if its not active. 1824 * 1825 * @throws UnsupportedOperationException If the device does not have 1826 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 1827 */ 1828 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 1829 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfo(int subId)1830 public SubscriptionInfo getActiveSubscriptionInfo(int subId) { 1831 if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId); 1832 if (!isValidSubscriptionId(subId)) { 1833 if (DBG) { 1834 logd("[getActiveSubscriptionInfo]- invalid subId"); 1835 } 1836 return null; 1837 } 1838 1839 SubscriptionInfo subInfo = null; 1840 1841 try { 1842 ISub iSub = TelephonyManager.getSubscriptionService(); 1843 if (iSub != null) { 1844 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(), 1845 mContext.getAttributionTag()); 1846 } 1847 } catch (RemoteException ex) { 1848 // ignore it 1849 } 1850 1851 return subInfo; 1852 } 1853 1854 /** 1855 * Gets an active SubscriptionInfo {@link SubscriptionInfo} associated with the Sim IccId. 1856 * 1857 * @param iccId the IccId of SIM card 1858 * @return SubscriptionInfo, maybe null if its not active 1859 * 1860 * @throws UnsupportedOperationException If the device does not have 1861 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 1862 * @hide 1863 */ 1864 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) 1865 @Nullable 1866 @SystemApi getActiveSubscriptionInfoForIcc(@onNull String iccId)1867 public SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String iccId) { 1868 if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId); 1869 if (iccId == null) { 1870 logd("[getActiveSubscriptionInfoForIccIndex]- null iccid"); 1871 return null; 1872 } 1873 1874 SubscriptionInfo result = null; 1875 1876 try { 1877 ISub iSub = TelephonyManager.getSubscriptionService(); 1878 if (iSub != null) { 1879 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(), 1880 mContext.getAttributionTag()); 1881 } 1882 } catch (RemoteException ex) { 1883 // ignore it 1884 } 1885 1886 return result; 1887 } 1888 1889 /** 1890 * Get the active SubscriptionInfo associated with the slotIndex 1891 * 1892 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 1893 * or that the calling app has carrier privileges (see 1894 * {@link TelephonyManager#hasCarrierPrivileges}). 1895 * 1896 * @param slotIndex the slot which the subscription is inserted 1897 * @return SubscriptionInfo, maybe null if its not active 1898 * 1899 * @throws UnsupportedOperationException If the device does not have 1900 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 1901 */ 1902 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 1903 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfoForSimSlotIndex(int slotIndex)1904 public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) { 1905 if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex); 1906 if (!isValidSlotIndex(slotIndex)) { 1907 logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex"); 1908 return null; 1909 } 1910 1911 SubscriptionInfo result = null; 1912 1913 try { 1914 ISub iSub = TelephonyManager.getSubscriptionService(); 1915 if (iSub != null) { 1916 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex, 1917 mContext.getOpPackageName(), mContext.getAttributionTag()); 1918 } 1919 } catch (RemoteException ex) { 1920 // ignore it 1921 } 1922 1923 return result; 1924 } 1925 1926 /** 1927 * Get all subscription info records from SIMs that are inserted now or previously inserted. 1928 * 1929 * <p> 1930 * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission, 1931 * {@link SubscriptionInfo#getNumber()} will return empty string. 1932 * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER}, 1933 * {@link SubscriptionInfo#getIccId()} will return an empty string, and 1934 * {@link SubscriptionInfo#getGroupUuid()} will return {@code null}. 1935 * 1936 * <p> 1937 * The carrier app will only get the list of subscriptions that it has carrier privilege on, 1938 * but will have non-stripped {@link SubscriptionInfo} in the list. 1939 * 1940 * @return List of all {@link SubscriptionInfo} records from SIMs that are inserted or 1941 * previously inserted. Sorted by {@link SubscriptionInfo#getSimSlotIndex()}, then 1942 * {@link SubscriptionInfo#getSubscriptionId()}. 1943 * 1944 * @throws SecurityException if callers do not hold the required permission. 1945 * @throws UnsupportedOperationException If the device does not have 1946 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 1947 */ 1948 @NonNull 1949 @RequiresPermission(anyOf = { 1950 Manifest.permission.READ_PHONE_STATE, 1951 "carrier privileges", 1952 }) getAllSubscriptionInfoList()1953 public List<SubscriptionInfo> getAllSubscriptionInfoList() { 1954 List<SubscriptionInfo> result = null; 1955 try { 1956 ISub iSub = TelephonyManager.getSubscriptionService(); 1957 if (iSub != null) { 1958 result = iSub.getAllSubInfoList(mContext.getOpPackageName(), 1959 mContext.getAttributionTag()); 1960 } 1961 } catch (RemoteException ex) { 1962 // ignore it 1963 } 1964 1965 if (result == null) { 1966 result = Collections.emptyList(); 1967 } 1968 return result; 1969 } 1970 1971 /** 1972 * Get the SubscriptionInfo(s) of the currently active SIM(s). 1973 * 1974 * <p> Returned records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by 1975 * {@link SubscriptionInfo#getSubscriptionId}. Beginning with Android SDK 35, this method will 1976 * never return null. 1977 * 1978 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 1979 * or that the calling app has carrier privileges (see 1980 * {@link TelephonyManager#hasCarrierPrivileges}). 1981 * 1982 * @return a list of the active {@link SubscriptionInfo} that is visible to the caller. If 1983 * an empty list or null is returned, then there are no active subscriptions that 1984 * are visible to the caller. If the number of active subscriptions available to 1985 * any caller changes, then this change will be indicated by 1986 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged}. 1987 * 1988 * @throws UnsupportedOperationException If the device does not have 1989 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 1990 */ 1991 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfoList()1992 public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList() { 1993 List<SubscriptionInfo> activeList = null; 1994 1995 try { 1996 ISub iSub = TelephonyManager.getSubscriptionService(); 1997 if (iSub != null) { 1998 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(), 1999 mContext.getAttributionTag(), mIsForAllUserProfiles); 2000 } 2001 } catch (RemoteException ex) { 2002 // ignore it 2003 } 2004 2005 if (activeList != null) { 2006 activeList = activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo)) 2007 .collect(Collectors.toList()); 2008 } else { 2009 activeList = Collections.emptyList(); 2010 } 2011 return activeList; 2012 } 2013 2014 /** 2015 * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s). 2016 * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} 2017 * then by {@link SubscriptionInfo#getSubscriptionId}. 2018 * 2019 * Hidden subscriptions refer to those are not meant visible to the users. 2020 * For example, an opportunistic subscription that is grouped with other 2021 * subscriptions should remain invisible to users as they are only functionally 2022 * supplementary to primary ones. 2023 * 2024 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 2025 * or that the calling app has carrier privileges (see 2026 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible 2027 * to the calling app are returned. 2028 * 2029 * @return Sorted list of the currently available {@link SubscriptionInfo} 2030 * records on the device. 2031 * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return 2032 * both active and hidden SubscriptionInfos. 2033 * 2034 * @throws UnsupportedOperationException If the device does not have 2035 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2036 */ getCompleteActiveSubscriptionInfoList()2037 public @NonNull List<SubscriptionInfo> getCompleteActiveSubscriptionInfoList() { 2038 return getActiveSubscriptionInfoList(/* userVisibleonly */ false); 2039 } 2040 2041 /** 2042 * Create a new subscription manager instance that can see all subscriptions across 2043 * user profiles. 2044 * 2045 * The permission check for accessing all subscriptions will be enforced upon calling the 2046 * individual APIs linked below. 2047 * 2048 * @return a SubscriptionManager that can see all subscriptions regardless its user profile 2049 * association. 2050 * 2051 * @see #getActiveSubscriptionInfoList 2052 * @see #getActiveSubscriptionInfoCount 2053 * @see UserHandle 2054 */ 2055 @FlaggedApi(Flags.FLAG_ENFORCE_SUBSCRIPTION_USER_FILTER) 2056 @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES) createForAllUserProfiles()2057 @NonNull public SubscriptionManager createForAllUserProfiles() { 2058 return new SubscriptionManager(mContext, true/*isForAllUserProfiles*/); 2059 } 2060 2061 /** 2062 * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly 2063 * is true, it will filter out the hidden subscriptions. 2064 * 2065 * @hide 2066 */ getActiveSubscriptionInfoList(boolean userVisibleOnly)2067 public @NonNull List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) { 2068 List<SubscriptionInfo> activeList = null; 2069 2070 try { 2071 ISub iSub = TelephonyManager.getSubscriptionService(); 2072 if (iSub != null) { 2073 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(), 2074 mContext.getAttributionTag(), true /*isForAllUserProfiles*/); 2075 } 2076 } catch (RemoteException ex) { 2077 // ignore it 2078 } 2079 2080 if (activeList == null || activeList.isEmpty()) { 2081 return Collections.emptyList(); 2082 } else if (userVisibleOnly) { 2083 return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo)) 2084 .collect(Collectors.toList()); 2085 } else { 2086 return activeList; 2087 } 2088 } 2089 2090 /** 2091 * Gets the SubscriptionInfo(s) of all available subscriptions, if any. 2092 * 2093 * <p>Available subscriptions include active ones (those with a non-negative 2094 * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded 2095 * subscriptions. 2096 * 2097 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by 2098 * {@link SubscriptionInfo#getSubscriptionId}. 2099 * 2100 * @return Sorted list of the current {@link SubscriptionInfo} records available on the 2101 * device. 2102 * <ul> 2103 * <li> 2104 * If null is returned the current state is unknown but if a 2105 * {@link OnSubscriptionsChangedListener} has been registered 2106 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future. 2107 * <li> 2108 * If the list is empty then there are no {@link SubscriptionInfo} records currently available. 2109 * <li> 2110 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex} 2111 * then by {@link SubscriptionInfo#getSubscriptionId}. 2112 * </ul> 2113 * 2114 * <p> 2115 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required 2116 * for #getAvailableSubscriptionInfoList to be invoked. 2117 * 2118 * @throws UnsupportedOperationException If the device does not have 2119 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2120 * @hide 2121 */ 2122 @SystemApi getAvailableSubscriptionInfoList()2123 public @Nullable List<SubscriptionInfo> getAvailableSubscriptionInfoList() { 2124 List<SubscriptionInfo> result = null; 2125 2126 try { 2127 ISub iSub = TelephonyManager.getSubscriptionService(); 2128 if (iSub != null) { 2129 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(), 2130 mContext.getAttributionTag()); 2131 } 2132 } catch (RemoteException ex) { 2133 // ignore it 2134 } 2135 return (result == null) ? Collections.emptyList() : result; 2136 } 2137 2138 /** 2139 * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if 2140 * any. 2141 * 2142 * <p>Only those subscriptions for which the calling app has carrier privileges per the 2143 * subscription metadata, if any, will be included in the returned list. 2144 * 2145 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by 2146 * {@link SubscriptionInfo#getSubscriptionId}. 2147 * 2148 * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the 2149 * device which are accessible to the caller. 2150 * <ul> 2151 * <li> 2152 * If null is returned the current state is unknown but if a 2153 * {@link OnSubscriptionsChangedListener} has been registered 2154 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future. 2155 * <li> 2156 * If the list is empty then there are no {@link SubscriptionInfo} records currently available. 2157 * <li> 2158 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex} 2159 * then by {@link SubscriptionInfo#getSubscriptionId}. 2160 * </ul> 2161 * 2162 * @throws UnsupportedOperationException If the device does not have 2163 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}. 2164 */ getAccessibleSubscriptionInfoList()2165 public @Nullable List<SubscriptionInfo> getAccessibleSubscriptionInfoList() { 2166 List<SubscriptionInfo> result = null; 2167 2168 try { 2169 ISub iSub = TelephonyManager.getSubscriptionService(); 2170 if (iSub != null) { 2171 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName()); 2172 } 2173 } catch (RemoteException ex) { 2174 // ignore it 2175 } 2176 return (result == null) ? Collections.emptyList() : result; 2177 } 2178 2179 /** 2180 * Request a refresh of the platform cache of profile information for the eUICC which 2181 * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}. 2182 * 2183 * <p>Should be called by the EuiccService implementation whenever this information changes due 2184 * to an operation done outside the scope of a request initiated by the platform to the 2185 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that 2186 * were made through the EuiccService. 2187 * 2188 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 2189 * 2190 * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID. 2191 * 2192 * @throws UnsupportedOperationException If the device does not have 2193 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}. 2194 * @hide 2195 */ 2196 @SystemApi requestEmbeddedSubscriptionInfoListRefresh()2197 public void requestEmbeddedSubscriptionInfoListRefresh() { 2198 int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc(); 2199 try { 2200 ISub iSub = TelephonyManager.getSubscriptionService(); 2201 if (iSub != null) { 2202 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId); 2203 } 2204 } catch (RemoteException ex) { 2205 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed."); 2206 } 2207 } 2208 2209 /** 2210 * Request a refresh of the platform cache of profile information for the eUICC with the given 2211 * {@code cardId}. 2212 * 2213 * <p>Should be called by the EuiccService implementation whenever this information changes due 2214 * to an operation done outside the scope of a request initiated by the platform to the 2215 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that 2216 * were made through the EuiccService. 2217 * 2218 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 2219 * 2220 * @param cardId the card ID of the eUICC. 2221 * 2222 * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID. 2223 * 2224 * @throws UnsupportedOperationException If the device does not have 2225 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}. 2226 * @hide 2227 */ 2228 @SystemApi requestEmbeddedSubscriptionInfoListRefresh(int cardId)2229 public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) { 2230 try { 2231 ISub iSub = TelephonyManager.getSubscriptionService(); 2232 if (iSub != null) { 2233 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId); 2234 } 2235 } catch (RemoteException ex) { 2236 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed."); 2237 } 2238 } 2239 2240 /** 2241 * Get the active subscription count. 2242 * 2243 * @return The current number of active subscriptions. 2244 * 2245 * @see #getActiveSubscriptionInfoList() 2246 * 2247 * @throws UnsupportedOperationException If the device does not have 2248 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2249 */ 2250 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getActiveSubscriptionInfoCount()2251 public int getActiveSubscriptionInfoCount() { 2252 int result = 0; 2253 2254 try { 2255 ISub iSub = TelephonyManager.getSubscriptionService(); 2256 if (iSub != null) { 2257 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(), 2258 mContext.getAttributionTag(), mIsForAllUserProfiles); 2259 } 2260 } catch (RemoteException ex) { 2261 // ignore it 2262 } 2263 2264 return result; 2265 } 2266 2267 /** 2268 * @return the maximum number of active subscriptions that will be returned by 2269 * {@link #getActiveSubscriptionInfoList} and the value returned by 2270 * {@link #getActiveSubscriptionInfoCount}. 2271 */ getActiveSubscriptionInfoCountMax()2272 public int getActiveSubscriptionInfoCountMax() { 2273 int result = 0; 2274 2275 try { 2276 ISub iSub = TelephonyManager.getSubscriptionService(); 2277 if (iSub != null) { 2278 result = iSub.getActiveSubInfoCountMax(); 2279 } 2280 } catch (RemoteException ex) { 2281 // ignore it 2282 } 2283 2284 return result; 2285 } 2286 2287 /** 2288 * Add a new SubscriptionInfo to SubscriptionInfo database if needed 2289 * @param iccId the IccId of the SIM card 2290 * @param slotIndex the slot which the SIM is inserted 2291 * @return the URL of the newly created row or the updated row 2292 * @hide 2293 */ addSubscriptionInfoRecord(String iccId, int slotIndex)2294 public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) { 2295 if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex); 2296 if (iccId == null) { 2297 logd("[addSubscriptionInfoRecord]- null iccId"); 2298 } 2299 if (!isValidSlotIndex(slotIndex)) { 2300 logd("[addSubscriptionInfoRecord]- invalid slotIndex"); 2301 } 2302 2303 addSubscriptionInfoRecord(iccId, null, slotIndex, SUBSCRIPTION_TYPE_LOCAL_SIM); 2304 2305 // FIXME: Always returns null? 2306 return null; 2307 2308 } 2309 2310 /** 2311 * Add a new SubscriptionInfo to SubscriptionInfo database if needed 2312 * @param uniqueId This is the unique identifier for the subscription within the 2313 * specific subscription type. 2314 * @param displayName human-readable name of the device the subscription corresponds to. 2315 * @param slotIndex the slot assigned to this subscription. It is ignored for subscriptionType 2316 * of {@link #SUBSCRIPTION_TYPE_REMOTE_SIM}. 2317 * @param subscriptionType the {@link #SUBSCRIPTION_TYPE} 2318 * 2319 * @throws UnsupportedOperationException If the device does not have 2320 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2321 * @hide 2322 */ 2323 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) addSubscriptionInfoRecord(@onNull String uniqueId, @Nullable String displayName, int slotIndex, @SubscriptionType int subscriptionType)2324 public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName, 2325 int slotIndex, @SubscriptionType int subscriptionType) { 2326 if (VDBG) { 2327 logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId 2328 + ", displayName:" + displayName + ", slotIndex:" + slotIndex 2329 + ", subscriptionType: " + subscriptionType); 2330 } 2331 if (uniqueId == null) { 2332 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null"); 2333 return; 2334 } 2335 2336 try { 2337 ISub iSub = TelephonyManager.getSubscriptionService(); 2338 if (iSub == null) { 2339 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- ISub service is null"); 2340 return; 2341 } 2342 int result = iSub.addSubInfo(uniqueId, displayName, slotIndex, subscriptionType); 2343 if (result < 0) { 2344 Log.e(LOG_TAG, "Adding of subscription didn't succeed: error = " + result); 2345 } else { 2346 logd("successfully added new subscription"); 2347 } 2348 } catch (RemoteException ex) { 2349 // ignore it 2350 } 2351 } 2352 2353 /** 2354 * Remove subscription info record from the subscription database. 2355 * 2356 * @param uniqueId This is the unique identifier for the subscription within the specific 2357 * subscription type. 2358 * @param subscriptionType the type of subscription to be removed. 2359 * 2360 * @throws NullPointerException if {@code uniqueId} is {@code null}. 2361 * @throws SecurityException if callers do not hold the required permission. 2362 * 2363 * @throws UnsupportedOperationException If the device does not have 2364 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2365 * @hide 2366 */ 2367 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) removeSubscriptionInfoRecord(@onNull String uniqueId, @SubscriptionType int subscriptionType)2368 public void removeSubscriptionInfoRecord(@NonNull String uniqueId, 2369 @SubscriptionType int subscriptionType) { 2370 if (VDBG) { 2371 logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId 2372 + ", subscriptionType: " + subscriptionType); 2373 } 2374 if (uniqueId == null) { 2375 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null"); 2376 return; 2377 } 2378 2379 try { 2380 ISub iSub = TelephonyManager.getSubscriptionService(); 2381 if (iSub == null) { 2382 Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null"); 2383 return; 2384 } 2385 boolean result = iSub.removeSubInfo(uniqueId, subscriptionType); 2386 if (!result) { 2387 Log.e(LOG_TAG, "Removal of subscription didn't succeed"); 2388 } else { 2389 logd("successfully removed subscription"); 2390 } 2391 } catch (RemoteException ex) { 2392 // ignore it 2393 } 2394 } 2395 2396 /** 2397 * Set SIM icon tint color for subscription ID 2398 * @param tint the RGB value of icon tint color of the SIM 2399 * @param subId the unique subscription ID in database 2400 * @return the number of records updated 2401 * @hide 2402 */ 2403 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setIconTint(@olorInt int tint, int subId)2404 public int setIconTint(@ColorInt int tint, int subId) { 2405 if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId); 2406 return setSubscriptionPropertyHelper(subId, "setIconTint", 2407 (iSub)-> iSub.setIconTint(subId, tint) 2408 ); 2409 } 2410 2411 /** 2412 * Set the display name for a subscription ID 2413 * @param displayName the display name of SIM card 2414 * @param subId the unique Subscritpion ID in database 2415 * @param nameSource SIM display name source 2416 * @return the number of records updated or < 0 if invalid subId 2417 * @hide 2418 */ 2419 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDisplayName(@ullable String displayName, int subId, @SimDisplayNameSource int nameSource)2420 public int setDisplayName(@Nullable String displayName, int subId, 2421 @SimDisplayNameSource int nameSource) { 2422 if (VDBG) { 2423 logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId 2424 + " nameSource:" + nameSource); 2425 } 2426 return setSubscriptionPropertyHelper(subId, "setDisplayName", 2427 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource) 2428 ); 2429 } 2430 2431 /** 2432 * Set phone number by subId 2433 * @param number the phone number of the SIM 2434 * @param subId the unique SubscriptionInfo index in database 2435 * @return the number of records updated 2436 * @hide 2437 */ 2438 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setDisplayNumber(String number, int subId)2439 public int setDisplayNumber(String number, int subId) { 2440 if (number == null) { 2441 logd("[setDisplayNumber]- fail"); 2442 return -1; 2443 } 2444 return setSubscriptionPropertyHelper(subId, "setDisplayNumber", 2445 (iSub)-> iSub.setDisplayNumber(number, subId) 2446 ); 2447 } 2448 2449 /** 2450 * Set data roaming by simInfo index 2451 * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming 2452 * @param subId the unique SubscriptionInfo index in database 2453 * @return the number of records updated 2454 * @hide 2455 */ 2456 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setDataRoaming(int roaming, int subId)2457 public int setDataRoaming(int roaming, int subId) { 2458 if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId); 2459 return setSubscriptionPropertyHelper(subId, "setDataRoaming", 2460 (iSub)->iSub.setDataRoaming(roaming, subId) 2461 ); 2462 } 2463 2464 /** 2465 * Get slotIndex associated with the subscription. 2466 * 2467 * @param subscriptionId the unique SubscriptionInfo index in database 2468 * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied 2469 * subscriptionId doesn't have an associated slot index. 2470 */ getSlotIndex(int subscriptionId)2471 public static int getSlotIndex(int subscriptionId) { 2472 return sGetSlotIndexCache.query(subscriptionId); 2473 } 2474 2475 /** 2476 * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size 2477 * of the array is 1. This API was mistakenly designed to return multiple subscription ids, 2478 * which is not possible in the current Android telephony architecture. 2479 * 2480 * @param slotIndex The logical SIM slot index. 2481 * 2482 * @return Subscription id of the active subscription on the specified logical SIM slot index. 2483 * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will 2484 * be returned. {@code null} if the provided {@code slotIndex} is not valid. 2485 * 2486 * @deprecated Use {@link #getSubscriptionId(int)} instead. 2487 */ 2488 @Deprecated 2489 @Nullable getSubscriptionIds(int slotIndex)2490 public int[] getSubscriptionIds(int slotIndex) { 2491 if (!isValidSlotIndex(slotIndex)) { 2492 return null; 2493 } 2494 return new int[]{getSubscriptionId(slotIndex)}; 2495 } 2496 2497 /** 2498 * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size 2499 * of the array is 1. This API was mistakenly designed to return multiple subscription ids, 2500 * which is not possible in the current Android telephony architecture. 2501 * 2502 * @param slotIndex The logical SIM slot index. 2503 * 2504 * @return Subscription id of the active subscription on the specified logical SIM slot index. 2505 * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will 2506 * be returned. {@code null} if the provided {@code slotIndex} is not valid. 2507 * 2508 * @deprecated Use {@link #getSubscriptionId(int)} instead. 2509 * @hide 2510 */ 2511 @Deprecated getSubId(int slotIndex)2512 public static int[] getSubId(int slotIndex) { 2513 if (!isValidSlotIndex(slotIndex)) { 2514 return null; 2515 } 2516 return new int[]{getSubscriptionId(slotIndex)}; 2517 } 2518 2519 /** 2520 * Get the subscription id for specified logical SIM slot index. 2521 * 2522 * @param slotIndex The logical SIM slot index. 2523 * @return The subscription id. {@link #INVALID_SUBSCRIPTION_ID} if SIM is absent. 2524 */ getSubscriptionId(int slotIndex)2525 public static int getSubscriptionId(int slotIndex) { 2526 if (!isValidSlotIndex(slotIndex)) { 2527 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2528 } 2529 2530 return sGetSubIdCache.query(slotIndex); 2531 } 2532 2533 /** @hide */ 2534 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) getPhoneId(int subId)2535 public static int getPhoneId(int subId) { 2536 return sGetPhoneIdCache.query(subId); 2537 } 2538 logd(String msg)2539 private static void logd(String msg) { 2540 Rlog.d(LOG_TAG, msg); 2541 } 2542 loge(String msg)2543 private static void loge(String msg) { 2544 Rlog.e(LOG_TAG, msg); 2545 } 2546 2547 /** 2548 * Returns the system's default subscription id. 2549 * 2550 * For a voice capable device, it will return getDefaultVoiceSubscriptionId. 2551 * For a data only device, it will return the getDefaultDataSubscriptionId. 2552 * May return an INVALID_SUBSCRIPTION_ID on error. 2553 * 2554 * @return the "system" default subscription id. 2555 */ getDefaultSubscriptionId()2556 public static int getDefaultSubscriptionId() { 2557 return sGetDefaultSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier()); 2558 } 2559 2560 /** 2561 * Returns the system's default voice subscription id. 2562 * 2563 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID. 2564 * 2565 * @return the default voice subscription Id. 2566 * 2567 * @throws UnsupportedOperationException If the device does not have 2568 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2569 */ getDefaultVoiceSubscriptionId()2570 public static int getDefaultVoiceSubscriptionId() { 2571 int subId = INVALID_SUBSCRIPTION_ID; 2572 2573 try { 2574 ISub iSub = TelephonyManager.getSubscriptionService(); 2575 if (iSub != null) { 2576 subId = iSub.getDefaultVoiceSubIdAsUser(Process.myUserHandle().getIdentifier()); 2577 } 2578 } catch (RemoteException ex) { 2579 // ignore it 2580 } 2581 2582 if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId); 2583 return subId; 2584 } 2585 2586 /** 2587 * Sets the system's default voice subscription id. 2588 * 2589 * On a data-only device, this is a no-op. 2590 * 2591 * May throw a {@link RuntimeException} if the provided subscription id is equal to 2592 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} 2593 * 2594 * @param subscriptionId A valid subscription ID to set as the system default, or 2595 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} 2596 * 2597 * @throws UnsupportedOperationException If the device does not have 2598 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2599 * @hide 2600 */ 2601 @SystemApi 2602 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDefaultVoiceSubscriptionId(int subscriptionId)2603 public void setDefaultVoiceSubscriptionId(int subscriptionId) { 2604 if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId); 2605 try { 2606 ISub iSub = TelephonyManager.getSubscriptionService(); 2607 if (iSub != null) { 2608 iSub.setDefaultVoiceSubId(subscriptionId); 2609 } 2610 } catch (RemoteException ex) { 2611 // ignore it 2612 } 2613 } 2614 2615 /** 2616 * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards 2617 * compatibility. 2618 * 2619 * @throws UnsupportedOperationException If the device does not have 2620 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2621 * @hide 2622 */ setDefaultVoiceSubId(int subId)2623 public void setDefaultVoiceSubId(int subId) { 2624 setDefaultVoiceSubscriptionId(subId); 2625 } 2626 2627 /** 2628 * Return the SubscriptionInfo for default voice subscription. 2629 * 2630 * Will return null on data only devices, or on error. 2631 * 2632 * @return the SubscriptionInfo for the default voice subscription. 2633 * @hide 2634 */ 2635 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getDefaultVoiceSubscriptionInfo()2636 public SubscriptionInfo getDefaultVoiceSubscriptionInfo() { 2637 return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId()); 2638 } 2639 2640 /** @hide */ 2641 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getDefaultVoicePhoneId()2642 public static int getDefaultVoicePhoneId() { 2643 return getPhoneId(getDefaultVoiceSubscriptionId()); 2644 } 2645 2646 /** 2647 * Returns the system's default SMS subscription id. 2648 * 2649 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID. 2650 * 2651 * @return the default SMS subscription Id. 2652 */ getDefaultSmsSubscriptionId()2653 public static int getDefaultSmsSubscriptionId() { 2654 return sGetDefaultSmsSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier()); 2655 } 2656 2657 /** 2658 * Set the subscription which will be used by default for SMS, with the subscription which 2659 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied 2660 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}). 2661 * 2662 * @param subscriptionId the supplied subscription ID 2663 * 2664 * @throws UnsupportedOperationException If the device does not have 2665 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2666 * @hide 2667 */ 2668 @SystemApi 2669 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setDefaultSmsSubId(int subscriptionId)2670 public void setDefaultSmsSubId(int subscriptionId) { 2671 if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId); 2672 try { 2673 ISub iSub = TelephonyManager.getSubscriptionService(); 2674 if (iSub != null) { 2675 iSub.setDefaultSmsSubId(subscriptionId); 2676 } 2677 } catch (RemoteException ex) { 2678 ex.rethrowFromSystemServer(); 2679 } 2680 } 2681 2682 /** 2683 * Returns the system's default data subscription id. 2684 * 2685 * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID. 2686 * 2687 * @return the default data subscription Id. 2688 */ getDefaultDataSubscriptionId()2689 public static int getDefaultDataSubscriptionId() { 2690 return sGetDefaultDataSubIdCache.query(null); 2691 } 2692 2693 /** 2694 * Set the subscription which will be used by default for data, with the subscription which 2695 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied 2696 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}). 2697 * 2698 * @param subscriptionId the supplied subscription ID 2699 * 2700 * @throws UnsupportedOperationException If the device does not have 2701 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2702 * @hide 2703 */ 2704 @SystemApi 2705 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setDefaultDataSubId(int subscriptionId)2706 public void setDefaultDataSubId(int subscriptionId) { 2707 if (VDBG) logd("setDataSubscription sub id = " + subscriptionId); 2708 try { 2709 ISub iSub = TelephonyManager.getSubscriptionService(); 2710 if (iSub != null) { 2711 iSub.setDefaultDataSubId(subscriptionId); 2712 } 2713 } catch (RemoteException ex) { 2714 // ignore it 2715 } 2716 } 2717 2718 /** 2719 * Return the SubscriptionInfo for default data subscription. 2720 * 2721 * Will return null on voice only devices, or on error. 2722 * 2723 * @return the SubscriptionInfo for the default data subscription. 2724 * 2725 * @throws UnsupportedOperationException If the device does not have 2726 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2727 * @hide 2728 */ 2729 @UnsupportedAppUsage getDefaultDataSubscriptionInfo()2730 public SubscriptionInfo getDefaultDataSubscriptionInfo() { 2731 return getActiveSubscriptionInfo(getDefaultDataSubscriptionId()); 2732 } 2733 2734 /** 2735 * Check if the supplied subscription ID is valid. 2736 * 2737 * <p>A valid subscription ID is not necessarily an active subscription ID 2738 * (see {@link #isActiveSubscriptionId(int)}) or an usable subscription ID 2739 * (see {@link #isUsableSubscriptionId(int)}). Unless specifically noted, subscription 2740 * APIs work with a valid subscription ID. 2741 * 2742 * @param subscriptionId The subscription ID. 2743 * @return {@code true} if the supplied subscriptionId is valid; {@code false} otherwise. 2744 */ isValidSubscriptionId(int subscriptionId)2745 public static boolean isValidSubscriptionId(int subscriptionId) { 2746 return subscriptionId > INVALID_SUBSCRIPTION_ID; 2747 } 2748 2749 /** 2750 * Check if the supplied subscription ID is usable. 2751 * 2752 * <p>A usable subscription ID is a valid subscription ID, but not necessarily an active 2753 * subscription ID (see {@link #isActiveSubscriptionId(int)}). Some subscription APIs 2754 * require a usable subscription ID, and this is noted in their documentation; otherwise, a 2755 * subscription ID does not need to be usable for subscription functions, only valid. 2756 * 2757 * @param subscriptionId the subscription ID 2758 * @return {@code true} if the subscription ID is usable; {@code false} otherwise. 2759 */ isUsableSubscriptionId(int subscriptionId)2760 public static boolean isUsableSubscriptionId(int subscriptionId) { 2761 return isUsableSubIdValue(subscriptionId); 2762 } 2763 2764 /** 2765 * @return true if subId is an usable subId value else false. A 2766 * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID. 2767 * @hide 2768 */ 2769 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) isUsableSubIdValue(int subId)2770 public static boolean isUsableSubIdValue(int subId) { 2771 return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE; 2772 } 2773 2774 /** @hide */ 2775 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) isValidSlotIndex(int slotIndex)2776 public static boolean isValidSlotIndex(int slotIndex) { 2777 return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount(); 2778 } 2779 2780 /** @hide */ 2781 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isValidPhoneId(int phoneId)2782 public static boolean isValidPhoneId(int phoneId) { 2783 return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount(); 2784 } 2785 2786 /** @hide */ 2787 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) putPhoneIdAndSubIdExtra(Intent intent, int phoneId)2788 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) { 2789 int subId = SubscriptionManager.getSubscriptionId(phoneId); 2790 if (isValidSubscriptionId(subId)) { 2791 putPhoneIdAndSubIdExtra(intent, phoneId, subId); 2792 } else { 2793 logd("putPhoneIdAndSubIdExtra: no valid subs"); 2794 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); 2795 intent.putExtra(EXTRA_SLOT_INDEX, phoneId); 2796 } 2797 } 2798 2799 /** @hide */ 2800 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId)2801 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) { 2802 if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId); 2803 intent.putExtra(EXTRA_SLOT_INDEX, phoneId); 2804 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); 2805 putSubscriptionIdExtra(intent, subId); 2806 } 2807 2808 /** 2809 * Get visible subscription Id(s) of the currently active SIM(s). 2810 * 2811 * @return the list of subId's that are active, 2812 * is never null but the length may be 0. 2813 * 2814 * @throws UnsupportedOperationException If the device does not have 2815 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2816 * @hide 2817 */ 2818 @SystemApi 2819 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getActiveSubscriptionIdList()2820 public @NonNull int[] getActiveSubscriptionIdList() { 2821 return getActiveSubscriptionIdList(/* visibleOnly */ true); 2822 } 2823 2824 /** 2825 * Get both hidden and visible subscription Id(s) of the currently active SIM(s). 2826 * 2827 * Hidden subscriptions refer to those are not meant visible to the users. 2828 * For example, an opportunistic subscription that is grouped with other 2829 * subscriptions should remain invisible to users as they are only functionally 2830 * supplementary to primary ones. 2831 * 2832 * @return the list of subId's that are active, 2833 * is never null but the length may be 0. 2834 * 2835 * @throws UnsupportedOperationException If the device does not have 2836 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 2837 * @hide 2838 */ 2839 @SystemApi 2840 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getCompleteActiveSubscriptionIdList()2841 public @NonNull int[] getCompleteActiveSubscriptionIdList() { 2842 return getActiveSubscriptionIdList(/* visibleOnly */false); 2843 } 2844 2845 /** 2846 * @return a non-null list of subId's that are active. 2847 * 2848 * @hide 2849 */ getActiveSubscriptionIdList(boolean visibleOnly)2850 public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) { 2851 try { 2852 ISub iSub = TelephonyManager.getSubscriptionService(); 2853 if (iSub != null) { 2854 int[] subId = iSub.getActiveSubIdList(visibleOnly); 2855 if (subId != null) return subId; 2856 } 2857 } catch (RemoteException ex) { 2858 // ignore it 2859 } 2860 2861 return new int[0]; 2862 } 2863 2864 /** 2865 * Returns true if the device is considered roaming on the current 2866 * network for a subscription. 2867 * <p> 2868 * Availability: Only when user registered to a network. 2869 * 2870 * @param subId The subscription ID 2871 * @return true if the network for the subscription is roaming, false otherwise 2872 */ isNetworkRoaming(int subId)2873 public boolean isNetworkRoaming(int subId) { 2874 final int phoneId = getPhoneId(subId); 2875 if (phoneId < 0) { 2876 // What else can we do? 2877 return false; 2878 } 2879 return TelephonyManager.getDefault().isNetworkRoaming(subId); 2880 } 2881 2882 /** 2883 * Set a field in the subscription database. Note not all fields are supported. 2884 * 2885 * @param subscriptionId Subscription Id of Subscription. 2886 * @param columnName Column name in the database. Note not all fields are supported. 2887 * @param value Value to store in the database. 2888 * 2889 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 2890 * exposed. 2891 * @throws SecurityException if callers do not hold the required permission. 2892 * 2893 * @see android.provider.Telephony.SimInfo for all the columns. 2894 * 2895 * @hide 2896 */ 2897 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setSubscriptionProperty(int subscriptionId, @NonNull String columnName, @NonNull String value)2898 public static void setSubscriptionProperty(int subscriptionId, @NonNull String columnName, 2899 @NonNull String value) { 2900 try { 2901 ISub iSub = TelephonyManager.getSubscriptionService(); 2902 if (iSub != null) { 2903 iSub.setSubscriptionProperty(subscriptionId, columnName, value); 2904 } 2905 } catch (RemoteException ex) { 2906 // ignore it 2907 } 2908 } 2909 2910 /** 2911 * Serialize list of contacts uri to string 2912 * @hide 2913 */ serializeUriLists(List<Uri> uris)2914 public static String serializeUriLists(List<Uri> uris) { 2915 List<String> contacts = new ArrayList<>(); 2916 for (Uri uri : uris) { 2917 contacts.add(uri.toString()); 2918 } 2919 try { 2920 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 2921 ObjectOutputStream oos = new ObjectOutputStream(bos); 2922 oos.writeObject(contacts); 2923 oos.flush(); 2924 return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT); 2925 } catch (IOException e) { 2926 logd("serializeUriLists IO exception"); 2927 } 2928 return ""; 2929 } 2930 2931 /** 2932 * Get specific field in string format from the subscription info database. 2933 * 2934 * @param context The calling context. 2935 * @param subscriptionId Subscription id of the subscription. 2936 * @param columnName Column name in subscription database. 2937 * 2938 * @return Value in string format associated with {@code subscriptionId} and {@code columnName} 2939 * from the database. Empty string if the {@code subscriptionId} is invalid (for backward 2940 * compatible). 2941 * 2942 * @throws IllegalArgumentException if the field is not exposed. 2943 * 2944 * @see android.provider.Telephony.SimInfo for all the columns. 2945 * 2946 * @hide 2947 */ 2948 @NonNull 2949 @RequiresPermission(anyOf = { 2950 Manifest.permission.READ_PHONE_STATE, 2951 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 2952 "carrier privileges", 2953 }) getStringSubscriptionProperty(@onNull Context context, int subscriptionId, @NonNull String columnName)2954 private static String getStringSubscriptionProperty(@NonNull Context context, 2955 int subscriptionId, @NonNull String columnName) { 2956 String resultValue = null; 2957 try { 2958 ISub iSub = TelephonyManager.getSubscriptionService(); 2959 if (iSub != null) { 2960 resultValue = iSub.getSubscriptionProperty(subscriptionId, columnName, 2961 context.getOpPackageName(), context.getAttributionTag()); 2962 } 2963 } catch (RemoteException ex) { 2964 // ignore it 2965 } 2966 return TextUtils.emptyIfNull(resultValue); 2967 } 2968 2969 /** 2970 * Get specific field in {@code boolean} format from the subscription info database. 2971 * 2972 * @param subscriptionId Subscription id of the subscription. 2973 * @param columnName Column name in subscription database. 2974 * @param defaultValue Default value in case not found or error. 2975 * @param context The calling context. 2976 * 2977 * @return Value in {@code boolean} format associated with {@code subscriptionId} and 2978 * {@code columnName} from the database, or {@code defaultValue} if not found or error. 2979 * 2980 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 2981 * exposed. 2982 * 2983 * @see android.provider.Telephony.SimInfo for all the columns. 2984 * 2985 * @hide 2986 */ 2987 @RequiresPermission(anyOf = { 2988 Manifest.permission.READ_PHONE_STATE, 2989 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 2990 "carrier privileges", 2991 }) getBooleanSubscriptionProperty(int subscriptionId, @NonNull String columnName, boolean defaultValue, @NonNull Context context)2992 public static boolean getBooleanSubscriptionProperty(int subscriptionId, 2993 @NonNull String columnName, boolean defaultValue, @NonNull Context context) { 2994 String result = getStringSubscriptionProperty(context, subscriptionId, columnName); 2995 if (!result.isEmpty()) { 2996 try { 2997 return Integer.parseInt(result) == 1; 2998 } catch (NumberFormatException err) { 2999 logd("getBooleanSubscriptionProperty NumberFormat exception"); 3000 } 3001 } 3002 return defaultValue; 3003 } 3004 3005 /** 3006 * Get specific field in {@code integer} format from the subscription info database. 3007 * 3008 * @param subscriptionId Subscription id of the subscription. 3009 * @param columnName Column name in subscription database. 3010 * @param defaultValue Default value in case not found or error. 3011 * @param context The calling context. 3012 * 3013 * @return Value in {@code integer} format associated with {@code subscriptionId} and 3014 * {@code columnName} from the database, or {@code defaultValue} if not found or error. 3015 * 3016 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 3017 * exposed. 3018 * 3019 * @see android.provider.Telephony.SimInfo for all the columns. 3020 * 3021 * @hide 3022 */ 3023 @RequiresPermission(anyOf = { 3024 Manifest.permission.READ_PHONE_STATE, 3025 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3026 "carrier privileges", 3027 }) getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName, int defaultValue, @NonNull Context context)3028 public static int getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName, 3029 int defaultValue, @NonNull Context context) { 3030 String result = getStringSubscriptionProperty(context, subscriptionId, columnName); 3031 if (!result.isEmpty()) { 3032 try { 3033 return Integer.parseInt(result); 3034 } catch (NumberFormatException err) { 3035 logd("getIntegerSubscriptionProperty NumberFormat exception"); 3036 } 3037 } 3038 return defaultValue; 3039 } 3040 3041 /** 3042 * Get specific field in {@code long} format from the subscription info database. 3043 * 3044 * @param subscriptionId Subscription id of the subscription. 3045 * @param columnName Column name in subscription database. 3046 * @param defaultValue Default value in case not found or error. 3047 * @param context The calling context. 3048 * 3049 * @return Value in {@code long} format associated with {@code subscriptionId} and 3050 * {@code columnName} from the database, or {@code defaultValue} if not found or error. 3051 * 3052 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not 3053 * exposed. 3054 * 3055 * @see android.provider.Telephony.SimInfo for all the columns. 3056 * 3057 * @hide 3058 */ 3059 @RequiresPermission(anyOf = { 3060 Manifest.permission.READ_PHONE_STATE, 3061 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3062 "carrier privileges", 3063 }) getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName, long defaultValue, @NonNull Context context)3064 public static long getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName, 3065 long defaultValue, @NonNull Context context) { 3066 String result = getStringSubscriptionProperty(context, subscriptionId, columnName); 3067 if (!result.isEmpty()) { 3068 try { 3069 return Long.parseLong(result); 3070 } catch (NumberFormatException err) { 3071 logd("getLongSubscriptionProperty NumberFormat exception"); 3072 } 3073 } 3074 return defaultValue; 3075 } 3076 3077 /** 3078 * Returns the {@link Resources} from the given {@link Context} for the MCC/MNC associated with 3079 * the subscription. If the subscription ID is invalid, the base resources are returned instead. 3080 * 3081 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 3082 * 3083 * @param context Context object 3084 * @param subId Subscription Id of Subscription whose resources are required 3085 * @return Resources associated with Subscription. 3086 * 3087 * @throws UnsupportedOperationException If the device does not have 3088 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3089 * @hide 3090 */ 3091 @NonNull 3092 @SystemApi getResourcesForSubId(@onNull Context context, int subId)3093 public static Resources getResourcesForSubId(@NonNull Context context, int subId) { 3094 return getResourcesForSubId(context, subId, false); 3095 } 3096 3097 /** 3098 * Returns the resources associated with Subscription. 3099 * @param context Context object 3100 * @param subId Subscription Id of Subscription who's resources are required 3101 * @param useRootLocale if root locale should be used. Localized locale is used if false. 3102 * @return Resources associated with Subscription. 3103 * @hide 3104 */ 3105 @NonNull getResourcesForSubId(Context context, int subId, boolean useRootLocale)3106 public static Resources getResourcesForSubId(Context context, int subId, 3107 boolean useRootLocale) { 3108 // Check if the Resources already exists in the cache based on the given context. Find a 3109 // Resource that match Configuration. 3110 Pair<String, Configuration> cacheKey = null; 3111 if (isValidSubscriptionId(subId)) { 3112 Configuration configurationKey = 3113 new Configuration(context.getResources().getConfiguration()); 3114 if (useRootLocale) { 3115 configurationKey.setLocale(Locale.ROOT); 3116 } 3117 cacheKey = Pair.create(context.getPackageName() + ", subid=" + subId, configurationKey); 3118 synchronized (sResourcesCache) { 3119 Resources cached = sResourcesCache.get(cacheKey); 3120 if (cached != null) { 3121 // Cache hit. Use cached Resources. 3122 return cached; 3123 } 3124 } 3125 } 3126 3127 final SubscriptionInfo subInfo = 3128 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId); 3129 3130 Configuration overrideConfig = new Configuration(); 3131 if (subInfo != null) { 3132 overrideConfig.mcc = subInfo.getMcc(); 3133 overrideConfig.mnc = subInfo.getMnc(); 3134 if (overrideConfig.mnc == 0) { 3135 overrideConfig.mnc = Configuration.MNC_ZERO; 3136 cacheKey = null; 3137 } 3138 } else { 3139 cacheKey = null; 3140 } 3141 3142 if (useRootLocale) { 3143 overrideConfig.setLocale(Locale.ROOT); 3144 } 3145 3146 // Create new context with new configuration so that we can avoid modifying the passed in 3147 // context. 3148 // Note that if the original context configuration changes, the resources here will also 3149 // change for all values except those overridden by newConfig (e.g. if the device has an 3150 // orientation change). 3151 Context newContext = context.createConfigurationContext(overrideConfig); 3152 Resources res = newContext.getResources(); 3153 3154 if (cacheKey != null) { 3155 synchronized (sResourcesCache) { 3156 // Save the newly created Resources in the resource cache. 3157 sResourcesCache.put(cacheKey, res); 3158 } 3159 } 3160 return res; 3161 } 3162 3163 /** 3164 * Checks if the supplied subscription ID corresponds to a subscription which is actively in 3165 * use on the device. An active subscription ID is a valid and usable subscription ID. 3166 * 3167 * @param subscriptionId the subscription ID. 3168 * @return {@code true} if the supplied subscription ID corresponds to an active subscription; 3169 * {@code false} if it does not correspond to an active subscription; or throw a 3170 * SecurityException if the caller hasn't got the right permission. 3171 *i 3172 * @throws UnsupportedOperationException If the device does not have 3173 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3174 */ 3175 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) isActiveSubscriptionId(int subscriptionId)3176 public boolean isActiveSubscriptionId(int subscriptionId) { 3177 return isActiveSubId(subscriptionId); 3178 } 3179 3180 /** 3181 * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription 3182 * and the SIM providing the subscription is present in a slot and in "LOADED" state. 3183 * @hide 3184 */ 3185 @UnsupportedAppUsage isActiveSubId(int subId)3186 public boolean isActiveSubId(int subId) { 3187 try { 3188 ISub iSub = TelephonyManager.getSubscriptionService(); 3189 if (iSub != null) { 3190 return iSub.isActiveSubId(subId, mContext.getOpPackageName(), 3191 mContext.getAttributionTag()); 3192 } 3193 } catch (RemoteException ex) { 3194 } 3195 return false; 3196 } 3197 3198 /** 3199 * Get the description of the billing relationship plan between a carrier 3200 * and a specific subscriber. 3201 * <p> 3202 * This method is only accessible to the following narrow set of apps: 3203 * <ul> 3204 * <li>The carrier app for this subscriberId, as determined by 3205 * {@link TelephonyManager#hasCarrierPrivileges()}. 3206 * <li>The carrier app explicitly delegated access through 3207 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3208 * </ul> 3209 * 3210 * @param subId the subscriber this relationship applies to 3211 * @throws SecurityException if the caller doesn't meet the requirements 3212 * outlined above. 3213 */ getSubscriptionPlans(int subId)3214 public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) { 3215 SubscriptionPlan[] subscriptionPlans = 3216 getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName()); 3217 return subscriptionPlans == null 3218 ? Collections.emptyList() : Arrays.asList(subscriptionPlans); 3219 } 3220 3221 /** 3222 * Set the description of the billing relationship plan between a carrier 3223 * and a specific subscriber. 3224 * <p> 3225 * This method is only accessible to the following narrow set of apps: 3226 * <ul> 3227 * <li>The carrier app for this subscriberId, as determined by 3228 * {@link TelephonyManager#hasCarrierPrivileges()}. 3229 * <li>The carrier app explicitly delegated access through 3230 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3231 * </ul> 3232 * 3233 * @param subId the subscriber this relationship applies to. An empty list 3234 * may be sent to clear any existing plans. 3235 * @param plans the list of plans. The first plan is always the primary and 3236 * most important plan. Any additional plans are secondary and 3237 * may not be displayed or used by decision making logic. 3238 * @throws SecurityException if the caller doesn't meet the requirements 3239 * outlined above. 3240 * @throws IllegalArgumentException if plans don't meet the requirements 3241 * defined in {@link SubscriptionPlan}. 3242 * @deprecated use {@link #setSubscriptionPlans(int, List, long)} instead. 3243 */ 3244 @Deprecated setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans)3245 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) { 3246 setSubscriptionPlans(subId, plans, 0); 3247 } 3248 3249 /** 3250 * Set the description of the billing relationship plan between a carrier 3251 * and a specific subscriber. 3252 * <p> 3253 * This method is only accessible to the following narrow set of apps: 3254 * <ul> 3255 * <li>The carrier app for this subscriberId, as determined by 3256 * {@link TelephonyManager#hasCarrierPrivileges()}. 3257 * <li>The carrier app explicitly delegated access through 3258 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3259 * </ul> 3260 * 3261 * @param subId the subscriber this relationship applies to. An empty list 3262 * may be sent to clear any existing plans. 3263 * @param plans the list of plans. The first plan is always the primary and 3264 * most important plan. Any additional plans are secondary and 3265 * may not be displayed or used by decision making logic. 3266 * @param expirationDurationMillis the duration after which the subscription plans 3267 * will be automatically cleared, or {@code 0} to leave the plans until 3268 * explicitly cleared, or the next reboot, whichever happens first. 3269 * @throws SecurityException if the caller doesn't meet the requirements 3270 * outlined above. 3271 * @throws IllegalArgumentException if plans don't meet the requirements 3272 * defined in {@link SubscriptionPlan}. 3273 */ setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans, @DurationMillisLong long expirationDurationMillis)3274 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans, 3275 @DurationMillisLong long expirationDurationMillis) { 3276 getNetworkPolicyManager().setSubscriptionPlans(subId, 3277 plans.toArray(new SubscriptionPlan[0]), expirationDurationMillis, 3278 mContext.getOpPackageName()); 3279 } 3280 3281 /** 3282 * Temporarily override the billing relationship plan between a carrier and 3283 * a specific subscriber to be considered unmetered. This will be reflected 3284 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}. 3285 * <p> 3286 * This method is only accessible to the following narrow set of apps: 3287 * <ul> 3288 * <li>The carrier app for this subscriberId, as determined by 3289 * {@link TelephonyManager#hasCarrierPrivileges()}. 3290 * <li>The carrier app explicitly delegated access through 3291 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3292 * </ul> 3293 * 3294 * @param subId the subscriber this override applies to. 3295 * @param overrideUnmetered set if the billing relationship should be 3296 * considered unmetered. 3297 * @param expirationDurationMillis the duration after which the requested override 3298 * will be automatically cleared, or {@code 0} to leave in the 3299 * requested state until explicitly cleared, or the next reboot, 3300 * whichever happens first. 3301 * @throws SecurityException if the caller doesn't meet the requirements 3302 * outlined above. 3303 */ setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long expirationDurationMillis)3304 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, 3305 @DurationMillisLong long expirationDurationMillis) { 3306 setSubscriptionOverrideUnmetered(subId, overrideUnmetered, 3307 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis); 3308 } 3309 3310 /** 3311 * Temporarily override the billing relationship plan between a carrier and 3312 * a specific subscriber to be considered unmetered. This will be reflected 3313 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}. 3314 * <p> 3315 * This method is only accessible to the following narrow set of apps: 3316 * <ul> 3317 * <li>The carrier app for this subscriberId, as determined by 3318 * {@link TelephonyManager#hasCarrierPrivileges()}. 3319 * <li>The carrier app explicitly delegated access through 3320 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3321 * </ul> 3322 * 3323 * @param subId the subscriber this override applies to. 3324 * @param overrideUnmetered set if the billing relationship should be 3325 * considered unmetered. 3326 * @param networkTypes the network types this override applies to. If no 3327 * network types are specified, override values will be ignored. 3328 * @param expirationDurationMillis the duration after which the requested override 3329 * will be automatically cleared, or {@code 0} to leave in the 3330 * requested state until explicitly cleared, or the next reboot, 3331 * whichever happens first. 3332 * @throws SecurityException if the caller doesn't meet the requirements 3333 * outlined above. 3334 */ setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)3335 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, 3336 @NonNull @Annotation.NetworkType int[] networkTypes, 3337 @DurationMillisLong long expirationDurationMillis) { 3338 final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0; 3339 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED, 3340 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName()); 3341 } 3342 3343 /** 3344 * Temporarily override the billing relationship plan between a carrier and 3345 * a specific subscriber to be considered congested. This will cause the 3346 * device to delay certain network requests when possible, such as developer 3347 * jobs that are willing to run in a flexible time window. 3348 * <p> 3349 * This method is only accessible to the following narrow set of apps: 3350 * <ul> 3351 * <li>The carrier app for this subscriberId, as determined by 3352 * {@link TelephonyManager#hasCarrierPrivileges()}. 3353 * <li>The carrier app explicitly delegated access through 3354 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3355 * </ul> 3356 * 3357 * @param subId the subscriber this override applies to. 3358 * @param overrideCongested set if the subscription should be considered 3359 * congested. 3360 * @param expirationDurationMillis the duration after which the requested override 3361 * will be automatically cleared, or {@code 0} to leave in the 3362 * requested state until explicitly cleared, or the next reboot, 3363 * whichever happens first. 3364 * @throws SecurityException if the caller doesn't meet the requirements 3365 * outlined above. 3366 */ setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long expirationDurationMillis)3367 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, 3368 @DurationMillisLong long expirationDurationMillis) { 3369 setSubscriptionOverrideCongested(subId, overrideCongested, 3370 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis); 3371 } 3372 3373 /** 3374 * Temporarily override the billing relationship plan between a carrier and 3375 * a specific subscriber to be considered congested. This will cause the 3376 * device to delay certain network requests when possible, such as developer 3377 * jobs that are willing to run in a flexible time window. 3378 * <p> 3379 * This method is only accessible to the following narrow set of apps: 3380 * <ul> 3381 * <li>The carrier app for this subscriberId, as determined by 3382 * {@link TelephonyManager#hasCarrierPrivileges()}. 3383 * <li>The carrier app explicitly delegated access through 3384 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. 3385 * </ul> 3386 * 3387 * @param subId the subscriber this override applies to. 3388 * @param overrideCongested set if the subscription should be considered congested. 3389 * @param networkTypes the network types this override applies to. If no network types are 3390 * specified, override values will be ignored. 3391 * @param expirationDurationMillis the duration after which the requested override 3392 * will be automatically cleared, or {@code 0} to leave in the requested state until explicitly 3393 * cleared, or the next reboot, whichever happens first. 3394 * 3395 * @throws SecurityException if the caller doesn't meet the requirements outlined above. 3396 */ setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)3397 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, 3398 @NonNull @Annotation.NetworkType int[] networkTypes, 3399 @DurationMillisLong long expirationDurationMillis) { 3400 final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0; 3401 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED, 3402 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName()); 3403 } 3404 3405 /** 3406 * Checks whether the app with the given context is authorized to manage the given subscription 3407 * according to its metadata. 3408 * 3409 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns 3410 * true). To check for permissions for non-embedded subscription as well, 3411 * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}. 3412 * 3413 * @param info The subscription to check. 3414 * @return whether the app is authorized to manage this subscription per its metadata. 3415 * @see android.telephony.TelephonyManager#hasCarrierPrivileges 3416 */ canManageSubscription(SubscriptionInfo info)3417 public boolean canManageSubscription(SubscriptionInfo info) { 3418 return canManageSubscription(info, mContext.getPackageName()); 3419 } 3420 3421 /** 3422 * Checks whether the given app is authorized to manage the given subscription. An app can only 3423 * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the 3424 * {@link android.telephony.SubscriptionInfo} with the access status. 3425 * 3426 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns 3427 * true). To check for permissions for non-embedded subscription as well, 3428 * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}. 3429 * 3430 * @param info The subscription to check. 3431 * @param packageName Package name of the app to check. 3432 * 3433 * @return whether the app is authorized to manage this subscription per its access rules. 3434 * @see android.telephony.TelephonyManager#hasCarrierPrivileges 3435 * @hide 3436 */ 3437 @SystemApi canManageSubscription(@onNull SubscriptionInfo info, @NonNull String packageName)3438 public boolean canManageSubscription(@NonNull SubscriptionInfo info, 3439 @NonNull String packageName) { 3440 if (info == null || info.getAccessRules() == null || packageName == null) { 3441 return false; 3442 } 3443 PackageManager packageManager = mContext.getPackageManager(); 3444 PackageInfo packageInfo; 3445 try { 3446 packageInfo = packageManager.getPackageInfo(packageName, 3447 PackageManager.GET_SIGNING_CERTIFICATES); 3448 } catch (PackageManager.NameNotFoundException e) { 3449 logd("Unknown package: " + packageName); 3450 return false; 3451 } 3452 for (UiccAccessRule rule : info.getAccessRules()) { 3453 if (rule.getCarrierPrivilegeStatus(packageInfo) 3454 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 3455 return true; 3456 } 3457 } 3458 return false; 3459 } 3460 3461 /** 3462 * Set which subscription is preferred for cellular data. 3463 * It's also usually the subscription we set up internet connection on. 3464 * 3465 * PreferredData overwrites user setting of default data subscription. And it's used 3466 * by AlternativeNetworkService or carrier apps to switch primary and CBRS 3467 * subscription dynamically in multi-SIM devices. 3468 * 3469 * @param subId which subscription is preferred to for cellular data. If it's 3470 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}, it means 3471 * it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()} 3472 * is used to determine which modem is preferred. 3473 * @param needValidation whether Telephony will wait until the network is validated by 3474 * connectivity service before switching data to it. More details see 3475 * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}. 3476 * @param executor The executor of where the callback will execute. 3477 * @param callback Callback will be triggered once it succeeds or failed. 3478 * Pass null if don't care about the result. 3479 * 3480 * @throws IllegalStateException when subscription manager service is not available. 3481 * @throws SecurityException when clients do not have MODIFY_PHONE_STATE permission. 3482 * @throws UnsupportedOperationException If the device does not have 3483 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3484 * @hide 3485 */ 3486 @SystemApi 3487 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setPreferredDataSubscriptionId(int subId, boolean needValidation, @Nullable @CallbackExecutor Executor executor, @Nullable @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback)3488 public void setPreferredDataSubscriptionId(int subId, boolean needValidation, 3489 @Nullable @CallbackExecutor Executor executor, @Nullable 3490 @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) { 3491 if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId); 3492 try { 3493 ISub iSub = TelephonyManager.getSubscriptionService(); 3494 if (iSub == null) { 3495 throw new IllegalStateException("subscription manager service is null."); 3496 } 3497 3498 ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() { 3499 @Override 3500 public void onComplete(int result) { 3501 if (executor == null || callback == null) { 3502 return; 3503 } 3504 final long identity = Binder.clearCallingIdentity(); 3505 try { 3506 executor.execute(() -> { 3507 callback.accept(result); 3508 }); 3509 } finally { 3510 Binder.restoreCallingIdentity(identity); 3511 } 3512 } 3513 }; 3514 iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub); 3515 } catch (RemoteException ex) { 3516 loge("setPreferredDataSubscriptionId RemoteException=" + ex); 3517 ex.rethrowFromSystemServer(); 3518 } 3519 } 3520 3521 /** 3522 * Get which subscription is preferred for cellular data. 3523 * It's also usually the subscription we set up internet connection on. 3524 * 3525 * PreferredData overwrites user setting of default data subscription. And it's used 3526 * by AlternativeNetworkService or carrier apps to switch primary and CBRS 3527 * subscription dynamically in multi-SIM devices. 3528 * 3529 * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if 3530 * there's no prefered subscription. 3531 * 3532 * @hide 3533 * 3534 */ 3535 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getPreferredDataSubscriptionId()3536 public int getPreferredDataSubscriptionId() { 3537 int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 3538 try { 3539 ISub iSub = TelephonyManager.getSubscriptionService(); 3540 if (iSub != null) { 3541 preferredSubId = iSub.getPreferredDataSubscriptionId(); 3542 } 3543 } catch (RemoteException ex) { 3544 // ignore it 3545 } 3546 3547 return preferredSubId; 3548 } 3549 3550 /** 3551 * Return opportunistic subscriptions that can be visible to the caller. 3552 * Opportunistic subscriptions are for opportunistic networks, which are cellular 3553 * networks with limited capabilities and coverage, for example, CBRS. 3554 * 3555 * <p>Requires Permission: 3556 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 3557 * or that the calling app has carrier privileges (see 3558 * {@link TelephonyManager#hasCarrierPrivileges}). 3559 * 3560 * @return the list of opportunistic subscription info. If none exists, an empty list. 3561 * 3562 * @throws UnsupportedOperationException If the device does not have 3563 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3564 */ 3565 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3566 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) getOpportunisticSubscriptions()3567 public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() { 3568 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3569 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null; 3570 List<SubscriptionInfo> subInfoList = null; 3571 3572 try { 3573 ISub iSub = TelephonyManager.getSubscriptionService(); 3574 if (iSub != null) { 3575 subInfoList = iSub.getOpportunisticSubscriptions(contextPkg, 3576 contextAttributionTag); 3577 } 3578 } catch (RemoteException ex) { 3579 // ignore it 3580 } 3581 3582 if (subInfoList == null) { 3583 subInfoList = new ArrayList<>(); 3584 } 3585 3586 return subInfoList; 3587 } 3588 3589 /** 3590 * Switch to a certain subscription 3591 * 3592 * @param subId sub id 3593 * @param callbackIntent pending intent that will be sent after operation is done. 3594 * 3595 * @deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int, 3596 * PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use 3597 * {@link EuiccManager#switchToSubscription(int, PendingIntent)} or 3598 * {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead. 3599 * 3600 * @throws UnsupportedOperationException If the device does not have 3601 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}. 3602 */ 3603 @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) 3604 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_EUICC) 3605 @Deprecated switchToSubscription(int subId, @NonNull PendingIntent callbackIntent)3606 public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) { 3607 Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null"); 3608 EuiccManager euiccManager = new EuiccManager(mContext); 3609 euiccManager.switchToSubscription(subId, callbackIntent); 3610 } 3611 3612 /** 3613 * Set whether a subscription is opportunistic, that is, whether the network it connects 3614 * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has 3615 * following impacts: 3616 * 1) Even if it's active, it will be dormant most of the time. The modem will not try 3617 * to scan or camp until it knows an available network is nearby to save power. 3618 * 2) Telephony relies on system app or carrier input to notify nearby available networks. 3619 * See {@link TelephonyManager#updateAvailableNetworks(List, Executor, Consumer)} 3620 * for more information. 3621 * 3) In multi-SIM devices, when the network is nearby and camped, system may automatically 3622 * switch internet data between it and default data subscription, based on carrier 3623 * recommendation and its signal strength and metered-ness, etc. 3624 * 3625 * 3626 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier 3627 * privilege permission of the subscription. 3628 * 3629 * @param opportunistic whether it’s opportunistic subscription. 3630 * @param subId the unique SubscriptionInfo index in database 3631 * @return {@code true} if the operation is succeed, {@code false} otherwise. 3632 * 3633 * @throws UnsupportedOperationException If the device does not have 3634 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3635 */ 3636 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3637 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setOpportunistic(boolean opportunistic, int subId)3638 public boolean setOpportunistic(boolean opportunistic, int subId) { 3639 if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId); 3640 return setSubscriptionPropertyHelper(subId, "setOpportunistic", 3641 (iSub)-> iSub.setOpportunistic( 3642 opportunistic, subId, mContext.getOpPackageName())) == 1; 3643 } 3644 3645 /** 3646 * Inform SubscriptionManager that subscriptions in the list are bundled 3647 * as a group. It can be multiple primary (non-opportunistic) subscriptions, 3648 * or one or more primary plus one or more opportunistic subscriptions. 3649 * 3650 * This API will always create a new immutable group and assign group UUID to all the 3651 * subscriptions, regardless whether they are in a group already or not. 3652 * 3653 * Grouped subscriptions will have below behaviors: 3654 * 1) They will share the same user settings. 3655 * 2) The opportunistic subscriptions in the group is considered invisible and will not 3656 * return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier 3657 * privilege permission of the subscriptions. 3658 * 3) The opportunistic subscriptions in the group can't be active by itself. If all other 3659 * non-opportunistic ones are deactivated (unplugged or disabled in Settings), 3660 * the opportunistic ones will be deactivated automatically. 3661 * 3662 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} 3663 * permission or had carrier privilege permission on the subscriptions: 3664 * {@link TelephonyManager#hasCarrierPrivileges()} or 3665 * {@link #canManageSubscription(SubscriptionInfo)} 3666 * 3667 * @throws SecurityException if the caller doesn't meet the requirements 3668 * outlined above. 3669 * @throws IllegalArgumentException if any of the subscriptions in the list doesn't exist. 3670 * @throws IllegalStateException if Telephony service is in bad state. 3671 * @throws UnsupportedOperationException If the device does not have 3672 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3673 * 3674 * @param subIdList list of subId that will be in the same group 3675 * @return groupUUID a UUID assigned to the subscription group. 3676 * 3677 */ 3678 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3679 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) createSubscriptionGroup(@onNull List<Integer> subIdList)3680 public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) { 3681 Preconditions.checkNotNull(subIdList, "can't create group for null subId list"); 3682 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3683 if (VDBG) { 3684 logd("[createSubscriptionGroup]"); 3685 } 3686 3687 ParcelUuid groupUuid = null; 3688 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); 3689 try { 3690 ISub iSub = TelephonyManager.getSubscriptionService(); 3691 if (iSub != null) { 3692 groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug); 3693 } else { 3694 throw new IllegalStateException("telephony service is null."); 3695 } 3696 } catch (RemoteException ex) { 3697 loge("createSubscriptionGroup RemoteException " + ex); 3698 ex.rethrowAsRuntimeException(); 3699 } 3700 3701 return groupUuid; 3702 } 3703 3704 /** 3705 * Add a list of subscriptions into a group. 3706 * See {@link #createSubscriptionGroup(List)} for more details. 3707 * 3708 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} 3709 * permission or had carrier privilege permission on the subscriptions: 3710 * {@link TelephonyManager#hasCarrierPrivileges()} or 3711 * {@link #canManageSubscription(SubscriptionInfo)} 3712 * 3713 * @throws SecurityException if the caller doesn't meet the requirements 3714 * outlined above. 3715 * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist. 3716 * @throws IllegalStateException if Telephony service is in bad state. 3717 * @throws UnsupportedOperationException If the device does not have 3718 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3719 * 3720 * @param subIdList list of subId that need adding into the group 3721 * @param groupUuid the groupUuid the subscriptions are being added to. 3722 * 3723 */ 3724 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3725 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) addSubscriptionsIntoGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3726 public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList, 3727 @NonNull ParcelUuid groupUuid) { 3728 Preconditions.checkNotNull(subIdList, "subIdList can't be null."); 3729 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null."); 3730 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3731 if (VDBG) { 3732 logd("[addSubscriptionsIntoGroup]"); 3733 } 3734 3735 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); 3736 3737 try { 3738 ISub iSub = TelephonyManager.getSubscriptionService(); 3739 if (iSub != null) { 3740 iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug); 3741 } else { 3742 throw new IllegalStateException("telephony service is null."); 3743 } 3744 } catch (RemoteException ex) { 3745 loge("addSubscriptionsIntoGroup RemoteException " + ex); 3746 ex.rethrowAsRuntimeException(); 3747 } 3748 } 3749 isSystemProcess()3750 private boolean isSystemProcess() { 3751 return Process.myUid() == Process.SYSTEM_UID; 3752 } 3753 3754 /** 3755 * Remove a list of subscriptions from their subscription group. 3756 * 3757 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} 3758 * permission or has carrier privilege permission on all of the subscriptions provided in 3759 * {@code subIdList}. 3760 * 3761 * @param subIdList list of subId that need removing from their groups. 3762 * @param groupUuid The UUID of the subscription group. 3763 * 3764 * @throws SecurityException if the caller doesn't meet the requirements outlined above. 3765 * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong the 3766 * specified group. 3767 * @throws IllegalStateException if Telephony service is in bad state. 3768 * @throws UnsupportedOperationException If the device does not have 3769 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3770 * 3771 * @see #createSubscriptionGroup(List) 3772 */ 3773 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3774 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) removeSubscriptionsFromGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3775 public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList, 3776 @NonNull ParcelUuid groupUuid) { 3777 Preconditions.checkNotNull(subIdList, "subIdList can't be null."); 3778 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null."); 3779 String callingPackage = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3780 if (VDBG) { 3781 logd("[removeSubscriptionsFromGroup]"); 3782 } 3783 3784 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); 3785 3786 try { 3787 ISub iSub = TelephonyManager.getSubscriptionService(); 3788 if (iSub != null) { 3789 iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, callingPackage); 3790 } else { 3791 throw new IllegalStateException("telephony service is null."); 3792 } 3793 } catch (RemoteException ex) { 3794 loge("removeSubscriptionsFromGroup RemoteException " + ex); 3795 ex.rethrowAsRuntimeException(); 3796 } 3797 } 3798 3799 /** 3800 * Get subscriptionInfo list of subscriptions that are in the same group of given subId. 3801 * 3802 * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE} 3803 * or carrier privilege permission on the subscription. 3804 * {@link TelephonyManager#hasCarrierPrivileges()} 3805 * 3806 * <p>Starting with API level 33, the caller also needs permission to access device identifiers 3807 * to get the list of subscriptions associated with a group UUID. 3808 * This method can be invoked if one of the following requirements is met: 3809 * <ul> 3810 * <li>If the app has carrier privilege permission. 3811 * {@link TelephonyManager#hasCarrierPrivileges()} 3812 * <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} permission and 3813 * access to device identifiers. 3814 * </ul> 3815 * 3816 * @throws IllegalStateException if Telephony service is in bad state. 3817 * @throws SecurityException if the caller doesn't meet the requirements 3818 * outlined above. 3819 * @throws UnsupportedOperationException If the device does not have 3820 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3821 * 3822 * @param groupUuid of which list of subInfo will be returned. 3823 * @return list of subscriptionInfo that belong to the same group, including the given 3824 * subscription itself. It will return an empty list if no subscription belongs to the group. 3825 */ 3826 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 3827 @RequiresPermission(Manifest.permission.READ_PHONE_STATE) getSubscriptionsInGroup(@onNull ParcelUuid groupUuid)3828 public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) { 3829 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null"); 3830 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>"; 3831 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null; 3832 if (VDBG) { 3833 logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid); 3834 } 3835 3836 List<SubscriptionInfo> result = null; 3837 try { 3838 ISub iSub = TelephonyManager.getSubscriptionService(); 3839 if (iSub != null) { 3840 result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg, 3841 contextAttributionTag); 3842 } else { 3843 if (!isSystemProcess()) { 3844 throw new IllegalStateException("telephony service is null."); 3845 } 3846 } 3847 } catch (RemoteException ex) { 3848 loge("removeSubscriptionsFromGroup RemoteException " + ex); 3849 if (!isSystemProcess()) { 3850 ex.rethrowAsRuntimeException(); 3851 } 3852 } 3853 3854 // TODO(b/296125268) Really this method should throw, but it's common enough that for 3855 // system callers it's worth having a little magic for the system process until it's 3856 // made safer. 3857 if (result == null) result = Collections.emptyList(); 3858 3859 return result; 3860 } 3861 3862 /** 3863 * Whether a subscription is visible to API caller. If it's a bundled opportunistic 3864 * subscription, it should be hidden anywhere in Settings, dialer, status bar etc. 3865 * Exception is if caller owns carrier privilege, in which case they will 3866 * want to see their own hidden subscriptions. 3867 * 3868 * @param info the subscriptionInfo to check against. 3869 * 3870 * @return {@code true} if this subscription should be visible to the API caller. 3871 * 3872 * @hide 3873 */ isSubscriptionVisible(SubscriptionInfo info)3874 public boolean isSubscriptionVisible(SubscriptionInfo info) { 3875 if (info == null) return false; 3876 // If subscription is NOT grouped opportunistic subscription, it's visible. 3877 if (info.getGroupUuid() == null || !info.isOpportunistic()) return true; 3878 3879 // If the caller is the carrier app and owns the subscription, it should be visible 3880 // to the caller. 3881 boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext) 3882 .hasCarrierPrivileges(info.getSubscriptionId()) 3883 || canManageSubscription(info); 3884 return hasCarrierPrivilegePermission; 3885 } 3886 3887 /** 3888 * Return a list of subscriptions that are available and visible to the user. 3889 * Used by Settings app to show a list of subscriptions for user to pick. 3890 * 3891 * <p> 3892 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required 3893 * for getSelectableSubscriptionInfoList to be invoked. 3894 * @return list of user selectable subscriptions. 3895 * 3896 * @hide 3897 */ getSelectableSubscriptionInfoList()3898 public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() { 3899 List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList(); 3900 if (availableList == null) { 3901 return null; 3902 } else { 3903 // Multiple subscriptions in a group should only have one representative. 3904 // It should be the current active primary subscription if any, or any 3905 // primary subscription. 3906 List<SubscriptionInfo> selectableList = new ArrayList<>(); 3907 Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>(); 3908 3909 for (SubscriptionInfo info : availableList) { 3910 // Grouped opportunistic subscriptions are considered invisible 3911 // to users so they should never be returned. 3912 if (info.getGroupUuid() != null && info.isOpportunistic()) continue; 3913 3914 ParcelUuid groupUuid = info.getGroupUuid(); 3915 if (groupUuid == null) { 3916 // Doesn't belong to any group. Add in the list. 3917 selectableList.add(info); 3918 } else if (!groupMap.containsKey(groupUuid) 3919 || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX 3920 && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) { 3921 // If it belongs to a group that has never been recorded or it's the current 3922 // active subscription, add it in the list. 3923 selectableList.remove(groupMap.get(groupUuid)); 3924 selectableList.add(info); 3925 groupMap.put(groupUuid, info); 3926 } 3927 3928 } 3929 return selectableList; 3930 } 3931 } 3932 3933 /** 3934 * Enable or disable a subscription. This method is same as 3935 * {@link #setUiccApplicationsEnabled(int, boolean)}. 3936 * 3937 * @param subscriptionId Subscription to be enabled or disabled. 3938 * @param enable whether user is turning it on or off. 3939 * 3940 * @return whether the operation is successful. 3941 * 3942 * @throws UnsupportedOperationException If the device does not have 3943 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3944 * @hide 3945 */ 3946 @SystemApi 3947 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setSubscriptionEnabled(int subscriptionId, boolean enable)3948 public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) { 3949 try { 3950 ISub iSub = TelephonyManager.getSubscriptionService(); 3951 if (iSub != null) { 3952 iSub.setUiccApplicationsEnabled(enable, subscriptionId); 3953 } 3954 } catch (RemoteException ex) { 3955 return false; 3956 } 3957 return true; 3958 } 3959 3960 /** 3961 * Set uicc applications being enabled or disabled. 3962 * The value will be remembered on the subscription and will be applied whenever it's present. 3963 * If the subscription in currently present, it will also apply the setting to modem 3964 * immediately (the setting in the modem will not change until the modem receives and responds 3965 * to the request, but typically this should only take a few seconds. The user visible setting 3966 * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated 3967 * immediately.) 3968 * 3969 * @param subscriptionId which subscription to operate on. 3970 * @param enabled whether uicc applications are enabled or disabled. 3971 * 3972 * @throws UnsupportedOperationException If the device does not have 3973 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 3974 * @hide 3975 */ 3976 @SystemApi 3977 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setUiccApplicationsEnabled(int subscriptionId, boolean enabled)3978 public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) { 3979 if (VDBG) { 3980 logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled); 3981 } 3982 try { 3983 ISub iSub = TelephonyManager.getSubscriptionService(); 3984 if (iSub != null) { 3985 iSub.setUiccApplicationsEnabled(enabled, subscriptionId); 3986 } 3987 } catch (RemoteException ex) { 3988 // ignore it 3989 } 3990 } 3991 3992 /** 3993 * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM. 3994 * 3995 * Physical SIM refers non-euicc, or aka non-programmable SIM. 3996 * 3997 * It provides whether a physical SIM card can be disabled without taking it out, which is done 3998 * via {@link #setSubscriptionEnabled(int, boolean)} API. 3999 * 4000 * @return whether can disable subscriptions on physical SIMs. 4001 * 4002 * @throws UnsupportedOperationException If the device does not have 4003 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4004 * @hide 4005 */ 4006 @SystemApi 4007 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) canDisablePhysicalSubscription()4008 public boolean canDisablePhysicalSubscription() { 4009 if (VDBG) { 4010 logd("canDisablePhysicalSubscription"); 4011 } 4012 try { 4013 ISub iSub = TelephonyManager.getSubscriptionService(); 4014 if (iSub != null) { 4015 return iSub.canDisablePhysicalSubscription(); 4016 } 4017 } catch (RemoteException ex) { 4018 // ignore it 4019 } 4020 4021 return false; 4022 } 4023 4024 /** 4025 * Check if the subscription is currently active in any slot. 4026 * 4027 * @param subscriptionId The subscription id. 4028 * 4029 * @throws UnsupportedOperationException If the device does not have 4030 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4031 * @hide 4032 */ 4033 @SystemApi 4034 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) isSubscriptionEnabled(int subscriptionId)4035 public boolean isSubscriptionEnabled(int subscriptionId) { 4036 try { 4037 ISub iSub = TelephonyManager.getSubscriptionService(); 4038 if (iSub != null) { 4039 return iSub.isSubscriptionEnabled(subscriptionId); 4040 } 4041 } catch (RemoteException ex) { 4042 // ignore it 4043 } 4044 4045 return false; 4046 } 4047 4048 /** 4049 * Set the device to device status sharing user preference for a subscription id. The setting 4050 * app uses this method to indicate with whom they wish to share device to device status 4051 * information. 4052 * 4053 * @param subscriptionId The subscription id. 4054 * @param sharing The status sharing preference. 4055 * 4056 * @throws SecurityException if the caller doesn't have permissions required. 4057 * @throws UnsupportedOperationException If the device does not have 4058 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4059 */ 4060 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDeviceToDeviceStatusSharingPreference(int subscriptionId, @DeviceToDeviceStatusSharingPreference int sharing)4061 public void setDeviceToDeviceStatusSharingPreference(int subscriptionId, 4062 @DeviceToDeviceStatusSharingPreference int sharing) { 4063 if (VDBG) { 4064 logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: " 4065 + subscriptionId); 4066 } 4067 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus", 4068 (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId)); 4069 } 4070 4071 /** 4072 * Returns the user-chosen device to device status sharing preference 4073 * @param subscriptionId Subscription id of subscription 4074 * @return The device to device status sharing preference 4075 * 4076 * @throws SecurityException if the caller doesn't have permissions required. 4077 * @throws UnsupportedOperationException If the device does not have 4078 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4079 */ getDeviceToDeviceStatusSharingPreference( int subscriptionId)4080 public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference( 4081 int subscriptionId) { 4082 if (VDBG) { 4083 logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId); 4084 } 4085 return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING, 4086 D2D_SHARING_DISABLED, mContext); 4087 } 4088 4089 /** 4090 * Set the list of contacts that allow device to device status sharing for a subscription id. 4091 * The setting app uses this method to indicate with whom they wish to share device to device 4092 * status information. 4093 * 4094 * @param subscriptionId The subscription id. 4095 * @param contacts The list of contacts that allow device to device status sharing. 4096 * 4097 * @throws SecurityException if the caller doesn't have permissions required. 4098 * @throws UnsupportedOperationException If the device does not have 4099 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4100 */ 4101 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setDeviceToDeviceStatusSharingContacts(int subscriptionId, @NonNull List<Uri> contacts)4102 public void setDeviceToDeviceStatusSharingContacts(int subscriptionId, 4103 @NonNull List<Uri> contacts) { 4104 String contactString = serializeUriLists(contacts); 4105 if (VDBG) { 4106 logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString 4107 + " subId: " + subscriptionId); 4108 } 4109 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus", 4110 (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts), 4111 subscriptionId)); 4112 } 4113 4114 /** 4115 * Get the list of contacts that allow device to device status sharing. 4116 * 4117 * @param subscriptionId Subscription id. 4118 * 4119 * @return The list of contacts that allow device to device status sharing. 4120 * 4121 * @throws UnsupportedOperationException If the device does not have 4122 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4123 */ getDeviceToDeviceStatusSharingContacts(int subscriptionId)4124 public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(int subscriptionId) { 4125 String result = getStringSubscriptionProperty(mContext, subscriptionId, 4126 D2D_STATUS_SHARING_SELECTED_CONTACTS); 4127 if (result != null) { 4128 try { 4129 byte[] b = Base64.decode(result, Base64.DEFAULT); 4130 ByteArrayInputStream bis = new ByteArrayInputStream(b); 4131 ObjectInputStream ois = new ObjectInputStream(bis); 4132 List<String> contacts = ArrayList.class.cast(ois.readObject()); 4133 List<Uri> uris = new ArrayList<>(); 4134 for (String contact : contacts) { 4135 uris.add(Uri.parse(contact)); 4136 } 4137 return uris; 4138 } catch (IOException e) { 4139 logd("getDeviceToDeviceStatusSharingContacts IO exception"); 4140 } catch (ClassNotFoundException e) { 4141 logd("getDeviceToDeviceStatusSharingContacts ClassNotFound exception"); 4142 } 4143 } 4144 return new ArrayList<>(); 4145 } 4146 4147 /** 4148 * Get the active subscription id by logical SIM slot index. 4149 * 4150 * @param slotIndex The logical SIM slot index. 4151 * @return The active subscription id. 4152 * 4153 * @throws IllegalArgumentException if the provided slot index is invalid. 4154 * @throws SecurityException if callers do not hold the required permission. 4155 * @throws UnsupportedOperationException If the device does not have 4156 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4157 * 4158 * @hide 4159 */ 4160 @SystemApi 4161 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getEnabledSubscriptionId(int slotIndex)4162 public int getEnabledSubscriptionId(int slotIndex) { 4163 int subId = INVALID_SUBSCRIPTION_ID; 4164 4165 try { 4166 ISub iSub = TelephonyManager.getSubscriptionService(); 4167 if (iSub != null) { 4168 subId = iSub.getEnabledSubscriptionId(slotIndex); 4169 } 4170 } catch (RemoteException ex) { 4171 // ignore it 4172 } 4173 4174 if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId); 4175 return subId; 4176 } 4177 4178 private interface CallISubMethodHelper { callMethod(ISub iSub)4179 int callMethod(ISub iSub) throws RemoteException; 4180 } 4181 setSubscriptionPropertyHelper(int subId, String methodName, CallISubMethodHelper helper)4182 private int setSubscriptionPropertyHelper(int subId, String methodName, 4183 CallISubMethodHelper helper) { 4184 if (!isValidSubscriptionId(subId)) { 4185 logd("[" + methodName + "]" + "- fail"); 4186 return -1; 4187 } 4188 4189 int result = 0; 4190 4191 try { 4192 ISub iSub = TelephonyManager.getSubscriptionService(); 4193 if (iSub != null) { 4194 result = helper.callMethod(iSub); 4195 } 4196 } catch (RemoteException ex) { 4197 // ignore it 4198 } 4199 4200 return result; 4201 } 4202 4203 /** 4204 * Get active data subscription id. Active data subscription refers to the subscription 4205 * currently chosen to provide cellular internet connection to the user. This may be 4206 * different from {@link #getDefaultDataSubscriptionId()}. 4207 * 4208 * @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if 4209 * not. 4210 * 4211 * @see TelephonyCallback.ActiveDataSubscriptionIdListener 4212 */ getActiveDataSubscriptionId()4213 public static int getActiveDataSubscriptionId() { 4214 return sGetActiveDataSubscriptionIdCache.query(null); 4215 } 4216 4217 /** 4218 * Helper method that puts a subscription id on an intent with the constants: 4219 * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX. 4220 * Both constants are used to support backwards compatibility. Once we know we got all places, 4221 * we can remove PhoneConstants.SUBSCRIPTION_KEY. 4222 * @param intent Intent to put sub id on. 4223 * @param subId SubscriptionId to put on intent. 4224 * 4225 * @hide 4226 */ putSubscriptionIdExtra(Intent intent, int subId)4227 public static void putSubscriptionIdExtra(Intent intent, int subId) { 4228 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); 4229 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 4230 } 4231 4232 /** @hide */ invalidateSubscriptionManagerServiceCaches()4233 public static void invalidateSubscriptionManagerServiceCaches() { 4234 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY); 4235 } 4236 4237 /** 4238 * Allows a test process to disable client-side caching operations. 4239 * 4240 * @hide 4241 */ disableCaching()4242 public static void disableCaching() { 4243 sGetDefaultSubIdCacheAsUser.disableLocal(); 4244 sGetDefaultDataSubIdCache.disableLocal(); 4245 sGetActiveDataSubscriptionIdCache.disableLocal(); 4246 sGetDefaultSmsSubIdCacheAsUser.disableLocal(); 4247 sGetSlotIndexCache.disableLocal(); 4248 sGetSubIdCache.disableLocal(); 4249 sGetPhoneIdCache.disableLocal(); 4250 } 4251 4252 /** 4253 * Clears all process-local binder caches. 4254 * 4255 * @hide */ clearCaches()4256 public static void clearCaches() { 4257 sGetDefaultSubIdCacheAsUser.clear(); 4258 sGetDefaultDataSubIdCache.clear(); 4259 sGetActiveDataSubscriptionIdCache.clear(); 4260 sGetDefaultSmsSubIdCacheAsUser.clear(); 4261 sGetSlotIndexCache.clear(); 4262 sGetSubIdCache.clear(); 4263 sGetPhoneIdCache.clear(); 4264 } 4265 4266 /** 4267 * Called to retrieve SIM-specific settings data to be backed up. 4268 * 4269 * @return data in byte[] to be backed up. 4270 * 4271 * @hide 4272 */ 4273 @NonNull 4274 @SystemApi 4275 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getAllSimSpecificSettingsForBackup()4276 public byte[] getAllSimSpecificSettingsForBackup() { 4277 Bundle bundle = mContext.getContentResolver().call( 4278 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, 4279 GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null); 4280 return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA); 4281 } 4282 4283 /** 4284 * Called during setup wizard restore flow to attempt to restore the backed up sim-specific 4285 * configs to device for all existing SIMs in the subscription database {@link SimInfo}. 4286 * Internally, it will store the backup data in an internal file. This file will persist on 4287 * device for device's lifetime and will be used later on when a SIM is inserted to restore that 4288 * specific SIM's settings. End result is subscription database is modified to match any backed 4289 * up configs for the appropriate inserted SIMs. 4290 * 4291 * <p> 4292 * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any 4293 * {@link SimInfo} entry is updated as the result of this method call. 4294 * 4295 * @param data with the sim specific configs to be backed up. 4296 * 4297 * @throws UnsupportedOperationException If the device does not have 4298 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4299 * @hide 4300 */ 4301 @SystemApi 4302 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) restoreAllSimSpecificSettingsFromBackup(@onNull byte[] data)4303 public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) { 4304 try { 4305 ISub iSub = TelephonyManager.getSubscriptionService(); 4306 if (iSub != null) { 4307 iSub.restoreAllSimSpecificSettingsFromBackup(data); 4308 } else { 4309 throw new IllegalStateException("subscription service unavailable."); 4310 } 4311 } catch (RemoteException ex) { 4312 if (!isSystemProcess()) { 4313 ex.rethrowAsRuntimeException(); 4314 } 4315 } 4316 } 4317 4318 /** 4319 * Returns the phone number for the given {@code subscriptionId} and {@code source}, 4320 * or an empty string if not available. 4321 * 4322 * <p>General apps that need to know the phone number should use {@link #getPhoneNumber(int)} 4323 * instead. This API may be suitable specific apps that needs to know the phone number from 4324 * a specific source. For example, a carrier app needs to know exactly what's on 4325 * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number 4326 * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated. 4327 * 4328 * <p>The API provides no guarantees of what format the number is in: the format can vary 4329 * depending on the {@code source} and the network etc. Programmatic parsing should be done 4330 * cautiously, for example, after formatting the number to a consistent format with 4331 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}. 4332 * 4333 * <p>Note the assumption is that one subscription (which usually means one SIM) has 4334 * only one phone number. The multiple sources backup each other so hopefully at least one 4335 * is available. For example, for a carrier that doesn't typically set phone numbers 4336 * on {@link #PHONE_NUMBER_SOURCE_UICC UICC}, the source {@link #PHONE_NUMBER_SOURCE_IMS IMS} 4337 * may provide one. Or, a carrier may decide to provide the phone number via source 4338 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} if neither source UICC nor IMS is available. 4339 * 4340 * <p>The availability and correctness of the phone number depends on the underlying source 4341 * and the network etc. Additional verification is needed to use this number for 4342 * security-related or other sensitive scenarios. 4343 * 4344 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} 4345 * for the default one. 4346 * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants. 4347 * 4348 * @return the phone number, or an empty string if not available. 4349 * 4350 * @throws IllegalArgumentException if {@code source} is invalid. 4351 * @throws IllegalStateException if the telephony process is not currently available. 4352 * @throws SecurityException if the caller doesn't have permissions required. 4353 * @throws UnsupportedOperationException If the device does not have 4354 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4355 * 4356 * @see #PHONE_NUMBER_SOURCE_UICC 4357 * @see #PHONE_NUMBER_SOURCE_CARRIER 4358 * @see #PHONE_NUMBER_SOURCE_IMS 4359 */ 4360 @RequiresPermission(anyOf = { 4361 android.Manifest.permission.READ_PHONE_NUMBERS, 4362 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 4363 "carrier privileges", 4364 }) 4365 @NonNull getPhoneNumber(int subscriptionId, @PhoneNumberSource int source)4366 public String getPhoneNumber(int subscriptionId, @PhoneNumberSource int source) { 4367 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) { 4368 subscriptionId = getDefaultSubscriptionId(); 4369 } 4370 if (source != PHONE_NUMBER_SOURCE_UICC 4371 && source != PHONE_NUMBER_SOURCE_CARRIER 4372 && source != PHONE_NUMBER_SOURCE_IMS) { 4373 throw new IllegalArgumentException("invalid source " + source); 4374 } 4375 try { 4376 ISub iSub = TelephonyManager.getSubscriptionService(); 4377 if (iSub != null) { 4378 return iSub.getPhoneNumber(subscriptionId, source, 4379 mContext.getOpPackageName(), mContext.getAttributionTag()); 4380 } else { 4381 throw new IllegalStateException("subscription service unavailable."); 4382 } 4383 } catch (RemoteException ex) { 4384 throw ex.rethrowAsRuntimeException(); 4385 } 4386 } 4387 4388 /** 4389 * Returns the phone number for the given {@code subId}, or an empty string if 4390 * not available. 4391 * 4392 * <p>This API is suitable for general apps that needs to know the phone number. 4393 * For specific apps that needs to know the phone number provided by a specific source, 4394 * {@link #getPhoneNumber(int, int)} may be suitable. 4395 * 4396 * <p>This API is built up on {@link #getPhoneNumber(int, int)}, but picks 4397 * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER} 4398 * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}. 4399 * 4400 * <p>The API provides no guarantees of what format the number is in: the format can vary 4401 * depending on the underlying source and the network etc. Programmatic parsing should be done 4402 * cautiously, for example, after formatting the number to a consistent format with 4403 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}. 4404 * 4405 * <p>The availability and correctness of the phone number depends on the underlying source 4406 * and the network etc. Additional verification is needed to use this number for 4407 * security-related or other sensitive scenarios. 4408 * 4409 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} 4410 * for the default one. 4411 * @return the phone number, or an empty string if not available. 4412 * 4413 * @throws IllegalStateException if the telephony process is not currently available. 4414 * @throws SecurityException if the caller doesn't have permissions required. 4415 * @throws UnsupportedOperationException If the device does not have 4416 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4417 * 4418 * @see #getPhoneNumber(int, int) 4419 */ 4420 @RequiresPermission(anyOf = { 4421 android.Manifest.permission.READ_PHONE_NUMBERS, 4422 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 4423 "carrier privileges", 4424 }) 4425 @NonNull getPhoneNumber(int subscriptionId)4426 public String getPhoneNumber(int subscriptionId) { 4427 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) { 4428 subscriptionId = getDefaultSubscriptionId(); 4429 } 4430 try { 4431 ISub iSub = TelephonyManager.getSubscriptionService(); 4432 if (iSub != null) { 4433 return iSub.getPhoneNumberFromFirstAvailableSource(subscriptionId, 4434 mContext.getOpPackageName(), mContext.getAttributionTag()); 4435 } else { 4436 throw new IllegalStateException("subscription service unavailable."); 4437 } 4438 } catch (RemoteException ex) { 4439 throw ex.rethrowAsRuntimeException(); 4440 } 4441 } 4442 4443 /** 4444 * Sets the phone number for the given {@code subId} for source 4445 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier}. 4446 * Sets an empty string to remove the previously set phone number. 4447 * 4448 * <p>The API is suitable for carrier apps to provide a phone number, for example when 4449 * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly. 4450 * 4451 * <p>It's recommended that the phone number is formatted to well-known formats, 4452 * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods. 4453 * 4454 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} 4455 * for the default one. 4456 * @param number the phone number, or an empty string to remove the previously set number. 4457 * @throws IllegalStateException if the telephony process is not currently available. 4458 * @throws NullPointerException if {@code number} is {@code null}. 4459 * @throws SecurityException if the caller doesn't have permissions required. 4460 * @throws UnsupportedOperationException If the device does not have 4461 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. 4462 */ 4463 @RequiresPermission("carrier privileges") setCarrierPhoneNumber(int subscriptionId, @NonNull String number)4464 public void setCarrierPhoneNumber(int subscriptionId, @NonNull String number) { 4465 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) { 4466 subscriptionId = getDefaultSubscriptionId(); 4467 } 4468 if (number == null) { 4469 throw new NullPointerException("invalid number null"); 4470 } 4471 try { 4472 ISub iSub = TelephonyManager.getSubscriptionService(); 4473 if (iSub != null) { 4474 iSub.setPhoneNumber(subscriptionId, PHONE_NUMBER_SOURCE_CARRIER, number, 4475 mContext.getOpPackageName(), mContext.getAttributionTag()); 4476 } else { 4477 throw new IllegalStateException("subscription service unavailable."); 4478 } 4479 } catch (RemoteException ex) { 4480 throw ex.rethrowAsRuntimeException(); 4481 } 4482 } 4483 4484 /** 4485 * Set the preferred usage setting. 4486 * 4487 * The cellular usage setting is a switch which controls the mode of operation for the cellular 4488 * radio to either require or not require voice service. It is not managed via Android’s 4489 * Settings. 4490 * 4491 * @param subscriptionId the subId of the subscription. 4492 * @param usageSetting the requested usage setting. 4493 * 4494 * @throws IllegalStateException if a specific mode or setting the mode is not supported on a 4495 * particular device. 4496 * 4497 * <p>Requires {@link android.Manifest.permission#MODIFY_PHONE_STATE} 4498 * or that the calling app has CarrierPrivileges for the given subscription. 4499 * 4500 * Note: This method will not allow the setting of USAGE_SETTING_UNKNOWN. 4501 * 4502 * @hide 4503 */ 4504 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) setUsageSetting(int subscriptionId, @UsageSetting int usageSetting)4505 void setUsageSetting(int subscriptionId, @UsageSetting int usageSetting) { 4506 if (VDBG) logd("[setUsageSetting]+ setting:" + usageSetting + " subId:" + subscriptionId); 4507 setSubscriptionPropertyHelper(subscriptionId, "setUsageSetting", 4508 (iSub)-> iSub.setUsageSetting( 4509 usageSetting, subscriptionId, mContext.getOpPackageName())); 4510 } 4511 4512 /** 4513 * Convert phone number source to string. 4514 * 4515 * @param source The phone name source. 4516 * 4517 * @return The phone name source in string format. 4518 * 4519 * @hide 4520 */ 4521 @NonNull phoneNumberSourceToString(@honeNumberSource int source)4522 public static String phoneNumberSourceToString(@PhoneNumberSource int source) { 4523 switch (source) { 4524 case SubscriptionManager.PHONE_NUMBER_SOURCE_UICC: return "UICC"; 4525 case SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER: return "CARRIER"; 4526 case SubscriptionManager.PHONE_NUMBER_SOURCE_IMS: return "IMS"; 4527 default: 4528 return "UNKNOWN(" + source + ")"; 4529 } 4530 } 4531 4532 /** 4533 * Convert display name source to string. 4534 * 4535 * @param source The display name source. 4536 * @return The display name source in string format. 4537 * 4538 * @hide 4539 */ 4540 @NonNull displayNameSourceToString( @ubscriptionManager.SimDisplayNameSource int source)4541 public static String displayNameSourceToString( 4542 @SubscriptionManager.SimDisplayNameSource int source) { 4543 switch (source) { 4544 case SubscriptionManager.NAME_SOURCE_UNKNOWN: return "UNKNOWN"; 4545 case SubscriptionManager.NAME_SOURCE_CARRIER_ID: return "CARRIER_ID"; 4546 case SubscriptionManager.NAME_SOURCE_SIM_SPN: return "SIM_SPN"; 4547 case SubscriptionManager.NAME_SOURCE_USER_INPUT: return "USER_INPUT"; 4548 case SubscriptionManager.NAME_SOURCE_CARRIER: return "CARRIER"; 4549 case SubscriptionManager.NAME_SOURCE_SIM_PNN: return "SIM_PNN"; 4550 default: 4551 return "UNKNOWN(" + source + ")"; 4552 } 4553 } 4554 4555 /** 4556 * Convert subscription type to string. 4557 * 4558 * @param type The subscription type. 4559 * @return The subscription type in string format. 4560 * 4561 * @hide 4562 */ 4563 @NonNull subscriptionTypeToString(@ubscriptionManager.SubscriptionType int type)4564 public static String subscriptionTypeToString(@SubscriptionManager.SubscriptionType int type) { 4565 switch (type) { 4566 case SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM: return "LOCAL_SIM"; 4567 case SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM: return "REMOTE_SIM"; 4568 default: 4569 return "UNKNOWN(" + type + ")"; 4570 } 4571 } 4572 4573 /** 4574 * Convert usage setting to string. 4575 * 4576 * @param usageSetting Usage setting. 4577 * @return The usage setting in string format. 4578 * 4579 * @hide 4580 */ 4581 @NonNull usageSettingToString(@ubscriptionManager.UsageSetting int usageSetting)4582 public static String usageSettingToString(@SubscriptionManager.UsageSetting int usageSetting) { 4583 switch (usageSetting) { 4584 case SubscriptionManager.USAGE_SETTING_UNKNOWN: return "UNKNOWN"; 4585 case SubscriptionManager.USAGE_SETTING_DEFAULT: return "DEFAULT"; 4586 case SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC: return "VOICE_CENTRIC"; 4587 case SubscriptionManager.USAGE_SETTING_DATA_CENTRIC: return "DATA_CENTRIC"; 4588 default: 4589 return "UNKNOWN(" + usageSetting + ")"; 4590 } 4591 } 4592 4593 /** 4594 * Set owner for this subscription. 4595 * 4596 * @param subscriptionId the subId of the subscription. 4597 * @param groupOwner The group owner to assign to the subscription 4598 * 4599 * @throws SecurityException if caller is not authorized. 4600 * 4601 * @hide 4602 */ 4603 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setGroupOwner(int subscriptionId, @NonNull String groupOwner)4604 public void setGroupOwner(int subscriptionId, @NonNull String groupOwner) { 4605 try { 4606 ISub iSub = TelephonyManager.getSubscriptionService(); 4607 if (iSub != null) { 4608 iSub.setGroupOwner(subscriptionId, groupOwner); 4609 } else { 4610 throw new IllegalStateException("[setGroupOwner]: " 4611 + "subscription service unavailable"); 4612 } 4613 } catch (RemoteException ex) { 4614 ex.rethrowAsRuntimeException(); 4615 } 4616 } 4617 4618 /** 4619 * Set userHandle for a subscription. 4620 * 4621 * Used to set an association between a subscription and a user on the device so that voice 4622 * calling and SMS from that subscription can be associated with that user. 4623 * Data services are always shared between users on the device. 4624 * 4625 * @param subscriptionId the subId of the subscription. 4626 * @param userHandle the userHandle associated with the subscription. 4627 * Pass {@code null} user handle to clear the association. 4628 * 4629 * @throws IllegalArgumentException if subscription is invalid. 4630 * @throws SecurityException if the caller doesn't have permissions required. 4631 * @throws IllegalStateException if subscription service is not available. 4632 * 4633 * @hide 4634 */ 4635 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle)4636 public void setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle) { 4637 if (!isValidSubscriptionId(subscriptionId)) { 4638 throw new IllegalArgumentException("[setSubscriptionUserHandle]: " 4639 + "Invalid subscriptionId: " + subscriptionId); 4640 } 4641 4642 try { 4643 ISub iSub = TelephonyManager.getSubscriptionService(); 4644 if (iSub != null) { 4645 iSub.setSubscriptionUserHandle(userHandle, subscriptionId); 4646 } else { 4647 throw new IllegalStateException("[setSubscriptionUserHandle]: " 4648 + "subscription service unavailable"); 4649 } 4650 } catch (RemoteException ex) { 4651 ex.rethrowAsRuntimeException(); 4652 } 4653 } 4654 4655 /** 4656 * Get UserHandle of this subscription. 4657 * 4658 * Used to get user handle associated with this subscription. 4659 * 4660 * @param subscriptionId the subId of the subscription. 4661 * @return userHandle associated with this subscription 4662 * or {@code null} if subscription is not associated with any user. 4663 * 4664 * @throws IllegalArgumentException if subscription is invalid. 4665 * @throws SecurityException if the caller doesn't have permissions required. 4666 * 4667 * @hide 4668 */ 4669 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) getSubscriptionUserHandle(int subscriptionId)4670 public @Nullable UserHandle getSubscriptionUserHandle(int subscriptionId) { 4671 if (!isValidSubscriptionId(subscriptionId)) { 4672 throw new IllegalArgumentException("[getSubscriptionUserHandle]: " 4673 + "Invalid subscriptionId: " + subscriptionId); 4674 } 4675 4676 try { 4677 ISub iSub = TelephonyManager.getSubscriptionService(); 4678 if (iSub != null) { 4679 return iSub.getSubscriptionUserHandle(subscriptionId); 4680 } else { 4681 Log.e(LOG_TAG, "[getSubscriptionUserHandle]: subscription service unavailable"); 4682 } 4683 } catch (RemoteException ex) { 4684 ex.rethrowAsRuntimeException(); 4685 } 4686 return null; 4687 } 4688 4689 /** 4690 * Check if subscription and user are associated with each other. 4691 * 4692 * @param subscriptionId the subId of the subscription 4693 * @param userHandle user handle of the user 4694 * @return {@code true} if subscription is associated with user 4695 * else {@code false} if subscription is not associated with user. 4696 * 4697 * @throws IllegalArgumentException if subscription doesn't exist. 4698 * @throws SecurityException if the caller doesn't have permissions required. 4699 * 4700 * @hide 4701 */ 4702 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) isSubscriptionAssociatedWithUser(int subscriptionId, @NonNull UserHandle userHandle)4703 public boolean isSubscriptionAssociatedWithUser(int subscriptionId, 4704 @NonNull UserHandle userHandle) { 4705 if (!isValidSubscriptionId(subscriptionId)) { 4706 throw new IllegalArgumentException("[isSubscriptionAssociatedWithUser]: " 4707 + "Invalid subscriptionId: " + subscriptionId); 4708 } 4709 4710 try { 4711 ISub iSub = TelephonyManager.getSubscriptionService(); 4712 if (iSub != null) { 4713 return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle); 4714 } else { 4715 Log.e(LOG_TAG, "[isSubscriptionAssociatedWithUser]: subscription service " 4716 + "unavailable"); 4717 } 4718 } catch (RemoteException ex) { 4719 ex.rethrowAsRuntimeException(); 4720 } 4721 return false; 4722 } 4723 4724 /** 4725 * Returns whether the given subscription is associated with the calling user. 4726 * 4727 * @param subscriptionId the subscription ID of the subscription 4728 * @return {@code true} if the subscription is associated with the user that the current process 4729 * is running in; {@code false} otherwise. 4730 * 4731 * @throws IllegalArgumentException if subscription doesn't exist. 4732 * @throws SecurityException if the caller doesn't have permissions required. 4733 */ 4734 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) 4735 @FlaggedApi(Flags.FLAG_SUBSCRIPTION_USER_ASSOCIATION_QUERY) isSubscriptionAssociatedWithUser(int subscriptionId)4736 public boolean isSubscriptionAssociatedWithUser(int subscriptionId) { 4737 if (!isValidSubscriptionId(subscriptionId)) { 4738 throw new IllegalArgumentException("[isSubscriptionAssociatedWithCallingUser]: " 4739 + "Invalid subscriptionId: " + subscriptionId); 4740 } 4741 4742 try { 4743 ISub iSub = TelephonyManager.getSubscriptionService(); 4744 if (iSub != null) { 4745 return iSub.isSubscriptionAssociatedWithCallingUser(subscriptionId); 4746 } else { 4747 throw new IllegalStateException("subscription service unavailable."); 4748 } 4749 } catch (RemoteException ex) { 4750 ex.rethrowAsRuntimeException(); 4751 } 4752 return false; 4753 } 4754 4755 /** 4756 * Get list of subscriptions associated with user. 4757 * 4758 * @param userHandle user handle of the user 4759 * @return list of subscriptionInfo associated with the user. 4760 * 4761 * @throws SecurityException if the caller doesn't have permissions required. 4762 * @throws IllegalStateException if subscription service is not available. 4763 * 4764 * @hide 4765 */ 4766 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION) getSubscriptionInfoListAssociatedWithUser( @onNull UserHandle userHandle)4767 public @NonNull List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser( 4768 @NonNull UserHandle userHandle) { 4769 try { 4770 ISub iSub = TelephonyManager.getSubscriptionService(); 4771 if (iSub != null) { 4772 return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle); 4773 } else { 4774 Log.e(LOG_TAG, "[getSubscriptionInfoListAssociatedWithUser]: " 4775 + "subscription service unavailable"); 4776 } 4777 } catch (RemoteException ex) { 4778 ex.rethrowAsRuntimeException(); 4779 } 4780 return new ArrayList<>(); 4781 } 4782 4783 /** 4784 * @return the bitmasks combination of all service capabilities. 4785 * @hide 4786 */ getAllServiceCapabilityBitmasks()4787 public static int getAllServiceCapabilityBitmasks() { 4788 return SERVICE_CAPABILITY_VOICE_BITMASK | SERVICE_CAPABILITY_SMS_BITMASK 4789 | SERVICE_CAPABILITY_DATA_BITMASK; 4790 } 4791 4792 /** 4793 * @return The set of service capability from a bitmask combined one. 4794 * @hide 4795 */ 4796 @NonNull 4797 @ServiceCapability getServiceCapabilitiesSet(int combinedServiceCapabilities)4798 public static Set<Integer> getServiceCapabilitiesSet(int combinedServiceCapabilities) { 4799 Set<Integer> capabilities = new HashSet<>(); 4800 for (int i = SERVICE_CAPABILITY_VOICE; i <= SERVICE_CAPABILITY_MAX; i++) { 4801 final int capabilityBitmask = serviceCapabilityToBitmask(i); 4802 if ((combinedServiceCapabilities & capabilityBitmask) == capabilityBitmask) { 4803 capabilities.add(i); 4804 } 4805 } 4806 return Collections.unmodifiableSet(capabilities); 4807 } 4808 4809 /** 4810 * @return The service capability bitmask from a {@link ServiceCapability} value. 4811 * @hide 4812 */ serviceCapabilityToBitmask(@erviceCapability int capability)4813 public static int serviceCapabilityToBitmask(@ServiceCapability int capability) { 4814 return 1 << (capability - 1); 4815 } 4816 4817 /** 4818 * Set the transfer status of the subscriptionInfo of the subId. 4819 * @param subscriptionId The unique SubscriptionInfo key in database. 4820 * @param status The transfer status to change. 4821 * 4822 * 4823 * @hide 4824 */ 4825 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION) 4826 @SystemApi 4827 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) setTransferStatus(int subscriptionId, @TransferStatus int status)4828 public void setTransferStatus(int subscriptionId, @TransferStatus int status) { 4829 try { 4830 ISub iSub = TelephonyManager.getSubscriptionService(); 4831 if (iSub != null) { 4832 iSub.setTransferStatus(subscriptionId, status); 4833 } 4834 } catch (RemoteException ex) { 4835 logd("setTransferStatus for subId = " + subscriptionId + " failed."); 4836 throw ex.rethrowFromSystemServer(); 4837 } 4838 } 4839 } 4840