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