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 17 package com.android.internal.telephony.uicc; 18 19 import static android.Manifest.permission.READ_PHONE_STATE; 20 import android.app.ActivityManagerNative; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.os.AsyncResult; 24 import android.os.Handler; 25 import android.os.Message; 26 import android.os.Registrant; 27 import android.os.RegistrantList; 28 import android.os.SystemProperties; 29 import android.os.UserHandle; 30 import android.telephony.Rlog; 31 import android.telephony.ServiceState; 32 import android.telephony.TelephonyManager; 33 34 import com.android.internal.telephony.CommandsInterface; 35 import com.android.internal.telephony.IccCard; 36 import com.android.internal.telephony.IccCardConstants; 37 import com.android.internal.telephony.PhoneConstants; 38 import com.android.internal.telephony.RILConstants; 39 import com.android.internal.telephony.TelephonyIntents; 40 import com.android.internal.telephony.IccCardConstants.State; 41 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 42 import com.android.internal.telephony.Phone; 43 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; 44 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState; 45 import com.android.internal.telephony.uicc.IccCardStatus.CardState; 46 import com.android.internal.telephony.uicc.IccCardStatus.PinState; 47 import com.android.internal.telephony.uicc.UiccController; 48 49 import java.io.FileDescriptor; 50 import java.io.PrintWriter; 51 52 import 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 72 public 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 mUiccApplication == null) { 286 setExternalState(State.UNKNOWN); 287 return; 288 } 289 290 switch (mUiccApplication.getState()) { 291 case APPSTATE_UNKNOWN: 292 case APPSTATE_DETECTED: 293 setExternalState(State.UNKNOWN); 294 break; 295 case APPSTATE_PIN: 296 setExternalState(State.PIN_REQUIRED); 297 break; 298 case APPSTATE_PUK: 299 setExternalState(State.PUK_REQUIRED); 300 break; 301 case APPSTATE_SUBSCRIPTION_PERSO: 302 if (mUiccApplication.getPersoSubState() == PersoSubState.PERSOSUBSTATE_SIM_NETWORK) { 303 setExternalState(State.NETWORK_LOCKED); 304 } else { 305 setExternalState(State.UNKNOWN); 306 } 307 break; 308 case APPSTATE_READY: 309 setExternalState(State.READY); 310 break; 311 } 312 } 313 314 private void registerUiccCardEvents() { 315 if (mUiccCard != null) mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null); 316 if (mUiccApplication != null) { 317 mUiccApplication.registerForReady(this, EVENT_APP_READY, null); 318 mUiccApplication.registerForLocked(this, EVENT_ICC_LOCKED, null); 319 mUiccApplication.registerForNetworkLocked(this, EVENT_NETWORK_LOCKED, null); 320 } 321 if (mIccRecords != null) { 322 mIccRecords.registerForImsiReady(this, EVENT_IMSI_READY, null); 323 mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null); 324 } 325 } 326 327 private void unregisterUiccCardEvents() { 328 if (mUiccCard != null) mUiccCard.unregisterForAbsent(this); 329 if (mUiccApplication != null) mUiccApplication.unregisterForReady(this); 330 if (mUiccApplication != null) mUiccApplication.unregisterForLocked(this); 331 if (mUiccApplication != null) mUiccApplication.unregisterForNetworkLocked(this); 332 if (mIccRecords != null) mIccRecords.unregisterForImsiReady(this); 333 if (mIccRecords != null) mIccRecords.unregisterForRecordsLoaded(this); 334 } 335 336 private void broadcastIccStateChangedIntent(String value, String reason) { 337 synchronized (mLock) { 338 if (mQuietMode) { 339 log("QuietMode: NOT Broadcasting intent ACTION_SIM_STATE_CHANGED " + value 340 + " reason " + reason); 341 return; 342 } 343 344 Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 345 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 346 intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone"); 347 intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value); 348 intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason); 349 350 if (DBG) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " + value 351 + " reason " + reason); 352 ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE, 353 UserHandle.USER_ALL); 354 } 355 } 356 357 private void processLockedState() { 358 synchronized (mLock) { 359 if (mUiccApplication == null) { 360 //Don't need to do anything if non-existent application is locked 361 return; 362 } 363 PinState pin1State = mUiccApplication.getPin1State(); 364 if (pin1State == PinState.PINSTATE_ENABLED_PERM_BLOCKED) { 365 setExternalState(State.PERM_DISABLED); 366 return; 367 } 368 369 AppState appState = mUiccApplication.getState(); 370 switch (appState) { 371 case APPSTATE_PIN: 372 mPinLockedRegistrants.notifyRegistrants(); 373 setExternalState(State.PIN_REQUIRED); 374 break; 375 case APPSTATE_PUK: 376 setExternalState(State.PUK_REQUIRED); 377 break; 378 case APPSTATE_DETECTED: 379 case APPSTATE_READY: 380 case APPSTATE_SUBSCRIPTION_PERSO: 381 case APPSTATE_UNKNOWN: 382 // Neither required 383 break; 384 } 385 } 386 } 387 388 private void setExternalState(State newState, boolean override) { 389 synchronized (mLock) { 390 if (!override && newState == mExternalState) { 391 return; 392 } 393 mExternalState = newState; 394 SystemProperties.set(PROPERTY_SIM_STATE, mExternalState.toString()); 395 broadcastIccStateChangedIntent(getIccStateIntentString(mExternalState), 396 getIccStateReason(mExternalState)); 397 } 398 } 399 400 private void setExternalState(State newState) { 401 setExternalState(newState, false); 402 } 403 404 public boolean getIccRecordsLoaded() { 405 synchronized (mLock) { 406 if (mIccRecords != null) { 407 return mIccRecords.getRecordsLoaded(); 408 } 409 return false; 410 } 411 } 412 413 private String getIccStateIntentString(State state) { 414 switch (state) { 415 case ABSENT: return IccCardConstants.INTENT_VALUE_ICC_ABSENT; 416 case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 417 case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 418 case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 419 case READY: return IccCardConstants.INTENT_VALUE_ICC_READY; 420 case NOT_READY: return IccCardConstants.INTENT_VALUE_ICC_NOT_READY; 421 case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED; 422 default: return IccCardConstants.INTENT_VALUE_ICC_UNKNOWN; 423 } 424 } 425 426 /** 427 * Locked state have a reason (PIN, PUK, NETWORK, PERM_DISABLED) 428 * @return reason 429 */ 430 private String getIccStateReason(State state) { 431 switch (state) { 432 case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN; 433 case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK; 434 case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_LOCKED_NETWORK; 435 case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED; 436 default: return null; 437 } 438 } 439 440 /* IccCard interface implementation */ 441 @Override 442 public State getState() { 443 synchronized (mLock) { 444 return mExternalState; 445 } 446 } 447 448 @Override 449 public IccRecords getIccRecords() { 450 synchronized (mLock) { 451 return mIccRecords; 452 } 453 } 454 455 @Override 456 public IccFileHandler getIccFileHandler() { 457 synchronized (mLock) { 458 if (mUiccApplication != null) { 459 return mUiccApplication.getIccFileHandler(); 460 } 461 return null; 462 } 463 } 464 465 /** 466 * Notifies handler of any transition into State.ABSENT 467 */ 468 @Override 469 public void registerForAbsent(Handler h, int what, Object obj) { 470 synchronized (mLock) { 471 Registrant r = new Registrant (h, what, obj); 472 473 mAbsentRegistrants.add(r); 474 475 if (getState() == State.ABSENT) { 476 r.notifyRegistrant(); 477 } 478 } 479 } 480 481 @Override 482 public void unregisterForAbsent(Handler h) { 483 synchronized (mLock) { 484 mAbsentRegistrants.remove(h); 485 } 486 } 487 488 /** 489 * Notifies handler of any transition into State.NETWORK_LOCKED 490 */ 491 @Override 492 public void registerForNetworkLocked(Handler h, int what, Object obj) { 493 synchronized (mLock) { 494 Registrant r = new Registrant (h, what, obj); 495 496 mNetworkLockedRegistrants.add(r); 497 498 if (getState() == State.NETWORK_LOCKED) { 499 r.notifyRegistrant(); 500 } 501 } 502 } 503 504 @Override 505 public void unregisterForNetworkLocked(Handler h) { 506 synchronized (mLock) { 507 mNetworkLockedRegistrants.remove(h); 508 } 509 } 510 511 /** 512 * Notifies handler of any transition into State.isPinLocked() 513 */ 514 @Override 515 public void registerForLocked(Handler h, int what, Object obj) { 516 synchronized (mLock) { 517 Registrant r = new Registrant (h, what, obj); 518 519 mPinLockedRegistrants.add(r); 520 521 if (getState().isPinLocked()) { 522 r.notifyRegistrant(); 523 } 524 } 525 } 526 527 @Override 528 public void unregisterForLocked(Handler h) { 529 synchronized (mLock) { 530 mPinLockedRegistrants.remove(h); 531 } 532 } 533 534 @Override 535 public void supplyPin(String pin, Message onComplete) { 536 synchronized (mLock) { 537 if (mUiccApplication != null) { 538 mUiccApplication.supplyPin(pin, onComplete); 539 } else if (onComplete != null) { 540 Exception e = new RuntimeException("ICC card is absent."); 541 AsyncResult.forMessage(onComplete).exception = e; 542 onComplete.sendToTarget(); 543 return; 544 } 545 } 546 } 547 548 @Override 549 public void supplyPuk(String puk, String newPin, Message onComplete) { 550 synchronized (mLock) { 551 if (mUiccApplication != null) { 552 mUiccApplication.supplyPuk(puk, newPin, onComplete); 553 } else if (onComplete != null) { 554 Exception e = new RuntimeException("ICC card is absent."); 555 AsyncResult.forMessage(onComplete).exception = e; 556 onComplete.sendToTarget(); 557 return; 558 } 559 } 560 } 561 562 @Override 563 public void supplyPin2(String pin2, Message onComplete) { 564 synchronized (mLock) { 565 if (mUiccApplication != null) { 566 mUiccApplication.supplyPin2(pin2, onComplete); 567 } else if (onComplete != null) { 568 Exception e = new RuntimeException("ICC card is absent."); 569 AsyncResult.forMessage(onComplete).exception = e; 570 onComplete.sendToTarget(); 571 return; 572 } 573 } 574 } 575 576 @Override 577 public void supplyPuk2(String puk2, String newPin2, Message onComplete) { 578 synchronized (mLock) { 579 if (mUiccApplication != null) { 580 mUiccApplication.supplyPuk2(puk2, newPin2, onComplete); 581 } else if (onComplete != null) { 582 Exception e = new RuntimeException("ICC card is absent."); 583 AsyncResult.forMessage(onComplete).exception = e; 584 onComplete.sendToTarget(); 585 return; 586 } 587 } 588 } 589 590 @Override 591 public void supplyNetworkDepersonalization(String pin, Message onComplete) { 592 synchronized (mLock) { 593 if (mUiccApplication != null) { 594 mUiccApplication.supplyNetworkDepersonalization(pin, onComplete); 595 } else if (onComplete != null) { 596 Exception e = new RuntimeException("CommandsInterface is not set."); 597 AsyncResult.forMessage(onComplete).exception = e; 598 onComplete.sendToTarget(); 599 return; 600 } 601 } 602 } 603 604 @Override 605 public boolean getIccLockEnabled() { 606 synchronized (mLock) { 607 /* defaults to true, if ICC is absent */ 608 Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccLockEnabled() : true; 609 return retValue; 610 } 611 } 612 613 @Override 614 public boolean getIccFdnEnabled() { 615 synchronized (mLock) { 616 Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccFdnEnabled() : false; 617 return retValue; 618 } 619 } 620 621 @Override 622 public void setIccLockEnabled(boolean enabled, String password, Message onComplete) { 623 synchronized (mLock) { 624 if (mUiccApplication != null) { 625 mUiccApplication.setIccLockEnabled(enabled, password, onComplete); 626 } else if (onComplete != null) { 627 Exception e = new RuntimeException("ICC card is absent."); 628 AsyncResult.forMessage(onComplete).exception = e; 629 onComplete.sendToTarget(); 630 return; 631 } 632 } 633 } 634 635 @Override 636 public void setIccFdnEnabled(boolean enabled, String password, Message onComplete) { 637 synchronized (mLock) { 638 if (mUiccApplication != null) { 639 mUiccApplication.setIccFdnEnabled(enabled, password, onComplete); 640 } else if (onComplete != null) { 641 Exception e = new RuntimeException("ICC card is absent."); 642 AsyncResult.forMessage(onComplete).exception = e; 643 onComplete.sendToTarget(); 644 return; 645 } 646 } 647 } 648 649 @Override 650 public void changeIccLockPassword(String oldPassword, String newPassword, Message onComplete) { 651 synchronized (mLock) { 652 if (mUiccApplication != null) { 653 mUiccApplication.changeIccLockPassword(oldPassword, newPassword, onComplete); 654 } else if (onComplete != null) { 655 Exception e = new RuntimeException("ICC card is absent."); 656 AsyncResult.forMessage(onComplete).exception = e; 657 onComplete.sendToTarget(); 658 return; 659 } 660 } 661 } 662 663 @Override 664 public void changeIccFdnPassword(String oldPassword, String newPassword, Message onComplete) { 665 synchronized (mLock) { 666 if (mUiccApplication != null) { 667 mUiccApplication.changeIccFdnPassword(oldPassword, newPassword, onComplete); 668 } else if (onComplete != null) { 669 Exception e = new RuntimeException("ICC card is absent."); 670 AsyncResult.forMessage(onComplete).exception = e; 671 onComplete.sendToTarget(); 672 return; 673 } 674 } 675 } 676 677 @Override 678 public String getServiceProviderName() { 679 synchronized (mLock) { 680 if (mIccRecords != null) { 681 return mIccRecords.getServiceProviderName(); 682 } 683 return null; 684 } 685 } 686 687 @Override 688 public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) { 689 synchronized (mLock) { 690 Boolean retValue = mUiccCard != null ? mUiccCard.isApplicationOnIcc(type) : false; 691 return retValue; 692 } 693 } 694 695 @Override 696 public boolean hasIccCard() { 697 synchronized (mLock) { 698 if (mUiccCard != null && mUiccCard.getCardState() != CardState.CARDSTATE_ABSENT) { 699 return true; 700 } 701 return false; 702 } 703 } 704 705 private void log(String s) { 706 Rlog.d(LOG_TAG, s); 707 } 708 709 private void loge(String msg) { 710 Rlog.e(LOG_TAG, msg); 711 } 712 713 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 714 pw.println("IccCardProxy: " + this); 715 pw.println(" mContext=" + mContext); 716 pw.println(" mCi=" + mCi); 717 pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size()); 718 for (int i = 0; i < mAbsentRegistrants.size(); i++) { 719 pw.println(" mAbsentRegistrants[" + i + "]=" 720 + ((Registrant)mAbsentRegistrants.get(i)).getHandler()); 721 } 722 pw.println(" mPinLockedRegistrants: size=" + mPinLockedRegistrants.size()); 723 for (int i = 0; i < mPinLockedRegistrants.size(); i++) { 724 pw.println(" mPinLockedRegistrants[" + i + "]=" 725 + ((Registrant)mPinLockedRegistrants.get(i)).getHandler()); 726 } 727 pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size()); 728 for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) { 729 pw.println(" mNetworkLockedRegistrants[" + i + "]=" 730 + ((Registrant)mNetworkLockedRegistrants.get(i)).getHandler()); 731 } 732 pw.println(" mCurrentAppType=" + mCurrentAppType); 733 pw.println(" mUiccController=" + mUiccController); 734 pw.println(" mUiccCard=" + mUiccCard); 735 pw.println(" mUiccApplication=" + mUiccApplication); 736 pw.println(" mIccRecords=" + mIccRecords); 737 pw.println(" mCdmaSSM=" + mCdmaSSM); 738 pw.println(" mRadioOn=" + mRadioOn); 739 pw.println(" mQuietMode=" + mQuietMode); 740 pw.println(" mInitialized=" + mInitialized); 741 pw.println(" mExternalState=" + mExternalState); 742 743 pw.flush(); 744 } 745 } 746