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