IccCardProxy.java revision d4c858abee72a9c4935855b62418d2b306ceda4b
1/* 2 * Copyright (C) 2012 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 17package com.android.internal.telephony.uicc; 18 19import static android.Manifest.permission.READ_PHONE_STATE; 20 21import android.app.ActivityManagerNative; 22import android.content.Context; 23import android.content.Intent; 24import android.os.AsyncResult; 25import android.os.Handler; 26import android.os.Message; 27import android.os.Registrant; 28import android.os.RegistrantList; 29import android.os.SystemProperties; 30import android.os.UserHandle; 31import android.telephony.Rlog; 32import android.telephony.ServiceState; 33import android.telephony.SubscriptionManager; 34import android.telephony.TelephonyManager; 35 36import com.android.internal.telephony.CommandsInterface; 37import com.android.internal.telephony.IccCard; 38import com.android.internal.telephony.IccCardConstants; 39import com.android.internal.telephony.PhoneConstants; 40import com.android.internal.telephony.MccTable; 41import com.android.internal.telephony.RILConstants; 42import com.android.internal.telephony.TelephonyIntents; 43import com.android.internal.telephony.IccCardConstants.State; 44import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 45import com.android.internal.telephony.Phone; 46import com.android.internal.telephony.Subscription; 47import com.android.internal.telephony.SubscriptionController; 48import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; 49import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState; 50import com.android.internal.telephony.uicc.IccCardStatus.CardState; 51import com.android.internal.telephony.uicc.IccCardStatus.PinState; 52import com.android.internal.telephony.uicc.UiccController; 53 54import java.io.FileDescriptor; 55import java.io.PrintWriter; 56 57import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA; 58import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC; 59import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; 60import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_STATE; 61 62 63/** 64 * @Deprecated use {@link UiccController}.getUiccCard instead. 65 * 66 * The Phone App assumes that there is only one icc card, and one icc application 67 * available at a time. Moreover, it assumes such object (represented with IccCard) 68 * is available all the time (whether {@link RILConstants#RIL_REQUEST_GET_SIM_STATUS} returned 69 * or not, whether card has desired application or not, whether there really is a card in the 70 * slot or not). 71 * 72 * UiccController, however, can handle multiple instances of icc objects (multiple 73 * {@link UiccCardApplication}, multiple {@link IccFileHandler}, multiple {@link IccRecords}) 74 * created and destroyed dynamically during phone operation. 75 * 76 * This class implements the IccCard interface that is always available (right after default 77 * phone object is constructed) to expose the current (based on voice radio technology) 78 * application on the uicc card, so that external apps won't break. 79 */ 80 81public class IccCardProxy extends Handler implements IccCard { 82 private static final boolean DBG = true; 83 private static final String LOG_TAG = "IccCardProxy"; 84 85 private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 1; 86 private static final int EVENT_RADIO_ON = 2; 87 private static final int EVENT_ICC_CHANGED = 3; 88 private static final int EVENT_ICC_ABSENT = 4; 89 private static final int EVENT_ICC_LOCKED = 5; 90 private static final int EVENT_APP_READY = 6; 91 private static final int EVENT_RECORDS_LOADED = 7; 92 private static final int EVENT_IMSI_READY = 8; 93 private static final int EVENT_NETWORK_LOCKED = 9; 94 private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 11; 95 96 private static final int EVENT_ICC_RECORD_EVENTS = 500; 97 private static final int EVENT_SUBSCRIPTION_ACTIVATED = 501; 98 private static final int EVENT_SUBSCRIPTION_DEACTIVATED = 502; 99 private static final int EVENT_CARRIER_PRIVILIGES_LOADED = 503; 100 101 // FIXME Rename mCardIndex to mSlotId. 102 private Integer mCardIndex = null; 103 private Subscription mSubscriptionData = null; 104 105 private final Object mLock = new Object(); 106 private Context mContext; 107 private CommandsInterface mCi; 108 109 private RegistrantList mAbsentRegistrants = new RegistrantList(); 110 private RegistrantList mPinLockedRegistrants = new RegistrantList(); 111 private RegistrantList mNetworkLockedRegistrants = new RegistrantList(); 112 113 private int mCurrentAppType = UiccController.APP_FAM_3GPP; //default to 3gpp? 114 private UiccController mUiccController = null; 115 private UiccCard mUiccCard = null; 116 private UiccCardApplication mUiccApplication = null; 117 private IccRecords mIccRecords = null; 118 private CdmaSubscriptionSourceManager mCdmaSSM = null; 119 private boolean mRadioOn = false; 120 private boolean mQuietMode = false; // when set to true IccCardProxy will not broadcast 121 // ACTION_SIM_STATE_CHANGED intents 122 private boolean mInitialized = false; 123 private State mExternalState = State.UNKNOWN; 124 125 private int mRecordsToLoad; // number of pending load requests 126 127 public IccCardProxy(Context context, CommandsInterface ci) { 128 log("Creating"); 129 mContext = context; 130 mCi = ci; 131 mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(context, 132 ci, this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); 133 mUiccController = UiccController.getInstance(); 134 mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); 135 ci.registerForOn(this,EVENT_RADIO_ON, null); 136 ci.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_UNAVAILABLE, null); 137 setExternalState(State.NOT_READY); 138 } 139 140 public IccCardProxy(Context context, CommandsInterface ci, int cardIndex) { 141 this(context, ci); 142 143 mCardIndex = cardIndex; 144 145 resetProperties(); 146 setExternalState(State.NOT_READY, false); 147 } 148 149 public void dispose() { 150 synchronized (mLock) { 151 log("Disposing"); 152 //Cleanup icc references 153 mUiccController.unregisterForIccChanged(this); 154 mUiccController = null; 155 mCi.unregisterForOn(this); 156 mCi.unregisterForOffOrNotAvailable(this); 157 mCdmaSSM.dispose(this); 158 } 159 } 160 161 /* 162 * The card application that the external world sees will be based on the 163 * voice radio technology only! 164 */ 165 public void setVoiceRadioTech(int radioTech) { 166 synchronized (mLock) { 167 if (DBG) { 168 log("Setting radio tech " + ServiceState.rilRadioTechnologyToString(radioTech)); 169 } 170 if (ServiceState.isGsm(radioTech)) { 171 mCurrentAppType = UiccController.APP_FAM_3GPP; 172 } else { 173 mCurrentAppType = UiccController.APP_FAM_3GPP2; 174 } 175 updateQuietMode(); 176 } 177 } 178 179 /** 180 * In case of 3gpp2 we need to find out if subscription used is coming from 181 * NV in which case we shouldn't broadcast any sim states changes. 182 */ 183 private void updateQuietMode() { 184 synchronized (mLock) { 185 boolean oldQuietMode = mQuietMode; 186 boolean newQuietMode; 187 int cdmaSource = Phone.CDMA_SUBSCRIPTION_UNKNOWN; 188 boolean isLteOnCdmaMode = TelephonyManager.getLteOnCdmaModeStatic() 189 == PhoneConstants.LTE_ON_CDMA_TRUE; 190 if (mCurrentAppType == UiccController.APP_FAM_3GPP) { 191 newQuietMode = false; 192 if (DBG) log("updateQuietMode: 3GPP subscription -> newQuietMode=" + newQuietMode); 193 } else { 194 if (isLteOnCdmaMode) { 195 log("updateQuietMode: is cdma/lte device, force IccCardProxy into 3gpp mode"); 196 mCurrentAppType = UiccController.APP_FAM_3GPP; 197 } 198 cdmaSource = mCdmaSSM != null ? 199 mCdmaSSM.getCdmaSubscriptionSource() : Phone.CDMA_SUBSCRIPTION_UNKNOWN; 200 201 newQuietMode = (cdmaSource == Phone.CDMA_SUBSCRIPTION_NV) 202 && (mCurrentAppType == UiccController.APP_FAM_3GPP2) 203 && !isLteOnCdmaMode; 204 } 205 206 if (mQuietMode == false && newQuietMode == true) { 207 // Last thing to do before switching to quiet mode is 208 // broadcast ICC_READY 209 log("Switching to QuietMode."); 210 setExternalState(State.READY); 211 mQuietMode = newQuietMode; 212 } else if (mQuietMode == true && newQuietMode == false) { 213 if (DBG) { 214 log("updateQuietMode: Switching out from QuietMode." 215 + " Force broadcast of current state=" + mExternalState); 216 } 217 mQuietMode = newQuietMode; 218 setExternalState(mExternalState, true); 219 } 220 if (DBG) { 221 log("updateQuietMode: QuietMode is " + mQuietMode + " (app_type=" 222 + mCurrentAppType + " isLteOnCdmaMode=" + isLteOnCdmaMode 223 + " cdmaSource=" + cdmaSource + ")"); 224 } 225 mInitialized = true; 226 sendMessage(obtainMessage(EVENT_ICC_CHANGED)); 227 } 228 } 229 230 @Override 231 public void handleMessage(Message msg) { 232 switch (msg.what) { 233 case EVENT_RADIO_OFF_OR_UNAVAILABLE: 234 mRadioOn = false; 235 break; 236 case EVENT_RADIO_ON: 237 mRadioOn = true; 238 if (!mInitialized) { 239 updateQuietMode(); 240 } 241 break; 242 case EVENT_ICC_CHANGED: 243 if (mInitialized) { 244 updateIccAvailability(); 245 } 246 break; 247 case EVENT_ICC_ABSENT: 248 mAbsentRegistrants.notifyRegistrants(); 249 setExternalState(State.ABSENT); 250 break; 251 case EVENT_ICC_LOCKED: 252 processLockedState(); 253 break; 254 case EVENT_APP_READY: 255 setExternalState(State.READY); 256 break; 257 case EVENT_RECORDS_LOADED: 258 if (mIccRecords != null) { 259 String operator = mIccRecords.getOperatorNumeric(); 260 int slotId = mCardIndex; 261 262 log("operator = " + operator + " slotId = " + slotId); 263 264 if (operator != null) { 265 log("update icc_operator_numeric=" + operator); 266 setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, slotId, operator); 267 String countryCode = operator.substring(0,3); 268 if (countryCode != null) { 269 setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, slotId, 270 MccTable.countryCodeForMcc(Integer.parseInt(countryCode))); 271 } else { 272 loge("EVENT_RECORDS_LOADED Country code is null"); 273 } 274 275 long[] subId = SubscriptionController.getInstance().getSubId(slotId); 276 // Update MCC MNC device configuration information only for default sub. 277 if (subId[0] == SubscriptionController.getInstance().getDefaultSubId()) { 278 log("update mccmnc=" + operator + " config for default subscription."); 279 MccTable.updateMccMncConfiguration(mContext, operator, false); 280 } 281 SubscriptionController.getInstance().setMccMnc(operator, subId[0]); 282 } else { 283 loge("EVENT_RECORDS_LOADED Operator name is null"); 284 } 285 } 286 onRecordsLoaded(); 287 break; 288 case EVENT_IMSI_READY: 289 broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_IMSI, null); 290 break; 291 case EVENT_NETWORK_LOCKED: 292 mNetworkLockedRegistrants.notifyRegistrants(); 293 setExternalState(State.NETWORK_LOCKED); 294 break; 295 case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: 296 updateQuietMode(); 297 break; 298 case EVENT_SUBSCRIPTION_ACTIVATED: 299 log("EVENT_SUBSCRIPTION_ACTIVATED"); 300 onSubscriptionActivated(); 301 break; 302 303 case EVENT_SUBSCRIPTION_DEACTIVATED: 304 log("EVENT_SUBSCRIPTION_DEACTIVATED"); 305 onSubscriptionDeactivated(); 306 break; 307 308 case EVENT_ICC_RECORD_EVENTS: 309 if ((mCurrentAppType == UiccController.APP_FAM_3GPP) && (mIccRecords != null)) { 310 int slotId = mCardIndex; 311 AsyncResult ar = (AsyncResult)msg.obj; 312 int eventCode = (Integer) ar.result; 313 if (eventCode == SIMRecords.EVENT_SPN) { 314 setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, slotId, 315 mIccRecords.getServiceProviderName()); 316 } 317 } 318 break; 319 320 case EVENT_CARRIER_PRIVILIGES_LOADED: 321 log("EVENT_CARRIER_PRIVILEGES_LOADED"); 322 onRecordsLoaded(); 323 break; 324 325 default: 326 loge("Unhandled message with number: " + msg.what); 327 break; 328 } 329 } 330 331 private void onSubscriptionActivated() { 332 //mSubscriptionData = SubscriptionManager.getCurrentSubscription(mCardIndex); 333 334 updateIccAvailability(); 335 updateStateProperty(); 336 } 337 338 private void onSubscriptionDeactivated() { 339 resetProperties(); 340 mSubscriptionData = null; 341 updateIccAvailability(); 342 updateStateProperty(); 343 } 344 345 private void onRecordsLoaded() { 346 synchronized (mLock) { 347 --mRecordsToLoad; 348 if (mRecordsToLoad == 0) { 349 broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_LOADED, null); 350 } 351 } 352 } 353 354 private void updateIccAvailability() { 355 synchronized (mLock) { 356 UiccCard newCard = mUiccController.getUiccCard(mCardIndex); 357 CardState state = CardState.CARDSTATE_ABSENT; 358 UiccCardApplication newApp = null; 359 IccRecords newRecords = null; 360 if (newCard != null) { 361 state = newCard.getCardState(); 362 newApp = newCard.getApplication(mCurrentAppType); 363 if (newApp != null) { 364 newRecords = newApp.getIccRecords(); 365 } 366 } 367 368 if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) { 369 if (DBG) log("Icc changed. Reregestering."); 370 mRecordsToLoad = 0; 371 unregisterUiccCardEvents(); 372 mUiccCard = newCard; 373 mUiccApplication = newApp; 374 mIccRecords = newRecords; 375 registerUiccCardEvents(); 376 } 377 378 updateExternalState(); 379 } 380 } 381 382 void resetProperties() { 383 if (mCurrentAppType == UiccController.APP_FAM_3GPP) { 384 log("update icc_operator_numeric=" + ""); 385 setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, mCardIndex, ""); 386 setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, mCardIndex, ""); 387 setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, mCardIndex, ""); 388 } 389 } 390 391 private void HandleDetectedState() { 392 // CAF_MSIM SAND 393// setExternalState(State.DETECTED, false); 394 } 395 396 private void updateExternalState() { 397 if (mUiccCard == null || mUiccCard.getCardState() == CardState.CARDSTATE_ABSENT) { 398 if (mRadioOn) { 399 setExternalState(State.ABSENT); 400 } else { 401 setExternalState(State.NOT_READY); 402 } 403 return; 404 } 405 406 if (mUiccCard.getCardState() == CardState.CARDSTATE_ERROR) { 407 setExternalState(State.CARD_IO_ERROR); 408 return; 409 } 410 411 if (mUiccApplication == null) { 412 setExternalState(State.NOT_READY); 413 return; 414 } 415 416 switch (mUiccApplication.getState()) { 417 case APPSTATE_UNKNOWN: 418 setExternalState(State.UNKNOWN); 419 break; 420 case APPSTATE_DETECTED: 421 HandleDetectedState(); 422 break; 423 case APPSTATE_PIN: 424 setExternalState(State.PIN_REQUIRED); 425 break; 426 case APPSTATE_PUK: 427 setExternalState(State.PUK_REQUIRED); 428 break; 429 case APPSTATE_SUBSCRIPTION_PERSO: 430 if (mUiccApplication.getPersoSubState() == 431 PersoSubState.PERSOSUBSTATE_SIM_NETWORK) { 432 setExternalState(State.NETWORK_LOCKED); 433 } else { 434 setExternalState(State.UNKNOWN); 435 } 436 break; 437 case APPSTATE_READY: 438 setExternalState(State.READY); 439 break; 440 } 441 } 442 443 private void registerUiccCardEvents() { 444 mRecordsToLoad = (mUiccCard != null ? 1 : 0) + 445 (mIccRecords != null ? 1 : 0); 446 447 if (mUiccCard != null) { 448 mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null); 449 mUiccCard.registerForCarrierPrivilegeRulesLoaded( 450 this, EVENT_CARRIER_PRIVILIGES_LOADED, null); 451 } 452 if (mUiccApplication != null) { 453 mUiccApplication.registerForReady(this, EVENT_APP_READY, null); 454 mUiccApplication.registerForLocked(this, EVENT_ICC_LOCKED, null); 455 mUiccApplication.registerForNetworkLocked(this, EVENT_NETWORK_LOCKED, null); 456 } 457 if (mIccRecords != null) { 458 mIccRecords.registerForImsiReady(this, EVENT_IMSI_READY, null); 459 mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null); 460 mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null); 461 } 462 } 463 464 private void unregisterUiccCardEvents() { 465 if (mUiccCard != null) mUiccCard.unregisterForAbsent(this); 466 if (mUiccCard != null) mUiccCard.unregisterForCarrierPrivilegeRulesLoaded(this); 467 if (mUiccApplication != null) mUiccApplication.unregisterForReady(this); 468 if (mUiccApplication != null) mUiccApplication.unregisterForLocked(this); 469 if (mUiccApplication != null) mUiccApplication.unregisterForNetworkLocked(this); 470 if (mIccRecords != null) mIccRecords.unregisterForImsiReady(this); 471 if (mIccRecords != null) mIccRecords.unregisterForRecordsLoaded(this); 472 if (mIccRecords != null) mIccRecords.unregisterForRecordsEvents(this); 473 } 474 475 private void updateStateProperty() { 476 setSystemProperty(PROPERTY_SIM_STATE, mCardIndex,getState().toString()); 477 } 478 479 private void broadcastIccStateChangedIntent(String value, String reason) { 480 synchronized (mLock) { 481 if (mCardIndex == null) { 482 loge("broadcastIccStateChangedIntent: Card Index is not set; Return!!"); 483 return; 484 } 485 486 if (mQuietMode) { 487 log("QuietMode: NOT Broadcasting intent ACTION_SIM_STATE_CHANGED " + value 488 + " reason " + reason); 489 return; 490 } 491 492 Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 493 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 494 intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone"); 495 intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value); 496 intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason); 497 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mCardIndex); 498 log("Broadcasting intent ACTION_SIM_STATE_CHANGED " + value 499 + " reason " + reason + " for mCardIndex : " + mCardIndex); 500 ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE, 501 UserHandle.USER_ALL); 502 } 503 } 504 505 private void setExternalState(State newState, boolean override) { 506 synchronized (mLock) { 507 if (mCardIndex == null) { 508 loge("setExternalState: Card Index is not set; Return!!"); 509 return; 510 } 511 512 if (!override && newState == mExternalState) { 513 return; 514 } 515 mExternalState = newState; 516 setSystemProperty(PROPERTY_SIM_STATE, mCardIndex, getState().toString()); 517 broadcastIccStateChangedIntent(getIccStateIntentString(mExternalState), 518 getIccStateReason(mExternalState)); 519 // TODO: Need to notify registrants for other states as well. 520 if ( State.ABSENT == mExternalState) { 521 mAbsentRegistrants.notifyRegistrants(); 522 } 523 } 524 } 525 526 private void processLockedState() { 527 synchronized (mLock) { 528 if (mUiccApplication == null) { 529 //Don't need to do anything if non-existent application is locked 530 return; 531 } 532 PinState pin1State = mUiccApplication.getPin1State(); 533 if (pin1State == PinState.PINSTATE_ENABLED_PERM_BLOCKED) { 534 setExternalState(State.PERM_DISABLED); 535 return; 536 } 537 538 AppState appState = mUiccApplication.getState(); 539 switch (appState) { 540 case APPSTATE_PIN: 541 mPinLockedRegistrants.notifyRegistrants(); 542 setExternalState(State.PIN_REQUIRED); 543 break; 544 case APPSTATE_PUK: 545 setExternalState(State.PUK_REQUIRED); 546 break; 547 case APPSTATE_DETECTED: 548 case APPSTATE_READY: 549 case APPSTATE_SUBSCRIPTION_PERSO: 550 case APPSTATE_UNKNOWN: 551 // Neither required 552 break; 553 } 554 } 555 } 556 557 private void setExternalState(State newState) { 558 setExternalState(newState, false); 559 } 560 561 public boolean getIccRecordsLoaded() { 562 synchronized (mLock) { 563 if (mIccRecords != null) { 564 return mIccRecords.getRecordsLoaded(); 565 } 566 return false; 567 } 568 } 569 570 private String getIccStateIntentString(State state) { 571 switch (state) { 572 case ABSENT: return IccCardConstants.INTENT_VALUE_ICC_ABSENT; 573 case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 574 case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 575 case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 576 case READY: return IccCardConstants.INTENT_VALUE_ICC_READY; 577 case NOT_READY: return IccCardConstants.INTENT_VALUE_ICC_NOT_READY; 578 case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 579 case CARD_IO_ERROR: return IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR; 580 default: return IccCardConstants.INTENT_VALUE_ICC_UNKNOWN; 581 } 582 } 583 584 /** 585 * Locked state have a reason (PIN, PUK, NETWORK, PERM_DISABLED, CARD_IO_ERROR) 586 * @return reason 587 */ 588 private String getIccStateReason(State state) { 589 switch (state) { 590 case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN; 591 case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK; 592 case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_LOCKED_NETWORK; 593 case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED; 594 case CARD_IO_ERROR: return IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR; 595 default: return null; 596 } 597 } 598 599 /* IccCard interface implementation */ 600 @Override 601 public State getState() { 602 synchronized (mLock) { 603 return mExternalState; 604 } 605 } 606 607 @Override 608 public IccRecords getIccRecords() { 609 synchronized (mLock) { 610 return mIccRecords; 611 } 612 } 613 614 @Override 615 public IccFileHandler getIccFileHandler() { 616 synchronized (mLock) { 617 if (mUiccApplication != null) { 618 return mUiccApplication.getIccFileHandler(); 619 } 620 return null; 621 } 622 } 623 624 /** 625 * Notifies handler of any transition into State.ABSENT 626 */ 627 @Override 628 public void registerForAbsent(Handler h, int what, Object obj) { 629 synchronized (mLock) { 630 Registrant r = new Registrant (h, what, obj); 631 632 mAbsentRegistrants.add(r); 633 634 if (getState() == State.ABSENT) { 635 r.notifyRegistrant(); 636 } 637 } 638 } 639 640 @Override 641 public void unregisterForAbsent(Handler h) { 642 synchronized (mLock) { 643 mAbsentRegistrants.remove(h); 644 } 645 } 646 647 /** 648 * Notifies handler of any transition into State.NETWORK_LOCKED 649 */ 650 @Override 651 public void registerForNetworkLocked(Handler h, int what, Object obj) { 652 synchronized (mLock) { 653 Registrant r = new Registrant (h, what, obj); 654 655 mNetworkLockedRegistrants.add(r); 656 657 if (getState() == State.NETWORK_LOCKED) { 658 r.notifyRegistrant(); 659 } 660 } 661 } 662 663 @Override 664 public void unregisterForNetworkLocked(Handler h) { 665 synchronized (mLock) { 666 mNetworkLockedRegistrants.remove(h); 667 } 668 } 669 670 /** 671 * Notifies handler of any transition into State.isPinLocked() 672 */ 673 @Override 674 public void registerForLocked(Handler h, int what, Object obj) { 675 synchronized (mLock) { 676 Registrant r = new Registrant (h, what, obj); 677 678 mPinLockedRegistrants.add(r); 679 680 if (getState().isPinLocked()) { 681 r.notifyRegistrant(); 682 } 683 } 684 } 685 686 @Override 687 public void unregisterForLocked(Handler h) { 688 synchronized (mLock) { 689 mPinLockedRegistrants.remove(h); 690 } 691 } 692 693 @Override 694 public void supplyPin(String pin, Message onComplete) { 695 synchronized (mLock) { 696 if (mUiccApplication != null) { 697 mUiccApplication.supplyPin(pin, onComplete); 698 } else if (onComplete != null) { 699 Exception e = new RuntimeException("ICC card is absent."); 700 AsyncResult.forMessage(onComplete).exception = e; 701 onComplete.sendToTarget(); 702 return; 703 } 704 } 705 } 706 707 @Override 708 public void supplyPuk(String puk, String newPin, Message onComplete) { 709 synchronized (mLock) { 710 if (mUiccApplication != null) { 711 mUiccApplication.supplyPuk(puk, newPin, onComplete); 712 } else if (onComplete != null) { 713 Exception e = new RuntimeException("ICC card is absent."); 714 AsyncResult.forMessage(onComplete).exception = e; 715 onComplete.sendToTarget(); 716 return; 717 } 718 } 719 } 720 721 @Override 722 public void supplyPin2(String pin2, Message onComplete) { 723 synchronized (mLock) { 724 if (mUiccApplication != null) { 725 mUiccApplication.supplyPin2(pin2, onComplete); 726 } else if (onComplete != null) { 727 Exception e = new RuntimeException("ICC card is absent."); 728 AsyncResult.forMessage(onComplete).exception = e; 729 onComplete.sendToTarget(); 730 return; 731 } 732 } 733 } 734 735 @Override 736 public void supplyPuk2(String puk2, String newPin2, Message onComplete) { 737 synchronized (mLock) { 738 if (mUiccApplication != null) { 739 mUiccApplication.supplyPuk2(puk2, newPin2, onComplete); 740 } else if (onComplete != null) { 741 Exception e = new RuntimeException("ICC card is absent."); 742 AsyncResult.forMessage(onComplete).exception = e; 743 onComplete.sendToTarget(); 744 return; 745 } 746 } 747 } 748 749 @Override 750 public void supplyNetworkDepersonalization(String pin, Message onComplete) { 751 synchronized (mLock) { 752 if (mUiccApplication != null) { 753 mUiccApplication.supplyNetworkDepersonalization(pin, onComplete); 754 } else if (onComplete != null) { 755 Exception e = new RuntimeException("CommandsInterface is not set."); 756 AsyncResult.forMessage(onComplete).exception = e; 757 onComplete.sendToTarget(); 758 return; 759 } 760 } 761 } 762 763 @Override 764 public boolean getIccLockEnabled() { 765 synchronized (mLock) { 766 /* defaults to false, if ICC is absent/deactivated */ 767 Boolean retValue = mUiccApplication != null ? 768 mUiccApplication.getIccLockEnabled() : false; 769 return retValue; 770 } 771 } 772 773 @Override 774 public boolean getIccFdnEnabled() { 775 synchronized (mLock) { 776 Boolean retValue = mUiccApplication != null ? 777 mUiccApplication.getIccFdnEnabled() : false; 778 return retValue; 779 } 780 } 781 782 public boolean getIccFdnAvailable() { 783 boolean retValue = mUiccApplication != null ? mUiccApplication.getIccFdnAvailable() : false; 784 return retValue; 785 } 786 787 public boolean getIccPin2Blocked() { 788 /* defaults to disabled */ 789 Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccPin2Blocked() : false; 790 return retValue; 791 } 792 793 public boolean getIccPuk2Blocked() { 794 /* defaults to disabled */ 795 Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccPuk2Blocked() : false; 796 return retValue; 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 isApplicationOnIcc(IccCardApplicationStatus.AppType type) { 867 synchronized (mLock) { 868 Boolean retValue = mUiccCard != null ? mUiccCard.isApplicationOnIcc(type) : false; 869 return retValue; 870 } 871 } 872 873 @Override 874 public boolean hasIccCard() { 875 synchronized (mLock) { 876 if (mUiccCard != null && mUiccCard.getCardState() != CardState.CARDSTATE_ABSENT) { 877 return true; 878 } 879 return false; 880 } 881 } 882 883 private void setSystemProperty(String property, int slotId, String value) { 884 long[] subId = SubscriptionController.getInstance().getSubId(slotId); 885 TelephonyManager.setTelephonyProperty(property, subId[0], value); 886 } 887 888 private void log(String s) { 889 Rlog.d(LOG_TAG, s); 890 } 891 892 private void loge(String msg) { 893 Rlog.e(LOG_TAG, msg); 894 } 895 896 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 897 pw.println("IccCardProxy: " + this); 898 pw.println(" mContext=" + mContext); 899 pw.println(" mCi=" + mCi); 900 pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size()); 901 for (int i = 0; i < mAbsentRegistrants.size(); i++) { 902 pw.println(" mAbsentRegistrants[" + i + "]=" 903 + ((Registrant)mAbsentRegistrants.get(i)).getHandler()); 904 } 905 pw.println(" mPinLockedRegistrants: size=" + mPinLockedRegistrants.size()); 906 for (int i = 0; i < mPinLockedRegistrants.size(); i++) { 907 pw.println(" mPinLockedRegistrants[" + i + "]=" 908 + ((Registrant)mPinLockedRegistrants.get(i)).getHandler()); 909 } 910 pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size()); 911 for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) { 912 pw.println(" mNetworkLockedRegistrants[" + i + "]=" 913 + ((Registrant)mNetworkLockedRegistrants.get(i)).getHandler()); 914 } 915 pw.println(" mCurrentAppType=" + mCurrentAppType); 916 pw.println(" mUiccController=" + mUiccController); 917 pw.println(" mUiccCard=" + mUiccCard); 918 pw.println(" mUiccApplication=" + mUiccApplication); 919 pw.println(" mIccRecords=" + mIccRecords); 920 pw.println(" mCdmaSSM=" + mCdmaSSM); 921 pw.println(" mRadioOn=" + mRadioOn); 922 pw.println(" mQuietMode=" + mQuietMode); 923 pw.println(" mInitialized=" + mInitialized); 924 pw.println(" mExternalState=" + mExternalState); 925 926 pw.flush(); 927 } 928} 929