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.mIsActive = portList.get(0).isActive(); 143 this.mIsEuicc = isEuicc; 144 this.mCardId = cardId; 145 this.mCardStateInfo = cardStateInfo; 146 this.mLogicalSlotIdx = portList.get(0).getLogicalSlotIndex(); 147 this.mIsExtendedApduSupported = isExtendedApduSupported; 148 this.mIsRemovable = isRemovable; 149 this.mPortList = portList; 150 } 151 152 /** 153 * @deprecated There is no longer isActive state for each slot because ports belonging 154 * to the physical slot could have different states 155 * we instead use {@link UiccPortInfo#isActive()} 156 * To get UiccPortInfo use {@link UiccSlotInfo#getPorts()} 157 * 158 * @return {@code true} if status is active. 159 * @throws UnsupportedOperationException if the calling app's target SDK is T and beyond. 160 */ 161 @Deprecated getIsActive()162 public boolean getIsActive() { 163 if (mLogicalSlotAccessRestricted) { 164 throw new UnsupportedOperationException("getIsActive() is not supported by " 165 + "UiccSlotInfo. Please Use UiccPortInfo API instead"); 166 } 167 //always return status from first port. 168 return getPorts().stream().findFirst().get().isActive(); 169 } 170 getIsEuicc()171 public boolean getIsEuicc() { 172 return mIsEuicc; 173 } 174 175 /** 176 * Returns the ICCID of the card in the slot, or the EID of an active eUICC. 177 * <p> 178 * If the UICC slot is for an active eUICC, returns the EID. 179 * If the UICC slot is for an inactive eUICC, returns the ICCID of the enabled profile, or the 180 * root profile if all other profiles are disabled. 181 * If the UICC slot is not an eUICC, returns the ICCID. 182 */ getCardId()183 public String getCardId() { 184 return mCardId; 185 } 186 187 @CardStateInfo getCardStateInfo()188 public int getCardStateInfo() { 189 return mCardStateInfo; 190 } 191 192 /** 193 * @deprecated There is no longer getLogicalSlotIndex 194 * There is no longer getLogicalSlotIdx as each port belonging to this physical slot could have 195 * different logical slot index. Use {@link UiccPortInfo#getLogicalSlotIndex()} instead 196 * 197 * @throws UnsupportedOperationException if the calling app's target SDK is T and beyond. 198 */ 199 @Deprecated getLogicalSlotIdx()200 public int getLogicalSlotIdx() { 201 if (mLogicalSlotAccessRestricted) { 202 throw new UnsupportedOperationException("getLogicalSlotIdx() is not supported by " 203 + "UiccSlotInfo. Please use UiccPortInfo API instead"); 204 } 205 //always return logical slot index from first port. 206 //portList always have at least one element. 207 return getPorts().stream().findFirst().get().getLogicalSlotIndex(); 208 } 209 210 /** 211 * @return {@code true} if this slot supports extended APDU from ATR, {@code false} otherwise. 212 */ getIsExtendedApduSupported()213 public boolean getIsExtendedApduSupported() { 214 return mIsExtendedApduSupported; 215 } 216 217 /** 218 * Return whether the UICC slot is for a removable UICC. 219 * <p> 220 * UICCs are generally removable, but eUICCs may be removable or built in to the device. 221 * 222 * @return true if the slot is for removable UICCs 223 */ isRemovable()224 public boolean isRemovable() { 225 return mIsRemovable; 226 } 227 228 /** 229 * Get Information regarding port, iccid and its active status. 230 * 231 * For device which support {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP}, it should return 232 * more than one {@link UiccPortInfo} object if the card is eUICC. 233 * 234 * @return Collection of {@link UiccPortInfo} 235 */ getPorts()236 public @NonNull Collection<UiccPortInfo> getPorts() { 237 return Collections.unmodifiableList(mPortList); 238 } 239 240 /** 241 * Set the flag to check compatibility of the calling app's target SDK is T and beyond. 242 * 243 * @param logicalSlotAccessRestricted is the flag to check compatibility. 244 * 245 * @hide 246 */ setLogicalSlotAccessRestricted(boolean logicalSlotAccessRestricted)247 public void setLogicalSlotAccessRestricted(boolean logicalSlotAccessRestricted) { 248 this.mLogicalSlotAccessRestricted = logicalSlotAccessRestricted; 249 } 250 251 @Override equals(@ullable Object obj)252 public boolean equals(@Nullable Object obj) { 253 if (this == obj) { 254 return true; 255 } 256 if (obj == null || getClass() != obj.getClass()) { 257 return false; 258 } 259 260 UiccSlotInfo that = (UiccSlotInfo) obj; 261 return (mIsActive == that.mIsActive) 262 && (mIsEuicc == that.mIsEuicc) 263 && (Objects.equals(mCardId, that.mCardId)) 264 && (mCardStateInfo == that.mCardStateInfo) 265 && (mLogicalSlotIdx == that.mLogicalSlotIdx) 266 && (mIsExtendedApduSupported == that.mIsExtendedApduSupported) 267 && (mIsRemovable == that.mIsRemovable) 268 && (Objects.equals(mPortList, that.mPortList)); 269 } 270 271 @Override hashCode()272 public int hashCode() { 273 return Objects.hash(mIsActive, mIsEuicc, mCardId, mCardStateInfo, mLogicalSlotIdx, 274 mIsExtendedApduSupported, mIsRemovable, mPortList); 275 } 276 277 @NonNull 278 @Override toString()279 public String toString() { 280 return "UiccSlotInfo (" 281 + ", mIsEuicc=" 282 + mIsEuicc 283 + ", mCardId=" 284 + SubscriptionInfo.givePrintableIccid(mCardId) 285 + ", cardState=" 286 + mCardStateInfo 287 + ", mIsExtendedApduSupported=" 288 + mIsExtendedApduSupported 289 + ", mIsRemovable=" 290 + mIsRemovable 291 + ", mPortList=" 292 + mPortList 293 + ", mLogicalSlotAccessRestricted=" 294 + mLogicalSlotAccessRestricted 295 + ")"; 296 } 297 } 298