1 /*
2  * Copyright (C) 2018 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.telephony;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.content.pm.PackageManager;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import com.android.internal.telephony.util.TelephonyUtils;
25 import com.android.telephony.Rlog;
26 
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Objects;
32 
33 /**
34  * The UiccCardInfo represents information about a currently inserted UICC or embedded eUICC.
35  */
36 public final class UiccCardInfo implements Parcelable {
37     private final boolean mIsEuicc;
38     private final int mCardId;
39     private final String mEid;
40     private final String mIccId;
41     private final int mPhysicalSlotIndex;
42     private final boolean mIsRemovable;
43     private final boolean mIsMultipleEnabledProfilesSupported;
44     private final List<UiccPortInfo> mPortList;
45     private boolean mIccIdAccessRestricted = false;
46 
47     public static final @NonNull Creator<UiccCardInfo> CREATOR = new Creator<UiccCardInfo>() {
48         @Override
49         public UiccCardInfo createFromParcel(Parcel in) {
50             return new UiccCardInfo(in);
51         }
52 
53         @Override
54         public UiccCardInfo[] newArray(int size) {
55             return new UiccCardInfo[size];
56         }
57     };
58 
UiccCardInfo(Parcel in)59     private UiccCardInfo(Parcel in) {
60         mIsEuicc = in.readBoolean();
61         mCardId = in.readInt();
62         mEid = in.readString8();
63         mIccId = in.readString8();
64         mPhysicalSlotIndex = in.readInt();
65         mIsRemovable = in.readBoolean();
66         mIsMultipleEnabledProfilesSupported = in.readBoolean();
67         mPortList = new ArrayList<UiccPortInfo>();
68         in.readTypedList(mPortList, UiccPortInfo.CREATOR);
69         mIccIdAccessRestricted = in.readBoolean();
70     }
71 
72     @Override
writeToParcel(Parcel dest, int flags)73     public void writeToParcel(Parcel dest, int flags) {
74         dest.writeBoolean(mIsEuicc);
75         dest.writeInt(mCardId);
76         dest.writeString8(mEid);
77         dest.writeString8(mIccId);
78         dest.writeInt(mPhysicalSlotIndex);
79         dest.writeBoolean(mIsRemovable);
80         dest.writeBoolean(mIsMultipleEnabledProfilesSupported);
81         dest.writeTypedList(mPortList, flags);
82         dest.writeBoolean(mIccIdAccessRestricted);
83     }
84 
85     @Override
describeContents()86     public int describeContents() {
87         return 0;
88     }
89 
90     /**
91      * Construct a UiccCardInfo.
92      *
93      * @param isEuicc is a flag to check is eUICC or not
94      * @param cardId is unique ID used to identify a UiccCard.
95      * @param eid is unique eUICC Identifier
96      * @param physicalSlotIndex is unique index referring to a physical SIM slot.
97      * @param isRemovable is a flag to check is removable or embedded
98      * @param isMultipleEnabledProfilesSupported is a flag to check is MEP enabled or not
99      * @param portList has the information regarding port, ICCID and its active status
100      *
101      * @hide
102      */
UiccCardInfo(boolean isEuicc, int cardId, String eid, int physicalSlotIndex, boolean isRemovable, boolean isMultipleEnabledProfilesSupported, @NonNull List<UiccPortInfo> portList)103     public UiccCardInfo(boolean isEuicc, int cardId, String eid, int physicalSlotIndex,
104             boolean isRemovable, boolean isMultipleEnabledProfilesSupported,
105             @NonNull List<UiccPortInfo> portList) {
106         this.mIsEuicc = isEuicc;
107         this.mCardId = cardId;
108         this.mEid = eid;
109         this.mIccId = null;
110         this.mPhysicalSlotIndex = physicalSlotIndex;
111         this.mIsRemovable = isRemovable;
112         this.mIsMultipleEnabledProfilesSupported = isMultipleEnabledProfilesSupported;
113         this.mPortList = portList;
114     }
115 
116     /**
117      * Return whether the UICC is an eUICC.
118      *
119      * @return true if the UICC is an eUICC.
120      */
isEuicc()121     public boolean isEuicc() {
122         return mIsEuicc;
123     }
124 
125     /**
126      * Get the card ID of the UICC. See {@link TelephonyManager#getCardIdForDefaultEuicc()} for more
127      * details on card ID.
128      */
getCardId()129     public int getCardId() {
130         return mCardId;
131     }
132 
133     /**
134      * Get the embedded ID (EID) of the eUICC. If the UiccCardInfo is not an eUICC
135      * (see {@link #isEuicc()}), or the EID is not available, returns null.
136      * <p>
137      * Note that this field may be omitted if the caller does not have the correct permissions
138      * (see {@link TelephonyManager#getUiccCardsInfo()}).
139      */
140     @Nullable
getEid()141     public String getEid() {
142         if (!mIsEuicc) {
143             return null;
144         }
145         return mEid;
146     }
147 
148     /**
149      * Get the ICCID of the UICC. If the ICCID is not availble, returns null.
150      * <p>
151      * Note that this field may be omitted if the caller does not have the correct permissions
152      * (see {@link TelephonyManager#getUiccCardsInfo()}).
153      *
154      * @deprecated with support for MEP(multiple enabled profile)
155      * {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP}, a SIM card can have more than one
156      * ICCID active at the same time. Instead use {@link UiccPortInfo#getIccId()} to retrieve ICCID.
157      * To find {@link UiccPortInfo} use {@link UiccCardInfo#getPorts()}.
158      *
159      * @throws UnsupportedOperationException if the calling app's target SDK is T and beyond.
160      */
161     @Nullable
162     @Deprecated
getIccId()163     public String getIccId() {
164         if (mIccIdAccessRestricted) {
165             throw new UnsupportedOperationException("getIccId() is not supported by UiccCardInfo."
166                 + " Please Use UiccPortInfo API instead");
167         }
168         //always return ICCID from first port.
169         return mPortList.isEmpty() ? null : mPortList.get(0).getIccId();
170     }
171 
172     /**
173      * Gets the slot index for the slot that the UICC is currently inserted in.
174      *
175      * @deprecated use {@link #getPhysicalSlotIndex()}
176      */
177     @Deprecated
getSlotIndex()178     public int getSlotIndex() {
179         return mPhysicalSlotIndex;
180     }
181 
182     /**
183      * Gets the physical slot index for the slot that the UICC is currently inserted in.
184      */
getPhysicalSlotIndex()185     public int getPhysicalSlotIndex() {
186         return mPhysicalSlotIndex;
187     }
188 
189     /**
190      * Return whether the UICC or eUICC is removable.
191      * <p>
192      * UICCs are generally removable, but eUICCs may be removable or built in to the device.
193      *
194      * @return true if the UICC or eUICC is removable
195      */
isRemovable()196     public boolean isRemovable() {
197         return mIsRemovable;
198     }
199 
200     /*
201      * Whether the UICC card supports multiple enabled profile(MEP)
202      * UICCs are generally MEP disabled, there can be only one active profile on the physical
203      * sim card.
204      *
205      * @return {@code true} if the UICC is supporting multiple enabled profile(MEP).
206      */
isMultipleEnabledProfilesSupported()207     public boolean isMultipleEnabledProfilesSupported() {
208         return mIsMultipleEnabledProfilesSupported;
209     }
210 
211     /**
212      * Get information regarding port, ICCID and its active status.
213      *
214      * For device which support {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP}, it should return
215      * more than one {@link UiccPortInfo} object if the card is eUICC.
216      *
217      * @return Collection of {@link UiccPortInfo}
218      */
getPorts()219     public @NonNull Collection<UiccPortInfo> getPorts() {
220         return Collections.unmodifiableList(mPortList);
221     }
222 
223     /**
224      * if the flag is set to {@code true} the calling app is not allowed to access deprecated
225      * {@link #getIccId()}
226      * @param iccIdAccessRestricted is the flag to check if app is allowed to access ICCID
227      *
228      * @hide
229      */
setIccIdAccessRestricted(boolean iccIdAccessRestricted)230     public void setIccIdAccessRestricted(boolean iccIdAccessRestricted) {
231         this.mIccIdAccessRestricted = iccIdAccessRestricted;
232     }
233 
234     @Override
equals(Object obj)235     public boolean equals(Object obj) {
236         if (this == obj) {
237             return true;
238         }
239         if (obj == null || getClass() != obj.getClass()) {
240             return false;
241         }
242 
243         UiccCardInfo that = (UiccCardInfo) obj;
244         return ((mIsEuicc == that.mIsEuicc)
245                 && (mCardId == that.mCardId)
246                 && (Objects.equals(mEid, that.mEid))
247                 && (Objects.equals(mIccId, that.mIccId))
248                 && (mPhysicalSlotIndex == that.mPhysicalSlotIndex)
249                 && (mIsRemovable == that.mIsRemovable)
250                 && (mIsMultipleEnabledProfilesSupported == that.mIsMultipleEnabledProfilesSupported)
251                 && (Objects.equals(mPortList, that.mPortList)));
252     }
253 
254     @Override
hashCode()255     public int hashCode() {
256         return Objects.hash(mIsEuicc, mCardId, mEid, mIccId, mPhysicalSlotIndex, mIsRemovable,
257                 mIsMultipleEnabledProfilesSupported, mPortList);
258     }
259 
260     @Override
toString()261     public String toString() {
262         return "UiccCardInfo (mIsEuicc="
263                 + mIsEuicc
264                 + ", mCardId="
265                 + mCardId
266                 + ", mEid="
267                 + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid)
268                 + ", mPhysicalSlotIndex="
269                 + mPhysicalSlotIndex
270                 + ", mIsRemovable="
271                 + mIsRemovable
272                 + ", mIsMultipleEnabledProfilesSupported="
273                 + mIsMultipleEnabledProfilesSupported
274                 + ", mPortList="
275                 + mPortList
276                 + ", mIccIdAccessRestricted="
277                 + mIccIdAccessRestricted
278                 + ")";
279     }
280 }