• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2012 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 com.android.internal.telephony.uicc;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.content.Context;
21 import android.os.Build;
22 import android.telephony.TelephonyManager;
23 import android.text.TextUtils;
24 
25 import com.android.internal.telephony.CommandsInterface;
26 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
27 import com.android.internal.telephony.uicc.euicc.EuiccCard;
28 import com.android.internal.telephony.uicc.euicc.EuiccPort;
29 import com.android.telephony.Rlog;
30 
31 import java.io.FileDescriptor;
32 import java.io.PrintWriter;
33 import java.util.HashMap;
34 
35 /**
36  * {@hide}
37  */
38 public class UiccCard {
39     protected static final String LOG_TAG = "UiccCard";
40     protected static final boolean DBG = true;
41 
42     public static final String EXTRA_ICC_CARD_ADDED =
43             "com.android.internal.telephony.uicc.ICC_CARD_ADDED";
44 
45     // The lock object is created by UiccSlot that owns this UiccCard - this is to share the lock
46     // between UiccSlot, UiccCard, EuiccCard, UiccPort, EuiccPort and UiccProfile for now.
47     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
48     protected final Object mLock;
49     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
50     private CardState mCardState;
51     protected String mCardId;
52     protected boolean mIsSupportsMultipleEnabledProfiles;
53 
54     protected HashMap<Integer, UiccPort> mUiccPorts = new HashMap<>();
55     private HashMap<Integer, Integer> mPhoneIdToPortIdx = new HashMap<>();
56 
UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock, boolean isSupportsMultipleEnabledProfiles)57     public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
58             boolean isSupportsMultipleEnabledProfiles) {
59         if (DBG) log("Creating");
60         mCardState = ics.mCardState;
61         mLock = lock;
62         mIsSupportsMultipleEnabledProfiles = isSupportsMultipleEnabledProfiles;
63         update(c, ci, ics, phoneId);
64     }
65 
66     /**
67      * Dispose the card and its related UiccPort objects.
68      */
dispose()69     public void dispose() {
70         synchronized (mLock) {
71             if (DBG) log("Disposing card");
72             for (UiccPort uiccPort : mUiccPorts.values()) {
73                 if (uiccPort != null) {
74                     uiccPort.dispose();
75                 }
76             }
77             mUiccPorts.clear();
78             mUiccPorts = null;
79             mPhoneIdToPortIdx.clear();
80             mPhoneIdToPortIdx = null;
81         }
82     }
83 
84     /**
85      * Dispose the port corresponding to the port index.
86      */
disposePort(int portIndex)87     public void disposePort(int portIndex) {
88         synchronized (mLock) {
89             if (DBG) log("Disposing port for index " + portIndex);
90             UiccPort port = getUiccPort(portIndex);
91             if (port != null) {
92                 mPhoneIdToPortIdx.remove(port.getPhoneId());
93                 port.dispose();
94             }
95             mUiccPorts.remove(portIndex);
96         }
97     }
98 
99     /**
100      * Update card. The main trigger for this is a change in the ICC Card status.
101      */
update(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId)102     public void update(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) {
103         synchronized (mLock) {
104             mCardState = ics.mCardState;
105             updateCardId(ics.iccid);
106             if (mCardState != CardState.CARDSTATE_ABSENT) {
107                 int portIdx = ics.mSlotPortMapping.mPortIndex;
108                 UiccPort port = mUiccPorts.get(portIdx);
109                 if (port == null) {
110                     if (this instanceof EuiccCard) {
111                         port = new EuiccPort(c, ci, ics, phoneId, mLock, this,
112                                 mIsSupportsMultipleEnabledProfiles); // eSim
113                     } else {
114                         port = new UiccPort(c, ci, ics, phoneId, mLock, this); // pSim
115                     }
116                     mUiccPorts.put(portIdx, port);
117                 } else {
118                     port.update(c, ci, ics, this);
119                 }
120                 mPhoneIdToPortIdx.put(phoneId, portIdx);
121             } else {
122                 throw new RuntimeException("Card state is absent when updating!");
123             }
124         }
125     }
126 
127     @Override
finalize()128     protected void finalize() {
129         if (DBG) log("UiccCard finalized");
130     }
131 
132     /**
133      * Updates the ID of the SIM card.
134      *
135      * <p>Whenever the {@link UiccCard#update(Context, CommandsInterface, IccCardStatus, int)}
136      * is called, this function needs to be called to update the card ID. Subclasses of
137      * {@link UiccCard} could override this function to set the {@link UiccCard#mCardId} to be
138      * something else instead of setting iccId.</p>
139      */
updateCardId(String iccId)140     protected void updateCardId(String iccId) {
141         mCardId = iccId;
142     }
143 
144 
145     /**
146      * Updates MEP(Multiple Enabled Profile) support flag.
147      *
148      * <p>If IccSlotStatus comes later, the number of ports reported is only known after the
149      * UiccCard creation which will impact UICC MEP capability.
150      */
updateSupportMultipleEnabledProfile(boolean supported)151     public void updateSupportMultipleEnabledProfile(boolean supported) {
152         mIsSupportsMultipleEnabledProfiles = supported;
153     }
154 
155     @UnsupportedAppUsage
getCardState()156     public CardState getCardState() {
157         synchronized (mLock) {
158             return mCardState;
159         }
160     }
161 
162     /**
163      * Returns the ID of this SIM card, it is the ICCID of the active profile on the card for a UICC
164      * card or the EID of the card for an eUICC card.
165      */
getCardId()166     public String getCardId() {
167         if (!TextUtils.isEmpty(mCardId)) {
168             return mCardId;
169         } else {
170             UiccProfile uiccProfile = mUiccPorts.get(TelephonyManager.DEFAULT_PORT_INDEX)
171                     .getUiccProfile();
172             return uiccProfile == null ? null : uiccProfile.getIccId();
173         }
174     }
175 
176     /**
177      * Returns all the UiccPorts associated with the card.
178      */
getUiccPortList()179     public UiccPort[] getUiccPortList() {
180         synchronized (mLock) {
181             return mUiccPorts.values().stream().toArray(UiccPort[]::new);
182         }
183     }
184 
185     /**
186      * Returns the UiccPort associated with the given phoneId
187      */
getUiccPortForPhone(int phoneId)188     public UiccPort getUiccPortForPhone(int phoneId) {
189         synchronized (mLock) {
190             return mUiccPorts.get(mPhoneIdToPortIdx.get(phoneId));
191         }
192     }
193 
194     /**
195      * Returns the UiccPort associated with the given port index.
196      */
getUiccPort(int portIdx)197     public UiccPort getUiccPort(int portIdx) {
198         synchronized (mLock) {
199             return mUiccPorts.get(portIdx);
200         }
201     }
202 
203     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
log(String msg)204     private void log(String msg) {
205         Rlog.d(LOG_TAG, msg);
206     }
207 
208     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
loge(String msg)209     private void loge(String msg) {
210         Rlog.e(LOG_TAG, msg);
211     }
212 
dump(FileDescriptor fd, PrintWriter pw, String[] args)213     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
214         pw.println("UiccCard:");
215         pw.println(" mCardState=" + mCardState);
216         pw.println(" mCardId=" + mCardId);
217         pw.println(" mNumberOfPorts=" + mUiccPorts.size());
218         pw.println( "mIsSupportsMultipleEnabledProfiles=" + mIsSupportsMultipleEnabledProfiles);
219         pw.println();
220         for (UiccPort uiccPort : mUiccPorts.values()) {
221             uiccPort.dump(fd, pw, args);
222         }
223     }
224 }
225