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