1 /*
2  * Copyright (C) 2021 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 
17 package android.telephony;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.util.Objects;
26 
27 /**
28  * UiccPortInfo class represents information about a single port contained on {@link UiccCardInfo}.
29  * Per GSMA SGP.22 V3.0, a port is a logical entity to which an active UICC profile can be bound on
30  * a UICC card. If UICC supports 2 ports, then the port index is numbered 0,1.
31  * Each port index is unique within an UICC, but not necessarily unique across UICC’s.
32  * For UICC's does not support MEP(Multi-enabled profile)
33  * {@link android.content.pm.PackageManager#FEATURE_TELEPHONY_EUICC_MEP}, just return the default
34  * port index 0.
35  */
36 public final class UiccPortInfo implements Parcelable{
37     private final String mIccId;
38     private final int mPortIndex;
39     private final int mLogicalSlotIndex;
40     private final boolean mIsActive;
41 
42     /**
43      * A redacted String if caller does not have permission to read ICCID.
44      */
45     public static final String ICCID_REDACTED = "FFFFFFFFFFFFFFFFFFFF";
46 
47     public static final @NonNull Creator<UiccPortInfo> CREATOR =
48             new Creator<UiccPortInfo>() {
49                 @Override
50                 public UiccPortInfo createFromParcel(Parcel in) {
51                     return new UiccPortInfo(in);
52                 }
53                 @Override
54                 public UiccPortInfo[] newArray(int size) {
55                     return new UiccPortInfo[size];
56                 }
57             };
58 
UiccPortInfo(Parcel in)59     private UiccPortInfo(Parcel in) {
60         mIccId = in.readString8();
61         mPortIndex = in.readInt();
62         mLogicalSlotIndex = in.readInt();
63         mIsActive = in.readBoolean();
64     }
65 
66     @Override
writeToParcel(@ullable Parcel dest, int flags)67     public void writeToParcel(@Nullable Parcel dest, int flags) {
68         dest.writeString8(mIccId);
69         dest.writeInt(mPortIndex);
70         dest.writeInt(mLogicalSlotIndex);
71         dest.writeBoolean(mIsActive);
72     }
73 
74     @Override
describeContents()75     public int describeContents() {
76         return 0;
77     }
78 
79     /**
80      * Construct a UiccPortInfo.
81      *
82      * @param iccId The ICCID of the profile.
83      * @param portIndex The port index is an enumeration of the ports available on the UICC.
84      * @param logicalSlotIndex is unique index referring to a logical SIM slot.
85      * @param isActive is flag to check if port was tied to a modem stack.
86      *
87      * @hide
88      */
UiccPortInfo(String iccId, int portIndex, int logicalSlotIndex, boolean isActive)89     public UiccPortInfo(String iccId, int portIndex, int logicalSlotIndex, boolean isActive) {
90         this.mIccId = iccId;
91         this.mPortIndex = portIndex;
92         this.mLogicalSlotIndex = logicalSlotIndex;
93         this.mIsActive = isActive;
94     }
95 
96     /**
97      * Get the ICCID of the profile associated with this port.
98      * If this port is not {@link #isActive()}, returns {@code null}.
99      * If the caller does not have access to the ICCID for this port, it will be redacted and
100      * {@link #ICCID_REDACTED} will be returned.
101      */
getIccId()102     public @Nullable String getIccId() {
103         return mIccId;
104     }
105 
106     /**
107      * The port index is an enumeration of the ports available on the UICC.
108      * Example: if eUICC1 supports 2 ports, then the port index is numbered 0,1.
109      * Each port index is unique within an UICC, but not necessarily unique across UICC’s.
110      * For UICC's does not support MEP(Multi-enabled profile), just return the default port index 0.
111      */
112     @IntRange(from = 0)
getPortIndex()113     public int getPortIndex() {
114         return mPortIndex;
115     }
116 
117     /**
118      * @return {@code true} if port was tied to a modem stack.
119      */
isActive()120     public boolean isActive() {
121         return mIsActive;
122     }
123 
124     /**
125      * Gets logical slot index for the slot that the UICC is currently attached.
126      * Logical slot index or ID: unique index referring to a logical SIM slot.
127      * Logical slot IDs start at 0 and go up depending on the number of supported active slots on
128      * a device.
129      * For example, a dual-SIM device typically has slot 0 and slot 1.
130      * If a device has multiple physical slots but only supports one active slot,
131      * it will have only the logical slot ID 0.
132      *
133      * @return the logical slot index for UICC port, if there is no logical slot index it returns
134      * {@link SubscriptionManager#INVALID_SIM_SLOT_INDEX}
135      */
136     @IntRange(from = 0)
getLogicalSlotIndex()137     public int getLogicalSlotIndex() {
138         return mLogicalSlotIndex;
139     }
140 
141     @Override
equals(@ullable Object obj)142     public boolean equals(@Nullable Object obj) {
143         if (this == obj) {
144             return true;
145         }
146         if (obj == null || getClass() != obj.getClass()) {
147             return false;
148         }
149 
150         UiccPortInfo that = (UiccPortInfo) obj;
151         return (Objects.equals(mIccId, that.mIccId))
152                 && (mPortIndex == that.mPortIndex)
153                 && (mLogicalSlotIndex == that.mLogicalSlotIndex)
154                 && (mIsActive == that.mIsActive);
155     }
156 
157     @Override
hashCode()158     public int hashCode() {
159         return Objects.hash(mIccId, mPortIndex, mLogicalSlotIndex, mIsActive);
160     }
161 
162     @NonNull
163     @Override
toString()164     public String toString() {
165         return "UiccPortInfo (isActive="
166                 + mIsActive
167                 + ", iccId="
168                 + SubscriptionInfo.getPrintableId(mIccId)
169                 + ", portIndex="
170                 + mPortIndex
171                 + ", mLogicalSlotIndex="
172                 + mLogicalSlotIndex
173                 + ")";
174     }
175 }
176