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