460 lines
15 KiB
Java
460 lines
15 KiB
Java
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package android.service.euicc;
|
|
|
|
import android.annotation.IntDef;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.SystemApi;
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
import android.os.Build;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.service.carrier.CarrierIdentifier;
|
|
import android.telephony.UiccAccessRule;
|
|
import android.text.TextUtils;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Information about an embedded profile (subscription) on an eUICC.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public final class EuiccProfileInfo implements Parcelable {
|
|
|
|
/** Profile policy rules (bit mask) */
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@IntDef(flag = true, prefix = { "POLICY_RULE_" }, value = {
|
|
POLICY_RULE_DO_NOT_DISABLE,
|
|
POLICY_RULE_DO_NOT_DELETE,
|
|
POLICY_RULE_DELETE_AFTER_DISABLING
|
|
})
|
|
/** @hide */
|
|
public @interface PolicyRule {}
|
|
/** Once this profile is enabled, it cannot be disabled. */
|
|
public static final int POLICY_RULE_DO_NOT_DISABLE = 1;
|
|
/** This profile cannot be deleted. */
|
|
public static final int POLICY_RULE_DO_NOT_DELETE = 1 << 1;
|
|
/** This profile should be deleted after being disabled. */
|
|
public static final int POLICY_RULE_DELETE_AFTER_DISABLING = 1 << 2;
|
|
|
|
/** Class of the profile */
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@IntDef(prefix = { "PROFILE_CLASS_" }, value = {
|
|
PROFILE_CLASS_TESTING,
|
|
PROFILE_CLASS_PROVISIONING,
|
|
PROFILE_CLASS_OPERATIONAL,
|
|
PROFILE_CLASS_UNSET
|
|
})
|
|
/** @hide */
|
|
public @interface ProfileClass {}
|
|
/** Testing profiles */
|
|
public static final int PROFILE_CLASS_TESTING = 0;
|
|
/** Provisioning profiles which are pre-loaded on eUICC */
|
|
public static final int PROFILE_CLASS_PROVISIONING = 1;
|
|
/** Operational profiles which can be pre-loaded or downloaded */
|
|
public static final int PROFILE_CLASS_OPERATIONAL = 2;
|
|
/**
|
|
* Profile class not set.
|
|
* @hide
|
|
*/
|
|
public static final int PROFILE_CLASS_UNSET = -1;
|
|
|
|
/** State of the profile */
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@IntDef(prefix = { "PROFILE_STATE_" }, value = {
|
|
PROFILE_STATE_DISABLED,
|
|
PROFILE_STATE_ENABLED,
|
|
PROFILE_STATE_UNSET
|
|
})
|
|
/** @hide */
|
|
public @interface ProfileState {}
|
|
/** Disabled profiles */
|
|
public static final int PROFILE_STATE_DISABLED = 0;
|
|
/** Enabled profile */
|
|
public static final int PROFILE_STATE_ENABLED = 1;
|
|
/**
|
|
* Profile state not set.
|
|
* @hide
|
|
*/
|
|
public static final int PROFILE_STATE_UNSET = -1;
|
|
|
|
/** The iccid of the subscription. */
|
|
private final String mIccid;
|
|
|
|
/** An optional nickname for the subscription. */
|
|
private final @Nullable String mNickname;
|
|
|
|
/** The service provider name for the subscription. */
|
|
private final String mServiceProviderName;
|
|
|
|
/** The profile name for the subscription. */
|
|
private final String mProfileName;
|
|
|
|
/** Profile class for the subscription. */
|
|
@ProfileClass private final int mProfileClass;
|
|
|
|
/** The profile state of the subscription. */
|
|
@ProfileState private final int mState;
|
|
|
|
/** The operator Id of the subscription. */
|
|
private final CarrierIdentifier mCarrierIdentifier;
|
|
|
|
/** The policy rules of the subscription. */
|
|
@PolicyRule private final int mPolicyRules;
|
|
|
|
/**
|
|
* Optional access rules defining which apps can manage this subscription. If unset, only the
|
|
* platform can manage it.
|
|
*/
|
|
private final @Nullable UiccAccessRule[] mAccessRules;
|
|
|
|
public static final @android.annotation.NonNull Creator<EuiccProfileInfo> CREATOR = new Creator<EuiccProfileInfo>() {
|
|
@Override
|
|
public EuiccProfileInfo createFromParcel(Parcel in) {
|
|
return new EuiccProfileInfo(in);
|
|
}
|
|
|
|
@Override
|
|
public EuiccProfileInfo[] newArray(int size) {
|
|
return new EuiccProfileInfo[size];
|
|
}
|
|
};
|
|
|
|
// TODO(b/70292228): Remove this method when LPA can be updated.
|
|
/**
|
|
* @hide
|
|
* @deprecated - Do not use.
|
|
*/
|
|
@Deprecated
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
|
public EuiccProfileInfo(String iccid, @Nullable UiccAccessRule[] accessRules,
|
|
@Nullable String nickname) {
|
|
if (!TextUtils.isDigitsOnly(iccid)) {
|
|
throw new IllegalArgumentException("iccid contains invalid characters: " + iccid);
|
|
}
|
|
this.mIccid = iccid;
|
|
this.mAccessRules = accessRules;
|
|
this.mNickname = nickname;
|
|
|
|
this.mServiceProviderName = null;
|
|
this.mProfileName = null;
|
|
this.mProfileClass = PROFILE_CLASS_UNSET;
|
|
this.mState = PROFILE_STATE_UNSET;
|
|
this.mCarrierIdentifier = null;
|
|
this.mPolicyRules = 0;
|
|
}
|
|
|
|
private EuiccProfileInfo(Parcel in) {
|
|
mIccid = in.readString();
|
|
mNickname = in.readString();
|
|
mServiceProviderName = in.readString();
|
|
mProfileName = in.readString();
|
|
mProfileClass = in.readInt();
|
|
mState = in.readInt();
|
|
byte exist = in.readByte();
|
|
if (exist == (byte) 1) {
|
|
mCarrierIdentifier = CarrierIdentifier.CREATOR.createFromParcel(in);
|
|
} else {
|
|
mCarrierIdentifier = null;
|
|
}
|
|
mPolicyRules = in.readInt();
|
|
mAccessRules = in.createTypedArray(UiccAccessRule.CREATOR);
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(Parcel dest, int flags) {
|
|
dest.writeString(mIccid);
|
|
dest.writeString(mNickname);
|
|
dest.writeString(mServiceProviderName);
|
|
dest.writeString(mProfileName);
|
|
dest.writeInt(mProfileClass);
|
|
dest.writeInt(mState);
|
|
if (mCarrierIdentifier != null) {
|
|
dest.writeByte((byte) 1);
|
|
mCarrierIdentifier.writeToParcel(dest, flags);
|
|
} else {
|
|
dest.writeByte((byte) 0);
|
|
}
|
|
dest.writeInt(mPolicyRules);
|
|
dest.writeTypedArray(mAccessRules, flags);
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
/** The builder to build a new {@link EuiccProfileInfo} instance. */
|
|
public static final class Builder {
|
|
private String mIccid;
|
|
private List<UiccAccessRule> mAccessRules;
|
|
private String mNickname;
|
|
private String mServiceProviderName;
|
|
private String mProfileName;
|
|
@ProfileClass private int mProfileClass;
|
|
@ProfileState private int mState;
|
|
private CarrierIdentifier mCarrierIdentifier;
|
|
@PolicyRule private int mPolicyRules;
|
|
|
|
public Builder(String value) {
|
|
if (!TextUtils.isDigitsOnly(value)) {
|
|
throw new IllegalArgumentException("iccid contains invalid characters: " + value);
|
|
}
|
|
mIccid = value;
|
|
}
|
|
|
|
public Builder(EuiccProfileInfo baseProfile) {
|
|
mIccid = baseProfile.mIccid;
|
|
mNickname = baseProfile.mNickname;
|
|
mServiceProviderName = baseProfile.mServiceProviderName;
|
|
mProfileName = baseProfile.mProfileName;
|
|
mProfileClass = baseProfile.mProfileClass;
|
|
mState = baseProfile.mState;
|
|
mCarrierIdentifier = baseProfile.mCarrierIdentifier;
|
|
mPolicyRules = baseProfile.mPolicyRules;
|
|
mAccessRules = baseProfile.mAccessRules == null
|
|
? Collections.emptyList()
|
|
: Arrays.asList(baseProfile.mAccessRules);
|
|
}
|
|
|
|
/** Builds the profile instance. */
|
|
public EuiccProfileInfo build() {
|
|
if (mIccid == null) {
|
|
throw new IllegalStateException("ICCID must be set for a profile.");
|
|
}
|
|
return new EuiccProfileInfo(
|
|
mIccid,
|
|
mNickname,
|
|
mServiceProviderName,
|
|
mProfileName,
|
|
mProfileClass,
|
|
mState,
|
|
mCarrierIdentifier,
|
|
mPolicyRules,
|
|
mAccessRules);
|
|
}
|
|
|
|
/** Sets the iccId of the subscription. */
|
|
public Builder setIccid(String value) {
|
|
if (!TextUtils.isDigitsOnly(value)) {
|
|
throw new IllegalArgumentException("iccid contains invalid characters: " + value);
|
|
}
|
|
mIccid = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the nickname of the subscription. */
|
|
public Builder setNickname(String value) {
|
|
mNickname = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the service provider name of the subscription. */
|
|
public Builder setServiceProviderName(String value) {
|
|
mServiceProviderName = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the profile name of the subscription. */
|
|
public Builder setProfileName(String value) {
|
|
mProfileName = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the profile class of the subscription. */
|
|
public Builder setProfileClass(@ProfileClass int value) {
|
|
mProfileClass = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the state of the subscription. */
|
|
public Builder setState(@ProfileState int value) {
|
|
mState = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the carrier identifier of the subscription. */
|
|
public Builder setCarrierIdentifier(CarrierIdentifier value) {
|
|
mCarrierIdentifier = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the policy rules of the subscription. */
|
|
public Builder setPolicyRules(@PolicyRule int value) {
|
|
mPolicyRules = value;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the access rules of the subscription. */
|
|
public Builder setUiccAccessRule(@Nullable List<UiccAccessRule> value) {
|
|
mAccessRules = value;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
private 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) {
|
|
this.mIccid = iccid;
|
|
this.mNickname = nickname;
|
|
this.mServiceProviderName = serviceProviderName;
|
|
this.mProfileName = profileName;
|
|
this.mProfileClass = profileClass;
|
|
this.mState = state;
|
|
this.mCarrierIdentifier = carrierIdentifier;
|
|
this.mPolicyRules = policyRules;
|
|
if (accessRules != null && accessRules.size() > 0) {
|
|
this.mAccessRules = accessRules.toArray(new UiccAccessRule[accessRules.size()]);
|
|
} else {
|
|
this.mAccessRules = null;
|
|
}
|
|
}
|
|
|
|
/** Gets the ICCID string. */
|
|
public String getIccid() {
|
|
return mIccid;
|
|
}
|
|
|
|
/** Gets the access rules. */
|
|
@Nullable
|
|
public List<UiccAccessRule> getUiccAccessRules() {
|
|
if (mAccessRules == null) return null;
|
|
return Arrays.asList(mAccessRules);
|
|
}
|
|
|
|
/** Gets the nickname. */
|
|
@Nullable
|
|
public String getNickname() {
|
|
return mNickname;
|
|
}
|
|
|
|
/** Gets the service provider name. */
|
|
public String getServiceProviderName() {
|
|
return mServiceProviderName;
|
|
}
|
|
|
|
/** Gets the profile name. */
|
|
public String getProfileName() {
|
|
return mProfileName;
|
|
}
|
|
|
|
/** Gets the profile class. */
|
|
@ProfileClass
|
|
public int getProfileClass() {
|
|
return mProfileClass;
|
|
}
|
|
|
|
/** Gets the state of the subscription. */
|
|
@ProfileState
|
|
public int getState() {
|
|
return mState;
|
|
}
|
|
|
|
/** Gets the carrier identifier. */
|
|
public CarrierIdentifier getCarrierIdentifier() {
|
|
return mCarrierIdentifier;
|
|
}
|
|
|
|
/** Gets the policy rules. */
|
|
@PolicyRule
|
|
public int getPolicyRules() {
|
|
return mPolicyRules;
|
|
}
|
|
|
|
/** Returns whether any policy rule exists. */
|
|
public boolean hasPolicyRules() {
|
|
return mPolicyRules != 0;
|
|
}
|
|
|
|
/** Checks whether a certain policy rule exists. */
|
|
public boolean hasPolicyRule(@PolicyRule int policy) {
|
|
return (mPolicyRules & policy) != 0;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(@Nullable Object obj) {
|
|
if (this == obj) {
|
|
return true;
|
|
}
|
|
if (obj == null || getClass() != obj.getClass()) {
|
|
return false;
|
|
}
|
|
|
|
EuiccProfileInfo that = (EuiccProfileInfo) obj;
|
|
return Objects.equals(mIccid, that.mIccid)
|
|
&& Objects.equals(mNickname, that.mNickname)
|
|
&& Objects.equals(mServiceProviderName, that.mServiceProviderName)
|
|
&& Objects.equals(mProfileName, that.mProfileName)
|
|
&& mProfileClass == that.mProfileClass
|
|
&& mState == that.mState
|
|
&& Objects.equals(mCarrierIdentifier, that.mCarrierIdentifier)
|
|
&& mPolicyRules == that.mPolicyRules
|
|
&& Arrays.equals(mAccessRules, that.mAccessRules);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
int result = 1;
|
|
result = 31 * result + Objects.hashCode(mIccid);
|
|
result = 31 * result + Objects.hashCode(mNickname);
|
|
result = 31 * result + Objects.hashCode(mServiceProviderName);
|
|
result = 31 * result + Objects.hashCode(mProfileName);
|
|
result = 31 * result + mProfileClass;
|
|
result = 31 * result + mState;
|
|
result = 31 * result + Objects.hashCode(mCarrierIdentifier);
|
|
result = 31 * result + mPolicyRules;
|
|
result = 31 * result + Arrays.hashCode(mAccessRules);
|
|
return result;
|
|
}
|
|
|
|
@NonNull
|
|
@Override
|
|
public String toString() {
|
|
return "EuiccProfileInfo (nickname="
|
|
+ mNickname
|
|
+ ", serviceProviderName="
|
|
+ mServiceProviderName
|
|
+ ", profileName="
|
|
+ mProfileName
|
|
+ ", profileClass="
|
|
+ mProfileClass
|
|
+ ", state="
|
|
+ mState
|
|
+ ", CarrierIdentifier="
|
|
+ mCarrierIdentifier
|
|
+ ", policyRules="
|
|
+ mPolicyRules
|
|
+ ", accessRules="
|
|
+ Arrays.toString(mAccessRules)
|
|
+ ")";
|
|
}
|
|
}
|