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