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