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