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