2 * Copyright (C) 2006, 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com
.android
.internal
.telephony
.uicc
;
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
;
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
;
35 import java
.io
.FileDescriptor
;
36 import java
.io
.PrintWriter
;
41 public class UiccCardApplication
{
42 private static final String LOG_TAG
= "UiccCardApplication";
43 private static final boolean DBG
= true;
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;
56 * These values are for authContext (parameter P2) per 3GPP TS 31.102 (Section 7.1.2)
58 public static final int AUTH_CONTEXT_EAP_SIM
= 128;
59 public static final int AUTH_CONTEXT_EAP_AKA
= 129;
60 public static final int AUTH_CONTEXT_UNDEFINED
= -1;
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
;
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.
79 private CommandsInterface mCi
;
80 private Context mContext
;
81 private IccRecords mIccRecords
;
82 private IccFileHandler mIccFh
;
84 private boolean mDestroyed
;//set to true once this App is commanded to be disposed of.
86 private RegistrantList mReadyRegistrants
= new RegistrantList();
87 private RegistrantList mPinLockedRegistrants
= new RegistrantList();
88 private RegistrantList mNetworkLockedRegistrants
= new RegistrantList();
90 UiccCardApplication(UiccCard uiccCard
,
91 IccCardApplicationStatus as
,
93 CommandsInterface ci
) {
94 if (DBG
) log("Creating UiccApp: " + as
);
96 mAppState
= as
.app_state
;
97 mAppType
= as
.app_type
;
98 mAuthContext
= getAuthContext(mAppType
);
99 mPersoSubState
= as
.perso_substate
;
101 mAppLabel
= as
.app_label
;
102 mPin1Replaced
= (as
.pin1_replaced
!= 0);
103 mPin1State
= as
.pin1
;
104 mPin2State
= as
.pin2
;
109 mIccFh
= createIccFileHandler(as
.app_type
);
110 mIccRecords
= createIccRecords(as
.app_type
, mContext
, mCi
);
111 if (mAppState
== AppState
.APPSTATE_READY
) {
115 mCi
.registerForNotAvailable(mHandler
, EVENT_RADIO_UNAVAILABLE
, null);
118 void update (IccCardApplicationStatus as
, Context c
, CommandsInterface ci
) {
119 synchronized (mLock
) {
121 loge("Application updated after destroyed! Fix me!");
125 if (DBG
) log(mAppType
+ " update. New " + as
);
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
;
136 mAppLabel
= as
.app_label
;
137 mPin1Replaced
= (as
.pin1_replaced
!= 0);
138 mPin1State
= as
.pin1
;
139 mPin2State
= as
.pin2
;
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
);
148 if (mPersoSubState
!= oldPersoSubState
&&
149 mPersoSubState
== PersoSubState
.PERSOSUBSTATE_SIM_NETWORK
) {
150 notifyNetworkLockedRegistrantsIfNeeded(null);
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
) {
161 notifyPinLockedRegistrantsIfNeeded(null);
162 notifyReadyRegistrantsIfNeeded(null);
168 synchronized (mLock
) {
169 if (DBG
) log(mAppType
+ " being Disposed");
171 if (mIccRecords
!= null) { mIccRecords
.dispose();}
172 if (mIccFh
!= null) { mIccFh
.dispose();}
175 mCi
.unregisterForNotAvailable(mHandler
);
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
);
187 // Unknown app type (maybe detection is still in progress)
192 private IccFileHandler
createIccFileHandler(AppType type
) {
195 return new SIMFileHandler(this, mAid
, mCi
);
197 return new RuimFileHandler(this, mAid
, mCi
);
199 return new UsimFileHandler(this, mAid
, mCi
);
201 return new CsimFileHandler(this, mAid
, mCi
);
203 return new IsimFileHandler(this, mAid
, mCi
);
209 /** Assumes mLock is held. */
211 //This shouldn't change run-time. So needs to be called only once.
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
));
222 * Interpret EVENT_QUERY_FACILITY_LOCK_DONE
223 * @param ar is asyncResult of Query_Facility_Locked
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
);
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;
239 mIccFdnEnabled
= (result
[0] == 1) ?
true : false;
240 mIccFdnAvailable
= true;
242 log("Query facility FDN : FDN service available: "+ mIccFdnAvailable
243 +" enabled: " + mIccFdnEnabled
);
245 loge("Bogus facility lock response");
250 private void onChangeFdnDone(AsyncResult ar
) {
251 synchronized (mLock
) {
252 int attemptsRemaining
= -1;
254 if (ar
.exception
== null) {
255 mIccFdnEnabled
= mDesiredFdnEnabled
;
256 if (DBG
) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
257 "mIccFdnEnabled=" + mIccFdnEnabled
);
259 attemptsRemaining
= parsePinPukErrorResult(ar
);
260 loge("Error change facility fdn with exception " + ar
.exception
);
262 Message response
= (Message
)ar
.userObj
;
263 response
.arg1
= attemptsRemaining
;
264 AsyncResult
.forMessage(response
).exception
= ar
.exception
;
265 response
.sendToTarget();
269 /** REMOVE when mIccLockEnabled is not needed, assumes mLock is held */
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
));
279 /** REMOVE when mIccLockEnabled is not needed*/
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
);
287 int[] ints
= (int[])ar
.result
;
288 if(ints
.length
!= 0) {
289 if (DBG
) log("Query facility lock : " + ints
[0]);
291 mIccLockEnabled
= (ints
[0] != 0);
293 if (mIccLockEnabled
) {
294 mPinLockedRegistrants
.notifyRegistrants();
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.
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."
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."
318 case PINSTATE_UNKNOWN
:
320 if (DBG
) log("Ignoring: pin1state=" + mPin1State
);
324 loge("Bogus facility lock response");
329 /** REMOVE when mIccLockEnabled is not needed */
330 private void onChangeFacilityLock(AsyncResult ar
) {
331 synchronized (mLock
) {
332 int attemptsRemaining
= -1;
334 if (ar
.exception
== null) {
335 mIccLockEnabled
= mDesiredPinLocked
;
336 if (DBG
) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: mIccLockEnabled= "
339 attemptsRemaining
= parsePinPukErrorResult(ar
);
340 loge("Error change facility lock with exception " + ar
.exception
);
342 Message response
= (Message
)ar
.userObj
;
343 AsyncResult
.forMessage(response
).exception
= ar
.exception
;
344 response
.arg1
= attemptsRemaining
;
345 response
.sendToTarget();
350 * Parse the error response to obtain number of attempts remaining
352 private int parsePinPukErrorResult(AsyncResult ar
) {
353 int[] result
= (int[]) ar
.result
;
354 if (result
== null) {
357 int length
= result
.length
;
358 int attemptsRemaining
= -1;
360 attemptsRemaining
= result
[0];
362 log("parsePinPukErrorResult: attemptsRemaining=" + attemptsRemaining
);
363 return attemptsRemaining
;
367 private Handler mHandler
= new Handler() {
369 public void handleMessage(Message msg
){
373 loge("Received message " + msg
+ "[" + msg
.what
374 + "] while being destroyed. Ignoring.");
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
);
390 Message response
= (Message
)ar
.userObj
;
391 AsyncResult
.forMessage(response
).exception
= ar
.exception
;
392 response
.arg1
= attemptsRemaining
;
393 response
.sendToTarget();
395 case EVENT_QUERY_FACILITY_FDN_DONE
:
396 ar
= (AsyncResult
)msg
.obj
;
397 onQueryFdnEnabled(ar
);
399 case EVENT_CHANGE_FACILITY_FDN_DONE
:
400 ar
= (AsyncResult
)msg
.obj
;
403 case EVENT_QUERY_FACILITY_LOCK_DONE
:
404 ar
= (AsyncResult
)msg
.obj
;
405 onQueryFacilityLock(ar
);
407 case EVENT_CHANGE_FACILITY_LOCK_DONE
:
408 ar
= (AsyncResult
)msg
.obj
;
409 onChangeFacilityLock(ar
);
411 case EVENT_RADIO_UNAVAILABLE
:
412 if (DBG
) log("handleMessage (EVENT_RADIO_UNAVAILABLE)");
413 mAppState
= AppState
.APPSTATE_UNKNOWN
;
416 loge("Unknown Event " + msg
.what
);
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
);
429 public void unregisterForReady(Handler h
) {
430 synchronized (mLock
) {
431 mReadyRegistrants
.remove(h
);
436 * Notifies handler of any transition into State.isPinLocked()
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
);
446 public void unregisterForLocked(Handler h
) {
447 synchronized (mLock
) {
448 mPinLockedRegistrants
.remove(h
);
453 * Notifies handler of any transition into State.NETWORK_LOCKED
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
);
463 public void unregisterForNetworkLocked(Handler h
) {
464 synchronized (mLock
) {
465 mNetworkLockedRegistrants
.remove(h
);
470 * Notifies specified registrant, assume mLock is held.
472 * @param r Registrant to be notified. If null - all registrants will be notified
474 private void notifyReadyRegistrantsIfNeeded(Registrant r
) {
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
487 if (DBG
) log("Notifying registrants: READY");
488 mReadyRegistrants
.notifyRegistrants();
490 if (DBG
) log("Notifying 1 registrant: READY");
491 r
.notifyRegistrant(new AsyncResult(null, null, null));
497 * Notifies specified registrant, assume mLock is held.
499 * @param r Registrant to be notified. If null - all registrants will be notified
501 private void notifyPinLockedRegistrantsIfNeeded(Registrant r
) {
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
515 if (DBG
) log("Notifying registrants: LOCKED");
516 mPinLockedRegistrants
.notifyRegistrants();
518 if (DBG
) log("Notifying 1 registrant: LOCKED");
519 r
.notifyRegistrant(new AsyncResult(null, null, null));
525 * Notifies specified registrant, assume mLock is held.
527 * @param r Registrant to be notified. If null - all registrants will be notified
529 private void notifyNetworkLockedRegistrantsIfNeeded(Registrant r
) {
534 if (mAppState
== AppState
.APPSTATE_SUBSCRIPTION_PERSO
&&
535 mPersoSubState
== PersoSubState
.PERSOSUBSTATE_SIM_NETWORK
) {
537 if (DBG
) log("Notifying registrants: NETWORK_LOCKED");
538 mNetworkLockedRegistrants
.notifyRegistrants();
540 if (DBG
) log("Notifying 1 registrant: NETWORK_LOCED");
541 r
.notifyRegistrant(new AsyncResult(null, null, null));
546 public AppState
getState() {
547 synchronized (mLock
) {
552 public AppType
getType() {
553 synchronized (mLock
) {
558 public int getAuthContext() {
559 synchronized (mLock
) {
565 * Returns the authContext based on the type of UiccCard.
567 * @param appType the app type
568 * @return authContext corresponding to the type or AUTH_CONTEXT_UNDEFINED if appType not
571 private static int getAuthContext(AppType appType
) {
576 authContext
= AUTH_CONTEXT_EAP_SIM
;
580 authContext
= AUTH_CONTEXT_EAP_AKA
;
584 authContext
= AUTH_CONTEXT_UNDEFINED
;
591 public PersoSubState
getPersoSubState() {
592 synchronized (mLock
) {
593 return mPersoSubState
;
597 public String
getAid() {
598 synchronized (mLock
) {
603 public String
getAppLabel() {
607 public PinState
getPin1State() {
608 synchronized (mLock
) {
610 return mUiccCard
.getUniversalPinState();
616 public IccFileHandler
getIccFileHandler() {
617 synchronized (mLock
) {
622 public IccRecords
getIccRecords() {
623 synchronized (mLock
) {
629 * Supply the ICC PIN to the ICC
631 * When the operation is complete, onComplete will be sent to its
634 * onComplete.obj will be an AsyncResult
635 * onComplete.arg1 = remaining attempts before puk locked or -1 if unknown
637 * ((AsyncResult)onComplete.obj).exception == null on success
638 * ((AsyncResult)onComplete.obj).exception != null on fail
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
647 public void supplyPin (String pin
, Message onComplete
) {
648 synchronized (mLock
) {
649 mCi
.supplyIccPinForApp(pin
, mAid
, mHandler
.obtainMessage(EVENT_PIN1_PUK1_DONE
,
655 * Supply the ICC PUK to the ICC
657 * When the operation is complete, onComplete will be sent to its
660 * onComplete.obj will be an AsyncResult
661 * onComplete.arg1 = remaining attempts before Icc will be permanently unusable
664 * ((AsyncResult)onComplete.obj).exception == null on success
665 * ((AsyncResult)onComplete.obj).exception != null on fail
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
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
));
683 public void supplyPin2 (String pin2
, Message onComplete
) {
684 synchronized (mLock
) {
685 mCi
.supplyIccPin2ForApp(pin2
, mAid
,
686 mHandler
.obtainMessage(EVENT_PIN2_PUK2_DONE
, 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
));
697 public void supplyNetworkDepersonalization (String pin
, Message onComplete
) {
698 synchronized (mLock
) {
699 if (DBG
) log("supplyNetworkDepersonalization");
700 mCi
.supplyNetworkDepersonalization(pin
, onComplete
);
705 * Check whether ICC pin lock is enabled
706 * This is a sync call which returns the cached pin enabled state
708 * @return true for ICC locked enabled
709 * false for ICC locked disabled
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;*/
724 * Check whether ICC fdn (fixed dialing number) is enabled
725 * This is a sync call which returns the cached pin enabled state
727 * @return true for ICC fdn enabled
728 * false for ICC fdn disabled
730 public boolean getIccFdnEnabled() {
731 synchronized (mLock
) {
732 return mIccFdnEnabled
;
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
741 public boolean getIccFdnAvailable() {
742 return mIccFdnAvailable
;
746 * Set the ICC pin lock enabled or disabled
747 * When the operation is complete, onComplete will be sent to its handler
749 * @param enabled "true" for locked "false" for unlocked.
750 * @param password needed to change the ICC pin state, aka. Pin1
752 * onComplete.obj will be an AsyncResult
753 * ((AsyncResult)onComplete.obj).exception == null on success
754 * ((AsyncResult)onComplete.obj).exception != null on fail
756 public void setIccLockEnabled (boolean enabled
,
757 String password
, Message onComplete
) {
758 synchronized (mLock
) {
760 serviceClassX
= CommandsInterface
.SERVICE_CLASS_VOICE
+
761 CommandsInterface
.SERVICE_CLASS_DATA
+
762 CommandsInterface
.SERVICE_CLASS_FAX
;
764 mDesiredPinLocked
= enabled
;
766 mCi
.setFacilityLockForApp(CommandsInterface
.CB_FACILITY_BA_SIM
,
767 enabled
, password
, serviceClassX
, mAid
,
768 mHandler
.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE
, onComplete
));
773 * Set the ICC fdn enabled or disabled
774 * When the operation is complete, onComplete will be sent to its handler
776 * @param enabled "true" for locked "false" for unlocked.
777 * @param password needed to change the ICC fdn enable, aka Pin2
779 * onComplete.obj will be an AsyncResult
780 * ((AsyncResult)onComplete.obj).exception == null on success
781 * ((AsyncResult)onComplete.obj).exception != null on fail
783 public void setIccFdnEnabled (boolean enabled
,
784 String password
, Message onComplete
) {
785 synchronized (mLock
) {
787 serviceClassX
= CommandsInterface
.SERVICE_CLASS_VOICE
+
788 CommandsInterface
.SERVICE_CLASS_DATA
+
789 CommandsInterface
.SERVICE_CLASS_FAX
+
790 CommandsInterface
.SERVICE_CLASS_SMS
;
792 mDesiredFdnEnabled
= enabled
;
794 mCi
.setFacilityLockForApp(CommandsInterface
.CB_FACILITY_BA_FD
,
795 enabled
, password
, serviceClassX
, mAid
,
796 mHandler
.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE
, onComplete
));
801 * Change the ICC password used in ICC pin lock
802 * When the operation is complete, onComplete will be sent to its handler
804 * @param oldPassword is the old password
805 * @param newPassword is the new password
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
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
));
822 * Change the ICC password used in ICC fdn enable
823 * When the operation is complete, onComplete will be sent to its handler
825 * @param oldPassword is the old password
826 * @param newPassword is the new password
828 * onComplete.obj will be an AsyncResult
829 * ((AsyncResult)onComplete.obj).exception == null on success
830 * ((AsyncResult)onComplete.obj).exception != null on fail
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
));
842 * @return true if ICC card is PIN2 blocked
844 public boolean getIccPin2Blocked() {
845 synchronized (mLock
) {
846 return mPin2State
== PinState
.PINSTATE_ENABLED_BLOCKED
;
851 * @return true if ICC card is PUK2 blocked
853 public boolean getIccPuk2Blocked() {
854 synchronized (mLock
) {
855 return mPin2State
== PinState
.PINSTATE_ENABLED_PERM_BLOCKED
;
859 public int getPhoneId() {
860 return mUiccCard
.getPhoneId();
863 protected UiccCard
getUiccCard() {
867 private void log(String msg
) {
868 Rlog
.d(LOG_TAG
, msg
);
871 private void loge(String msg
) {
872 Rlog
.e(LOG_TAG
, msg
);
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());
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());
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());