• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.app.usage.UsageStatsManager;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.SharedPreferences;
25 import android.content.pm.PackageInfo;
26 import android.content.pm.PackageManager;
27 import android.content.pm.Signature;
28 import android.database.ContentObserver;
29 import android.net.Uri;
30 import android.os.AsyncResult;
31 import android.os.Binder;
32 import android.os.Handler;
33 import android.os.Message;
34 import android.os.PersistableBundle;
35 import android.os.Registrant;
36 import android.os.RegistrantList;
37 import android.preference.PreferenceManager;
38 import android.provider.Settings;
39 import android.telephony.CarrierConfigManager;
40 import android.telephony.Rlog;
41 import android.telephony.ServiceState;
42 import android.telephony.SubscriptionInfo;
43 import android.telephony.SubscriptionManager;
44 import android.telephony.TelephonyManager;
45 import android.telephony.UiccAccessRule;
46 import android.text.TextUtils;
47 import android.util.ArrayMap;
48 import android.util.ArraySet;
49 
50 import com.android.internal.annotations.VisibleForTesting;
51 import com.android.internal.telephony.CommandsInterface;
52 import com.android.internal.telephony.IccCard;
53 import com.android.internal.telephony.IccCardConstants;
54 import com.android.internal.telephony.MccTable;
55 import com.android.internal.telephony.Phone;
56 import com.android.internal.telephony.PhoneConstants;
57 import com.android.internal.telephony.PhoneFactory;
58 import com.android.internal.telephony.SubscriptionController;
59 import com.android.internal.telephony.cat.CatService;
60 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
61 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
62 import com.android.internal.telephony.uicc.IccCardStatus.PinState;
63 import com.android.internal.telephony.uicc.euicc.EuiccCard;
64 
65 import java.io.FileDescriptor;
66 import java.io.PrintWriter;
67 import java.util.Arrays;
68 import java.util.Collections;
69 import java.util.List;
70 import java.util.Map;
71 import java.util.Set;
72 
73 /**
74  * This class represents the carrier profiles in the {@link UiccCard}. Each profile contains
75  * multiple {@link UiccCardApplication}, one {@link UiccCarrierPrivilegeRules} and one
76  * {@link CatService}.
77  *
78  * Profile is related to {@link android.telephony.SubscriptionInfo} but those two concepts are
79  * different. {@link android.telephony.SubscriptionInfo} contains all the subscription information
80  * while Profile contains all the {@link UiccCardApplication} which will be used to fetch those
81  * subscription information from the {@link UiccCard}.
82  *
83  * {@hide}
84  */
85 public class UiccProfile extends IccCard {
86     protected static final String LOG_TAG = "UiccProfile";
87     protected static final boolean DBG = true;
88     private static final boolean VDBG = false; //STOPSHIP if true
89 
90     private static final String OPERATOR_BRAND_OVERRIDE_PREFIX = "operator_branding_";
91 
92     // The lock object is created by UiccSlot that owns the UiccCard that owns this UiccProfile.
93     // This is to share the lock between UiccSlot, UiccCard and UiccProfile for now.
94     private final Object mLock;
95     private PinState mUniversalPinState;
96     private int mGsmUmtsSubscriptionAppIndex;
97     private int mCdmaSubscriptionAppIndex;
98     private int mImsSubscriptionAppIndex;
99     private UiccCardApplication[] mUiccApplications =
100             new UiccCardApplication[IccCardStatus.CARD_MAX_APPS];
101     private Context mContext;
102     private CommandsInterface mCi;
103     private final UiccCard mUiccCard; //parent
104     private CatService mCatService;
105     private UiccCarrierPrivilegeRules mCarrierPrivilegeRules;
106     private boolean mDisposed = false;
107 
108     private RegistrantList mCarrierPrivilegeRegistrants = new RegistrantList();
109     private RegistrantList mOperatorBrandOverrideRegistrants = new RegistrantList();
110 
111     private final int mPhoneId;
112 
113     private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 1;
114     private static final int EVENT_ICC_LOCKED = 2;
115     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
116     public static final int EVENT_APP_READY = 3;
117     private static final int EVENT_RECORDS_LOADED = 4;
118     private static final int EVENT_NETWORK_LOCKED = 5;
119     private static final int EVENT_EID_READY = 6;
120     private static final int EVENT_ICC_RECORD_EVENTS = 7;
121     private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 8;
122     private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 9;
123     private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 10;
124     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 11;
125     private static final int EVENT_SIM_IO_DONE = 12;
126     private static final int EVENT_CARRIER_PRIVILEGES_LOADED = 13;
127     private static final int EVENT_CARRIER_CONFIG_CHANGED = 14;
128 
129     private TelephonyManager mTelephonyManager;
130 
131     private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
132 
133     private int mCurrentAppType = UiccController.APP_FAM_3GPP; //default to 3gpp?
134     private UiccCardApplication mUiccApplication = null;
135     private IccRecords mIccRecords = null;
136     private IccCardConstants.State mExternalState = IccCardConstants.State.UNKNOWN;
137 
138     private final ContentObserver mProvisionCompleteContentObserver =
139             new ContentObserver(new Handler()) {
140                 @Override
141                 public void onChange(boolean selfChange) {
142                     mContext.getContentResolver().unregisterContentObserver(this);
143                     for (String pkgName : getUninstalledCarrierPackages()) {
144                         InstallCarrierAppUtils.showNotification(mContext, pkgName);
145                         InstallCarrierAppUtils.registerPackageInstallReceiver(mContext);
146                     }
147                 }
148             };
149 
150     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
151         @Override
152         public void onReceive(Context context, Intent intent) {
153             if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
154                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARRIER_CONFIG_CHANGED));
155             }
156         }
157     };
158 
159     @VisibleForTesting
160     public final Handler mHandler = new Handler() {
161         @Override
162         public void handleMessage(Message msg) {
163             // We still need to handle the following response messages even the UiccProfile has been
164             // disposed because whoever sent the request may be still waiting for the response.
165             if (mDisposed && msg.what != EVENT_OPEN_LOGICAL_CHANNEL_DONE
166                     && msg.what != EVENT_CLOSE_LOGICAL_CHANNEL_DONE
167                     && msg.what != EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE
168                     && msg.what != EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE
169                     && msg.what != EVENT_SIM_IO_DONE) {
170                 loge("handleMessage: Received " + msg.what
171                         + " after dispose(); ignoring the message");
172                 return;
173             }
174             loglocal("handleMessage: Received " + msg.what + " for phoneId " + mPhoneId);
175             switch (msg.what) {
176                 case EVENT_NETWORK_LOCKED:
177                     mNetworkLockedRegistrants.notifyRegistrants();
178                     // intentional fall through
179                 case EVENT_RADIO_OFF_OR_UNAVAILABLE:
180                 case EVENT_ICC_LOCKED:
181                 case EVENT_APP_READY:
182                 case EVENT_RECORDS_LOADED:
183                 case EVENT_EID_READY:
184                     if (VDBG) log("handleMessage: Received " + msg.what);
185                     updateExternalState();
186                     break;
187 
188                 case EVENT_ICC_RECORD_EVENTS:
189                     if ((mCurrentAppType == UiccController.APP_FAM_3GPP) && (mIccRecords != null)) {
190                         AsyncResult ar = (AsyncResult) msg.obj;
191                         int eventCode = (Integer) ar.result;
192                         if (eventCode == SIMRecords.EVENT_SPN) {
193                             mTelephonyManager.setSimOperatorNameForPhone(
194                                     mPhoneId, mIccRecords.getServiceProviderName());
195                         }
196                     }
197                     break;
198 
199                 case EVENT_CARRIER_PRIVILEGES_LOADED:
200                     if (VDBG) log("handleMessage: EVENT_CARRIER_PRIVILEGES_LOADED");
201                     onCarrierPrivilegesLoadedMessage();
202                     updateExternalState();
203                     break;
204 
205                 case EVENT_CARRIER_CONFIG_CHANGED:
206                     handleCarrierNameOverride();
207                     break;
208 
209                 case EVENT_OPEN_LOGICAL_CHANNEL_DONE:
210                 case EVENT_CLOSE_LOGICAL_CHANNEL_DONE:
211                 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
212                 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
213                 case EVENT_SIM_IO_DONE:
214                     AsyncResult ar = (AsyncResult) msg.obj;
215                     if (ar.exception != null) {
216                         loglocal("handleMessage: Exception " + ar.exception);
217                         log("handleMessage: Error in SIM access with exception" + ar.exception);
218                     }
219                     AsyncResult.forMessage((Message) ar.userObj, ar.result, ar.exception);
220                     ((Message) ar.userObj).sendToTarget();
221                     break;
222 
223                 default:
224                     loge("handleMessage: Unhandled message with number: " + msg.what);
225                     break;
226             }
227         }
228     };
229 
UiccProfile(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, UiccCard uiccCard, Object lock)230     public UiccProfile(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId,
231             UiccCard uiccCard, Object lock) {
232         if (DBG) log("Creating profile");
233         mLock = lock;
234         mUiccCard = uiccCard;
235         mPhoneId = phoneId;
236         // set current app type based on phone type - do this before calling update() as that
237         // calls updateIccAvailability() which uses mCurrentAppType
238         Phone phone = PhoneFactory.getPhone(phoneId);
239         if (phone != null) {
240             setCurrentAppType(phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM);
241         }
242 
243         if (mUiccCard instanceof EuiccCard) {
244             ((EuiccCard) mUiccCard).registerForEidReady(mHandler, EVENT_EID_READY, null);
245         }
246 
247         update(c, ci, ics);
248         ci.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_UNAVAILABLE, null);
249         resetProperties();
250 
251         IntentFilter intentfilter = new IntentFilter();
252         intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
253         c.registerReceiver(mReceiver, intentfilter);
254     }
255 
256     /**
257      * Dispose the UiccProfile.
258      */
dispose()259     public void dispose() {
260         if (DBG) log("Disposing profile");
261 
262         // mUiccCard is outside of mLock in order to prevent deadlocking. This is safe because
263         // EuiccCard#unregisterForEidReady handles its own lock
264         if (mUiccCard instanceof EuiccCard) {
265             ((EuiccCard) mUiccCard).unregisterForEidReady(mHandler);
266         }
267         synchronized (mLock) {
268             unregisterAllAppEvents();
269             unregisterCurrAppEvents();
270 
271             InstallCarrierAppUtils.hideAllNotifications(mContext);
272             InstallCarrierAppUtils.unregisterPackageInstallReceiver(mContext);
273 
274             mCi.unregisterForOffOrNotAvailable(mHandler);
275             mContext.unregisterReceiver(mReceiver);
276 
277             if (mCatService != null) mCatService.dispose();
278             for (UiccCardApplication app : mUiccApplications) {
279                 if (app != null) {
280                     app.dispose();
281                 }
282             }
283             mCatService = null;
284             mUiccApplications = null;
285             mCarrierPrivilegeRules = null;
286             mDisposed = true;
287         }
288     }
289 
290     /**
291      * The card application that the external world sees will be based on the
292      * voice radio technology only!
293      */
setVoiceRadioTech(int radioTech)294     public void setVoiceRadioTech(int radioTech) {
295         synchronized (mLock) {
296             if (DBG) {
297                 log("Setting radio tech " + ServiceState.rilRadioTechnologyToString(radioTech));
298             }
299             setCurrentAppType(ServiceState.isGsm(radioTech));
300             updateIccAvailability(false);
301         }
302     }
303 
setCurrentAppType(boolean isGsm)304     private void setCurrentAppType(boolean isGsm) {
305         if (VDBG) log("setCurrentAppType");
306         synchronized (mLock) {
307             boolean isLteOnCdmaMode = TelephonyManager.getLteOnCdmaModeStatic()
308                     == PhoneConstants.LTE_ON_CDMA_TRUE;
309             if (isGsm || isLteOnCdmaMode) {
310                 mCurrentAppType = UiccController.APP_FAM_3GPP;
311             } else {
312                 mCurrentAppType = UiccController.APP_FAM_3GPP2;
313             }
314         }
315     }
316 
317     /**
318      * Override the carrier name with either carrier config or SPN
319      * if an override is provided.
320      */
handleCarrierNameOverride()321     private void handleCarrierNameOverride() {
322         SubscriptionController subCon = SubscriptionController.getInstance();
323         final int subId = subCon.getSubIdUsingPhoneId(mPhoneId);
324         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
325             loge("subId not valid for Phone " + mPhoneId);
326             return;
327         }
328 
329         CarrierConfigManager configLoader = (CarrierConfigManager)
330                 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
331         if (configLoader == null) {
332             loge("Failed to load a Carrier Config");
333             return;
334         }
335 
336         PersistableBundle config = configLoader.getConfigForSubId(subId);
337         boolean preferCcName = config.getBoolean(
338                 CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
339         String ccName = config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
340         // If carrier config is priority, use it regardless - the preference
341         // and the name were both set by the carrier, so this is safe;
342         // otherwise, if the SPN is priority but we don't have one *and* we have
343         // a name in carrier config, use the carrier config name as a backup.
344         if (preferCcName || (TextUtils.isEmpty(getServiceProviderName())
345                 && !TextUtils.isEmpty(ccName))) {
346             if (mIccRecords != null) {
347                 mIccRecords.setServiceProviderName(ccName);
348             }
349             mTelephonyManager.setSimOperatorNameForPhone(mPhoneId, ccName);
350             mOperatorBrandOverrideRegistrants.notifyRegistrants();
351         }
352 
353         updateCarrierNameForSubscription(subCon, subId);
354     }
355 
updateCarrierNameForSubscription(SubscriptionController subCon, int subId)356     private void updateCarrierNameForSubscription(SubscriptionController subCon, int subId) {
357         /* update display name with carrier override */
358         SubscriptionInfo subInfo = subCon.getActiveSubscriptionInfo(
359                 subId, mContext.getOpPackageName());
360 
361         if (subInfo == null || subInfo.getNameSource()
362                 == SubscriptionManager.NAME_SOURCE_USER_INPUT) {
363             // either way, there is no subinfo to update
364             return;
365         }
366 
367         CharSequence oldSubName = subInfo.getDisplayName();
368         String newCarrierName = mTelephonyManager.getSimOperatorName(subId);
369 
370         if (!TextUtils.isEmpty(newCarrierName) && !newCarrierName.equals(oldSubName)) {
371             log("sim name[" + mPhoneId + "] = " + newCarrierName);
372             subCon.setDisplayName(newCarrierName, subId);
373         }
374     }
375 
updateIccAvailability(boolean allAppsChanged)376     private void updateIccAvailability(boolean allAppsChanged) {
377         synchronized (mLock) {
378             UiccCardApplication newApp;
379             IccRecords newRecords = null;
380             newApp = getApplication(mCurrentAppType);
381             if (newApp != null) {
382                 newRecords = newApp.getIccRecords();
383             }
384 
385             if (allAppsChanged) {
386                 unregisterAllAppEvents();
387                 registerAllAppEvents();
388             }
389 
390             if (mIccRecords != newRecords || mUiccApplication != newApp) {
391                 if (DBG) log("Icc changed. Reregistering.");
392                 unregisterCurrAppEvents();
393                 mUiccApplication = newApp;
394                 mIccRecords = newRecords;
395                 registerCurrAppEvents();
396             }
397             updateExternalState();
398         }
399     }
400 
resetProperties()401     void resetProperties() {
402         if (mCurrentAppType == UiccController.APP_FAM_3GPP) {
403             log("update icc_operator_numeric=" + "");
404             mTelephonyManager.setSimOperatorNumericForPhone(mPhoneId, "");
405             mTelephonyManager.setSimCountryIsoForPhone(mPhoneId, "");
406             mTelephonyManager.setSimOperatorNameForPhone(mPhoneId, "");
407         }
408     }
409 
410     /**
411      * Update the external SIM state
412      */
413     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
updateExternalState()414     public void updateExternalState() {
415         // First check if card state is IO_ERROR or RESTRICTED
416         if (mUiccCard.getCardState() == IccCardStatus.CardState.CARDSTATE_ERROR) {
417             setExternalState(IccCardConstants.State.CARD_IO_ERROR);
418             return;
419         }
420 
421         if (mUiccCard.getCardState() == IccCardStatus.CardState.CARDSTATE_RESTRICTED) {
422             setExternalState(IccCardConstants.State.CARD_RESTRICTED);
423             return;
424         }
425 
426         if (mUiccCard instanceof EuiccCard && ((EuiccCard) mUiccCard).getEid() == null) {
427             if (DBG) log("EID is not ready yet.");
428             return;
429         }
430 
431         // By process of elimination, the UICC Card State = PRESENT and state needs to be decided
432         // based on apps
433         if (mUiccApplication == null) {
434             loge("updateExternalState: setting state to NOT_READY because mUiccApplication is "
435                     + "null");
436             setExternalState(IccCardConstants.State.NOT_READY);
437             return;
438         }
439 
440         // Check if SIM is locked
441         boolean cardLocked = false;
442         IccCardConstants.State lockedState = null;
443         IccCardApplicationStatus.AppState appState = mUiccApplication.getState();
444 
445         PinState pin1State = mUiccApplication.getPin1State();
446         if (pin1State == PinState.PINSTATE_ENABLED_PERM_BLOCKED) {
447             if (VDBG) log("updateExternalState: PERM_DISABLED");
448             cardLocked = true;
449             lockedState = IccCardConstants.State.PERM_DISABLED;
450         } else {
451             if (appState == IccCardApplicationStatus.AppState.APPSTATE_PIN) {
452                 if (VDBG) log("updateExternalState: PIN_REQUIRED");
453                 cardLocked = true;
454                 lockedState = IccCardConstants.State.PIN_REQUIRED;
455             } else if (appState == IccCardApplicationStatus.AppState.APPSTATE_PUK) {
456                 if (VDBG) log("updateExternalState: PUK_REQUIRED");
457                 cardLocked = true;
458                 lockedState = IccCardConstants.State.PUK_REQUIRED;
459             } else if (appState == IccCardApplicationStatus.AppState.APPSTATE_SUBSCRIPTION_PERSO) {
460                 if (mUiccApplication.getPersoSubState()
461                         == IccCardApplicationStatus.PersoSubState.PERSOSUBSTATE_SIM_NETWORK) {
462                     if (VDBG) log("updateExternalState: PERSOSUBSTATE_SIM_NETWORK");
463                     cardLocked = true;
464                     lockedState = IccCardConstants.State.NETWORK_LOCKED;
465                 }
466             }
467         }
468 
469         // If SIM is locked, broadcast state as NOT_READY/LOCKED depending on if records are loaded
470         if (cardLocked) {
471             if (mIccRecords != null && (mIccRecords.getLockedRecordsLoaded()
472                     || mIccRecords.getNetworkLockedRecordsLoaded())) { // locked records loaded
473                 if (VDBG) {
474                     log("updateExternalState: card locked and records loaded; "
475                             + "setting state to locked");
476                 }
477                 setExternalState(lockedState);
478             } else {
479                 if (VDBG) {
480                     log("updateExternalState: card locked but records not loaded; "
481                             + "setting state to NOT_READY");
482                 }
483                 setExternalState(IccCardConstants.State.NOT_READY);
484             }
485             return;
486         }
487 
488         // Check for remaining app states
489         switch (appState) {
490             case APPSTATE_UNKNOWN:
491                 /*
492                  * APPSTATE_UNKNOWN is a catch-all state reported whenever the app
493                  * is not explicitly in one of the other states. To differentiate the
494                  * case where we know that there is a card present, but the APP is not
495                  * ready, we choose NOT_READY here instead of unknown. This is possible
496                  * in at least two cases:
497                  * 1) A transient during the process of the SIM bringup
498                  * 2) There is no valid App on the SIM to load, which can be the case with an
499                  *    eSIM/soft SIM.
500                  */
501                 if (VDBG) {
502                     log("updateExternalState: app state is unknown; setting state to NOT_READY");
503                 }
504                 setExternalState(IccCardConstants.State.NOT_READY);
505                 break;
506             case APPSTATE_READY:
507                 checkAndUpdateIfAnyAppToBeIgnored();
508                 if (areAllApplicationsReady()) {
509                     if (areAllRecordsLoaded() && areCarrierPriviligeRulesLoaded()) {
510                         if (VDBG) log("updateExternalState: setting state to LOADED");
511                         setExternalState(IccCardConstants.State.LOADED);
512                     } else {
513                         if (VDBG) {
514                             log("updateExternalState: setting state to READY; records loaded "
515                                     + areAllRecordsLoaded() + ", carrier privilige rules loaded "
516                                     + areCarrierPriviligeRulesLoaded());
517                         }
518                         setExternalState(IccCardConstants.State.READY);
519                     }
520                 } else {
521                     if (VDBG) {
522                         log("updateExternalState: app state is READY but not for all apps; "
523                                 + "setting state to NOT_READY");
524                     }
525                     setExternalState(IccCardConstants.State.NOT_READY);
526                 }
527                 break;
528         }
529     }
530 
registerAllAppEvents()531     private void registerAllAppEvents() {
532         // todo: all of these should be notified to UiccProfile directly without needing to register
533         for (UiccCardApplication app : mUiccApplications) {
534             if (app != null) {
535                 if (VDBG) log("registerUiccCardEvents: registering for EVENT_APP_READY");
536                 app.registerForReady(mHandler, EVENT_APP_READY, null);
537                 IccRecords ir = app.getIccRecords();
538                 if (ir != null) {
539                     if (VDBG) log("registerUiccCardEvents: registering for EVENT_RECORDS_LOADED");
540                     ir.registerForRecordsLoaded(mHandler, EVENT_RECORDS_LOADED, null);
541                     ir.registerForRecordsEvents(mHandler, EVENT_ICC_RECORD_EVENTS, null);
542                 }
543             }
544         }
545     }
546 
unregisterAllAppEvents()547     private void unregisterAllAppEvents() {
548         for (UiccCardApplication app : mUiccApplications) {
549             if (app != null) {
550                 app.unregisterForReady(mHandler);
551                 IccRecords ir = app.getIccRecords();
552                 if (ir != null) {
553                     ir.unregisterForRecordsLoaded(mHandler);
554                     ir.unregisterForRecordsEvents(mHandler);
555                 }
556             }
557         }
558     }
559 
registerCurrAppEvents()560     private void registerCurrAppEvents() {
561         // In case of locked, only listen to the current application.
562         if (mIccRecords != null) {
563             mIccRecords.registerForLockedRecordsLoaded(mHandler, EVENT_ICC_LOCKED, null);
564             mIccRecords.registerForNetworkLockedRecordsLoaded(mHandler, EVENT_NETWORK_LOCKED, null);
565         }
566     }
567 
unregisterCurrAppEvents()568     private void unregisterCurrAppEvents() {
569         if (mIccRecords != null) {
570             mIccRecords.unregisterForLockedRecordsLoaded(mHandler);
571             mIccRecords.unregisterForNetworkLockedRecordsLoaded(mHandler);
572         }
573     }
574 
setExternalState(IccCardConstants.State newState, boolean override)575     private void setExternalState(IccCardConstants.State newState, boolean override) {
576         synchronized (mLock) {
577             if (!SubscriptionManager.isValidSlotIndex(mPhoneId)) {
578                 loge("setExternalState: mPhoneId=" + mPhoneId + " is invalid; Return!!");
579                 return;
580             }
581 
582             if (!override && newState == mExternalState) {
583                 log("setExternalState: !override and newstate unchanged from " + newState);
584                 return;
585             }
586             mExternalState = newState;
587             if (mExternalState == IccCardConstants.State.LOADED) {
588                 // Update the MCC/MNC.
589                 if (mIccRecords != null) {
590                     String operator = mIccRecords.getOperatorNumeric();
591                     log("setExternalState: operator=" + operator + " mPhoneId=" + mPhoneId);
592 
593                     if (!TextUtils.isEmpty(operator)) {
594                         mTelephonyManager.setSimOperatorNumericForPhone(mPhoneId, operator);
595                         String countryCode = operator.substring(0, 3);
596                         if (countryCode != null) {
597                             mTelephonyManager.setSimCountryIsoForPhone(mPhoneId,
598                                     MccTable.countryCodeForMcc(Integer.parseInt(countryCode)));
599                         } else {
600                             loge("setExternalState: state LOADED; Country code is null");
601                         }
602                     } else {
603                         loge("setExternalState: state LOADED; Operator name is null");
604                     }
605                 }
606             }
607             log("setExternalState: set mPhoneId=" + mPhoneId + " mExternalState=" + mExternalState);
608             mTelephonyManager.setSimStateForPhone(mPhoneId, getState().toString());
609 
610             UiccController.updateInternalIccState(getIccStateIntentString(mExternalState),
611                     getIccStateReason(mExternalState), mPhoneId);
612         }
613     }
614 
setExternalState(IccCardConstants.State newState)615     private void setExternalState(IccCardConstants.State newState) {
616         setExternalState(newState, false);
617     }
618 
619     /**
620      * Function to check if all ICC records have been loaded
621      * @return true if all ICC records have been loaded, false otherwise.
622      */
getIccRecordsLoaded()623     public boolean getIccRecordsLoaded() {
624         synchronized (mLock) {
625             if (mIccRecords != null) {
626                 return mIccRecords.getRecordsLoaded();
627             }
628             return false;
629         }
630     }
631 
getIccStateIntentString(IccCardConstants.State state)632     private String getIccStateIntentString(IccCardConstants.State state) {
633         switch (state) {
634             case ABSENT: return IccCardConstants.INTENT_VALUE_ICC_ABSENT;
635             case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
636             case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
637             case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
638             case READY: return IccCardConstants.INTENT_VALUE_ICC_READY;
639             case NOT_READY: return IccCardConstants.INTENT_VALUE_ICC_NOT_READY;
640             case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
641             case CARD_IO_ERROR: return IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR;
642             case CARD_RESTRICTED: return IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED;
643             case LOADED: return IccCardConstants.INTENT_VALUE_ICC_LOADED;
644             default: return IccCardConstants.INTENT_VALUE_ICC_UNKNOWN;
645         }
646     }
647 
648     /**
649      * Locked state have a reason (PIN, PUK, NETWORK, PERM_DISABLED, CARD_IO_ERROR)
650      * @return reason
651      */
getIccStateReason(IccCardConstants.State state)652     private String getIccStateReason(IccCardConstants.State state) {
653         switch (state) {
654             case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN;
655             case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK;
656             case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_LOCKED_NETWORK;
657             case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED;
658             case CARD_IO_ERROR: return IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR;
659             case CARD_RESTRICTED: return IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED;
660             default: return null;
661         }
662     }
663 
664     /* IccCard interface implementation */
665     @Override
getState()666     public IccCardConstants.State getState() {
667         synchronized (mLock) {
668             return mExternalState;
669         }
670     }
671 
672     @Override
getIccRecords()673     public IccRecords getIccRecords() {
674         synchronized (mLock) {
675             return mIccRecords;
676         }
677     }
678 
679     /**
680      * Notifies handler of any transition into State.NETWORK_LOCKED
681      */
682     @Override
registerForNetworkLocked(Handler h, int what, Object obj)683     public void registerForNetworkLocked(Handler h, int what, Object obj) {
684         synchronized (mLock) {
685             Registrant r = new Registrant(h, what, obj);
686 
687             mNetworkLockedRegistrants.add(r);
688 
689             if (getState() == IccCardConstants.State.NETWORK_LOCKED) {
690                 r.notifyRegistrant();
691             }
692         }
693     }
694 
695     @Override
unregisterForNetworkLocked(Handler h)696     public void unregisterForNetworkLocked(Handler h) {
697         synchronized (mLock) {
698             mNetworkLockedRegistrants.remove(h);
699         }
700     }
701 
702     @Override
supplyPin(String pin, Message onComplete)703     public void supplyPin(String pin, Message onComplete) {
704         synchronized (mLock) {
705             if (mUiccApplication != null) {
706                 mUiccApplication.supplyPin(pin, onComplete);
707             } else if (onComplete != null) {
708                 Exception e = new RuntimeException("ICC card is absent.");
709                 AsyncResult.forMessage(onComplete).exception = e;
710                 onComplete.sendToTarget();
711                 return;
712             }
713         }
714     }
715 
716     @Override
supplyPuk(String puk, String newPin, Message onComplete)717     public void supplyPuk(String puk, String newPin, Message onComplete) {
718         synchronized (mLock) {
719             if (mUiccApplication != null) {
720                 mUiccApplication.supplyPuk(puk, newPin, onComplete);
721             } else if (onComplete != null) {
722                 Exception e = new RuntimeException("ICC card is absent.");
723                 AsyncResult.forMessage(onComplete).exception = e;
724                 onComplete.sendToTarget();
725                 return;
726             }
727         }
728     }
729 
730     @Override
supplyPin2(String pin2, Message onComplete)731     public void supplyPin2(String pin2, Message onComplete) {
732         synchronized (mLock) {
733             if (mUiccApplication != null) {
734                 mUiccApplication.supplyPin2(pin2, onComplete);
735             } else if (onComplete != null) {
736                 Exception e = new RuntimeException("ICC card is absent.");
737                 AsyncResult.forMessage(onComplete).exception = e;
738                 onComplete.sendToTarget();
739                 return;
740             }
741         }
742     }
743 
744     @Override
supplyPuk2(String puk2, String newPin2, Message onComplete)745     public void supplyPuk2(String puk2, String newPin2, Message onComplete) {
746         synchronized (mLock) {
747             if (mUiccApplication != null) {
748                 mUiccApplication.supplyPuk2(puk2, newPin2, onComplete);
749             } else if (onComplete != null) {
750                 Exception e = new RuntimeException("ICC card is absent.");
751                 AsyncResult.forMessage(onComplete).exception = e;
752                 onComplete.sendToTarget();
753                 return;
754             }
755         }
756     }
757 
758     @Override
supplyNetworkDepersonalization(String pin, Message onComplete)759     public void supplyNetworkDepersonalization(String pin, Message onComplete) {
760         synchronized (mLock) {
761             if (mUiccApplication != null) {
762                 mUiccApplication.supplyNetworkDepersonalization(pin, onComplete);
763             } else if (onComplete != null) {
764                 Exception e = new RuntimeException("CommandsInterface is not set.");
765                 AsyncResult.forMessage(onComplete).exception = e;
766                 onComplete.sendToTarget();
767                 return;
768             }
769         }
770     }
771 
772     @Override
getIccLockEnabled()773     public boolean getIccLockEnabled() {
774         synchronized (mLock) {
775             /* defaults to false, if ICC is absent/deactivated */
776             return mUiccApplication != null && mUiccApplication.getIccLockEnabled();
777         }
778     }
779 
780     @Override
getIccFdnEnabled()781     public boolean getIccFdnEnabled() {
782         synchronized (mLock) {
783             return mUiccApplication != null && mUiccApplication.getIccFdnEnabled();
784         }
785     }
786 
787     @Override
getIccPin2Blocked()788     public boolean getIccPin2Blocked() {
789         /* defaults to disabled */
790         return mUiccApplication != null && mUiccApplication.getIccPin2Blocked();
791     }
792 
793     @Override
getIccPuk2Blocked()794     public boolean getIccPuk2Blocked() {
795         /* defaults to disabled */
796         return mUiccApplication != null && mUiccApplication.getIccPuk2Blocked();
797     }
798 
799     @Override
setIccLockEnabled(boolean enabled, String password, Message onComplete)800     public void setIccLockEnabled(boolean enabled, String password, Message onComplete) {
801         synchronized (mLock) {
802             if (mUiccApplication != null) {
803                 mUiccApplication.setIccLockEnabled(enabled, password, onComplete);
804             } else if (onComplete != null) {
805                 Exception e = new RuntimeException("ICC card is absent.");
806                 AsyncResult.forMessage(onComplete).exception = e;
807                 onComplete.sendToTarget();
808                 return;
809             }
810         }
811     }
812 
813     @Override
setIccFdnEnabled(boolean enabled, String password, Message onComplete)814     public void setIccFdnEnabled(boolean enabled, String password, Message onComplete) {
815         synchronized (mLock) {
816             if (mUiccApplication != null) {
817                 mUiccApplication.setIccFdnEnabled(enabled, password, onComplete);
818             } else if (onComplete != null) {
819                 Exception e = new RuntimeException("ICC card is absent.");
820                 AsyncResult.forMessage(onComplete).exception = e;
821                 onComplete.sendToTarget();
822                 return;
823             }
824         }
825     }
826 
827     @Override
changeIccLockPassword(String oldPassword, String newPassword, Message onComplete)828     public void changeIccLockPassword(String oldPassword, String newPassword, Message onComplete) {
829         synchronized (mLock) {
830             if (mUiccApplication != null) {
831                 mUiccApplication.changeIccLockPassword(oldPassword, newPassword, onComplete);
832             } else if (onComplete != null) {
833                 Exception e = new RuntimeException("ICC card is absent.");
834                 AsyncResult.forMessage(onComplete).exception = e;
835                 onComplete.sendToTarget();
836                 return;
837             }
838         }
839     }
840 
841     @Override
changeIccFdnPassword(String oldPassword, String newPassword, Message onComplete)842     public void changeIccFdnPassword(String oldPassword, String newPassword, Message onComplete) {
843         synchronized (mLock) {
844             if (mUiccApplication != null) {
845                 mUiccApplication.changeIccFdnPassword(oldPassword, newPassword, onComplete);
846             } else if (onComplete != null) {
847                 Exception e = new RuntimeException("ICC card is absent.");
848                 AsyncResult.forMessage(onComplete).exception = e;
849                 onComplete.sendToTarget();
850                 return;
851             }
852         }
853     }
854 
855     @Override
getServiceProviderName()856     public String getServiceProviderName() {
857         synchronized (mLock) {
858             if (mIccRecords != null) {
859                 return mIccRecords.getServiceProviderName();
860             }
861             return null;
862         }
863     }
864 
865     @Override
hasIccCard()866     public boolean hasIccCard() {
867         // mUiccCard is initialized in constructor, so won't be null
868         if (mUiccCard.getCardState()
869                 != IccCardStatus.CardState.CARDSTATE_ABSENT) {
870             return true;
871         }
872         loge("hasIccCard: UiccProfile is not null but UiccCard is null or card state is "
873                 + "ABSENT");
874         return false;
875     }
876 
877     /**
878      * Update the UiccProfile.
879      */
update(Context c, CommandsInterface ci, IccCardStatus ics)880     public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
881         synchronized (mLock) {
882             mUniversalPinState = ics.mUniversalPinState;
883             mGsmUmtsSubscriptionAppIndex = ics.mGsmUmtsSubscriptionAppIndex;
884             mCdmaSubscriptionAppIndex = ics.mCdmaSubscriptionAppIndex;
885             mImsSubscriptionAppIndex = ics.mImsSubscriptionAppIndex;
886             mContext = c;
887             mCi = ci;
888             mTelephonyManager = (TelephonyManager) mContext.getSystemService(
889                     Context.TELEPHONY_SERVICE);
890 
891             //update applications
892             if (DBG) log(ics.mApplications.length + " applications");
893             for (int i = 0; i < mUiccApplications.length; i++) {
894                 if (mUiccApplications[i] == null) {
895                     //Create newly added Applications
896                     if (i < ics.mApplications.length) {
897                         mUiccApplications[i] = new UiccCardApplication(this,
898                                 ics.mApplications[i], mContext, mCi);
899                     }
900                 } else if (i >= ics.mApplications.length) {
901                     //Delete removed applications
902                     mUiccApplications[i].dispose();
903                     mUiccApplications[i] = null;
904                 } else {
905                     //Update the rest
906                     mUiccApplications[i].update(ics.mApplications[i], mContext, mCi);
907                 }
908             }
909 
910             createAndUpdateCatServiceLocked();
911 
912             // Reload the carrier privilege rules if necessary.
913             log("Before privilege rules: " + mCarrierPrivilegeRules + " : " + ics.mCardState);
914             if (mCarrierPrivilegeRules == null && ics.mCardState == CardState.CARDSTATE_PRESENT) {
915                 mCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(this,
916                         mHandler.obtainMessage(EVENT_CARRIER_PRIVILEGES_LOADED));
917             } else if (mCarrierPrivilegeRules != null
918                     && ics.mCardState != CardState.CARDSTATE_PRESENT) {
919                 mCarrierPrivilegeRules = null;
920             }
921 
922             sanitizeApplicationIndexesLocked();
923             updateIccAvailability(true);
924         }
925     }
926 
createAndUpdateCatServiceLocked()927     private void createAndUpdateCatServiceLocked() {
928         if (mUiccApplications.length > 0 && mUiccApplications[0] != null) {
929             // Initialize or Reinitialize CatService
930             if (mCatService == null) {
931                 mCatService = CatService.getInstance(mCi, mContext, this, mPhoneId);
932             } else {
933                 mCatService.update(mCi, mContext, this);
934             }
935         } else {
936             if (mCatService != null) {
937                 mCatService.dispose();
938             }
939             mCatService = null;
940         }
941     }
942 
943     @Override
finalize()944     protected void finalize() {
945         if (DBG) log("UiccProfile finalized");
946     }
947 
948     /**
949      * This function makes sure that application indexes are valid
950      * and resets invalid indexes. (This should never happen, but in case
951      * RIL misbehaves we need to manage situation gracefully)
952      */
sanitizeApplicationIndexesLocked()953     private void sanitizeApplicationIndexesLocked() {
954         mGsmUmtsSubscriptionAppIndex =
955                 checkIndexLocked(
956                         mGsmUmtsSubscriptionAppIndex, AppType.APPTYPE_SIM, AppType.APPTYPE_USIM);
957         mCdmaSubscriptionAppIndex =
958                 checkIndexLocked(
959                         mCdmaSubscriptionAppIndex, AppType.APPTYPE_RUIM, AppType.APPTYPE_CSIM);
960         mImsSubscriptionAppIndex =
961                 checkIndexLocked(mImsSubscriptionAppIndex, AppType.APPTYPE_ISIM, null);
962     }
963 
964     /**
965      * Checks if the app is supported for the purposes of checking if all apps are ready/loaded, so
966      * this only checks for SIM/USIM and CSIM/RUIM apps. ISIM is considered not supported for this
967      * purpose as there are cards that have ISIM app that is never read (there are SIMs for which
968      * the state of ISIM goes to DETECTED but never to READY).
969      */
isSupportedApplication(UiccCardApplication app)970     private boolean isSupportedApplication(UiccCardApplication app) {
971         // TODO: 2/15/18 Add check to see if ISIM app will go to READY state, and if yes, check for
972         // ISIM also (currently ISIM is considered as not supported in this function)
973         if (app.getType() != AppType.APPTYPE_USIM && app.getType() != AppType.APPTYPE_CSIM
974                 && app.getType() != AppType.APPTYPE_SIM && app.getType() != AppType.APPTYPE_RUIM) {
975             return false;
976         }
977         return true;
978     }
979 
checkAndUpdateIfAnyAppToBeIgnored()980     private void checkAndUpdateIfAnyAppToBeIgnored() {
981         boolean[] appReadyStateTracker = new boolean[AppType.APPTYPE_ISIM.ordinal() + 1];
982         for (UiccCardApplication app : mUiccApplications) {
983             if (app != null && isSupportedApplication(app) && app.isReady()) {
984                 appReadyStateTracker[app.getType().ordinal()] = true;
985             }
986         }
987 
988         for (UiccCardApplication app : mUiccApplications) {
989             if (app != null && isSupportedApplication(app) && !app.isReady()) {
990                 /* Checks if the  appReadyStateTracker has already an entry in ready state
991                    with same type as app */
992                 if (appReadyStateTracker[app.getType().ordinal()]) {
993                     app.setAppIgnoreState(true);
994                 }
995             }
996         }
997     }
998 
areAllApplicationsReady()999     private boolean areAllApplicationsReady() {
1000         for (UiccCardApplication app : mUiccApplications) {
1001             if (app != null && isSupportedApplication(app) && !app.isReady()
1002                     && !app.isAppIgnored()) {
1003                 if (VDBG) log("areAllApplicationsReady: return false");
1004                 return false;
1005             }
1006         }
1007 
1008         if (VDBG) {
1009             log("areAllApplicationsReady: outside loop, return " + (mUiccApplication != null));
1010         }
1011         return mUiccApplication != null;
1012     }
1013 
areAllRecordsLoaded()1014     private boolean areAllRecordsLoaded() {
1015         for (UiccCardApplication app : mUiccApplications) {
1016             if (app != null && isSupportedApplication(app) && !app.isAppIgnored()) {
1017                 IccRecords ir = app.getIccRecords();
1018                 if (ir == null || !ir.isLoaded()) {
1019                     if (VDBG) log("areAllRecordsLoaded: return false");
1020                     return false;
1021                 }
1022             }
1023         }
1024         if (VDBG) {
1025             log("areAllRecordsLoaded: outside loop, return " + (mUiccApplication != null));
1026         }
1027         return mUiccApplication != null;
1028     }
1029 
checkIndexLocked(int index, AppType expectedAppType, AppType altExpectedAppType)1030     private int checkIndexLocked(int index, AppType expectedAppType, AppType altExpectedAppType) {
1031         if (mUiccApplications == null || index >= mUiccApplications.length) {
1032             loge("App index " + index + " is invalid since there are no applications");
1033             return -1;
1034         }
1035 
1036         if (index < 0) {
1037             // This is normal. (i.e. no application of this type)
1038             return -1;
1039         }
1040 
1041         if (mUiccApplications[index].getType() != expectedAppType
1042                 && mUiccApplications[index].getType() != altExpectedAppType) {
1043             loge("App index " + index + " is invalid since it's not "
1044                     + expectedAppType + " and not " + altExpectedAppType);
1045             return -1;
1046         }
1047 
1048         // Seems to be valid
1049         return index;
1050     }
1051 
1052     /**
1053      * Registers the handler when operator brand name is overridden.
1054      *
1055      * @param h Handler for notification message.
1056      * @param what User-defined message code.
1057      * @param obj User object.
1058      */
registerForOpertorBrandOverride(Handler h, int what, Object obj)1059     public void registerForOpertorBrandOverride(Handler h, int what, Object obj) {
1060         synchronized (mLock) {
1061             Registrant r = new Registrant(h, what, obj);
1062             mOperatorBrandOverrideRegistrants.add(r);
1063         }
1064     }
1065 
1066     /**
1067      * Registers the handler when carrier privilege rules are loaded.
1068      *
1069      * @param h Handler for notification message.
1070      * @param what User-defined message code.
1071      * @param obj User object.
1072      */
registerForCarrierPrivilegeRulesLoaded(Handler h, int what, Object obj)1073     public void registerForCarrierPrivilegeRulesLoaded(Handler h, int what, Object obj) {
1074         synchronized (mLock) {
1075             Registrant r = new Registrant(h, what, obj);
1076 
1077             mCarrierPrivilegeRegistrants.add(r);
1078 
1079             if (areCarrierPriviligeRulesLoaded()) {
1080                 r.notifyRegistrant();
1081             }
1082         }
1083     }
1084 
1085     /**
1086      * Unregister for notifications when carrier privilege rules are loaded.
1087      *
1088      * @param h Handler to be removed from the registrant list.
1089      */
unregisterForCarrierPrivilegeRulesLoaded(Handler h)1090     public void unregisterForCarrierPrivilegeRulesLoaded(Handler h) {
1091         synchronized (mLock) {
1092             mCarrierPrivilegeRegistrants.remove(h);
1093         }
1094     }
1095 
1096     /**
1097      * Unregister for notifications when operator brand name is overriden.
1098      *
1099      * @param h Handler to be removed from the registrant list.
1100      */
unregisterForOperatorBrandOverride(Handler h)1101     public void unregisterForOperatorBrandOverride(Handler h) {
1102         synchronized (mLock) {
1103             mOperatorBrandOverrideRegistrants.remove(h);
1104         }
1105     }
1106 
isPackageInstalled(Context context, String pkgName)1107     static boolean isPackageInstalled(Context context, String pkgName) {
1108         PackageManager pm = context.getPackageManager();
1109         try {
1110             pm.getPackageInfo(pkgName, PackageManager.GET_ACTIVITIES);
1111             if (DBG) log(pkgName + " is installed.");
1112             return true;
1113         } catch (PackageManager.NameNotFoundException e) {
1114             if (DBG) log(pkgName + " is not installed.");
1115             return false;
1116         }
1117     }
1118 
promptInstallCarrierApp(String pkgName)1119     private void promptInstallCarrierApp(String pkgName) {
1120         Intent showDialogIntent = InstallCarrierAppTrampolineActivity.get(mContext, pkgName);
1121         mContext.startActivity(showDialogIntent);
1122     }
1123 
onCarrierPrivilegesLoadedMessage()1124     private void onCarrierPrivilegesLoadedMessage() {
1125         UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(
1126                 Context.USAGE_STATS_SERVICE);
1127         if (usm != null) {
1128             usm.onCarrierPrivilegedAppsChanged();
1129         }
1130 
1131         InstallCarrierAppUtils.hideAllNotifications(mContext);
1132         InstallCarrierAppUtils.unregisterPackageInstallReceiver(mContext);
1133 
1134         synchronized (mLock) {
1135             mCarrierPrivilegeRegistrants.notifyRegistrants();
1136             boolean isProvisioned = Settings.Global.getInt(
1137                     mContext.getContentResolver(),
1138                     Settings.Global.DEVICE_PROVISIONED, 1) == 1;
1139             // Only show dialog if the phone is through with Setup Wizard.  Otherwise, wait for
1140             // completion and show a notification instead
1141             if (isProvisioned) {
1142                 for (String pkgName : getUninstalledCarrierPackages()) {
1143                     promptInstallCarrierApp(pkgName);
1144                 }
1145             } else {
1146                 final Uri uri = Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED);
1147                 mContext.getContentResolver().registerContentObserver(
1148                         uri,
1149                         false,
1150                         mProvisionCompleteContentObserver);
1151             }
1152         }
1153     }
1154 
getUninstalledCarrierPackages()1155     private Set<String> getUninstalledCarrierPackages() {
1156         String whitelistSetting = Settings.Global.getString(
1157                 mContext.getContentResolver(),
1158                 Settings.Global.CARRIER_APP_WHITELIST);
1159         if (TextUtils.isEmpty(whitelistSetting)) {
1160             return Collections.emptySet();
1161         }
1162         Map<String, String> certPackageMap = parseToCertificateToPackageMap(whitelistSetting);
1163         if (certPackageMap.isEmpty()) {
1164             return Collections.emptySet();
1165         }
1166 
1167         Set<String> uninstalledCarrierPackages = new ArraySet<>();
1168         List<UiccAccessRule> accessRules = mCarrierPrivilegeRules.getAccessRules();
1169         for (UiccAccessRule accessRule : accessRules) {
1170             String certHexString = accessRule.getCertificateHexString().toUpperCase();
1171             String pkgName = certPackageMap.get(certHexString);
1172             if (!TextUtils.isEmpty(pkgName) && !isPackageInstalled(mContext, pkgName)) {
1173                 uninstalledCarrierPackages.add(pkgName);
1174             }
1175         }
1176         return uninstalledCarrierPackages;
1177     }
1178 
1179     /**
1180      * Converts a string in the format: key1:value1;key2:value2... into a map where the keys are
1181      * hex representations of app certificates - all upper case - and the values are package names
1182      * @hide
1183      */
1184     @VisibleForTesting
parseToCertificateToPackageMap(String whitelistSetting)1185     public static Map<String, String> parseToCertificateToPackageMap(String whitelistSetting) {
1186         final String pairDelim = "\\s*;\\s*";
1187         final String keyValueDelim = "\\s*:\\s*";
1188 
1189         List<String> keyValuePairList = Arrays.asList(whitelistSetting.split(pairDelim));
1190 
1191         if (keyValuePairList.isEmpty()) {
1192             return Collections.emptyMap();
1193         }
1194 
1195         Map<String, String> map = new ArrayMap<>(keyValuePairList.size());
1196         for (String keyValueString: keyValuePairList) {
1197             String[] keyValue = keyValueString.split(keyValueDelim);
1198 
1199             if (keyValue.length == 2) {
1200                 map.put(keyValue[0].toUpperCase(), keyValue[1]);
1201             } else {
1202                 loge("Incorrect length of key-value pair in carrier app whitelist map.  "
1203                         + "Length should be exactly 2");
1204             }
1205         }
1206 
1207         return map;
1208     }
1209 
1210     /**
1211      * Check whether the specified type of application exists in the profile.
1212      *
1213      * @param type UICC application type.
1214      */
isApplicationOnIcc(IccCardApplicationStatus.AppType type)1215     public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) {
1216         synchronized (mLock) {
1217             for (int i = 0; i < mUiccApplications.length; i++) {
1218                 if (mUiccApplications[i] != null && mUiccApplications[i].getType() == type) {
1219                     return true;
1220                 }
1221             }
1222             return false;
1223         }
1224     }
1225 
1226     /**
1227      * Return the universal pin state of the profile.
1228      */
getUniversalPinState()1229     public PinState getUniversalPinState() {
1230         synchronized (mLock) {
1231             return mUniversalPinState;
1232         }
1233     }
1234 
1235     /**
1236      * Return the application of the specified family.
1237      *
1238      * @param family UICC application family.
1239      * @return application corresponding to family or a null if no match found
1240      */
getApplication(int family)1241     public UiccCardApplication getApplication(int family) {
1242         synchronized (mLock) {
1243             int index = IccCardStatus.CARD_MAX_APPS;
1244             switch (family) {
1245                 case UiccController.APP_FAM_3GPP:
1246                     index = mGsmUmtsSubscriptionAppIndex;
1247                     break;
1248                 case UiccController.APP_FAM_3GPP2:
1249                     index = mCdmaSubscriptionAppIndex;
1250                     break;
1251                 case UiccController.APP_FAM_IMS:
1252                     index = mImsSubscriptionAppIndex;
1253                     break;
1254             }
1255             if (index >= 0 && index < mUiccApplications.length) {
1256                 return mUiccApplications[index];
1257             }
1258             return null;
1259         }
1260     }
1261 
1262     /**
1263      * Return the application with the index of the array.
1264      *
1265      * @param index Index of the application array.
1266      * @return application corresponding to index or a null if no match found
1267      */
getApplicationIndex(int index)1268     public UiccCardApplication getApplicationIndex(int index) {
1269         synchronized (mLock) {
1270             if (index >= 0 && index < mUiccApplications.length) {
1271                 return mUiccApplications[index];
1272             }
1273             return null;
1274         }
1275     }
1276 
1277     /**
1278      * Returns the SIM application of the specified type.
1279      *
1280      * @param type ICC application type
1281      * (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
1282      * @return application corresponding to type or a null if no match found
1283      */
getApplicationByType(int type)1284     public UiccCardApplication getApplicationByType(int type) {
1285         synchronized (mLock) {
1286             for (int i = 0; i < mUiccApplications.length; i++) {
1287                 if (mUiccApplications[i] != null
1288                         && mUiccApplications[i].getType().ordinal() == type) {
1289                     return mUiccApplications[i];
1290                 }
1291             }
1292             return null;
1293         }
1294     }
1295 
1296     /**
1297      * Resets the application with the input AID. Returns true if any changes were made.
1298      *
1299      * A null aid implies a card level reset - all applications must be reset.
1300      */
resetAppWithAid(String aid)1301     public boolean resetAppWithAid(String aid) {
1302         synchronized (mLock) {
1303             boolean changed = false;
1304             for (int i = 0; i < mUiccApplications.length; i++) {
1305                 if (mUiccApplications[i] != null
1306                         && (TextUtils.isEmpty(aid) || aid.equals(mUiccApplications[i].getAid()))) {
1307                     // Delete removed applications
1308                     mUiccApplications[i].dispose();
1309                     mUiccApplications[i] = null;
1310                     changed = true;
1311                 }
1312             }
1313             if (TextUtils.isEmpty(aid)) {
1314                 if (mCarrierPrivilegeRules != null) {
1315                     mCarrierPrivilegeRules = null;
1316                     changed = true;
1317                 }
1318                 if (mCatService != null) {
1319                     mCatService.dispose();
1320                     mCatService = null;
1321                     changed = true;
1322                 }
1323             }
1324             return changed;
1325         }
1326     }
1327 
1328     /**
1329      * Exposes {@link CommandsInterface#iccOpenLogicalChannel}
1330      */
iccOpenLogicalChannel(String aid, int p2, Message response)1331     public void iccOpenLogicalChannel(String aid, int p2, Message response) {
1332         loglocal("iccOpenLogicalChannel: " + aid + " , " + p2 + " by pid:" + Binder.getCallingPid()
1333                 + " uid:" + Binder.getCallingUid());
1334         mCi.iccOpenLogicalChannel(aid, p2,
1335                 mHandler.obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE, response));
1336     }
1337 
1338     /**
1339      * Exposes {@link CommandsInterface#iccCloseLogicalChannel}
1340      */
iccCloseLogicalChannel(int channel, Message response)1341     public void iccCloseLogicalChannel(int channel, Message response) {
1342         loglocal("iccCloseLogicalChannel: " + channel);
1343         mCi.iccCloseLogicalChannel(channel,
1344                 mHandler.obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE, response));
1345     }
1346 
1347     /**
1348      * Exposes {@link CommandsInterface#iccTransmitApduLogicalChannel}
1349      */
iccTransmitApduLogicalChannel(int channel, int cla, int command, int p1, int p2, int p3, String data, Message response)1350     public void iccTransmitApduLogicalChannel(int channel, int cla, int command,
1351             int p1, int p2, int p3, String data, Message response) {
1352         mCi.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3,
1353                 data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, response));
1354     }
1355 
1356     /**
1357      * Exposes {@link CommandsInterface#iccTransmitApduBasicChannel}
1358      */
iccTransmitApduBasicChannel(int cla, int command, int p1, int p2, int p3, String data, Message response)1359     public void iccTransmitApduBasicChannel(int cla, int command,
1360             int p1, int p2, int p3, String data, Message response) {
1361         mCi.iccTransmitApduBasicChannel(cla, command, p1, p2, p3,
1362                 data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, response));
1363     }
1364 
1365     /**
1366      * Exposes {@link CommandsInterface#iccIO}
1367      */
iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, String pathID, Message response)1368     public void iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
1369             String pathID, Message response) {
1370         mCi.iccIO(command, fileID, pathID, p1, p2, p3, null, null,
1371                 mHandler.obtainMessage(EVENT_SIM_IO_DONE, response));
1372     }
1373 
1374     /**
1375      * Exposes {@link CommandsInterface#sendEnvelopeWithStatus}
1376      */
sendEnvelopeWithStatus(String contents, Message response)1377     public void sendEnvelopeWithStatus(String contents, Message response) {
1378         mCi.sendEnvelopeWithStatus(contents, response);
1379     }
1380 
1381     /**
1382      * Returns number of applications on this card
1383      */
getNumApplications()1384     public int getNumApplications() {
1385         int count = 0;
1386         for (UiccCardApplication a : mUiccApplications) {
1387             if (a != null) {
1388                 count++;
1389             }
1390         }
1391         return count;
1392     }
1393 
1394     /**
1395      * Returns the id of the phone which is associated with this profile.
1396      */
getPhoneId()1397     public int getPhoneId() {
1398         return mPhoneId;
1399     }
1400 
1401     /**
1402      * Returns true iff carrier privileges rules are null (dont need to be loaded) or loaded.
1403      */
areCarrierPriviligeRulesLoaded()1404     public boolean areCarrierPriviligeRulesLoaded() {
1405         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1406         return carrierPrivilegeRules == null
1407                 || carrierPrivilegeRules.areCarrierPriviligeRulesLoaded();
1408     }
1409 
1410     /**
1411      * Returns true if there are some carrier privilege rules loaded and specified.
1412      */
hasCarrierPrivilegeRules()1413     public boolean hasCarrierPrivilegeRules() {
1414         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1415         return carrierPrivilegeRules != null && carrierPrivilegeRules.hasCarrierPrivilegeRules();
1416     }
1417 
1418     /**
1419      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
1420      */
getCarrierPrivilegeStatus(Signature signature, String packageName)1421     public int getCarrierPrivilegeStatus(Signature signature, String packageName) {
1422         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1423         return carrierPrivilegeRules == null
1424                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
1425                 carrierPrivilegeRules.getCarrierPrivilegeStatus(signature, packageName);
1426     }
1427 
1428     /**
1429      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
1430      */
getCarrierPrivilegeStatus(PackageManager packageManager, String packageName)1431     public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) {
1432         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1433         return carrierPrivilegeRules == null
1434                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
1435                 carrierPrivilegeRules.getCarrierPrivilegeStatus(packageManager, packageName);
1436     }
1437 
1438     /**
1439      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
1440      */
getCarrierPrivilegeStatus(PackageInfo packageInfo)1441     public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
1442         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1443         return carrierPrivilegeRules == null
1444                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
1445                 carrierPrivilegeRules.getCarrierPrivilegeStatus(packageInfo);
1446     }
1447 
1448     /**
1449      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForCurrentTransaction}.
1450      */
getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager)1451     public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) {
1452         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1453         return carrierPrivilegeRules == null
1454                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
1455                 carrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction(
1456                         packageManager);
1457     }
1458 
1459     /**
1460      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForUid}.
1461      */
getCarrierPrivilegeStatusForUid(PackageManager packageManager, int uid)1462     public int getCarrierPrivilegeStatusForUid(PackageManager packageManager, int uid) {
1463         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1464         return carrierPrivilegeRules == null
1465                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
1466                 carrierPrivilegeRules.getCarrierPrivilegeStatusForUid(packageManager, uid);
1467     }
1468 
1469     /**
1470      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
1471      */
getCarrierPackageNamesForIntent( PackageManager packageManager, Intent intent)1472     public List<String> getCarrierPackageNamesForIntent(
1473             PackageManager packageManager, Intent intent) {
1474         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
1475         return carrierPrivilegeRules == null ? null :
1476                 carrierPrivilegeRules.getCarrierPackageNamesForIntent(
1477                         packageManager, intent);
1478     }
1479 
1480     /** Returns a reference to the current {@link UiccCarrierPrivilegeRules}. */
getCarrierPrivilegeRules()1481     private UiccCarrierPrivilegeRules getCarrierPrivilegeRules() {
1482         synchronized (mLock) {
1483             return mCarrierPrivilegeRules;
1484         }
1485     }
1486 
1487     /**
1488      * Sets the overridden operator brand.
1489      */
setOperatorBrandOverride(String brand)1490     public boolean setOperatorBrandOverride(String brand) {
1491         log("setOperatorBrandOverride: " + brand);
1492         log("current iccId: " + SubscriptionInfo.givePrintableIccid(getIccId()));
1493 
1494         String iccId = getIccId();
1495         if (TextUtils.isEmpty(iccId)) {
1496             return false;
1497         }
1498 
1499         SharedPreferences.Editor spEditor =
1500                 PreferenceManager.getDefaultSharedPreferences(mContext).edit();
1501         String key = OPERATOR_BRAND_OVERRIDE_PREFIX + iccId;
1502         if (brand == null) {
1503             spEditor.remove(key).commit();
1504         } else {
1505             spEditor.putString(key, brand).commit();
1506         }
1507         mOperatorBrandOverrideRegistrants.notifyRegistrants();
1508         return true;
1509     }
1510 
1511     /**
1512      * Returns the overridden operator brand.
1513      */
getOperatorBrandOverride()1514     public String getOperatorBrandOverride() {
1515         String iccId = getIccId();
1516         if (TextUtils.isEmpty(iccId)) {
1517             return null;
1518         }
1519         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1520         return sp.getString(OPERATOR_BRAND_OVERRIDE_PREFIX + iccId, null);
1521     }
1522 
1523     /**
1524      * Returns the iccid of the profile.
1525      */
getIccId()1526     public String getIccId() {
1527         // ICCID should be same across all the apps.
1528         for (UiccCardApplication app : mUiccApplications) {
1529             if (app != null) {
1530                 IccRecords ir = app.getIccRecords();
1531                 if (ir != null && ir.getIccId() != null) {
1532                     return ir.getIccId();
1533                 }
1534             }
1535         }
1536         return null;
1537     }
1538 
log(String msg)1539     private static void log(String msg) {
1540         Rlog.d(LOG_TAG, msg);
1541     }
1542 
loge(String msg)1543     private static void loge(String msg) {
1544         Rlog.e(LOG_TAG, msg);
1545     }
1546 
loglocal(String msg)1547     private void loglocal(String msg) {
1548         if (DBG) UiccController.sLocalLog.log("UiccProfile[" + mPhoneId + "]: " + msg);
1549     }
1550 
1551     /**
1552      * Reloads carrier privileges as if a change were just detected.  Useful to force a profile
1553      * refresh without having to physically insert or remove a SIM card.
1554      */
1555     @VisibleForTesting
refresh()1556     public void refresh() {
1557         mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARRIER_PRIVILEGES_LOADED));
1558     }
1559 
1560     /**
1561      * Dump
1562      */
dump(FileDescriptor fd, PrintWriter pw, String[] args)1563     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1564         pw.println("UiccProfile:");
1565         pw.println(" mCi=" + mCi);
1566         pw.println(" mCatService=" + mCatService);
1567         for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
1568             pw.println("  mCarrierPrivilegeRegistrants[" + i + "]="
1569                     + ((Registrant) mCarrierPrivilegeRegistrants.get(i)).getHandler());
1570         }
1571         for (int i = 0; i < mOperatorBrandOverrideRegistrants.size(); i++) {
1572             pw.println("  mOperatorBrandOverrideRegistrants[" + i + "]="
1573                     + ((Registrant) mOperatorBrandOverrideRegistrants.get(i)).getHandler());
1574         }
1575         pw.println(" mUniversalPinState=" + mUniversalPinState);
1576         pw.println(" mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex);
1577         pw.println(" mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex);
1578         pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex);
1579         pw.println(" mUiccApplications: length=" + mUiccApplications.length);
1580         for (int i = 0; i < mUiccApplications.length; i++) {
1581             if (mUiccApplications[i] == null) {
1582                 pw.println("  mUiccApplications[" + i + "]=" + null);
1583             } else {
1584                 pw.println("  mUiccApplications[" + i + "]="
1585                         + mUiccApplications[i].getType() + " " + mUiccApplications[i]);
1586             }
1587         }
1588         pw.println();
1589         // Print details of all applications
1590         for (UiccCardApplication app : mUiccApplications) {
1591             if (app != null) {
1592                 app.dump(fd, pw, args);
1593                 pw.println();
1594             }
1595         }
1596         // Print details of all IccRecords
1597         for (UiccCardApplication app : mUiccApplications) {
1598             if (app != null) {
1599                 IccRecords ir = app.getIccRecords();
1600                 if (ir != null) {
1601                     ir.dump(fd, pw, args);
1602                     pw.println();
1603                 }
1604             }
1605         }
1606         // Print UiccCarrierPrivilegeRules and registrants.
1607         if (mCarrierPrivilegeRules == null) {
1608             pw.println(" mCarrierPrivilegeRules: null");
1609         } else {
1610             pw.println(" mCarrierPrivilegeRules: " + mCarrierPrivilegeRules);
1611             mCarrierPrivilegeRules.dump(fd, pw, args);
1612         }
1613         pw.println(" mCarrierPrivilegeRegistrants: size=" + mCarrierPrivilegeRegistrants.size());
1614         for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
1615             pw.println("  mCarrierPrivilegeRegistrants[" + i + "]="
1616                     + ((Registrant) mCarrierPrivilegeRegistrants.get(i)).getHandler());
1617         }
1618         pw.flush();
1619 
1620         pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
1621         for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) {
1622             pw.println("  mNetworkLockedRegistrants[" + i + "]="
1623                     + ((Registrant) mNetworkLockedRegistrants.get(i)).getHandler());
1624         }
1625         pw.println(" mCurrentAppType=" + mCurrentAppType);
1626         pw.println(" mUiccCard=" + mUiccCard);
1627         pw.println(" mUiccApplication=" + mUiccApplication);
1628         pw.println(" mIccRecords=" + mIccRecords);
1629         pw.println(" mExternalState=" + mExternalState);
1630         pw.flush();
1631     }
1632 }
1633