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