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