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