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 17 package com.android.internal.telephony.uicc; 18 19 import android.content.Context; 20 import android.os.AsyncResult; 21 import android.os.Handler; 22 import android.os.Message; 23 import android.os.Registrant; 24 import android.os.RegistrantList; 25 import android.telephony.Rlog; 26 27 import com.android.internal.telephony.CommandsInterface; 28 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; 29 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 30 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState; 31 import com.android.internal.telephony.uicc.IccCardStatus.PinState; 32 33 import java.io.FileDescriptor; 34 import java.io.PrintWriter; 35 36 /** 37 * {@hide} 38 */ 39 public 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 private 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 PinState getPin1State() { 552 synchronized (mLock) { 553 if (mPin1Replaced) { 554 return mUiccCard.getUniversalPinState(); 555 } 556 return mPin1State; 557 } 558 } 559 560 public IccFileHandler getIccFileHandler() { 561 synchronized (mLock) { 562 return mIccFh; 563 } 564 } 565 566 public IccRecords getIccRecords() { 567 synchronized (mLock) { 568 return mIccRecords; 569 } 570 } 571 572 /** 573 * Supply the ICC PIN to the ICC 574 * 575 * When the operation is complete, onComplete will be sent to its 576 * Handler. 577 * 578 * onComplete.obj will be an AsyncResult 579 * onComplete.arg1 = remaining attempts before puk locked or -1 if unknown 580 * 581 * ((AsyncResult)onComplete.obj).exception == null on success 582 * ((AsyncResult)onComplete.obj).exception != null on fail 583 * 584 * If the supplied PIN is incorrect: 585 * ((AsyncResult)onComplete.obj).exception != null 586 * && ((AsyncResult)onComplete.obj).exception 587 * instanceof com.android.internal.telephony.gsm.CommandException) 588 * && ((CommandException)(((AsyncResult)onComplete.obj).exception)) 589 * .getCommandError() == CommandException.Error.PASSWORD_INCORRECT 590 */ 591 public void supplyPin (String pin, Message onComplete) { 592 synchronized (mLock) { 593 mCi.supplyIccPinForApp(pin, mAid, mHandler.obtainMessage(EVENT_PIN1_PUK1_DONE, 594 onComplete)); 595 } 596 } 597 598 /** 599 * Supply the ICC PUK to the ICC 600 * 601 * When the operation is complete, onComplete will be sent to its 602 * Handler. 603 * 604 * onComplete.obj will be an AsyncResult 605 * onComplete.arg1 = remaining attempts before Icc will be permanently unusable 606 * or -1 if unknown 607 * 608 * ((AsyncResult)onComplete.obj).exception == null on success 609 * ((AsyncResult)onComplete.obj).exception != null on fail 610 * 611 * If the supplied PIN is incorrect: 612 * ((AsyncResult)onComplete.obj).exception != null 613 * && ((AsyncResult)onComplete.obj).exception 614 * instanceof com.android.internal.telephony.gsm.CommandException) 615 * && ((CommandException)(((AsyncResult)onComplete.obj).exception)) 616 * .getCommandError() == CommandException.Error.PASSWORD_INCORRECT 617 * 618 * 619 */ 620 public void supplyPuk (String puk, String newPin, Message onComplete) { 621 synchronized (mLock) { 622 mCi.supplyIccPukForApp(puk, newPin, mAid, 623 mHandler.obtainMessage(EVENT_PIN1_PUK1_DONE, onComplete)); 624 } 625 } 626 627 public void supplyPin2 (String pin2, Message onComplete) { 628 synchronized (mLock) { 629 mCi.supplyIccPin2ForApp(pin2, mAid, 630 mHandler.obtainMessage(EVENT_PIN2_PUK2_DONE, onComplete)); 631 } 632 } 633 634 public void supplyPuk2 (String puk2, String newPin2, Message onComplete) { 635 synchronized (mLock) { 636 mCi.supplyIccPuk2ForApp(puk2, newPin2, mAid, 637 mHandler.obtainMessage(EVENT_PIN2_PUK2_DONE, onComplete)); 638 } 639 } 640 641 public void supplyNetworkDepersonalization (String pin, Message onComplete) { 642 synchronized (mLock) { 643 if (DBG) log("supplyNetworkDepersonalization"); 644 mCi.supplyNetworkDepersonalization(pin, onComplete); 645 } 646 } 647 648 /** 649 * Check whether ICC pin lock is enabled 650 * This is a sync call which returns the cached pin enabled state 651 * 652 * @return true for ICC locked enabled 653 * false for ICC locked disabled 654 */ 655 public boolean getIccLockEnabled() { 656 return mIccLockEnabled; 657 /* STOPSHIP: Remove line above and all code associated with setting 658 mIccLockEanbled once all RIL correctly sends the pin1 state. 659 // Use getPin1State to take into account pin1Replaced flag 660 PinState pinState = getPin1State(); 661 return pinState == PinState.PINSTATE_ENABLED_NOT_VERIFIED || 662 pinState == PinState.PINSTATE_ENABLED_VERIFIED || 663 pinState == PinState.PINSTATE_ENABLED_BLOCKED || 664 pinState == PinState.PINSTATE_ENABLED_PERM_BLOCKED;*/ 665 } 666 667 /** 668 * Check whether ICC fdn (fixed dialing number) is enabled 669 * This is a sync call which returns the cached pin enabled state 670 * 671 * @return true for ICC fdn enabled 672 * false for ICC fdn disabled 673 */ 674 public boolean getIccFdnEnabled() { 675 synchronized (mLock) { 676 return mIccFdnEnabled; 677 } 678 } 679 680 /** 681 * Check whether fdn (fixed dialing number) service is available. 682 * @return true if ICC fdn service available 683 * false if ICC fdn service not available 684 */ 685 public boolean getIccFdnAvailable() { 686 return mIccFdnAvailable; 687 } 688 689 /** 690 * Set the ICC pin lock enabled or disabled 691 * When the operation is complete, onComplete will be sent to its handler 692 * 693 * @param enabled "true" for locked "false" for unlocked. 694 * @param password needed to change the ICC pin state, aka. Pin1 695 * @param onComplete 696 * onComplete.obj will be an AsyncResult 697 * ((AsyncResult)onComplete.obj).exception == null on success 698 * ((AsyncResult)onComplete.obj).exception != null on fail 699 */ 700 public void setIccLockEnabled (boolean enabled, 701 String password, Message onComplete) { 702 synchronized (mLock) { 703 int serviceClassX; 704 serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + 705 CommandsInterface.SERVICE_CLASS_DATA + 706 CommandsInterface.SERVICE_CLASS_FAX; 707 708 mDesiredPinLocked = enabled; 709 710 mCi.setFacilityLockForApp(CommandsInterface.CB_FACILITY_BA_SIM, 711 enabled, password, serviceClassX, mAid, 712 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete)); 713 } 714 } 715 716 /** 717 * Set the ICC fdn enabled or disabled 718 * When the operation is complete, onComplete will be sent to its handler 719 * 720 * @param enabled "true" for locked "false" for unlocked. 721 * @param password needed to change the ICC fdn enable, aka Pin2 722 * @param onComplete 723 * onComplete.obj will be an AsyncResult 724 * ((AsyncResult)onComplete.obj).exception == null on success 725 * ((AsyncResult)onComplete.obj).exception != null on fail 726 */ 727 public void setIccFdnEnabled (boolean enabled, 728 String password, Message onComplete) { 729 synchronized (mLock) { 730 int serviceClassX; 731 serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + 732 CommandsInterface.SERVICE_CLASS_DATA + 733 CommandsInterface.SERVICE_CLASS_FAX + 734 CommandsInterface.SERVICE_CLASS_SMS; 735 736 mDesiredFdnEnabled = enabled; 737 738 mCi.setFacilityLockForApp(CommandsInterface.CB_FACILITY_BA_FD, 739 enabled, password, serviceClassX, mAid, 740 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete)); 741 } 742 } 743 744 /** 745 * Change the ICC password used in ICC pin lock 746 * When the operation is complete, onComplete will be sent to its handler 747 * 748 * @param oldPassword is the old password 749 * @param newPassword is the new password 750 * @param onComplete 751 * onComplete.obj will be an AsyncResult 752 * onComplete.arg1 = attempts remaining or -1 if unknown 753 * ((AsyncResult)onComplete.obj).exception == null on success 754 * ((AsyncResult)onComplete.obj).exception != null on fail 755 */ 756 public void changeIccLockPassword(String oldPassword, String newPassword, 757 Message onComplete) { 758 synchronized (mLock) { 759 if (DBG) log("changeIccLockPassword"); 760 mCi.changeIccPinForApp(oldPassword, newPassword, mAid, 761 mHandler.obtainMessage(EVENT_CHANGE_PIN1_DONE, onComplete)); 762 } 763 } 764 765 /** 766 * Change the ICC password used in ICC fdn enable 767 * When the operation is complete, onComplete will be sent to its handler 768 * 769 * @param oldPassword is the old password 770 * @param newPassword is the new password 771 * @param onComplete 772 * onComplete.obj will be an AsyncResult 773 * ((AsyncResult)onComplete.obj).exception == null on success 774 * ((AsyncResult)onComplete.obj).exception != null on fail 775 */ 776 public void changeIccFdnPassword(String oldPassword, String newPassword, 777 Message onComplete) { 778 synchronized (mLock) { 779 if (DBG) log("changeIccFdnPassword"); 780 mCi.changeIccPin2ForApp(oldPassword, newPassword, mAid, 781 mHandler.obtainMessage(EVENT_CHANGE_PIN2_DONE, onComplete)); 782 } 783 } 784 785 /** 786 * @return true if ICC card is PIN2 blocked 787 */ 788 public boolean getIccPin2Blocked() { 789 synchronized (mLock) { 790 return mPin2State == PinState.PINSTATE_ENABLED_BLOCKED; 791 } 792 } 793 794 /** 795 * @return true if ICC card is PUK2 blocked 796 */ 797 public boolean getIccPuk2Blocked() { 798 synchronized (mLock) { 799 return mPin2State == PinState.PINSTATE_ENABLED_PERM_BLOCKED; 800 } 801 } 802 803 private void log(String msg) { 804 Rlog.d(LOG_TAG, msg); 805 } 806 807 private void loge(String msg) { 808 Rlog.e(LOG_TAG, msg); 809 } 810 811 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 812 pw.println("UiccCardApplication: " + this); 813 pw.println(" mUiccCard=" + mUiccCard); 814 pw.println(" mAppState=" + mAppState); 815 pw.println(" mAppType=" + mAppType); 816 pw.println(" mPersoSubState=" + mPersoSubState); 817 pw.println(" mAid=" + mAid); 818 pw.println(" mAppLabel=" + mAppLabel); 819 pw.println(" mPin1Replaced=" + mPin1Replaced); 820 pw.println(" mPin1State=" + mPin1State); 821 pw.println(" mPin2State=" + mPin2State); 822 pw.println(" mIccFdnEnabled=" + mIccFdnEnabled); 823 pw.println(" mDesiredFdnEnabled=" + mDesiredFdnEnabled); 824 pw.println(" mIccLockEnabled=" + mIccLockEnabled); 825 pw.println(" mDesiredPinLocked=" + mDesiredPinLocked); 826 pw.println(" mCi=" + mCi); 827 pw.println(" mIccRecords=" + mIccRecords); 828 pw.println(" mIccFh=" + mIccFh); 829 pw.println(" mDestroyed=" + mDestroyed); 830 pw.println(" mReadyRegistrants: size=" + mReadyRegistrants.size()); 831 for (int i = 0; i < mReadyRegistrants.size(); i++) { 832 pw.println(" mReadyRegistrants[" + i + "]=" 833 + ((Registrant)mReadyRegistrants.get(i)).getHandler()); 834 } 835 pw.println(" mPinLockedRegistrants: size=" + mPinLockedRegistrants.size()); 836 for (int i = 0; i < mPinLockedRegistrants.size(); i++) { 837 pw.println(" mPinLockedRegistrants[" + i + "]=" 838 + ((Registrant)mPinLockedRegistrants.get(i)).getHandler()); 839 } 840 pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size()); 841 for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) { 842 pw.println(" mNetworkLockedRegistrants[" + i + "]=" 843 + ((Registrant)mNetworkLockedRegistrants.get(i)).getHandler()); 844 } 845 pw.flush(); 846 } 847 } 848