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