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