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