/* * Copyright (C) 2018 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.telephony; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.PackageManager; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.telephony.util.TelephonyUtils; import com.android.telephony.Rlog; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; /** * The UiccCardInfo represents information about a currently inserted UICC or embedded eUICC. */ public final class UiccCardInfo implements Parcelable { private final boolean mIsEuicc; private final int mCardId; private final String mEid; private final String mIccId; private final int mPhysicalSlotIndex; private final boolean mIsRemovable; private final boolean mIsMultipleEnabledProfilesSupported; private final List mPortList; private boolean mIccIdAccessRestricted = false; public static final @NonNull Creator CREATOR = new Creator() { @Override public UiccCardInfo createFromParcel(Parcel in) { return new UiccCardInfo(in); } @Override public UiccCardInfo[] newArray(int size) { return new UiccCardInfo[size]; } }; private UiccCardInfo(Parcel in) { mIsEuicc = in.readBoolean(); mCardId = in.readInt(); mEid = in.readString8(); mIccId = in.readString8(); mPhysicalSlotIndex = in.readInt(); mIsRemovable = in.readBoolean(); mIsMultipleEnabledProfilesSupported = in.readBoolean(); mPortList = new ArrayList(); in.readTypedList(mPortList, UiccPortInfo.CREATOR); mIccIdAccessRestricted = in.readBoolean(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeBoolean(mIsEuicc); dest.writeInt(mCardId); dest.writeString8(mEid); dest.writeString8(mIccId); dest.writeInt(mPhysicalSlotIndex); dest.writeBoolean(mIsRemovable); dest.writeBoolean(mIsMultipleEnabledProfilesSupported); dest.writeTypedList(mPortList, flags); dest.writeBoolean(mIccIdAccessRestricted); } @Override public int describeContents() { return 0; } /** * Construct a UiccCardInfo. * * @param isEuicc is a flag to check is eUICC or not * @param cardId is unique ID used to identify a UiccCard. * @param eid is unique eUICC Identifier * @param physicalSlotIndex is unique index referring to a physical SIM slot. * @param isRemovable is a flag to check is removable or embedded * @param isMultipleEnabledProfilesSupported is a flag to check is MEP enabled or not * @param portList has the information regarding port, ICCID and its active status * * @hide */ public UiccCardInfo(boolean isEuicc, int cardId, String eid, int physicalSlotIndex, boolean isRemovable, boolean isMultipleEnabledProfilesSupported, @NonNull List portList) { this.mIsEuicc = isEuicc; this.mCardId = cardId; this.mEid = eid; this.mIccId = null; this.mPhysicalSlotIndex = physicalSlotIndex; this.mIsRemovable = isRemovable; this.mIsMultipleEnabledProfilesSupported = isMultipleEnabledProfilesSupported; this.mPortList = portList; } /** * Return whether the UICC is an eUICC. * * @return true if the UICC is an eUICC. */ public boolean isEuicc() { return mIsEuicc; } /** * Get the card ID of the UICC. See {@link TelephonyManager#getCardIdForDefaultEuicc()} for more * details on card ID. */ public int getCardId() { return mCardId; } /** * Get the embedded ID (EID) of the eUICC. If the UiccCardInfo is not an eUICC * (see {@link #isEuicc()}), or the EID is not available, returns null. *

* Note that this field may be omitted if the caller does not have the correct permissions * (see {@link TelephonyManager#getUiccCardsInfo()}). */ @Nullable public String getEid() { if (!mIsEuicc) { return null; } return mEid; } /** * Get the ICCID of the UICC. If the ICCID is not availble, returns null. *

* Note that this field may be omitted if the caller does not have the correct permissions * (see {@link TelephonyManager#getUiccCardsInfo()}). * * @deprecated with support for MEP(multiple enabled profile) * {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP}, a SIM card can have more than one * ICCID active at the same time. Instead use {@link UiccPortInfo#getIccId()} to retrieve ICCID. * To find {@link UiccPortInfo} use {@link UiccCardInfo#getPorts()}. * * @throws UnsupportedOperationException if the calling app's target SDK is T and beyond. */ @Nullable @Deprecated public String getIccId() { if (mIccIdAccessRestricted) { throw new UnsupportedOperationException("getIccId() is not supported by UiccCardInfo." + " Please Use UiccPortInfo API instead"); } //always return ICCID from first port. return mPortList.isEmpty() ? null : mPortList.get(0).getIccId(); } /** * Gets the slot index for the slot that the UICC is currently inserted in. * * @deprecated use {@link #getPhysicalSlotIndex()} */ @Deprecated public int getSlotIndex() { return mPhysicalSlotIndex; } /** * Gets the physical slot index for the slot that the UICC is currently inserted in. */ public int getPhysicalSlotIndex() { return mPhysicalSlotIndex; } /** * Return whether the UICC or eUICC is removable. *

* UICCs are generally removable, but eUICCs may be removable or built in to the device. * * @return true if the UICC or eUICC is removable */ public boolean isRemovable() { return mIsRemovable; } /* * Whether the UICC card supports multiple enabled profile(MEP) * UICCs are generally MEP disabled, there can be only one active profile on the physical * sim card. * * @return {@code true} if the UICC is supporting multiple enabled profile(MEP). */ public boolean isMultipleEnabledProfilesSupported() { return mIsMultipleEnabledProfilesSupported; } /** * Get information regarding port, ICCID and its active status. * * For device which support {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP}, it should return * more than one {@link UiccPortInfo} object if the card is eUICC. * * @return Collection of {@link UiccPortInfo} */ public @NonNull Collection getPorts() { return Collections.unmodifiableList(mPortList); } /** * if the flag is set to {@code true} the calling app is not allowed to access deprecated * {@link #getIccId()} * @param iccIdAccessRestricted is the flag to check if app is allowed to access ICCID * * @hide */ public void setIccIdAccessRestricted(boolean iccIdAccessRestricted) { this.mIccIdAccessRestricted = iccIdAccessRestricted; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } UiccCardInfo that = (UiccCardInfo) obj; return ((mIsEuicc == that.mIsEuicc) && (mCardId == that.mCardId) && (Objects.equals(mEid, that.mEid)) && (Objects.equals(mIccId, that.mIccId)) && (mPhysicalSlotIndex == that.mPhysicalSlotIndex) && (mIsRemovable == that.mIsRemovable) && (mIsMultipleEnabledProfilesSupported == that.mIsMultipleEnabledProfilesSupported) && (Objects.equals(mPortList, that.mPortList))); } @Override public int hashCode() { return Objects.hash(mIsEuicc, mCardId, mEid, mIccId, mPhysicalSlotIndex, mIsRemovable, mIsMultipleEnabledProfilesSupported, mPortList); } @Override public String toString() { return "UiccCardInfo (mIsEuicc=" + mIsEuicc + ", mCardId=" + mCardId + ", mEid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid) + ", mPhysicalSlotIndex=" + mPhysicalSlotIndex + ", mIsRemovable=" + mIsRemovable + ", mIsMultipleEnabledProfilesSupported=" + mIsMultipleEnabledProfilesSupported + ", mPortList=" + mPortList + ", mIccIdAccessRestricted=" + mIccIdAccessRestricted + ")"; } }