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 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 */ 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 */ 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 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 */ 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 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 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 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) 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 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 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 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 568 private void unregisterCurrAppEvents() { 569 if (mIccRecords != null) { 570 mIccRecords.unregisterForLockedRecordsLoaded(mHandler); 571 mIccRecords.unregisterForNetworkLockedRecordsLoaded(mHandler); 572 } 573 } 574 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 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 */ 623 public boolean getIccRecordsLoaded() { 624 synchronized (mLock) { 625 if (mIccRecords != null) { 626 return mIccRecords.getRecordsLoaded(); 627 } 628 return false; 629 } 630 } 631 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 */ 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 666 public IccCardConstants.State getState() { 667 synchronized (mLock) { 668 return mExternalState; 669 } 670 } 671 672 @Override 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 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 696 public void unregisterForNetworkLocked(Handler h) { 697 synchronized (mLock) { 698 mNetworkLockedRegistrants.remove(h); 699 } 700 } 701 702 @Override 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 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 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 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 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 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 781 public boolean getIccFdnEnabled() { 782 synchronized (mLock) { 783 return mUiccApplication != null && mUiccApplication.getIccFdnEnabled(); 784 } 785 } 786 787 @Override 788 public boolean getIccPin2Blocked() { 789 /* defaults to disabled */ 790 return mUiccApplication != null && mUiccApplication.getIccPin2Blocked(); 791 } 792 793 @Override 794 public boolean getIccPuk2Blocked() { 795 /* defaults to disabled */ 796 return mUiccApplication != null && mUiccApplication.getIccPuk2Blocked(); 797 } 798 799 @Override 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 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 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 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 856 public String getServiceProviderName() { 857 synchronized (mLock) { 858 if (mIccRecords != null) { 859 return mIccRecords.getServiceProviderName(); 860 } 861 return null; 862 } 863 } 864 865 @Override 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 */ 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 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 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 */ 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 */ 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 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 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 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 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 */ 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 */ 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 */ 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 */ 1101 public void unregisterForOperatorBrandOverride(Handler h) { 1102 synchronized (mLock) { 1103 mOperatorBrandOverrideRegistrants.remove(h); 1104 } 1105 } 1106 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 1119 private void promptInstallCarrierApp(String pkgName) { 1120 Intent showDialogIntent = InstallCarrierAppTrampolineActivity.get(mContext, pkgName); 1121 mContext.startActivity(showDialogIntent); 1122 } 1123 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 1413 public boolean hasCarrierPrivilegeRules() { 1414 UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules(); 1415 return carrierPrivilegeRules != null && carrierPrivilegeRules.hasCarrierPrivilegeRules(); 1416 } 1417 1418 /** 1419 * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}. 1420 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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}. */ 1481 private UiccCarrierPrivilegeRules getCarrierPrivilegeRules() { 1482 synchronized (mLock) { 1483 return mCarrierPrivilegeRules; 1484 } 1485 } 1486 1487 /** 1488 * Sets the overridden operator brand. 1489 */ 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 */ 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 */ 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 1539 private static void log(String msg) { 1540 Rlog.d(LOG_TAG, msg); 1541 } 1542 1543 private static void loge(String msg) { 1544 Rlog.e(LOG_TAG, msg); 1545 } 1546 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 1556 public void refresh() { 1557 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARRIER_PRIVILEGES_LOADED)); 1558 } 1559 1560 /** 1561 * Dump 1562 */ 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