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