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