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