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