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.IntDef; 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.content.pm.PackageManager; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.ArrayList; 29 import java.util.Collection; 30 import java.util.Collections; 31 import java.util.List; 32 import java.util.Objects; 33 34 /** 35 * Class for the information of a UICC slot. 36 * @hide 37 */ 38 @SystemApi 39 public class UiccSlotInfo implements Parcelable { 40 /** 41 * Card state. 42 * @hide 43 */ 44 @Retention(RetentionPolicy.SOURCE) 45 @IntDef(prefix = { "CARD_STATE_INFO_" }, value = { 46 CARD_STATE_INFO_ABSENT, 47 CARD_STATE_INFO_PRESENT, 48 CARD_STATE_INFO_ERROR, 49 CARD_STATE_INFO_RESTRICTED 50 }) 51 public @interface CardStateInfo {} 52 53 /** Card state absent. */ 54 public static final int CARD_STATE_INFO_ABSENT = 1; 55 56 /** Card state present. */ 57 public static final int CARD_STATE_INFO_PRESENT = 2; 58 59 /** Card state error. */ 60 public static final int CARD_STATE_INFO_ERROR = 3; 61 62 /** Card state restricted. */ 63 public static final int CARD_STATE_INFO_RESTRICTED = 4; 64 65 private final boolean mIsActive; 66 private final boolean mIsEuicc; 67 private final String mCardId; 68 private final @CardStateInfo int mCardStateInfo; 69 private final int mLogicalSlotIdx; 70 private final boolean mIsExtendedApduSupported; 71 private final boolean mIsRemovable; 72 private final List<UiccPortInfo> mPortList; 73 private boolean mLogicalSlotAccessRestricted = false; 74 75 public static final @NonNull Creator<UiccSlotInfo> CREATOR = new Creator<UiccSlotInfo>() { 76 @Override 77 public UiccSlotInfo createFromParcel(Parcel in) { 78 return new UiccSlotInfo(in); 79 } 80 81 @Override 82 public UiccSlotInfo[] newArray(int size) { 83 return new UiccSlotInfo[size]; 84 } 85 }; 86 UiccSlotInfo(Parcel in)87 private UiccSlotInfo(Parcel in) { 88 mIsActive = in.readBoolean(); 89 mIsEuicc = in.readBoolean(); 90 mCardId = in.readString8(); 91 mCardStateInfo = in.readInt(); 92 mLogicalSlotIdx = in.readInt(); 93 mIsExtendedApduSupported = in.readBoolean(); 94 mIsRemovable = in.readBoolean(); 95 mPortList = new ArrayList<UiccPortInfo>(); 96 in.readTypedList(mPortList, UiccPortInfo.CREATOR); 97 mLogicalSlotAccessRestricted = in.readBoolean(); 98 } 99 100 @Override writeToParcel(Parcel dest, int flags)101 public void writeToParcel(Parcel dest, int flags) { 102 dest.writeBoolean(mIsActive); 103 dest.writeBoolean(mIsEuicc); 104 dest.writeString8(mCardId); 105 dest.writeInt(mCardStateInfo); 106 dest.writeInt(mLogicalSlotIdx); 107 dest.writeBoolean(mIsExtendedApduSupported); 108 dest.writeBoolean(mIsRemovable); 109 dest.writeTypedList(mPortList, flags); 110 dest.writeBoolean(mLogicalSlotAccessRestricted); 111 } 112 113 @Override describeContents()114 public int describeContents() { 115 return 0; 116 } 117 118 /** 119 * Construct a UiccSlotInfo. 120 * @deprecated apps should not be constructing UiccSlotInfo objects 121 */ 122 @Deprecated UiccSlotInfo(boolean isActive, boolean isEuicc, String cardId, @CardStateInfo int cardStateInfo, int logicalSlotIdx, boolean isExtendedApduSupported)123 public UiccSlotInfo(boolean isActive, boolean isEuicc, String cardId, 124 @CardStateInfo int cardStateInfo, int logicalSlotIdx, boolean isExtendedApduSupported) { 125 this.mIsActive = isActive; 126 this.mIsEuicc = isEuicc; 127 this.mCardId = cardId; 128 this.mCardStateInfo = cardStateInfo; 129 this.mLogicalSlotIdx = logicalSlotIdx; 130 this.mIsExtendedApduSupported = isExtendedApduSupported; 131 this.mIsRemovable = false; 132 this.mPortList = new ArrayList<UiccPortInfo>(); 133 } 134 135 /** 136 * Construct a UiccSlotInfo. 137 * @hide 138 */ UiccSlotInfo(boolean isEuicc, String cardId, @CardStateInfo int cardStateInfo, boolean isExtendedApduSupported, boolean isRemovable, @NonNull List<UiccPortInfo> portList)139 public UiccSlotInfo(boolean isEuicc, String cardId, 140 @CardStateInfo int cardStateInfo, boolean isExtendedApduSupported, 141 boolean isRemovable, @NonNull List<UiccPortInfo> portList) { 142 this.mIsEuicc = isEuicc; 143 this.mCardId = cardId; 144 this.mCardStateInfo = cardStateInfo; 145 this.mIsExtendedApduSupported = isExtendedApduSupported; 146 this.mIsRemovable = isRemovable; 147 this.mPortList = portList; 148 this.mIsActive = !portList.isEmpty() && portList.get(0).isActive(); 149 this.mLogicalSlotIdx = portList.isEmpty() 150 ? SubscriptionManager.INVALID_PHONE_INDEX 151 : portList.get(0).getLogicalSlotIndex(); 152 } 153 154 /** 155 * @deprecated There is no longer isActive state for each slot because ports belonging 156 * to the physical slot could have different states 157 * we instead use {@link UiccPortInfo#isActive()} 158 * To get UiccPortInfo use {@link UiccSlotInfo#getPorts()} 159 * 160 * @return {@code true} if status is active. 161 * @throws UnsupportedOperationException if the calling app's target SDK is T and beyond. 162 */ 163 @Deprecated getIsActive()164 public boolean getIsActive() { 165 if (mLogicalSlotAccessRestricted) { 166 throw new UnsupportedOperationException("getIsActive() is not supported by " 167 + "UiccSlotInfo. Please Use UiccPortInfo API instead"); 168 } 169 return mIsActive; 170 } 171 getIsEuicc()172 public boolean getIsEuicc() { 173 return mIsEuicc; 174 } 175 176 /** 177 * Returns the ICCID of the card in the slot, or the EID of an active eUICC. 178 * <p> 179 * If the UICC slot is for an active eUICC, returns the EID. 180 * If the UICC slot is for an inactive eUICC, returns the ICCID of the enabled profile, or the 181 * root profile if all other profiles are disabled. 182 * If the UICC slot is not an eUICC, returns the ICCID. 183 */ getCardId()184 public String getCardId() { 185 return mCardId; 186 } 187 188 @CardStateInfo getCardStateInfo()189 public int getCardStateInfo() { 190 return mCardStateInfo; 191 } 192 193 /** 194 * @deprecated There is no longer getLogicalSlotIndex 195 * There is no longer getLogicalSlotIdx as each port belonging to this physical slot could have 196 * different logical slot index. Use {@link UiccPortInfo#getLogicalSlotIndex()} instead 197 * 198 * @throws UnsupportedOperationException if the calling app's target SDK is T and beyond. 199 */ 200 @Deprecated getLogicalSlotIdx()201 public int getLogicalSlotIdx() { 202 if (mLogicalSlotAccessRestricted) { 203 throw new UnsupportedOperationException("getLogicalSlotIdx() is not supported by " 204 + "UiccSlotInfo. Please use UiccPortInfo API instead"); 205 } 206 return mLogicalSlotIdx; 207 } 208 209 /** 210 * @return {@code true} if this slot supports extended APDU from ATR, {@code false} otherwise. 211 */ getIsExtendedApduSupported()212 public boolean getIsExtendedApduSupported() { 213 return mIsExtendedApduSupported; 214 } 215 216 /** 217 * Return whether the UICC slot is for a removable UICC. 218 * <p> 219 * UICCs are generally removable, but eUICCs may be removable or built in to the device. 220 * 221 * @return true if the slot is for removable UICCs 222 */ isRemovable()223 public boolean isRemovable() { 224 return mIsRemovable; 225 } 226 227 /** 228 * Get Information regarding port, iccid and its active status. 229 * 230 * For device which support {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP}, it should return 231 * more than one {@link UiccPortInfo} object if the card is eUICC. 232 * 233 * @return Collection of {@link UiccPortInfo} 234 */ getPorts()235 public @NonNull Collection<UiccPortInfo> getPorts() { 236 return Collections.unmodifiableList(mPortList); 237 } 238 239 /** 240 * Set the flag to check compatibility of the calling app's target SDK is T and beyond. 241 * 242 * @param logicalSlotAccessRestricted is the flag to check compatibility. 243 * 244 * @hide 245 */ setLogicalSlotAccessRestricted(boolean logicalSlotAccessRestricted)246 public void setLogicalSlotAccessRestricted(boolean logicalSlotAccessRestricted) { 247 this.mLogicalSlotAccessRestricted = logicalSlotAccessRestricted; 248 } 249 250 @Override equals(@ullable Object obj)251 public boolean equals(@Nullable Object obj) { 252 if (this == obj) { 253 return true; 254 } 255 if (obj == null || getClass() != obj.getClass()) { 256 return false; 257 } 258 259 UiccSlotInfo that = (UiccSlotInfo) obj; 260 return (mIsActive == that.mIsActive) 261 && (mIsEuicc == that.mIsEuicc) 262 && (Objects.equals(mCardId, that.mCardId)) 263 && (mCardStateInfo == that.mCardStateInfo) 264 && (mLogicalSlotIdx == that.mLogicalSlotIdx) 265 && (mIsExtendedApduSupported == that.mIsExtendedApduSupported) 266 && (mIsRemovable == that.mIsRemovable) 267 && (Objects.equals(mPortList, that.mPortList)); 268 } 269 270 @Override hashCode()271 public int hashCode() { 272 return Objects.hash(mIsActive, mIsEuicc, mCardId, mCardStateInfo, mLogicalSlotIdx, 273 mIsExtendedApduSupported, mIsRemovable, mPortList); 274 } 275 276 @NonNull 277 @Override toString()278 public String toString() { 279 return "UiccSlotInfo (" 280 + ", mIsEuicc=" 281 + mIsEuicc 282 + ", mCardId=" 283 + SubscriptionInfo.getPrintableId(mCardId) 284 + ", cardState=" 285 + mCardStateInfo 286 + ", mIsExtendedApduSupported=" 287 + mIsExtendedApduSupported 288 + ", mIsRemovable=" 289 + mIsRemovable 290 + ", mPortList=" 291 + mPortList 292 + ", mLogicalSlotAccessRestricted=" 293 + mLogicalSlotAccessRestricted 294 + ")"; 295 } 296 } 297