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.text.TextUtils.formatSimple; 20 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.compat.annotation.UnsupportedAppUsage; 24 import android.content.Context; 25 import android.content.pm.PackageInfo; 26 import android.content.pm.PackageManager; 27 import android.graphics.Bitmap; 28 import android.graphics.Canvas; 29 import android.graphics.Color; 30 import android.graphics.Paint; 31 import android.graphics.PorterDuff; 32 import android.graphics.PorterDuffColorFilter; 33 import android.graphics.Rect; 34 import android.graphics.Typeface; 35 import android.os.Build; 36 import android.os.Parcel; 37 import android.os.ParcelUuid; 38 import android.os.Parcelable; 39 import android.text.TextUtils; 40 import android.util.DisplayMetrics; 41 import android.util.Log; 42 43 import com.android.internal.telephony.util.TelephonyUtils; 44 import com.android.telephony.Rlog; 45 46 import java.util.ArrayList; 47 import java.util.Arrays; 48 import java.util.Collections; 49 import java.util.List; 50 import java.util.Objects; 51 52 /** 53 * A Parcelable class for Subscription Information. 54 */ 55 public class SubscriptionInfo implements Parcelable { 56 57 /** 58 * Size of text to render on the icon. 59 */ 60 private static final int TEXT_SIZE = 16; 61 62 /** 63 * Subscription Identifier, this is a device unique number 64 * and not an index into an array 65 */ 66 private int mId; 67 68 /** 69 * The GID for a SIM that maybe associated with this subscription, empty if unknown 70 */ 71 private String mIccId; 72 73 /** 74 * The index of the slot that currently contains the subscription 75 * and not necessarily unique and maybe INVALID_SLOT_ID if unknown 76 */ 77 private int mSimSlotIndex; 78 79 /** 80 * The name displayed to the user that identifies this subscription 81 */ 82 private CharSequence mDisplayName; 83 84 /** 85 * String that identifies SPN/PLMN 86 * TODO : Add a new field that identifies only SPN for a sim 87 */ 88 private CharSequence mCarrierName; 89 90 /** 91 * The subscription carrier id. 92 * @see TelephonyManager#getSimCarrierId() 93 */ 94 private int mCarrierId; 95 96 /** 97 * The source of the name, NAME_SOURCE_DEFAULT_SOURCE, NAME_SOURCE_SIM_SPN, 98 * NAME_SOURCE_SIM_PNN, or NAME_SOURCE_USER_INPUT. 99 */ 100 private int mNameSource; 101 102 /** 103 * The color to be used for tinting the icon when displaying to the user 104 */ 105 private int mIconTint; 106 107 /** 108 * A number presented to the user identify this subscription 109 */ 110 private String mNumber; 111 112 /** 113 * Data roaming state, DATA_ROAMING_ENABLE, DATA_ROAMING_DISABLE 114 */ 115 private int mDataRoaming; 116 117 /** 118 * SIM Icon bitmap 119 */ 120 private Bitmap mIconBitmap; 121 122 /** 123 * Mobile Country Code 124 */ 125 private String mMcc; 126 127 /** 128 * Mobile Network Code 129 */ 130 private String mMnc; 131 132 /** 133 * EHPLMNs associated with the subscription 134 */ 135 private String[] mEhplmns; 136 137 /** 138 * HPLMNs associated with the subscription 139 */ 140 private String[] mHplmns; 141 142 /** 143 * ISO Country code for the subscription's provider 144 */ 145 private String mCountryIso; 146 147 /** 148 * Whether the subscription is an embedded one. 149 */ 150 private boolean mIsEmbedded; 151 152 /** 153 * The access rules for this subscription, if it is embedded and defines any. 154 * This does not include access rules for non-embedded subscriptions. 155 */ 156 @Nullable 157 private UiccAccessRule[] mNativeAccessRules; 158 159 /** 160 * The carrier certificates for this subscription that are saved in carrier configs. 161 * This does not include access rules from the Uicc, whether embedded or non-embedded. 162 */ 163 @Nullable 164 private UiccAccessRule[] mCarrierConfigAccessRules; 165 166 /** 167 * The string ID of the SIM card. It is the ICCID of the active profile for a UICC card and the 168 * EID for an eUICC card. 169 */ 170 private String mCardString; 171 172 /** 173 * The card ID of the SIM card. This maps uniquely to the card string. 174 */ 175 private int mCardId; 176 177 /** 178 * Whether the subscription is opportunistic. 179 */ 180 private boolean mIsOpportunistic; 181 182 /** 183 * A UUID assigned to the subscription group. It returns null if not assigned. 184 * Check {@link SubscriptionManager#createSubscriptionGroup(List)} for more details. 185 */ 186 @Nullable 187 private ParcelUuid mGroupUUID; 188 189 /** 190 * A package name that specifies who created the group. Null if mGroupUUID is null. 191 */ 192 private String mGroupOwner; 193 194 /** 195 * Whether group of the subscription is disabled. 196 * This is only useful if it's a grouped opportunistic subscription. In this case, if all 197 * primary (non-opportunistic) subscriptions in the group are deactivated (unplugged pSIM 198 * or deactivated eSIM profile), we should disable this opportunistic subscription. 199 */ 200 private boolean mIsGroupDisabled = false; 201 202 /** 203 * Profile class, PROFILE_CLASS_TESTING, PROFILE_CLASS_OPERATIONAL 204 * PROFILE_CLASS_PROVISIONING, or PROFILE_CLASS_UNSET. 205 * A profile on the eUICC can be defined as test, operational, provisioning, or unset. 206 * The profile class will be populated from the profile metadata if present. Otherwise, 207 * the profile class defaults to unset if there is no profile metadata or the subscription 208 * is not on an eUICC ({@link #isEmbedded} returns false). 209 */ 210 private int mProfileClass; 211 212 /** 213 * Type of subscription 214 */ 215 private int mSubscriptionType; 216 217 /** 218 * Whether uicc applications are configured to enable or disable. 219 * By default it's true. 220 */ 221 private boolean mAreUiccApplicationsEnabled = true; 222 223 /** 224 * Public copy constructor. 225 * @hide 226 */ SubscriptionInfo(SubscriptionInfo info)227 public SubscriptionInfo(SubscriptionInfo info) { 228 this(info.mId, info.mIccId, info.mSimSlotIndex, info.mDisplayName, info.mCarrierName, 229 info.mNameSource, info.mIconTint, info.mNumber, info.mDataRoaming, info.mIconBitmap, 230 info.mMcc, info.mMnc, info.mCountryIso, info.mIsEmbedded, info.mNativeAccessRules, 231 info.mCardString, info.mCardId, info.mIsOpportunistic, 232 info.mGroupUUID == null ? null : info.mGroupUUID.toString(), info.mIsGroupDisabled, 233 info.mCarrierId, info.mProfileClass, info.mSubscriptionType, info.mGroupOwner, 234 info.mCarrierConfigAccessRules, info.mAreUiccApplicationsEnabled); 235 } 236 237 /** 238 * @hide 239 */ SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, @Nullable UiccAccessRule[] nativeAccessRules, String cardString)240 public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, 241 CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, 242 Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, 243 @Nullable UiccAccessRule[] nativeAccessRules, String cardString) { 244 this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, 245 roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1, 246 false, null, false, TelephonyManager.UNKNOWN_CARRIER_ID, 247 SubscriptionManager.PROFILE_CLASS_UNSET, 248 SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true); 249 } 250 251 /** 252 * @hide 253 */ SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, @Nullable UiccAccessRule[] nativeAccessRules, String cardString, boolean isOpportunistic, @Nullable String groupUUID, int carrierId, int profileClass)254 public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, 255 CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, 256 Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, 257 @Nullable UiccAccessRule[] nativeAccessRules, String cardString, 258 boolean isOpportunistic, @Nullable String groupUUID, int carrierId, int profileClass) { 259 this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, 260 roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1, 261 isOpportunistic, groupUUID, false, carrierId, profileClass, 262 SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true); 263 } 264 265 /** 266 * @hide 267 */ SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, @Nullable UiccAccessRule[] nativeAccessRules, String cardString, int cardId, boolean isOpportunistic, @Nullable String groupUUID, boolean isGroupDisabled, int carrierId, int profileClass, int subType, @Nullable String groupOwner, @Nullable UiccAccessRule[] carrierConfigAccessRules, boolean areUiccApplicationsEnabled)268 public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, 269 CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, 270 Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, 271 @Nullable UiccAccessRule[] nativeAccessRules, String cardString, int cardId, 272 boolean isOpportunistic, @Nullable String groupUUID, boolean isGroupDisabled, 273 int carrierId, int profileClass, int subType, @Nullable String groupOwner, 274 @Nullable UiccAccessRule[] carrierConfigAccessRules, 275 boolean areUiccApplicationsEnabled) { 276 this.mId = id; 277 this.mIccId = iccId; 278 this.mSimSlotIndex = simSlotIndex; 279 this.mDisplayName = displayName; 280 this.mCarrierName = carrierName; 281 this.mNameSource = nameSource; 282 this.mIconTint = iconTint; 283 this.mNumber = number; 284 this.mDataRoaming = roaming; 285 this.mIconBitmap = icon; 286 this.mMcc = mcc; 287 this.mMnc = mnc; 288 this.mCountryIso = countryIso; 289 this.mIsEmbedded = isEmbedded; 290 this.mNativeAccessRules = nativeAccessRules; 291 this.mCardString = cardString; 292 this.mCardId = cardId; 293 this.mIsOpportunistic = isOpportunistic; 294 this.mGroupUUID = groupUUID == null ? null : ParcelUuid.fromString(groupUUID); 295 this.mIsGroupDisabled = isGroupDisabled; 296 this.mCarrierId = carrierId; 297 this.mProfileClass = profileClass; 298 this.mSubscriptionType = subType; 299 this.mGroupOwner = groupOwner; 300 this.mCarrierConfigAccessRules = carrierConfigAccessRules; 301 this.mAreUiccApplicationsEnabled = areUiccApplicationsEnabled; 302 } 303 304 /** 305 * @return the subscription ID. 306 */ getSubscriptionId()307 public int getSubscriptionId() { 308 return this.mId; 309 } 310 311 /** 312 * Returns the ICC ID. 313 * 314 * Starting with API level 29 Security Patch 2021-04-05, returns the ICC ID if the calling app 315 * has been granted the READ_PRIVILEGED_PHONE_STATE permission, has carrier privileges (see 316 * {@link TelephonyManager#hasCarrierPrivileges}), or is a device owner or profile owner that 317 * has been granted the READ_PHONE_STATE permission. The profile owner is an app that owns a 318 * managed profile on the device; for more details see <a 319 * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile 320 * owner access is deprecated and will be removed in a future release. 321 * 322 * @return the ICC ID, or an empty string if one of these requirements is not met 323 */ getIccId()324 public String getIccId() { 325 return this.mIccId; 326 } 327 328 /** 329 * @hide 330 */ clearIccId()331 public void clearIccId() { 332 this.mIccId = ""; 333 } 334 335 /** 336 * @return the slot index of this Subscription's SIM card. 337 */ getSimSlotIndex()338 public int getSimSlotIndex() { 339 return this.mSimSlotIndex; 340 } 341 342 /** 343 * @return the carrier id of this Subscription carrier. 344 * @see TelephonyManager#getSimCarrierId() 345 */ getCarrierId()346 public int getCarrierId() { 347 return this.mCarrierId; 348 } 349 350 /** 351 * @return the name displayed to the user that identifies this subscription 352 */ getDisplayName()353 public CharSequence getDisplayName() { 354 return this.mDisplayName; 355 } 356 357 /** 358 * Sets the name displayed to the user that identifies this subscription 359 * @hide 360 */ 361 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setDisplayName(CharSequence name)362 public void setDisplayName(CharSequence name) { 363 this.mDisplayName = name; 364 } 365 366 /** 367 * @return the name displayed to the user that identifies Subscription provider name 368 */ getCarrierName()369 public CharSequence getCarrierName() { 370 return this.mCarrierName; 371 } 372 373 /** 374 * Sets the name displayed to the user that identifies Subscription provider name 375 * @hide 376 */ setCarrierName(CharSequence name)377 public void setCarrierName(CharSequence name) { 378 this.mCarrierName = name; 379 } 380 381 /** 382 * @return the source of the name, eg NAME_SOURCE_DEFAULT_SOURCE, NAME_SOURCE_SIM_SPN or 383 * NAME_SOURCE_USER_INPUT. 384 * @hide 385 */ 386 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getNameSource()387 public int getNameSource() { 388 return this.mNameSource; 389 } 390 391 /** 392 * @hide 393 */ setAssociatedPlmns(String[] ehplmns, String[] hplmns)394 public void setAssociatedPlmns(String[] ehplmns, String[] hplmns) { 395 mEhplmns = ehplmns; 396 mHplmns = hplmns; 397 } 398 399 /** 400 * Creates and returns an icon {@code Bitmap} to represent this {@code SubscriptionInfo} in a 401 * user interface. 402 * 403 * @param context A {@code Context} to get the {@code DisplayMetrics}s from. 404 * 405 * @return A bitmap icon for this {@code SubscriptionInfo}. 406 */ createIconBitmap(Context context)407 public Bitmap createIconBitmap(Context context) { 408 int width = mIconBitmap.getWidth(); 409 int height = mIconBitmap.getHeight(); 410 DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 411 412 // Create a new bitmap of the same size because it will be modified. 413 Bitmap workingBitmap = Bitmap.createBitmap(metrics, width, height, mIconBitmap.getConfig()); 414 415 Canvas canvas = new Canvas(workingBitmap); 416 Paint paint = new Paint(); 417 418 // Tint the icon with the color. 419 paint.setColorFilter(new PorterDuffColorFilter(mIconTint, PorterDuff.Mode.SRC_ATOP)); 420 canvas.drawBitmap(mIconBitmap, 0, 0, paint); 421 paint.setColorFilter(null); 422 423 // Write the sim slot index. 424 paint.setAntiAlias(true); 425 paint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL)); 426 paint.setColor(Color.WHITE); 427 // Set text size scaled by density 428 paint.setTextSize(TEXT_SIZE * metrics.density); 429 // Convert sim slot index to localized string 430 final String index = formatSimple("%d", mSimSlotIndex + 1); 431 final Rect textBound = new Rect(); 432 paint.getTextBounds(index, 0, 1, textBound); 433 final float xOffset = (width / 2.f) - textBound.centerX(); 434 final float yOffset = (height / 2.f) - textBound.centerY(); 435 canvas.drawText(index, xOffset, yOffset, paint); 436 437 return workingBitmap; 438 } 439 440 /** 441 * A highlight color to use in displaying information about this {@code PhoneAccount}. 442 * 443 * @return A hexadecimal color value. 444 */ getIconTint()445 public int getIconTint() { 446 return mIconTint; 447 } 448 449 /** 450 * Sets the color displayed to the user that identifies this subscription 451 * @hide 452 */ 453 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setIconTint(int iconTint)454 public void setIconTint(int iconTint) { 455 this.mIconTint = iconTint; 456 } 457 458 /** 459 * Returns the number of this subscription. 460 * 461 * Starting with API level 30, returns the number of this subscription if the calling app meets 462 * one of the following requirements: 463 * <ul> 464 * <li>If the calling app's target SDK is API level 29 or lower and the app has been granted 465 * the READ_PHONE_STATE permission. 466 * <li>If the calling app has been granted any of READ_PRIVILEGED_PHONE_STATE, 467 * READ_PHONE_NUMBERS, or READ_SMS. 468 * <li>If the calling app has carrier privileges (see {@link 469 * TelephonyManager#hasCarrierPrivileges}). 470 * <li>If the calling app is the default SMS role holder. 471 * </ul> 472 * 473 * @return the number of this subscription, or an empty string if one of these requirements is 474 * not met 475 */ getNumber()476 public String getNumber() { 477 return mNumber; 478 } 479 480 /** 481 * @hide 482 */ clearNumber()483 public void clearNumber() { 484 mNumber = ""; 485 } 486 487 /** 488 * @return the data roaming state for this subscription, either 489 * {@link SubscriptionManager#DATA_ROAMING_ENABLE} or {@link SubscriptionManager#DATA_ROAMING_DISABLE}. 490 */ getDataRoaming()491 public int getDataRoaming() { 492 return this.mDataRoaming; 493 } 494 495 /** 496 * @return the MCC. 497 * @deprecated Use {@link #getMccString()} instead. 498 */ 499 @Deprecated getMcc()500 public int getMcc() { 501 try { 502 return this.mMcc == null ? 0 : Integer.valueOf(this.mMcc); 503 } catch (NumberFormatException e) { 504 Log.w(SubscriptionInfo.class.getSimpleName(), "MCC string is not a number"); 505 return 0; 506 } 507 } 508 509 /** 510 * @return the MNC. 511 * @deprecated Use {@link #getMncString()} instead. 512 */ 513 @Deprecated getMnc()514 public int getMnc() { 515 try { 516 return this.mMnc == null ? 0 : Integer.valueOf(this.mMnc); 517 } catch (NumberFormatException e) { 518 Log.w(SubscriptionInfo.class.getSimpleName(), "MNC string is not a number"); 519 return 0; 520 } 521 } 522 523 /** 524 * @return The MCC, as a string. 525 */ getMccString()526 public @Nullable String getMccString() { 527 return this.mMcc; 528 } 529 530 /** 531 * @return The MNC, as a string. 532 */ getMncString()533 public @Nullable String getMncString() { 534 return this.mMnc; 535 } 536 537 /** 538 * @return the ISO country code 539 */ getCountryIso()540 public String getCountryIso() { 541 return this.mCountryIso; 542 } 543 544 /** @return whether the subscription is an eUICC one. */ isEmbedded()545 public boolean isEmbedded() { 546 return this.mIsEmbedded; 547 } 548 549 /** 550 * An opportunistic subscription connects to a network that is 551 * limited in functionality and / or coverage. 552 * 553 * @return whether subscription is opportunistic. 554 */ isOpportunistic()555 public boolean isOpportunistic() { 556 return mIsOpportunistic; 557 } 558 559 /** 560 * Used in scenarios where different subscriptions are bundled as a group. 561 * It's typically a primary and an opportunistic subscription. (see {@link #isOpportunistic()}) 562 * Such that those subscriptions will have some affiliated behaviors such as opportunistic 563 * subscription may be invisible to the user. 564 * 565 * @return group UUID a String of group UUID if it belongs to a group. Otherwise 566 * it will return null. 567 */ getGroupUuid()568 public @Nullable ParcelUuid getGroupUuid() { 569 return mGroupUUID; 570 } 571 572 /** 573 * @hide 574 */ clearGroupUuid()575 public void clearGroupUuid() { 576 this.mGroupUUID = null; 577 } 578 579 /** 580 * @hide 581 */ getEhplmns()582 public List<String> getEhplmns() { 583 return mEhplmns == null ? Collections.emptyList() : Arrays.asList(mEhplmns); 584 } 585 586 /** 587 * @hide 588 */ getHplmns()589 public List<String> getHplmns() { 590 return mHplmns == null ? Collections.emptyList() : Arrays.asList(mHplmns); 591 } 592 593 /** 594 * Return owner package of group the subscription belongs to. 595 * 596 * @hide 597 */ getGroupOwner()598 public @Nullable String getGroupOwner() { 599 return mGroupOwner; 600 } 601 602 /** 603 * @return the profile class of this subscription. 604 * @hide 605 */ 606 @SystemApi getProfileClass()607 public @SubscriptionManager.ProfileClass int getProfileClass() { 608 return this.mProfileClass; 609 } 610 611 /** 612 * This method returns the type of a subscription. It can be 613 * {@link SubscriptionManager#SUBSCRIPTION_TYPE_LOCAL_SIM} or 614 * {@link SubscriptionManager#SUBSCRIPTION_TYPE_REMOTE_SIM}. 615 * @return the type of subscription 616 */ getSubscriptionType()617 public @SubscriptionManager.SubscriptionType int getSubscriptionType() { 618 return mSubscriptionType; 619 } 620 621 /** 622 * Checks whether the app with the given context is authorized to manage this subscription 623 * according to its metadata. Only supported for embedded subscriptions (if {@link #isEmbedded} 624 * returns true). 625 * 626 * @param context Context of the application to check. 627 * @return whether the app is authorized to manage this subscription per its metadata. 628 * @hide 629 * @deprecated - Do not use. 630 */ 631 @Deprecated canManageSubscription(Context context)632 public boolean canManageSubscription(Context context) { 633 return canManageSubscription(context, context.getPackageName()); 634 } 635 636 /** 637 * Checks whether the given app is authorized to manage this subscription according to its 638 * metadata. Only supported for embedded subscriptions (if {@link #isEmbedded} returns true). 639 * 640 * @param context Any context. 641 * @param packageName Package name of the app to check. 642 * @return whether the app is authorized to manage this subscription per its metadata. 643 * @hide 644 * @deprecated - Do not use. 645 */ 646 @Deprecated canManageSubscription(Context context, String packageName)647 public boolean canManageSubscription(Context context, String packageName) { 648 List<UiccAccessRule> allAccessRules = getAllAccessRules(); 649 if (allAccessRules == null) { 650 return false; 651 } 652 PackageManager packageManager = context.getPackageManager(); 653 PackageInfo packageInfo; 654 try { 655 packageInfo = packageManager.getPackageInfo(packageName, 656 PackageManager.GET_SIGNING_CERTIFICATES); 657 } catch (PackageManager.NameNotFoundException e) { 658 Log.d("SubscriptionInfo", "canManageSubscription: Unknown package: " + packageName, e); 659 return false; 660 } 661 for (UiccAccessRule rule : allAccessRules) { 662 if (rule.getCarrierPrivilegeStatus(packageInfo) 663 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 664 return true; 665 } 666 } 667 return false; 668 } 669 670 /** 671 * @return the {@link UiccAccessRule}s that are stored in Uicc, dictating who 672 * is authorized to manage this subscription. 673 * TODO and fix it properly in R / master: either deprecate this and have 3 APIs 674 * native + carrier + all, or have this return all by default. 675 * @hide 676 */ 677 @SystemApi getAccessRules()678 public @Nullable List<UiccAccessRule> getAccessRules() { 679 if (mNativeAccessRules == null) return null; 680 return Arrays.asList(mNativeAccessRules); 681 } 682 683 /** 684 * @return the {@link UiccAccessRule}s that are both stored on Uicc and in carrierConfigs 685 * dictating who is authorized to manage this subscription. 686 * @hide 687 */ getAllAccessRules()688 public @Nullable List<UiccAccessRule> getAllAccessRules() { 689 List<UiccAccessRule> merged = new ArrayList<>(); 690 if (mNativeAccessRules != null) { 691 merged.addAll(getAccessRules()); 692 } 693 if (mCarrierConfigAccessRules != null) { 694 merged.addAll(Arrays.asList(mCarrierConfigAccessRules)); 695 } 696 return merged.isEmpty() ? null : merged; 697 } 698 699 /** 700 * Returns the card string of the SIM card which contains the subscription. 701 * 702 * Starting with API level 29 Security Patch 2021-04-05, returns the card string if the calling 703 * app has been granted the READ_PRIVILEGED_PHONE_STATE permission, has carrier privileges (see 704 * {@link TelephonyManager#hasCarrierPrivileges}), or is a device owner or profile owner that 705 * has been granted the READ_PHONE_STATE permission. The profile owner is an app that owns a 706 * managed profile on the device; for more details see <a 707 * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile 708 * owner access is deprecated and will be removed in a future release. 709 * 710 * @return the card string of the SIM card which contains the subscription or an empty string 711 * if these requirements are not met. The card string is the ICCID for UICCs or the EID for 712 * eUICCs. 713 * @hide 714 * //TODO rename usages in LPA: UiccSlotUtil.java, UiccSlotsManager.java, UiccSlotInfoTest.java 715 */ getCardString()716 public String getCardString() { 717 return this.mCardString; 718 } 719 720 /** 721 * @hide 722 */ clearCardString()723 public void clearCardString() { 724 this.mCardString = ""; 725 } 726 727 /** 728 * Returns the card ID of the SIM card which contains the subscription (see 729 * {@link UiccCardInfo#getCardId()}. 730 * @return the cardId 731 */ getCardId()732 public int getCardId() { 733 return this.mCardId; 734 } 735 736 /** 737 * Set whether the subscription's group is disabled. 738 * @hide 739 */ setGroupDisabled(boolean isGroupDisabled)740 public void setGroupDisabled(boolean isGroupDisabled) { 741 this.mIsGroupDisabled = isGroupDisabled; 742 } 743 744 /** 745 * Return whether the subscription's group is disabled. 746 * @hide 747 */ 748 @SystemApi isGroupDisabled()749 public boolean isGroupDisabled() { 750 return mIsGroupDisabled; 751 } 752 753 /** 754 * Return whether uicc applications are set to be enabled or disabled. 755 * @hide 756 */ 757 @SystemApi areUiccApplicationsEnabled()758 public boolean areUiccApplicationsEnabled() { 759 return mAreUiccApplicationsEnabled; 760 } 761 762 public static final @android.annotation.NonNull Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() { 763 @Override 764 public SubscriptionInfo createFromParcel(Parcel source) { 765 int id = source.readInt(); 766 String iccId = source.readString(); 767 int simSlotIndex = source.readInt(); 768 CharSequence displayName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 769 CharSequence carrierName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 770 int nameSource = source.readInt(); 771 int iconTint = source.readInt(); 772 String number = source.readString(); 773 int dataRoaming = source.readInt(); 774 String mcc = source.readString(); 775 String mnc = source.readString(); 776 String countryIso = source.readString(); 777 Bitmap iconBitmap = source.readParcelable(Bitmap.class.getClassLoader()); 778 boolean isEmbedded = source.readBoolean(); 779 UiccAccessRule[] nativeAccessRules = source.createTypedArray(UiccAccessRule.CREATOR); 780 String cardString = source.readString(); 781 int cardId = source.readInt(); 782 boolean isOpportunistic = source.readBoolean(); 783 String groupUUID = source.readString(); 784 boolean isGroupDisabled = source.readBoolean(); 785 int carrierid = source.readInt(); 786 int profileClass = source.readInt(); 787 int subType = source.readInt(); 788 String[] ehplmns = source.createStringArray(); 789 String[] hplmns = source.createStringArray(); 790 String groupOwner = source.readString(); 791 UiccAccessRule[] carrierConfigAccessRules = source.createTypedArray( 792 UiccAccessRule.CREATOR); 793 boolean areUiccApplicationsEnabled = source.readBoolean(); 794 795 SubscriptionInfo info = new SubscriptionInfo(id, iccId, simSlotIndex, displayName, 796 carrierName, nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, 797 countryIso, isEmbedded, nativeAccessRules, cardString, cardId, isOpportunistic, 798 groupUUID, isGroupDisabled, carrierid, profileClass, subType, groupOwner, 799 carrierConfigAccessRules, areUiccApplicationsEnabled); 800 info.setAssociatedPlmns(ehplmns, hplmns); 801 return info; 802 } 803 804 @Override 805 public SubscriptionInfo[] newArray(int size) { 806 return new SubscriptionInfo[size]; 807 } 808 }; 809 810 @Override writeToParcel(Parcel dest, int flags)811 public void writeToParcel(Parcel dest, int flags) { 812 dest.writeInt(mId); 813 dest.writeString(mIccId); 814 dest.writeInt(mSimSlotIndex); 815 TextUtils.writeToParcel(mDisplayName, dest, 0); 816 TextUtils.writeToParcel(mCarrierName, dest, 0); 817 dest.writeInt(mNameSource); 818 dest.writeInt(mIconTint); 819 dest.writeString(mNumber); 820 dest.writeInt(mDataRoaming); 821 dest.writeString(mMcc); 822 dest.writeString(mMnc); 823 dest.writeString(mCountryIso); 824 dest.writeParcelable(mIconBitmap, flags); 825 dest.writeBoolean(mIsEmbedded); 826 dest.writeTypedArray(mNativeAccessRules, flags); 827 dest.writeString(mCardString); 828 dest.writeInt(mCardId); 829 dest.writeBoolean(mIsOpportunistic); 830 dest.writeString(mGroupUUID == null ? null : mGroupUUID.toString()); 831 dest.writeBoolean(mIsGroupDisabled); 832 dest.writeInt(mCarrierId); 833 dest.writeInt(mProfileClass); 834 dest.writeInt(mSubscriptionType); 835 dest.writeStringArray(mEhplmns); 836 dest.writeStringArray(mHplmns); 837 dest.writeString(mGroupOwner); 838 dest.writeTypedArray(mCarrierConfigAccessRules, flags); 839 dest.writeBoolean(mAreUiccApplicationsEnabled); 840 } 841 842 @Override describeContents()843 public int describeContents() { 844 return 0; 845 } 846 847 /** 848 * @hide 849 */ givePrintableIccid(String iccId)850 public static String givePrintableIccid(String iccId) { 851 String iccIdToPrint = null; 852 if (iccId != null) { 853 if (iccId.length() > 9 && !TelephonyUtils.IS_DEBUGGABLE) { 854 iccIdToPrint = iccId.substring(0, 9) + Rlog.pii(false, iccId.substring(9)); 855 } else { 856 iccIdToPrint = iccId; 857 } 858 } 859 return iccIdToPrint; 860 } 861 862 @Override toString()863 public String toString() { 864 String iccIdToPrint = givePrintableIccid(mIccId); 865 String cardStringToPrint = givePrintableIccid(mCardString); 866 return "{id=" + mId + " iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex 867 + " carrierId=" + mCarrierId + " displayName=" + mDisplayName 868 + " carrierName=" + mCarrierName + " nameSource=" + mNameSource 869 + " iconTint=" + mIconTint 870 + " number=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mNumber) 871 + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc=" + mMcc 872 + " mnc=" + mMnc + " countryIso=" + mCountryIso + " isEmbedded=" + mIsEmbedded 873 + " nativeAccessRules=" + Arrays.toString(mNativeAccessRules) 874 + " cardString=" + cardStringToPrint + " cardId=" + mCardId 875 + " isOpportunistic=" + mIsOpportunistic + " groupUUID=" + mGroupUUID 876 + " isGroupDisabled=" + mIsGroupDisabled 877 + " profileClass=" + mProfileClass 878 + " ehplmns=" + Arrays.toString(mEhplmns) 879 + " hplmns=" + Arrays.toString(mHplmns) 880 + " subscriptionType=" + mSubscriptionType 881 + " groupOwner=" + mGroupOwner 882 + " carrierConfigAccessRules=" + Arrays.toString(mCarrierConfigAccessRules) 883 + " areUiccApplicationsEnabled=" + mAreUiccApplicationsEnabled + "}"; 884 } 885 886 @Override hashCode()887 public int hashCode() { 888 return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded, 889 mIsOpportunistic, mGroupUUID, mIccId, mNumber, mMcc, mMnc, mCountryIso, mCardString, 890 mCardId, mDisplayName, mCarrierName, mNativeAccessRules, mIsGroupDisabled, 891 mCarrierId, mProfileClass, mGroupOwner, mAreUiccApplicationsEnabled); 892 } 893 894 @Override equals(Object obj)895 public boolean equals(Object obj) { 896 if (obj == null) return false; 897 if (obj == this) return true; 898 899 SubscriptionInfo toCompare; 900 try { 901 toCompare = (SubscriptionInfo) obj; 902 } catch (ClassCastException ex) { 903 return false; 904 } 905 906 return mId == toCompare.mId 907 && mSimSlotIndex == toCompare.mSimSlotIndex 908 && mNameSource == toCompare.mNameSource 909 && mIconTint == toCompare.mIconTint 910 && mDataRoaming == toCompare.mDataRoaming 911 && mIsEmbedded == toCompare.mIsEmbedded 912 && mIsOpportunistic == toCompare.mIsOpportunistic 913 && mIsGroupDisabled == toCompare.mIsGroupDisabled 914 && mAreUiccApplicationsEnabled == toCompare.mAreUiccApplicationsEnabled 915 && mCarrierId == toCompare.mCarrierId 916 && Objects.equals(mGroupUUID, toCompare.mGroupUUID) 917 && Objects.equals(mIccId, toCompare.mIccId) 918 && Objects.equals(mNumber, toCompare.mNumber) 919 && Objects.equals(mMcc, toCompare.mMcc) 920 && Objects.equals(mMnc, toCompare.mMnc) 921 && Objects.equals(mCountryIso, toCompare.mCountryIso) 922 && Objects.equals(mCardString, toCompare.mCardString) 923 && Objects.equals(mCardId, toCompare.mCardId) 924 && Objects.equals(mGroupOwner, toCompare.mGroupOwner) 925 && TextUtils.equals(mDisplayName, toCompare.mDisplayName) 926 && TextUtils.equals(mCarrierName, toCompare.mCarrierName) 927 && Arrays.equals(mNativeAccessRules, toCompare.mNativeAccessRules) 928 && mProfileClass == toCompare.mProfileClass 929 && Arrays.equals(mEhplmns, toCompare.mEhplmns) 930 && Arrays.equals(mHplmns, toCompare.mHplmns); 931 } 932 } 933