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