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