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