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.content.Intent;
22 import android.content.pm.PackageInfo;
23 import android.content.pm.PackageManager;
24 import android.content.pm.Signature;
25 import android.os.Handler;
26 import android.os.Message;
27 import android.telephony.TelephonyManager;
28 import android.text.TextUtils;
29 
30 import com.android.internal.telephony.CommandsInterface;
31 import com.android.internal.telephony.TelephonyComponentFactory;
32 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
33 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
34 import com.android.internal.telephony.uicc.IccCardStatus.PinState;
35 import com.android.telephony.Rlog;
36 
37 import java.io.FileDescriptor;
38 import java.io.PrintWriter;
39 import java.util.List;
40 
41 /**
42  * {@hide}
43  */
44 public class UiccCard {
45     protected static final String LOG_TAG = "UiccCard";
46     protected static final boolean DBG = true;
47 
48     public static final String EXTRA_ICC_CARD_ADDED =
49             "com.android.internal.telephony.uicc.ICC_CARD_ADDED";
50 
51     // The lock object is created by UiccSlot that owns this UiccCard - this is to share the lock
52     // between UiccSlot, UiccCard, EuiccCard, and UiccProfile for now.
53     @UnsupportedAppUsage
54     protected final Object mLock;
55     @UnsupportedAppUsage
56     private CardState mCardState;
57     private String mIccid;
58     protected String mCardId;
59     private UiccProfile mUiccProfile;
60     @UnsupportedAppUsage
61     private Context mContext;
62     @UnsupportedAppUsage
63     private CommandsInterface mCi;
64     @UnsupportedAppUsage
65     private final int mPhoneId;
66 
UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock)67     public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
68         if (DBG) log("Creating");
69         mCardState = ics.mCardState;
70         mPhoneId = phoneId;
71         mLock = lock;
72         update(c, ci, ics);
73     }
74 
dispose()75     public void dispose() {
76         synchronized (mLock) {
77             if (DBG) log("Disposing card");
78             if (mUiccProfile != null) {
79                 mUiccProfile.dispose();
80             }
81             mUiccProfile = null;
82         }
83     }
84 
update(Context c, CommandsInterface ci, IccCardStatus ics)85     public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
86         synchronized (mLock) {
87             mCardState = ics.mCardState;
88             mContext = c;
89             mCi = ci;
90             mIccid = ics.iccid;
91             updateCardId();
92 
93             if (mCardState != CardState.CARDSTATE_ABSENT) {
94                 if (mUiccProfile == null) {
95                     mUiccProfile = TelephonyComponentFactory.getInstance()
96                             .inject(UiccProfile.class.getName()).makeUiccProfile(
97                             mContext, mCi, ics, mPhoneId, this, mLock);
98                 } else {
99                     mUiccProfile.update(mContext, mCi, ics);
100                 }
101             } else {
102                 throw new RuntimeException("Card state is absent when updating!");
103             }
104         }
105     }
106 
107     @Override
finalize()108     protected void finalize() {
109         if (DBG) log("UiccCard finalized");
110     }
111 
112     /**
113      * Updates the ID of the SIM card.
114      *
115      * <p>Whenever the {@link UiccCard#update(Context, CommandsInterface, IccCardStatus)} is called,
116      * this function needs to be called to update the card ID. Subclasses of {@link UiccCard}
117      * could override this function to set the {@link UiccCard#mCardId} to be something else instead
118      * of {@link UiccCard#mIccid}.</p>
119      */
updateCardId()120     protected void updateCardId() {
121         mCardId = mIccid;
122     }
123 
124     /**
125      * Notifies handler when carrier privilege rules are loaded.
126      * @deprecated Please use
127      * {@link UiccProfile#registerForCarrierPrivilegeRulesLoaded(Handler, int, Object)} instead.
128      */
129     @Deprecated
registerForCarrierPrivilegeRulesLoaded(Handler h, int what, Object obj)130     public void registerForCarrierPrivilegeRulesLoaded(Handler h, int what, Object obj) {
131         synchronized (mLock) {
132             if (mUiccProfile != null) {
133                 mUiccProfile.registerForCarrierPrivilegeRulesLoaded(h, what, obj);
134             } else {
135                 loge("registerForCarrierPrivilegeRulesLoaded Failed!");
136             }
137         }
138     }
139 
140     /**
141      * @deprecated Please use
142      * {@link UiccProfile#unregisterForCarrierPrivilegeRulesLoaded(Handler)} instead.
143      */
144     @Deprecated
unregisterForCarrierPrivilegeRulesLoaded(Handler h)145     public void unregisterForCarrierPrivilegeRulesLoaded(Handler h) {
146         synchronized (mLock) {
147             if (mUiccProfile != null) {
148                 mUiccProfile.unregisterForCarrierPrivilegeRulesLoaded(h);
149             } else {
150                 loge("unregisterForCarrierPrivilegeRulesLoaded Failed!");
151             }
152         }
153     }
154 
155     /**
156      * @deprecated Please use {@link UiccProfile#isApplicationOnIcc(AppType)} instead.
157      */
158     @UnsupportedAppUsage
159     @Deprecated
isApplicationOnIcc(IccCardApplicationStatus.AppType type)160     public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) {
161         synchronized (mLock) {
162             if (mUiccProfile != null) {
163                 return mUiccProfile.isApplicationOnIcc(type);
164             } else {
165                 return false;
166             }
167         }
168     }
169 
170     @UnsupportedAppUsage
getCardState()171     public CardState getCardState() {
172         synchronized (mLock) {
173             return mCardState;
174         }
175     }
176 
177     /**
178      * @deprecated Please use {@link UiccProfile#getUniversalPinState()} instead.
179      */
180     @Deprecated
getUniversalPinState()181     public PinState getUniversalPinState() {
182         synchronized (mLock) {
183             if (mUiccProfile != null) {
184                 return mUiccProfile.getUniversalPinState();
185             } else {
186                 return PinState.PINSTATE_UNKNOWN;
187             }
188         }
189     }
190 
191     /**
192      * @deprecated Please use {@link UiccProfile#getApplication(int)} instead.
193      */
194     @UnsupportedAppUsage
195     @Deprecated
getApplication(int family)196     public UiccCardApplication getApplication(int family) {
197         synchronized (mLock) {
198             if (mUiccProfile != null) {
199                 return mUiccProfile.getApplication(family);
200             } else {
201                 return null;
202             }
203         }
204     }
205 
206     /**
207      * @deprecated Please use {@link UiccProfile#getApplicationIndex(int)} instead.
208      */
209     @UnsupportedAppUsage
210     @Deprecated
getApplicationIndex(int index)211     public UiccCardApplication getApplicationIndex(int index) {
212         synchronized (mLock) {
213             if (mUiccProfile != null) {
214                 return mUiccProfile.getApplicationIndex(index);
215             } else {
216                 return null;
217             }
218         }
219     }
220 
221     /**
222      * Returns the SIM application of the specified type.
223      *
224      * @param type ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
225      * @return application corresponding to type or a null if no match found
226      *
227      * @deprecated Please use {@link UiccProfile#getApplicationByType(int)} instead.
228      */
229     @UnsupportedAppUsage
230     @Deprecated
getApplicationByType(int type)231     public UiccCardApplication getApplicationByType(int type) {
232         synchronized (mLock) {
233             if (mUiccProfile != null) {
234                 return mUiccProfile.getApplicationByType(type);
235             } else {
236                 return null;
237             }
238         }
239     }
240 
241     /**
242      * Resets the application with the input AID. Returns true if any changes were made.
243      *
244      * A null aid implies a card level reset - all applications must be reset.
245      *
246      * @deprecated Please use {@link UiccProfile#resetAppWithAid(String, boolean)} instead.
247      */
248     @Deprecated
resetAppWithAid(String aid, boolean reset)249     public boolean resetAppWithAid(String aid, boolean reset) {
250         synchronized (mLock) {
251             if (mUiccProfile != null) {
252                 return mUiccProfile.resetAppWithAid(aid, reset);
253             } else {
254                 return false;
255             }
256         }
257     }
258 
259     /**
260      * Exposes {@link CommandsInterface#iccOpenLogicalChannel}
261      * @deprecated Please use
262      * {@link UiccProfile#iccOpenLogicalChannel(String, int, Message)} instead.
263      */
264     @Deprecated
iccOpenLogicalChannel(String AID, int p2, Message response)265     public void iccOpenLogicalChannel(String AID, int p2, Message response) {
266         if (mUiccProfile != null) {
267             mUiccProfile.iccOpenLogicalChannel(AID, p2, response);
268         } else {
269             loge("iccOpenLogicalChannel Failed!");
270         }
271     }
272 
273     /**
274      * Exposes {@link CommandsInterface#iccCloseLogicalChannel}
275      * @deprecated Please use
276      * {@link UiccProfile#iccCloseLogicalChannel(int, Message)} instead.
277      */
278     @Deprecated
iccCloseLogicalChannel(int channel, Message response)279     public void iccCloseLogicalChannel(int channel, Message response) {
280         if (mUiccProfile != null) {
281             mUiccProfile.iccCloseLogicalChannel(channel, response);
282         } else {
283             loge("iccCloseLogicalChannel Failed!");
284         }
285     }
286 
287     /**
288      * Exposes {@link CommandsInterface#iccTransmitApduLogicalChannel}
289      * @deprecated Please use {@link
290      * UiccProfile#iccTransmitApduLogicalChannel(int, int, int, int, int, int, String, Message)}
291      * instead.
292      */
293     @Deprecated
iccTransmitApduLogicalChannel(int channel, int cla, int command, int p1, int p2, int p3, String data, Message response)294     public void iccTransmitApduLogicalChannel(int channel, int cla, int command,
295             int p1, int p2, int p3, String data, Message response) {
296         if (mUiccProfile != null) {
297             mUiccProfile.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3,
298                     data, response);
299         } else {
300             loge("iccTransmitApduLogicalChannel Failed!");
301         }
302     }
303 
304     /**
305      * Exposes {@link CommandsInterface#iccTransmitApduBasicChannel}
306      * @deprecated Please use
307      * {@link UiccProfile#iccTransmitApduBasicChannel(int, int, int, int, int, String, Message)}
308      * instead.
309      */
310     @Deprecated
iccTransmitApduBasicChannel(int cla, int command, int p1, int p2, int p3, String data, Message response)311     public void iccTransmitApduBasicChannel(int cla, int command,
312             int p1, int p2, int p3, String data, Message response) {
313         if (mUiccProfile != null) {
314             mUiccProfile.iccTransmitApduBasicChannel(cla, command, p1, p2, p3, data, response);
315         } else {
316             loge("iccTransmitApduBasicChannel Failed!");
317         }
318     }
319 
320     /**
321      * Exposes {@link CommandsInterface#iccIO}
322      * @deprecated Please use
323      * {@link UiccProfile#iccExchangeSimIO(int, int, int, int, int, String, Message)} instead.
324      */
325     @Deprecated
iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, String pathID, Message response)326     public void iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
327             String pathID, Message response) {
328         if (mUiccProfile != null) {
329             mUiccProfile.iccExchangeSimIO(fileID, command, p1, p2, p3, pathID, response);
330         } else {
331             loge("iccExchangeSimIO Failed!");
332         }
333     }
334 
335     /**
336      * Exposes {@link CommandsInterface#sendEnvelopeWithStatus}
337      * @deprecated Please use {@link UiccProfile#sendEnvelopeWithStatus(String, Message)} instead.
338      */
339     @Deprecated
sendEnvelopeWithStatus(String contents, Message response)340     public void sendEnvelopeWithStatus(String contents, Message response) {
341         if (mUiccProfile != null) {
342             mUiccProfile.sendEnvelopeWithStatus(contents, response);
343         } else {
344             loge("sendEnvelopeWithStatus Failed!");
345         }
346     }
347 
348     /**
349      * Returns number of applications on this card
350      * @deprecated Please use {@link UiccProfile#getNumApplications()} instead.
351      */
352     @UnsupportedAppUsage
353     @Deprecated
getNumApplications()354     public int getNumApplications() {
355         if (mUiccProfile != null) {
356             return mUiccProfile.getNumApplications();
357         } else {
358             return 0;
359         }
360     }
361 
getPhoneId()362     public int getPhoneId() {
363         return mPhoneId;
364     }
365 
getUiccProfile()366     public UiccProfile getUiccProfile() {
367         return mUiccProfile;
368     }
369 
370     /**
371      * Returns true iff carrier privileges rules are null (dont need to be loaded) or loaded.
372      * @deprecated Please use {@link UiccProfile#areCarrierPriviligeRulesLoaded()} instead.
373      */
374     @Deprecated
areCarrierPriviligeRulesLoaded()375     public boolean areCarrierPriviligeRulesLoaded() {
376         if (mUiccProfile != null) {
377             return mUiccProfile.areCarrierPriviligeRulesLoaded();
378         } else {
379             return false;
380         }
381     }
382 
383     /**
384      * Returns true if there are some carrier privilege rules loaded and specified.
385      * @deprecated Please use {@link UiccProfile#hasCarrierPrivilegeRules()} instead.
386      */
387     @Deprecated
hasCarrierPrivilegeRules()388     public boolean hasCarrierPrivilegeRules() {
389         if (mUiccProfile != null) {
390             return mUiccProfile.hasCarrierPrivilegeRules();
391         } else {
392             return false;
393         }
394     }
395 
396     /**
397      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
398      * @deprecated Please use
399      * {@link UiccProfile#getCarrierPrivilegeStatus(Signature, String)} instead.
400      */
401     @Deprecated
getCarrierPrivilegeStatus(Signature signature, String packageName)402     public int getCarrierPrivilegeStatus(Signature signature, String packageName) {
403         if (mUiccProfile != null) {
404             return mUiccProfile.getCarrierPrivilegeStatus(signature, packageName);
405         } else {
406             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
407         }
408     }
409 
410     /**
411      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
412      * @deprecated Please use
413      * {@link UiccProfile#getCarrierPrivilegeStatus(PackageManager, String)} instead.
414      */
415     @Deprecated
getCarrierPrivilegeStatus(PackageManager packageManager, String packageName)416     public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) {
417         if (mUiccProfile != null) {
418             return mUiccProfile.getCarrierPrivilegeStatus(packageManager, packageName);
419         } else {
420             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
421         }
422     }
423 
424     /**
425      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
426      * @deprecated Please use {@link UiccProfile#getCarrierPrivilegeStatus(PackageInfo)} instead.
427      */
428     @Deprecated
getCarrierPrivilegeStatus(PackageInfo packageInfo)429     public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
430         if (mUiccProfile != null) {
431             return mUiccProfile.getCarrierPrivilegeStatus(packageInfo);
432         } else {
433             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
434         }
435     }
436 
437     /**
438      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForCurrentTransaction}.
439      * @deprecated Please use
440      * {@link UiccProfile#getCarrierPrivilegeStatusForCurrentTransaction(PackageManager)} instead.
441      */
442     @Deprecated
getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager)443     public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) {
444         if (mUiccProfile != null) {
445             return mUiccProfile.getCarrierPrivilegeStatusForCurrentTransaction(packageManager);
446         } else {
447             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
448         }
449     }
450 
451     /**
452      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
453      * @deprecated Please use
454      * {@link UiccProfile#getCarrierPackageNamesForIntent(PackageManager, Intent)} instead.
455      */
456     @UnsupportedAppUsage
457     @Deprecated
getCarrierPackageNamesForIntent( PackageManager packageManager, Intent intent)458     public List<String> getCarrierPackageNamesForIntent(
459             PackageManager packageManager, Intent intent) {
460         if (mUiccProfile != null) {
461             return mUiccProfile.getCarrierPackageNamesForIntent(packageManager, intent);
462         } else {
463             return null;
464         }
465     }
466 
467     /**
468      * @deprecated Please use {@link UiccProfile#setOperatorBrandOverride(String)} instead.
469      */
470     @Deprecated
setOperatorBrandOverride(String brand)471     public boolean setOperatorBrandOverride(String brand) {
472         if (mUiccProfile != null) {
473             return mUiccProfile.setOperatorBrandOverride(brand);
474         } else {
475             return false;
476         }
477     }
478 
479     /**
480      * @deprecated Please use {@link UiccProfile#getOperatorBrandOverride()} instead.
481      */
482     @UnsupportedAppUsage
483     @Deprecated
getOperatorBrandOverride()484     public String getOperatorBrandOverride() {
485         if (mUiccProfile != null) {
486             return mUiccProfile.getOperatorBrandOverride();
487         } else {
488             return null;
489         }
490     }
491 
492     @UnsupportedAppUsage
getIccId()493     public String getIccId() {
494         if (mIccid != null) {
495             return mIccid;
496         } else if (mUiccProfile != null) {
497             return mUiccProfile.getIccId();
498         } else {
499             return null;
500         }
501     }
502 
503     /**
504      * Returns the ID of this SIM card, it is the ICCID of the active profile on the card for a UICC
505      * card or the EID of the card for an eUICC card.
506      */
getCardId()507     public String getCardId() {
508         if (!TextUtils.isEmpty(mCardId)) {
509             return mCardId;
510         } else if (mUiccProfile != null) {
511             return mUiccProfile.getIccId();
512         } else {
513             return null;
514         }
515     }
516 
517     @UnsupportedAppUsage
log(String msg)518     private void log(String msg) {
519         Rlog.d(LOG_TAG, msg);
520     }
521 
522     @UnsupportedAppUsage
loge(String msg)523     private void loge(String msg) {
524         Rlog.e(LOG_TAG, msg);
525     }
526 
dump(FileDescriptor fd, PrintWriter pw, String[] args)527     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
528         pw.println("UiccCard:");
529         pw.println(" mCi=" + mCi);
530         pw.println(" mCardState=" + mCardState);
531         pw.println(" mCardId=" + mCardId);
532         pw.println(" mPhoneId=" + mPhoneId);
533         pw.println();
534         if (mUiccProfile != null) {
535             mUiccProfile.dump(fd, pw, args);
536         }
537     }
538 }
539