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