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