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