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