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