UiccCardApplication.java revision b93bb3538c55f173f94a4ee7510d9d1521d8f731
1/* 2 * Copyright (C) 2006, 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 android.content.Context; 20import android.os.AsyncResult; 21import android.os.Handler; 22import android.os.Message; 23import android.os.Registrant; 24import android.os.RegistrantList; 25import android.telephony.Rlog; 26 27import com.android.internal.telephony.CommandsInterface; 28import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; 29import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 30import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState; 31import com.android.internal.telephony.uicc.IccCardStatus.PinState; 32 33import java.io.FileDescriptor; 34import java.io.PrintWriter; 35 36/** 37 * {@hide} 38 */ 39public class UiccCardApplication { 40 private static final String LOG_TAG = "UiccCardApplication"; 41 private static final boolean DBG = true; 42 43 private static final int EVENT_PIN1_PUK1_DONE = 1; 44 private static final int EVENT_CHANGE_PIN1_DONE = 2; 45 private static final int EVENT_CHANGE_PIN2_DONE = 3; 46 private static final int EVENT_QUERY_FACILITY_FDN_DONE = 4; 47 private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 5; 48 private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 6; 49 private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 7; 50 private static final int EVENT_PIN2_PUK2_DONE = 8; 51 52 private final Object mLock = new Object(); 53 private UiccCard mUiccCard; //parent 54 private AppState mAppState; 55 private AppType mAppType; 56 private PersoSubState mPersoSubState; 57 private String mAid; 58 private String mAppLabel; 59 private boolean mPin1Replaced; 60 private PinState mPin1State; 61 private PinState mPin2State; 62 private boolean mIccFdnEnabled; 63 private boolean mDesiredFdnEnabled; 64 private boolean mIccLockEnabled; 65 private boolean mDesiredPinLocked; 66 private boolean mIccFdnAvailable = true; // Default is enabled. 67 68 private CommandsInterface mCi; 69 private Context mContext; 70 private IccRecords mIccRecords; 71 private IccFileHandler mIccFh; 72 73 private boolean mDestroyed;//set to true once this App is commanded to be disposed of. 74 75 private RegistrantList mReadyRegistrants = new RegistrantList(); 76 private RegistrantList mPinLockedRegistrants = new RegistrantList(); 77 private RegistrantList mNetworkLockedRegistrants = new RegistrantList(); 78 79 UiccCardApplication(UiccCard uiccCard, 80 IccCardApplicationStatus as, 81 Context c, 82 CommandsInterface ci) { 83 if (DBG) log("Creating UiccApp: " + as); 84 mUiccCard = uiccCard; 85 mAppState = as.app_state; 86 mAppType = as.app_type; 87 mPersoSubState = as.perso_substate; 88 mAid = as.aid; 89 mAppLabel = as.app_label; 90 mPin1Replaced = (as.pin1_replaced != 0); 91 mPin1State = as.pin1; 92 mPin2State = as.pin2; 93 94 mContext = c; 95 mCi = ci; 96 97 mIccFh = createIccFileHandler(as.app_type); 98 mIccRecords = createIccRecords(as.app_type, mContext, mCi); 99 if (mAppState == AppState.APPSTATE_READY) { 100 queryFdn(); 101 queryPin1State(); 102 } 103 } 104 105 void update (IccCardApplicationStatus as, Context c, CommandsInterface ci) { 106 synchronized (mLock) { 107 if (mDestroyed) { 108 loge("Application updated after destroyed! Fix me!"); 109 return; 110 } 111 112 if (DBG) log(mAppType + " update. New " + as); 113 mContext = c; 114 mCi = ci; 115 AppType oldAppType = mAppType; 116 AppState oldAppState = mAppState; 117 PersoSubState oldPersoSubState = mPersoSubState; 118 mAppType = as.app_type; 119 mAppState = as.app_state; 120 mPersoSubState = as.perso_substate; 121 mAid = as.aid; 122 mAppLabel = as.app_label; 123 mPin1Replaced = (as.pin1_replaced != 0); 124 mPin1State = as.pin1; 125 mPin2State = as.pin2; 126 127 if (mAppType != oldAppType) { 128 if (mIccFh != null) { mIccFh.dispose();} 129 if (mIccRecords != null) { mIccRecords.dispose();} 130 mIccFh = createIccFileHandler(as.app_type); 131 mIccRecords = createIccRecords(as.app_type, c, ci); 132 } 133 134 if (mPersoSubState != oldPersoSubState && 135 mPersoSubState == PersoSubState.PERSOSUBSTATE_SIM_NETWORK) { 136 notifyNetworkLockedRegistrantsIfNeeded(null); 137 } 138 139 if (mAppState != oldAppState) { 140 if (DBG) log(oldAppType + " changed state: " + oldAppState + " -> " + mAppState); 141 // If the app state turns to APPSTATE_READY, then query FDN status, 142 //as it might have failed in earlier attempt. 143 if (mAppState == AppState.APPSTATE_READY) { 144 queryFdn(); 145 queryPin1State(); 146 } 147 notifyPinLockedRegistrantsIfNeeded(null); 148 notifyReadyRegistrantsIfNeeded(null); 149 } 150 } 151 } 152 153 void dispose() { 154 synchronized (mLock) { 155 if (DBG) log(mAppType + " being Disposed"); 156 mDestroyed = true; 157 if (mIccRecords != null) { mIccRecords.dispose();} 158 if (mIccFh != null) { mIccFh.dispose();} 159 mIccRecords = null; 160 mIccFh = null; 161 } 162 } 163 164 private IccRecords createIccRecords(AppType type, Context c, CommandsInterface ci) { 165 if (type == AppType.APPTYPE_USIM || type == AppType.APPTYPE_SIM) { 166 return new SIMRecords(this, c, ci); 167 } else if (type == AppType.APPTYPE_RUIM || type == AppType.APPTYPE_CSIM){ 168 return new RuimRecords(this, c, ci); 169 } else if (type == AppType.APPTYPE_ISIM) { 170 return new IsimUiccRecords(this, c, ci); 171 } else { 172 // Unknown app type (maybe detection is still in progress) 173 return null; 174 } 175 } 176 177 private IccFileHandler createIccFileHandler(AppType type) { 178 switch (type) { 179 case APPTYPE_SIM: 180 return new SIMFileHandler(this, mAid, mCi); 181 case APPTYPE_RUIM: 182 return new RuimFileHandler(this, mAid, mCi); 183 case APPTYPE_USIM: 184 return new UsimFileHandler(this, mAid, mCi); 185 case APPTYPE_CSIM: 186 return new CsimFileHandler(this, mAid, mCi); 187 case APPTYPE_ISIM: 188 return new IsimFileHandler(this, mAid, mCi); 189 default: 190 return null; 191 } 192 } 193 194 /** Assumes mLock is held. */ 195 void queryFdn() { 196 //This shouldn't change run-time. So needs to be called only once. 197 int serviceClassX; 198 199 serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + 200 CommandsInterface.SERVICE_CLASS_DATA + 201 CommandsInterface.SERVICE_CLASS_FAX; 202 mCi.queryFacilityLockForApp ( 203 CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX, 204 mAid, mHandler.obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE)); 205 } 206 /** 207 * Interpret EVENT_QUERY_FACILITY_LOCK_DONE 208 * @param ar is asyncResult of Query_Facility_Locked 209 */ 210 private void onQueryFdnEnabled(AsyncResult ar) { 211 synchronized (mLock) { 212 if (ar.exception != null) { 213 if (DBG) log("Error in querying facility lock:" + ar.exception); 214 return; 215 } 216 217 int[] result = (int[])ar.result; 218 if(result.length != 0) { 219 //0 - Available & Disabled, 1-Available & Enabled, 2-Unavailable. 220 if (result[0] == 2) { 221 mIccFdnEnabled = false; 222 mIccFdnAvailable = false; 223 } else { 224 mIccFdnEnabled = (result[0] == 1) ? true : false; 225 mIccFdnAvailable = true; 226 } 227 log("Query facility FDN : FDN service available: "+ mIccFdnAvailable 228 +" enabled: " + mIccFdnEnabled); 229 } else { 230 loge("Bogus facility lock response"); 231 } 232 } 233 } 234 235 private void onChangeFdnDone(AsyncResult ar) { 236 synchronized (mLock) { 237 int attemptsRemaining = -1; 238 239 if (ar.exception == null) { 240 mIccFdnEnabled = mDesiredFdnEnabled; 241 if (DBG) log("EVENT_CHANGE_FACILITY_FDN_DONE: " + 242 "mIccFdnEnabled=" + mIccFdnEnabled); 243 } else { 244 attemptsRemaining = parsePinPukErrorResult(ar); 245 loge("Error change facility fdn with exception " + ar.exception); 246 } 247 Message response = (Message)ar.userObj; 248 response.arg1 = attemptsRemaining; 249 AsyncResult.forMessage(response).exception = ar.exception; 250 response.sendToTarget(); 251 } 252 } 253 254 /** REMOVE when mIccLockEnabled is not needed, assumes mLock is held */ 255 private void queryPin1State() { 256 int serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + 257 CommandsInterface.SERVICE_CLASS_DATA + 258 CommandsInterface.SERVICE_CLASS_FAX; 259 mCi.queryFacilityLockForApp ( 260 CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX, 261 mAid, mHandler.obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE)); 262 } 263 264 /** REMOVE when mIccLockEnabled is not needed*/ 265 private void onQueryFacilityLock(AsyncResult ar) { 266 synchronized (mLock) { 267 if(ar.exception != null) { 268 if (DBG) log("Error in querying facility lock:" + ar.exception); 269 return; 270 } 271 272 int[] ints = (int[])ar.result; 273 if(ints.length != 0) { 274 if (DBG) log("Query facility lock : " + ints[0]); 275 276 mIccLockEnabled = (ints[0] != 0); 277 278 if (mIccLockEnabled) { 279 mPinLockedRegistrants.notifyRegistrants(); 280 } 281 282 // Sanity check: we expect mPin1State to match mIccLockEnabled. 283 // When mPin1State is DISABLED mIccLockEanbled should be false. 284 // When mPin1State is ENABLED mIccLockEnabled should be true. 285 // 286 // Here we validate these assumptions to assist in identifying which ril/radio's 287 // have not correctly implemented GET_SIM_STATUS 288 switch (mPin1State) { 289 case PINSTATE_DISABLED: 290 if (mIccLockEnabled) { 291 loge("QUERY_FACILITY_LOCK:enabled GET_SIM_STATUS.Pin1:disabled." 292 + " Fixme"); 293 } 294 break; 295 case PINSTATE_ENABLED_NOT_VERIFIED: 296 case PINSTATE_ENABLED_VERIFIED: 297 case PINSTATE_ENABLED_BLOCKED: 298 case PINSTATE_ENABLED_PERM_BLOCKED: 299 if (!mIccLockEnabled) { 300 loge("QUERY_FACILITY_LOCK:disabled GET_SIM_STATUS.Pin1:enabled." 301 + " Fixme"); 302 } 303 case PINSTATE_UNKNOWN: 304 default: 305 if (DBG) log("Ignoring: pin1state=" + mPin1State); 306 break; 307 } 308 } else { 309 loge("Bogus facility lock response"); 310 } 311 } 312 } 313 314 /** REMOVE when mIccLockEnabled is not needed */ 315 private void onChangeFacilityLock(AsyncResult ar) { 316 synchronized (mLock) { 317 int attemptsRemaining = -1; 318 319 if (ar.exception == null) { 320 mIccLockEnabled = mDesiredPinLocked; 321 if (DBG) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: mIccLockEnabled= " 322 + mIccLockEnabled); 323 } else { 324 attemptsRemaining = parsePinPukErrorResult(ar); 325 loge("Error change facility lock with exception " + ar.exception); 326 } 327 Message response = (Message)ar.userObj; 328 AsyncResult.forMessage(response).exception = ar.exception; 329 response.arg1 = attemptsRemaining; 330 response.sendToTarget(); 331 } 332 } 333 334 /** 335 * Parse the error response to obtain number of attempts remaining 336 */ 337 private int parsePinPukErrorResult(AsyncResult ar) { 338 int[] result = (int[]) ar.result; 339 if (result == null) { 340 return -1; 341 } else { 342 int length = result.length; 343 int attemptsRemaining = -1; 344 if (length > 0) { 345 attemptsRemaining = result[0]; 346 } 347 log("parsePinPukErrorResult: attemptsRemaining=" + attemptsRemaining); 348 return attemptsRemaining; 349 } 350 } 351 352 private Handler mHandler = new Handler() { 353 @Override 354 public void handleMessage(Message msg){ 355 AsyncResult ar; 356 357 if (mDestroyed) { 358 loge("Received message " + msg + "[" + msg.what 359 + "] while being destroyed. Ignoring."); 360 return; 361 } 362 363 switch (msg.what) { 364 case EVENT_PIN1_PUK1_DONE: 365 case EVENT_PIN2_PUK2_DONE: 366 case EVENT_CHANGE_PIN1_DONE: 367 case EVENT_CHANGE_PIN2_DONE: 368 // a PIN/PUK/PIN2/PUK2 complete 369 // request has completed. ar.userObj is the response Message 370 int attemptsRemaining = -1; 371 ar = (AsyncResult)msg.obj; 372 if ((ar.exception != null) && (ar.result != null)) { 373 attemptsRemaining = parsePinPukErrorResult(ar); 374 } 375 Message response = (Message)ar.userObj; 376 AsyncResult.forMessage(response).exception = ar.exception; 377 response.arg1 = attemptsRemaining; 378 response.sendToTarget(); 379 break; 380 case EVENT_QUERY_FACILITY_FDN_DONE: 381 ar = (AsyncResult)msg.obj; 382 onQueryFdnEnabled(ar); 383 break; 384 case EVENT_CHANGE_FACILITY_FDN_DONE: 385 ar = (AsyncResult)msg.obj; 386 onChangeFdnDone(ar); 387 break; 388 case EVENT_QUERY_FACILITY_LOCK_DONE: 389 ar = (AsyncResult)msg.obj; 390 onQueryFacilityLock(ar); 391 break; 392 case EVENT_CHANGE_FACILITY_LOCK_DONE: 393 ar = (AsyncResult)msg.obj; 394 onChangeFacilityLock(ar); 395 break; 396 default: 397 loge("Unknown Event " + msg.what); 398 } 399 } 400 }; 401 402 public void registerForReady(Handler h, int what, Object obj) { 403 synchronized (mLock) { 404 Registrant r = new Registrant (h, what, obj); 405 mReadyRegistrants.add(r); 406 notifyReadyRegistrantsIfNeeded(r); 407 } 408 } 409 410 public void unregisterForReady(Handler h) { 411 synchronized (mLock) { 412 mReadyRegistrants.remove(h); 413 } 414 } 415 416 /** 417 * Notifies handler of any transition into State.isPinLocked() 418 */ 419 public void registerForLocked(Handler h, int what, Object obj) { 420 synchronized (mLock) { 421 Registrant r = new Registrant (h, what, obj); 422 mPinLockedRegistrants.add(r); 423 notifyPinLockedRegistrantsIfNeeded(r); 424 } 425 } 426 427 public void unregisterForLocked(Handler h) { 428 synchronized (mLock) { 429 mPinLockedRegistrants.remove(h); 430 } 431 } 432 433 /** 434 * Notifies handler of any transition into State.NETWORK_LOCKED 435 */ 436 public void registerForNetworkLocked(Handler h, int what, Object obj) { 437 synchronized (mLock) { 438 Registrant r = new Registrant (h, what, obj); 439 mNetworkLockedRegistrants.add(r); 440 notifyNetworkLockedRegistrantsIfNeeded(r); 441 } 442 } 443 444 public void unregisterForNetworkLocked(Handler h) { 445 synchronized (mLock) { 446 mNetworkLockedRegistrants.remove(h); 447 } 448 } 449 450 /** 451 * Notifies specified registrant, assume mLock is held. 452 * 453 * @param r Registrant to be notified. If null - all registrants will be notified 454 */ 455 private void notifyReadyRegistrantsIfNeeded(Registrant r) { 456 if (mDestroyed) { 457 return; 458 } 459 if (mAppState == AppState.APPSTATE_READY) { 460 if (mPin1State == PinState.PINSTATE_ENABLED_NOT_VERIFIED || 461 mPin1State == PinState.PINSTATE_ENABLED_BLOCKED || 462 mPin1State == PinState.PINSTATE_ENABLED_PERM_BLOCKED) { 463 loge("Sanity check failed! APPSTATE is ready while PIN1 is not verified!!!"); 464 // Don't notify if application is in insane state 465 return; 466 } 467 if (r == null) { 468 if (DBG) log("Notifying registrants: READY"); 469 mReadyRegistrants.notifyRegistrants(); 470 } else { 471 if (DBG) log("Notifying 1 registrant: READY"); 472 r.notifyRegistrant(new AsyncResult(null, null, null)); 473 } 474 } 475 } 476 477 /** 478 * Notifies specified registrant, assume mLock is held. 479 * 480 * @param r Registrant to be notified. If null - all registrants will be notified 481 */ 482 private void notifyPinLockedRegistrantsIfNeeded(Registrant r) { 483 if (mDestroyed) { 484 return; 485 } 486 487 if (mAppState == AppState.APPSTATE_PIN || 488 mAppState == AppState.APPSTATE_PUK) { 489 if (mPin1State == PinState.PINSTATE_ENABLED_VERIFIED || 490 mPin1State == PinState.PINSTATE_DISABLED) { 491 loge("Sanity check failed! APPSTATE is locked while PIN1 is not!!!"); 492 //Don't notify if application is in insane state 493 return; 494 } 495 if (r == null) { 496 if (DBG) log("Notifying registrants: LOCKED"); 497 mPinLockedRegistrants.notifyRegistrants(); 498 } else { 499 if (DBG) log("Notifying 1 registrant: LOCKED"); 500 r.notifyRegistrant(new AsyncResult(null, null, null)); 501 } 502 } 503 } 504 505 /** 506 * Notifies specified registrant, assume mLock is held. 507 * 508 * @param r Registrant to be notified. If null - all registrants will be notified 509 */ 510 private void notifyNetworkLockedRegistrantsIfNeeded(Registrant r) { 511 if (mDestroyed) { 512 return; 513 } 514 515 if (mAppState == AppState.APPSTATE_SUBSCRIPTION_PERSO && 516 mPersoSubState == PersoSubState.PERSOSUBSTATE_SIM_NETWORK) { 517 if (r == null) { 518 if (DBG) log("Notifying registrants: NETWORK_LOCKED"); 519 mNetworkLockedRegistrants.notifyRegistrants(); 520 } else { 521 if (DBG) log("Notifying 1 registrant: NETWORK_LOCED"); 522 r.notifyRegistrant(new AsyncResult(null, null, null)); 523 } 524 } 525 } 526 527 public AppState getState() { 528 synchronized (mLock) { 529 return mAppState; 530 } 531 } 532 533 public AppType getType() { 534 synchronized (mLock) { 535 return mAppType; 536 } 537 } 538 539 public PersoSubState getPersoSubState() { 540 synchronized (mLock) { 541 return mPersoSubState; 542 } 543 } 544 545 public String getAid() { 546 synchronized (mLock) { 547 return mAid; 548 } 549 } 550 551 public String getAppLabel() { 552 return mAppLabel; 553 } 554 555 public PinState getPin1State() { 556 synchronized (mLock) { 557 if (mPin1Replaced) { 558 return mUiccCard.getUniversalPinState(); 559 } 560 return mPin1State; 561 } 562 } 563 564 public IccFileHandler getIccFileHandler() { 565 synchronized (mLock) { 566 return mIccFh; 567 } 568 } 569 570 public IccRecords getIccRecords() { 571 synchronized (mLock) { 572 return mIccRecords; 573 } 574 } 575 576 /** 577 * Supply the ICC PIN to the ICC 578 * 579 * When the operation is complete, onComplete will be sent to its 580 * Handler. 581 * 582 * onComplete.obj will be an AsyncResult 583 * onComplete.arg1 = remaining attempts before puk locked or -1 if unknown 584 * 585 * ((AsyncResult)onComplete.obj).exception == null on success 586 * ((AsyncResult)onComplete.obj).exception != null on fail 587 * 588 * If the supplied PIN is incorrect: 589 * ((AsyncResult)onComplete.obj).exception != null 590 * && ((AsyncResult)onComplete.obj).exception 591 * instanceof com.android.internal.telephony.gsm.CommandException) 592 * && ((CommandException)(((AsyncResult)onComplete.obj).exception)) 593 * .getCommandError() == CommandException.Error.PASSWORD_INCORRECT 594 */ 595 public void supplyPin (String pin, Message onComplete) { 596 synchronized (mLock) { 597 mCi.supplyIccPinForApp(pin, mAid, mHandler.obtainMessage(EVENT_PIN1_PUK1_DONE, 598 onComplete)); 599 } 600 } 601 602 /** 603 * Supply the ICC PUK to the ICC 604 * 605 * When the operation is complete, onComplete will be sent to its 606 * Handler. 607 * 608 * onComplete.obj will be an AsyncResult 609 * onComplete.arg1 = remaining attempts before Icc will be permanently unusable 610 * or -1 if unknown 611 * 612 * ((AsyncResult)onComplete.obj).exception == null on success 613 * ((AsyncResult)onComplete.obj).exception != null on fail 614 * 615 * If the supplied PIN is incorrect: 616 * ((AsyncResult)onComplete.obj).exception != null 617 * && ((AsyncResult)onComplete.obj).exception 618 * instanceof com.android.internal.telephony.gsm.CommandException) 619 * && ((CommandException)(((AsyncResult)onComplete.obj).exception)) 620 * .getCommandError() == CommandException.Error.PASSWORD_INCORRECT 621 * 622 * 623 */ 624 public void supplyPuk (String puk, String newPin, Message onComplete) { 625 synchronized (mLock) { 626 mCi.supplyIccPukForApp(puk, newPin, mAid, 627 mHandler.obtainMessage(EVENT_PIN1_PUK1_DONE, onComplete)); 628 } 629 } 630 631 public void supplyPin2 (String pin2, Message onComplete) { 632 synchronized (mLock) { 633 mCi.supplyIccPin2ForApp(pin2, mAid, 634 mHandler.obtainMessage(EVENT_PIN2_PUK2_DONE, onComplete)); 635 } 636 } 637 638 public void supplyPuk2 (String puk2, String newPin2, Message onComplete) { 639 synchronized (mLock) { 640 mCi.supplyIccPuk2ForApp(puk2, newPin2, mAid, 641 mHandler.obtainMessage(EVENT_PIN2_PUK2_DONE, onComplete)); 642 } 643 } 644 645 public void supplyNetworkDepersonalization (String pin, Message onComplete) { 646 synchronized (mLock) { 647 if (DBG) log("supplyNetworkDepersonalization"); 648 mCi.supplyNetworkDepersonalization(pin, onComplete); 649 } 650 } 651 652 /** 653 * Check whether ICC pin lock is enabled 654 * This is a sync call which returns the cached pin enabled state 655 * 656 * @return true for ICC locked enabled 657 * false for ICC locked disabled 658 */ 659 public boolean getIccLockEnabled() { 660 return mIccLockEnabled; 661 /* STOPSHIP: Remove line above and all code associated with setting 662 mIccLockEanbled once all RIL correctly sends the pin1 state. 663 // Use getPin1State to take into account pin1Replaced flag 664 PinState pinState = getPin1State(); 665 return pinState == PinState.PINSTATE_ENABLED_NOT_VERIFIED || 666 pinState == PinState.PINSTATE_ENABLED_VERIFIED || 667 pinState == PinState.PINSTATE_ENABLED_BLOCKED || 668 pinState == PinState.PINSTATE_ENABLED_PERM_BLOCKED;*/ 669 } 670 671 /** 672 * Check whether ICC fdn (fixed dialing number) is enabled 673 * This is a sync call which returns the cached pin enabled state 674 * 675 * @return true for ICC fdn enabled 676 * false for ICC fdn disabled 677 */ 678 public boolean getIccFdnEnabled() { 679 synchronized (mLock) { 680 return mIccFdnEnabled; 681 } 682 } 683 684 /** 685 * Check whether fdn (fixed dialing number) service is available. 686 * @return true if ICC fdn service available 687 * false if ICC fdn service not available 688 */ 689 public boolean getIccFdnAvailable() { 690 return mIccFdnAvailable; 691 } 692 693 /** 694 * Set the ICC pin lock enabled or disabled 695 * When the operation is complete, onComplete will be sent to its handler 696 * 697 * @param enabled "true" for locked "false" for unlocked. 698 * @param password needed to change the ICC pin state, aka. Pin1 699 * @param onComplete 700 * onComplete.obj will be an AsyncResult 701 * ((AsyncResult)onComplete.obj).exception == null on success 702 * ((AsyncResult)onComplete.obj).exception != null on fail 703 */ 704 public void setIccLockEnabled (boolean enabled, 705 String password, Message onComplete) { 706 synchronized (mLock) { 707 int serviceClassX; 708 serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + 709 CommandsInterface.SERVICE_CLASS_DATA + 710 CommandsInterface.SERVICE_CLASS_FAX; 711 712 mDesiredPinLocked = enabled; 713 714 mCi.setFacilityLockForApp(CommandsInterface.CB_FACILITY_BA_SIM, 715 enabled, password, serviceClassX, mAid, 716 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete)); 717 } 718 } 719 720 /** 721 * Set the ICC fdn enabled or disabled 722 * When the operation is complete, onComplete will be sent to its handler 723 * 724 * @param enabled "true" for locked "false" for unlocked. 725 * @param password needed to change the ICC fdn enable, aka Pin2 726 * @param onComplete 727 * onComplete.obj will be an AsyncResult 728 * ((AsyncResult)onComplete.obj).exception == null on success 729 * ((AsyncResult)onComplete.obj).exception != null on fail 730 */ 731 public void setIccFdnEnabled (boolean enabled, 732 String password, Message onComplete) { 733 synchronized (mLock) { 734 int serviceClassX; 735 serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + 736 CommandsInterface.SERVICE_CLASS_DATA + 737 CommandsInterface.SERVICE_CLASS_FAX + 738 CommandsInterface.SERVICE_CLASS_SMS; 739 740 mDesiredFdnEnabled = enabled; 741 742 mCi.setFacilityLockForApp(CommandsInterface.CB_FACILITY_BA_FD, 743 enabled, password, serviceClassX, mAid, 744 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete)); 745 } 746 } 747 748 /** 749 * Change the ICC password used in ICC pin lock 750 * When the operation is complete, onComplete will be sent to its handler 751 * 752 * @param oldPassword is the old password 753 * @param newPassword is the new password 754 * @param onComplete 755 * onComplete.obj will be an AsyncResult 756 * onComplete.arg1 = attempts remaining or -1 if unknown 757 * ((AsyncResult)onComplete.obj).exception == null on success 758 * ((AsyncResult)onComplete.obj).exception != null on fail 759 */ 760 public void changeIccLockPassword(String oldPassword, String newPassword, 761 Message onComplete) { 762 synchronized (mLock) { 763 if (DBG) log("changeIccLockPassword"); 764 mCi.changeIccPinForApp(oldPassword, newPassword, mAid, 765 mHandler.obtainMessage(EVENT_CHANGE_PIN1_DONE, onComplete)); 766 } 767 } 768 769 /** 770 * Change the ICC password used in ICC fdn enable 771 * When the operation is complete, onComplete will be sent to its handler 772 * 773 * @param oldPassword is the old password 774 * @param newPassword is the new password 775 * @param onComplete 776 * onComplete.obj will be an AsyncResult 777 * ((AsyncResult)onComplete.obj).exception == null on success 778 * ((AsyncResult)onComplete.obj).exception != null on fail 779 */ 780 public void changeIccFdnPassword(String oldPassword, String newPassword, 781 Message onComplete) { 782 synchronized (mLock) { 783 if (DBG) log("changeIccFdnPassword"); 784 mCi.changeIccPin2ForApp(oldPassword, newPassword, mAid, 785 mHandler.obtainMessage(EVENT_CHANGE_PIN2_DONE, onComplete)); 786 } 787 } 788 789 /** 790 * @return true if ICC card is PIN2 blocked 791 */ 792 public boolean getIccPin2Blocked() { 793 synchronized (mLock) { 794 return mPin2State == PinState.PINSTATE_ENABLED_BLOCKED; 795 } 796 } 797 798 /** 799 * @return true if ICC card is PUK2 blocked 800 */ 801 public boolean getIccPuk2Blocked() { 802 synchronized (mLock) { 803 return mPin2State == PinState.PINSTATE_ENABLED_PERM_BLOCKED; 804 } 805 } 806 807 protected UiccCard getUiccCard() { 808 return mUiccCard; 809 } 810 811 private void log(String msg) { 812 Rlog.d(LOG_TAG, msg); 813 } 814 815 private void loge(String msg) { 816 Rlog.e(LOG_TAG, msg); 817 } 818 819 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 820 pw.println("UiccCardApplication: " + this); 821 pw.println(" mUiccCard=" + mUiccCard); 822 pw.println(" mAppState=" + mAppState); 823 pw.println(" mAppType=" + mAppType); 824 pw.println(" mPersoSubState=" + mPersoSubState); 825 pw.println(" mAid=" + mAid); 826 pw.println(" mAppLabel=" + mAppLabel); 827 pw.println(" mPin1Replaced=" + mPin1Replaced); 828 pw.println(" mPin1State=" + mPin1State); 829 pw.println(" mPin2State=" + mPin2State); 830 pw.println(" mIccFdnEnabled=" + mIccFdnEnabled); 831 pw.println(" mDesiredFdnEnabled=" + mDesiredFdnEnabled); 832 pw.println(" mIccLockEnabled=" + mIccLockEnabled); 833 pw.println(" mDesiredPinLocked=" + mDesiredPinLocked); 834 pw.println(" mCi=" + mCi); 835 pw.println(" mIccRecords=" + mIccRecords); 836 pw.println(" mIccFh=" + mIccFh); 837 pw.println(" mDestroyed=" + mDestroyed); 838 pw.println(" mReadyRegistrants: size=" + mReadyRegistrants.size()); 839 for (int i = 0; i < mReadyRegistrants.size(); i++) { 840 pw.println(" mReadyRegistrants[" + i + "]=" 841 + ((Registrant)mReadyRegistrants.get(i)).getHandler()); 842 } 843 pw.println(" mPinLockedRegistrants: size=" + mPinLockedRegistrants.size()); 844 for (int i = 0; i < mPinLockedRegistrants.size(); i++) { 845 pw.println(" mPinLockedRegistrants[" + i + "]=" 846 + ((Registrant)mPinLockedRegistrants.get(i)).getHandler()); 847 } 848 pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size()); 849 for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) { 850 pw.println(" mNetworkLockedRegistrants[" + i + "]=" 851 + ((Registrant)mNetworkLockedRegistrants.get(i)).getHandler()); 852 } 853 pw.flush(); 854 } 855} 856