1 /* 2 * Copyright (C) 2017 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 package android.service.euicc; 17 18 import android.annotation.IntDef; 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.compat.annotation.UnsupportedAppUsage; 23 import android.os.Build; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.service.carrier.CarrierIdentifier; 27 import android.telephony.SubscriptionInfo; 28 import android.telephony.UiccAccessRule; 29 import android.text.TextUtils; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.util.Arrays; 34 import java.util.Collections; 35 import java.util.List; 36 import java.util.Objects; 37 38 /** 39 * Information about an embedded profile (subscription) on an eUICC. 40 * 41 * @hide 42 */ 43 @SystemApi 44 public final class EuiccProfileInfo implements Parcelable { 45 46 /** 47 * Profile policy rules (bit mask) 48 * 49 * @removed mistakenly exposed previously 50 */ 51 @Retention(RetentionPolicy.SOURCE) 52 @IntDef(flag = true, prefix = { "POLICY_RULE_" }, value = { 53 POLICY_RULE_DO_NOT_DISABLE, 54 POLICY_RULE_DO_NOT_DELETE, 55 POLICY_RULE_DELETE_AFTER_DISABLING 56 }) 57 public @interface PolicyRule {} 58 /** Once this profile is enabled, it cannot be disabled. */ 59 public static final int POLICY_RULE_DO_NOT_DISABLE = 1; 60 /** This profile cannot be deleted. */ 61 public static final int POLICY_RULE_DO_NOT_DELETE = 1 << 1; 62 /** This profile should be deleted after being disabled. */ 63 public static final int POLICY_RULE_DELETE_AFTER_DISABLING = 1 << 2; 64 65 /** 66 * Class of the profile 67 * 68 * @removed mistakenly exposed previously 69 */ 70 @Retention(RetentionPolicy.SOURCE) 71 @IntDef(prefix = { "PROFILE_CLASS_" }, value = { 72 PROFILE_CLASS_TESTING, 73 PROFILE_CLASS_PROVISIONING, 74 PROFILE_CLASS_OPERATIONAL, 75 PROFILE_CLASS_UNSET 76 }) 77 public @interface ProfileClass {} 78 /** Testing profiles */ 79 public static final int PROFILE_CLASS_TESTING = 0; 80 /** Provisioning profiles which are pre-loaded on eUICC */ 81 public static final int PROFILE_CLASS_PROVISIONING = 1; 82 /** Operational profiles which can be pre-loaded or downloaded */ 83 public static final int PROFILE_CLASS_OPERATIONAL = 2; 84 /** 85 * Profile class not set. 86 * @hide 87 */ 88 public static final int PROFILE_CLASS_UNSET = -1; 89 90 /** 91 * State of the profile 92 * 93 * @removed mistakenly exposed previously 94 */ 95 @Retention(RetentionPolicy.SOURCE) 96 @IntDef(prefix = { "PROFILE_STATE_" }, value = { 97 PROFILE_STATE_DISABLED, 98 PROFILE_STATE_ENABLED, 99 PROFILE_STATE_UNSET 100 }) 101 public @interface ProfileState {} 102 /** Disabled profiles */ 103 public static final int PROFILE_STATE_DISABLED = 0; 104 /** Enabled profile */ 105 public static final int PROFILE_STATE_ENABLED = 1; 106 /** 107 * Profile state not set. 108 * @hide 109 */ 110 public static final int PROFILE_STATE_UNSET = -1; 111 112 /** The iccid of the subscription. */ 113 private final String mIccid; 114 115 /** An optional nickname for the subscription. */ 116 private final @Nullable String mNickname; 117 118 /** The service provider name for the subscription. */ 119 private final String mServiceProviderName; 120 121 /** The profile name for the subscription. */ 122 private final String mProfileName; 123 124 /** Profile class for the subscription. */ 125 @ProfileClass private final int mProfileClass; 126 127 /** The profile state of the subscription. */ 128 @ProfileState private final int mState; 129 130 /** The operator Id of the subscription. */ 131 private final CarrierIdentifier mCarrierIdentifier; 132 133 /** The policy rules of the subscription. */ 134 @PolicyRule private final int mPolicyRules; 135 136 /** 137 * Optional access rules defining which apps can manage this subscription. If unset, only the 138 * platform can manage it. 139 */ 140 private final @Nullable UiccAccessRule[] mAccessRules; 141 142 public static final @android.annotation.NonNull Creator<EuiccProfileInfo> CREATOR = new Creator<EuiccProfileInfo>() { 143 @Override 144 public EuiccProfileInfo createFromParcel(Parcel in) { 145 return new EuiccProfileInfo(in); 146 } 147 148 @Override 149 public EuiccProfileInfo[] newArray(int size) { 150 return new EuiccProfileInfo[size]; 151 } 152 }; 153 154 // TODO(b/70292228): Remove this method when LPA can be updated. 155 /** 156 * @hide 157 * @deprecated - Do not use. 158 */ 159 @Deprecated 160 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) EuiccProfileInfo(String iccid, @Nullable UiccAccessRule[] accessRules, @Nullable String nickname)161 public EuiccProfileInfo(String iccid, @Nullable UiccAccessRule[] accessRules, 162 @Nullable String nickname) { 163 if (!TextUtils.isDigitsOnly(iccid)) { 164 throw new IllegalArgumentException("iccid contains invalid characters: " + iccid); 165 } 166 this.mIccid = iccid; 167 this.mAccessRules = accessRules; 168 this.mNickname = nickname; 169 170 this.mServiceProviderName = null; 171 this.mProfileName = null; 172 this.mProfileClass = PROFILE_CLASS_UNSET; 173 this.mState = PROFILE_STATE_UNSET; 174 this.mCarrierIdentifier = null; 175 this.mPolicyRules = 0; 176 } 177 EuiccProfileInfo(Parcel in)178 private EuiccProfileInfo(Parcel in) { 179 mIccid = in.readString(); 180 mNickname = in.readString(); 181 mServiceProviderName = in.readString(); 182 mProfileName = in.readString(); 183 mProfileClass = in.readInt(); 184 mState = in.readInt(); 185 byte exist = in.readByte(); 186 if (exist == (byte) 1) { 187 mCarrierIdentifier = CarrierIdentifier.CREATOR.createFromParcel(in); 188 } else { 189 mCarrierIdentifier = null; 190 } 191 mPolicyRules = in.readInt(); 192 mAccessRules = in.createTypedArray(UiccAccessRule.CREATOR); 193 } 194 195 @Override writeToParcel(Parcel dest, int flags)196 public void writeToParcel(Parcel dest, int flags) { 197 dest.writeString(mIccid); 198 dest.writeString(mNickname); 199 dest.writeString(mServiceProviderName); 200 dest.writeString(mProfileName); 201 dest.writeInt(mProfileClass); 202 dest.writeInt(mState); 203 if (mCarrierIdentifier != null) { 204 dest.writeByte((byte) 1); 205 mCarrierIdentifier.writeToParcel(dest, flags); 206 } else { 207 dest.writeByte((byte) 0); 208 } 209 dest.writeInt(mPolicyRules); 210 dest.writeTypedArray(mAccessRules, flags); 211 } 212 213 @Override describeContents()214 public int describeContents() { 215 return 0; 216 } 217 218 /** The builder to build a new {@link EuiccProfileInfo} instance. */ 219 public static final class Builder { 220 private String mIccid; 221 private List<UiccAccessRule> mAccessRules; 222 private String mNickname; 223 private String mServiceProviderName; 224 private String mProfileName; 225 @ProfileClass private int mProfileClass; 226 @ProfileState private int mState; 227 private CarrierIdentifier mCarrierIdentifier; 228 @PolicyRule private int mPolicyRules; 229 Builder(String value)230 public Builder(String value) { 231 if (!TextUtils.isDigitsOnly(value)) { 232 throw new IllegalArgumentException("iccid contains invalid characters: " + value); 233 } 234 mIccid = value; 235 } 236 Builder(EuiccProfileInfo baseProfile)237 public Builder(EuiccProfileInfo baseProfile) { 238 mIccid = baseProfile.mIccid; 239 mNickname = baseProfile.mNickname; 240 mServiceProviderName = baseProfile.mServiceProviderName; 241 mProfileName = baseProfile.mProfileName; 242 mProfileClass = baseProfile.mProfileClass; 243 mState = baseProfile.mState; 244 mCarrierIdentifier = baseProfile.mCarrierIdentifier; 245 mPolicyRules = baseProfile.mPolicyRules; 246 mAccessRules = baseProfile.mAccessRules == null 247 ? Collections.emptyList() 248 : Arrays.asList(baseProfile.mAccessRules); 249 } 250 251 /** Builds the profile instance. */ build()252 public EuiccProfileInfo build() { 253 if (mIccid == null) { 254 throw new IllegalStateException("ICCID must be set for a profile."); 255 } 256 return new EuiccProfileInfo( 257 mIccid, 258 mNickname, 259 mServiceProviderName, 260 mProfileName, 261 mProfileClass, 262 mState, 263 mCarrierIdentifier, 264 mPolicyRules, 265 mAccessRules); 266 } 267 268 /** Sets the iccId of the subscription. */ setIccid(String value)269 public Builder setIccid(String value) { 270 if (!TextUtils.isDigitsOnly(value)) { 271 throw new IllegalArgumentException("iccid contains invalid characters: " + value); 272 } 273 mIccid = value; 274 return this; 275 } 276 277 /** Sets the nickname of the subscription. */ setNickname(String value)278 public Builder setNickname(String value) { 279 mNickname = value; 280 return this; 281 } 282 283 /** Sets the service provider name of the subscription. */ setServiceProviderName(String value)284 public Builder setServiceProviderName(String value) { 285 mServiceProviderName = value; 286 return this; 287 } 288 289 /** Sets the profile name of the subscription. */ setProfileName(String value)290 public Builder setProfileName(String value) { 291 mProfileName = value; 292 return this; 293 } 294 295 /** Sets the profile class of the subscription. */ setProfileClass(@rofileClass int value)296 public Builder setProfileClass(@ProfileClass int value) { 297 mProfileClass = value; 298 return this; 299 } 300 301 /** Sets the state of the subscription. */ setState(@rofileState int value)302 public Builder setState(@ProfileState int value) { 303 mState = value; 304 return this; 305 } 306 307 /** Sets the carrier identifier of the subscription. */ setCarrierIdentifier(CarrierIdentifier value)308 public Builder setCarrierIdentifier(CarrierIdentifier value) { 309 mCarrierIdentifier = value; 310 return this; 311 } 312 313 /** Sets the policy rules of the subscription. */ setPolicyRules(@olicyRule int value)314 public Builder setPolicyRules(@PolicyRule int value) { 315 mPolicyRules = value; 316 return this; 317 } 318 319 /** Sets the access rules of the subscription. */ setUiccAccessRule(@ullable List<UiccAccessRule> value)320 public Builder setUiccAccessRule(@Nullable List<UiccAccessRule> value) { 321 mAccessRules = value; 322 return this; 323 } 324 } 325 EuiccProfileInfo( String iccid, @Nullable String nickname, String serviceProviderName, String profileName, @ProfileClass int profileClass, @ProfileState int state, CarrierIdentifier carrierIdentifier, @PolicyRule int policyRules, @Nullable List<UiccAccessRule> accessRules)326 private EuiccProfileInfo( 327 String iccid, 328 @Nullable String nickname, 329 String serviceProviderName, 330 String profileName, 331 @ProfileClass int profileClass, 332 @ProfileState int state, 333 CarrierIdentifier carrierIdentifier, 334 @PolicyRule int policyRules, 335 @Nullable List<UiccAccessRule> accessRules) { 336 this.mIccid = iccid; 337 this.mNickname = nickname; 338 this.mServiceProviderName = serviceProviderName; 339 this.mProfileName = profileName; 340 this.mProfileClass = profileClass; 341 this.mState = state; 342 this.mCarrierIdentifier = carrierIdentifier; 343 this.mPolicyRules = policyRules; 344 if (accessRules != null && accessRules.size() > 0) { 345 this.mAccessRules = accessRules.toArray(new UiccAccessRule[accessRules.size()]); 346 } else { 347 this.mAccessRules = null; 348 } 349 } 350 351 /** Gets the ICCID string. */ getIccid()352 public String getIccid() { 353 return mIccid; 354 } 355 356 /** Gets the access rules. */ 357 @Nullable getUiccAccessRules()358 public List<UiccAccessRule> getUiccAccessRules() { 359 if (mAccessRules == null) return null; 360 return Arrays.asList(mAccessRules); 361 } 362 363 /** Gets the nickname. */ 364 @Nullable getNickname()365 public String getNickname() { 366 return mNickname; 367 } 368 369 /** Gets the service provider name. */ getServiceProviderName()370 public String getServiceProviderName() { 371 return mServiceProviderName; 372 } 373 374 /** Gets the profile name. */ getProfileName()375 public String getProfileName() { 376 return mProfileName; 377 } 378 379 /** Gets the profile class. */ 380 @ProfileClass getProfileClass()381 public int getProfileClass() { 382 return mProfileClass; 383 } 384 385 /** Gets the state of the subscription. */ 386 @ProfileState getState()387 public int getState() { 388 return mState; 389 } 390 391 /** Gets the carrier identifier. */ getCarrierIdentifier()392 public CarrierIdentifier getCarrierIdentifier() { 393 return mCarrierIdentifier; 394 } 395 396 /** Gets the policy rules. */ 397 @PolicyRule getPolicyRules()398 public int getPolicyRules() { 399 return mPolicyRules; 400 } 401 402 /** Returns whether any policy rule exists. */ hasPolicyRules()403 public boolean hasPolicyRules() { 404 return mPolicyRules != 0; 405 } 406 407 /** Checks whether a certain policy rule exists. */ hasPolicyRule(@olicyRule int policy)408 public boolean hasPolicyRule(@PolicyRule int policy) { 409 return (mPolicyRules & policy) != 0; 410 } 411 412 @Override equals(@ullable Object obj)413 public boolean equals(@Nullable Object obj) { 414 if (this == obj) { 415 return true; 416 } 417 if (obj == null || getClass() != obj.getClass()) { 418 return false; 419 } 420 421 EuiccProfileInfo that = (EuiccProfileInfo) obj; 422 return Objects.equals(mIccid, that.mIccid) 423 && Objects.equals(mNickname, that.mNickname) 424 && Objects.equals(mServiceProviderName, that.mServiceProviderName) 425 && Objects.equals(mProfileName, that.mProfileName) 426 && mProfileClass == that.mProfileClass 427 && mState == that.mState 428 && Objects.equals(mCarrierIdentifier, that.mCarrierIdentifier) 429 && mPolicyRules == that.mPolicyRules 430 && Arrays.equals(mAccessRules, that.mAccessRules); 431 } 432 433 @Override hashCode()434 public int hashCode() { 435 int result = 1; 436 result = 31 * result + Objects.hashCode(mIccid); 437 result = 31 * result + Objects.hashCode(mNickname); 438 result = 31 * result + Objects.hashCode(mServiceProviderName); 439 result = 31 * result + Objects.hashCode(mProfileName); 440 result = 31 * result + mProfileClass; 441 result = 31 * result + mState; 442 result = 31 * result + Objects.hashCode(mCarrierIdentifier); 443 result = 31 * result + mPolicyRules; 444 result = 31 * result + Arrays.hashCode(mAccessRules); 445 return result; 446 } 447 448 @NonNull 449 @Override toString()450 public String toString() { 451 return "EuiccProfileInfo (nickname=" 452 + mNickname 453 + ", serviceProviderName=" 454 + mServiceProviderName 455 + ", profileName=" 456 + mProfileName 457 + ", profileClass=" 458 + mProfileClass 459 + ", state=" 460 + mState 461 + ", CarrierIdentifier=" 462 + mCarrierIdentifier 463 + ", policyRules=" 464 + mPolicyRules 465 + ", accessRules=" 466 + Arrays.toString(mAccessRules) 467 + ", iccid=" 468 + SubscriptionInfo.getPrintableId(mIccid) 469 + ")"; 470 } 471 } 472