1e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka/*
2e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Copyright (C) 2012 The Android Open Source Project
3e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka *
4e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Licensed under the Apache License, Version 2.0 (the "License");
5e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * you may not use this file except in compliance with the License.
6e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * You may obtain a copy of the License at
7e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka *
8e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka *      http://www.apache.org/licenses/LICENSE-2.0
9e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka *
10e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Unless required by applicable law or agreed to in writing, software
11e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * distributed under the License is distributed on an "AS IS" BASIS,
12e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * See the License for the specific language governing permissions and
14e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * limitations under the License.
15e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */
16e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
17e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkapackage com.android.internal.telephony;
18e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
19e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport static android.Manifest.permission.READ_PHONE_STATE;
20e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.app.ActivityManagerNative;
21e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.Context;
22e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.Intent;
23e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.AsyncResult;
24e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.Handler;
25e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.Message;
26e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.Registrant;
27e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.RegistrantList;
28e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.SystemProperties;
29565013a713156a0ddcc46dc3a0077e4c268ce272Wink Savilleimport android.os.UserHandle;
30e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.util.Log;
31e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.telephony.ServiceState;
32e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.telephony.TelephonyManager;
33e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
34e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardConstants.State;
35e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardApplicationStatus.AppState;
36e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardApplicationStatus.PersoSubState;
37e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardStatus.CardState;
38e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardStatus.PinState;
39e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
40e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
41be3dc4b04cd65e576d250cf68f310d47637167ffWink Savilleimport com.android.internal.telephony.Phone;
42e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
43e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_STATE;
44e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
45e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka/**
46e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * @Deprecated use {@link UiccController}.getUiccCard instead.
47e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka *
48e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * The Phone App assumes that there is only one icc card, and one icc application
49e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * available at a time. Moreover, it assumes such object (represented with IccCard)
50e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * is available all the time (whether {@link RILConstants.RIL_REQUEST_GET_SIM_STATUS} returned
51e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * or not, whether card has desired application or not, whether there really is a card in the
52e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * slot or not).
53e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka *
54e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccController, however, can handle multiple instances of icc objects (multiple
55e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * {@link UiccCardApplication}, multiple {@link IccFileHandler}, multiple {@link IccRecords})
56e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * created and destroyed dynamically during phone operation.
57e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka *
58e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * This class implements the IccCard interface that is always available (right after default
59e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * phone object is constructed) to expose the current (based on voice radio technology)
60e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * application on the uicc card, so that external apps won't break.
61e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */
62e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
63e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkapublic class IccCardProxy extends Handler implements IccCard {
64e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final boolean DBG = true;
65e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final String LOG_TAG = "RIL_IccCardProxy";
66e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
67e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 1;
68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_RADIO_ON = 2;
69e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_ICC_CHANGED = 3;
70e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_ICC_ABSENT = 4;
71e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_ICC_LOCKED = 5;
72e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_APP_READY = 6;
73e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_RECORDS_LOADED = 7;
74e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_IMSI_READY = 8;
75e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_NETWORK_LOCKED = 9;
76e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 11;
77e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
78e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private final Object mLock = new Object();
79e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private Context mContext;
80e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private CommandsInterface mCi;
81e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
82e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private RegistrantList mAbsentRegistrants = new RegistrantList();
83e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private RegistrantList mPinLockedRegistrants = new RegistrantList();
84e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
85e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
86e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private int mCurrentAppType = UiccController.APP_FAM_3GPP; //default to 3gpp?
87e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private UiccController mUiccController = null;
88e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private UiccCard mUiccCard = null;
89e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private UiccCardApplication mUiccApplication = null;
90e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private IccRecords mIccRecords = null;
91e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private CdmaSubscriptionSourceManager mCdmaSSM = null;
92e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private boolean mRadioOn = false;
93e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private boolean mQuietMode = false; // when set to true IccCardProxy will not broadcast
94e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                                        // ACTION_SIM_STATE_CHANGED intents
95e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private boolean mInitialized = false;
96e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private State mExternalState = State.UNKNOWN;
97e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
98e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public IccCardProxy(Context context, CommandsInterface ci) {
99e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        log("Creating");
100e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        this.mContext = context;
101e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        this.mCi = ci;
102e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(context,
103e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                ci, this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
104e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mUiccController = UiccController.getInstance();
105e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
106e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        ci.registerForOn(this,EVENT_RADIO_ON, null);
107e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        ci.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_UNAVAILABLE, null);
108e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        setExternalState(State.NOT_READY);
109e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
110e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
111e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void dispose() {
112e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
113e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            log("Disposing");
114e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            //Cleanup icc references
115e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mUiccController.unregisterForIccChanged(this);
116e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mUiccController = null;
117e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mCi.unregisterForOn(this);
118e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mCi.unregisterForOffOrNotAvailable(this);
119e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mCdmaSSM.dispose(this);
120e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
121e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
122e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
123e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    /*
124e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * The card application that the external world sees will be based on the
125e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * voice radio technology only!
126e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     */
127e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void setVoiceRadioTech(int radioTech) {
128e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
129e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) {
130e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                log("Setting radio tech " + ServiceState.rilRadioTechnologyToString(radioTech));
131e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
132e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (ServiceState.isGsm(radioTech)) {
133e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mCurrentAppType = UiccController.APP_FAM_3GPP;
134e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else {
135e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mCurrentAppType = UiccController.APP_FAM_3GPP2;
136e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
137e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            updateQuietMode();
138e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
139e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
140e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
141e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    /**
142e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * In case of 3gpp2 we need to find out if subscription used is coming from
143be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville     * NV in which case we shouldn't broadcast any sim states changes.
144e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     */
145e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void updateQuietMode() {
146e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
147e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            boolean oldQuietMode = mQuietMode;
148e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            boolean newQuietMode;
149be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville            int cdmaSource = Phone.CDMA_SUBSCRIPTION_UNKNOWN;
150be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville            boolean isLteOnCdmaMode = TelephonyManager.getLteOnCdmaModeStatic()
151be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                    == PhoneConstants.LTE_ON_CDMA_TRUE;
152e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mCurrentAppType == UiccController.APP_FAM_3GPP) {
153e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                newQuietMode = false;
154be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                if (DBG) log("updateQuietMode: 3GPP subscription -> newQuietMode=" + newQuietMode);
155e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else {
156be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                if (isLteOnCdmaMode) {
157be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                    log("updateQuietMode: is cdma/lte device, force IccCardProxy into 3gpp mode");
158e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    mCurrentAppType = UiccController.APP_FAM_3GPP;
159e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
160be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                cdmaSource = mCdmaSSM != null ?
161be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                        mCdmaSSM.getCdmaSubscriptionSource() : Phone.CDMA_SUBSCRIPTION_UNKNOWN;
162be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville
163be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                newQuietMode = (cdmaSource == Phone.CDMA_SUBSCRIPTION_NV)
164e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        && (mCurrentAppType == UiccController.APP_FAM_3GPP2)
165be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                        && !isLteOnCdmaMode;
166e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
167e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
168e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mQuietMode == false && newQuietMode == true) {
169e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                // Last thing to do before switching to quiet mode is
170e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                // broadcast ICC_READY
171e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                log("Switching to QuietMode.");
172e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.READY);
173e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mQuietMode = newQuietMode;
174e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (mQuietMode == true && newQuietMode == false) {
175be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                if (DBG) {
176be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                    log("updateQuietMode: Switching out from QuietMode."
177be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                            + " Force broadcast of current state=" + mExternalState);
178be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                }
179e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mQuietMode = newQuietMode;
180e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(mExternalState, true);
181e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
182be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville            if (DBG) {
183be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                log("updateQuietMode: QuietMode is " + mQuietMode + " (app_type="
184be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                    + mCurrentAppType + " isLteOnCdmaMode=" + isLteOnCdmaMode
185be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville                    + " cdmaSource=" + cdmaSource + ")");
186be3dc4b04cd65e576d250cf68f310d47637167ffWink Saville            }
187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mInitialized = true;
188e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            sendMessage(obtainMessage(EVENT_ICC_CHANGED));
189e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
190e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
191e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
192e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void handleMessage(Message msg) {
193e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        switch (msg.what) {
194e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_RADIO_OFF_OR_UNAVAILABLE:
195e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mRadioOn = false;
196e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
197e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_RADIO_ON:
198e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mRadioOn = true;
199e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (!mInitialized) {
200e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    updateQuietMode();
201e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
202e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
203e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_ICC_CHANGED:
204e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (mInitialized) {
205e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    updateIccAvailability();
206e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
207e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
208e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_ICC_ABSENT:
209e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mAbsentRegistrants.notifyRegistrants();
210e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.ABSENT);
211e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
212e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_ICC_LOCKED:
213e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                processLockedState();
214e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
215e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_APP_READY:
216e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.READY);
217e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
218e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_RECORDS_LOADED:
219e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_LOADED, null);
220e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
221e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_IMSI_READY:
222e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_IMSI, null);
223e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
224e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_NETWORK_LOCKED:
225e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mNetworkLockedRegistrants.notifyRegistrants();
226e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.NETWORK_LOCKED);
227e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
228e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
229e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                updateQuietMode();
230e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
231e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            default:
232e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                loge("Unhandled message with number: " + msg.what);
233e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
234e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
235e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
236e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void updateIccAvailability() {
238e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
239e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            UiccCard newCard = mUiccController.getUiccCard();
240e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            CardState state = CardState.CARDSTATE_ABSENT;
241e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            UiccCardApplication newApp = null;
242e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            IccRecords newRecords = null;
243e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (newCard != null) {
244e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                state = newCard.getCardState();
245e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                newApp = newCard.getApplication(mCurrentAppType);
246e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (newApp != null) {
247e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    newRecords = newApp.getIccRecords();
248e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
249e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
250e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
251e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) {
252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (DBG) log("Icc changed. Reregestering.");
253e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                unregisterUiccCardEvents();
254e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccCard = newCard;
255e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication = newApp;
256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mIccRecords = newRecords;
257e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                registerUiccCardEvents();
258e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
259e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
260e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            updateExternalState();
261e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
262e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
263e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
264e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void updateExternalState() {
265e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccCard == null || mUiccCard.getCardState() == CardState.CARDSTATE_ABSENT) {
266e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mRadioOn) {
267e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.ABSENT);
268e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else {
269e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.NOT_READY);
270e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
271e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return;
272e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
273e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
274e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccCard.getCardState() == CardState.CARDSTATE_ERROR ||
275e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication == null) {
276e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            setExternalState(State.UNKNOWN);
277e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return;
278e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
279e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
280e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        switch (mUiccApplication.getState()) {
281e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case APPSTATE_UNKNOWN:
282e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case APPSTATE_DETECTED:
283e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.UNKNOWN);
284e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
285e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case APPSTATE_PIN:
286e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.PIN_REQUIRED);
287e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
288e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case APPSTATE_PUK:
289e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.PUK_REQUIRED);
290e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
291e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case APPSTATE_SUBSCRIPTION_PERSO:
292e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (mUiccApplication.getPersoSubState() == PersoSubState.PERSOSUBSTATE_SIM_NETWORK) {
293e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    setExternalState(State.NETWORK_LOCKED);
294e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                } else {
295e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    setExternalState(State.UNKNOWN);
296e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
297e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
298e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case APPSTATE_READY:
299e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.READY);
300e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
301e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
303e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
304e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void registerUiccCardEvents() {
305e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccCard != null) mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null);
306e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplication != null) {
307e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mUiccApplication.registerForReady(this, EVENT_APP_READY, null);
308e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mUiccApplication.registerForLocked(this, EVENT_ICC_LOCKED, null);
309e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mUiccApplication.registerForNetworkLocked(this, EVENT_NETWORK_LOCKED, null);
310e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
311e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mIccRecords != null) {
312e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mIccRecords.registerForImsiReady(this, EVENT_IMSI_READY, null);
313e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
314e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
315e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
316e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
317e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void unregisterUiccCardEvents() {
318e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccCard != null) mUiccCard.unregisterForAbsent(this);
319e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplication != null) mUiccApplication.unregisterForReady(this);
320e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplication != null) mUiccApplication.unregisterForLocked(this);
321e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplication != null) mUiccApplication.unregisterForNetworkLocked(this);
322e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mIccRecords != null) mIccRecords.unregisterForImsiReady(this);
323e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mIccRecords != null) mIccRecords.unregisterForRecordsLoaded(this);
324e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
325e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
326e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void broadcastIccStateChangedIntent(String value, String reason) {
327e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
328e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mQuietMode) {
329e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                log("QuietMode: NOT Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
330e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        + " reason " + reason);
331e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
332e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
333e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
334e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
335e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
336e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
337e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
338e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
339e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
340e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
341e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    + " reason " + reason);
342565013a713156a0ddcc46dc3a0077e4c268ce272Wink Saville            ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE,
343565013a713156a0ddcc46dc3a0077e4c268ce272Wink Saville                    UserHandle.USER_ALL);
344e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
345e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
346e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
347e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void processLockedState() {
348e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
349e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication == null) {
350e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                //Don't need to do anything if non-existent application is locked
351e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
352e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
353e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            PinState pin1State = mUiccApplication.getPin1State();
354e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (pin1State == PinState.PINSTATE_ENABLED_PERM_BLOCKED) {
355e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                setExternalState(State.PERM_DISABLED);
356e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
357e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
358e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
359e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            AppState appState = mUiccApplication.getState();
360e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            switch (appState) {
361e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case APPSTATE_PIN:
362e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    mPinLockedRegistrants.notifyRegistrants();
363e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    setExternalState(State.PIN_REQUIRED);
364e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    break;
365e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case APPSTATE_PUK:
366e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    setExternalState(State.PUK_REQUIRED);
367e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    break;
368e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
369e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
370e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
371e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
372e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void setExternalState(State newState, boolean override) {
373e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
374e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (!override && newState == mExternalState) {
375e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
376e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
377e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mExternalState = newState;
378e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            SystemProperties.set(PROPERTY_SIM_STATE, mExternalState.toString());
379e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            broadcastIccStateChangedIntent(getIccStateIntentString(mExternalState),
380e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    getIccStateReason(mExternalState));
381e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
382e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
383e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
384e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void setExternalState(State newState) {
385e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        setExternalState(newState, false);
386e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
387e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
388e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public boolean getIccRecordsLoaded() {
389e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
390e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mIccRecords != null) {
391e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return mIccRecords.getRecordsLoaded();
392e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
393e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return false;
394e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
395e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
396e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
397e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private String getIccStateIntentString(State state) {
398e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        switch (state) {
399e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case ABSENT: return IccCardConstants.INTENT_VALUE_ICC_ABSENT;
400e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
401e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
402e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
403e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case READY: return IccCardConstants.INTENT_VALUE_ICC_READY;
404e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case NOT_READY: return IccCardConstants.INTENT_VALUE_ICC_NOT_READY;
405e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
406e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            default: return IccCardConstants.INTENT_VALUE_ICC_UNKNOWN;
407e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
408e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
409e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
410e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    /**
411e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * Locked state have a reason (PIN, PUK, NETWORK, PERM_DISABLED)
412e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * @return reason
413e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     */
414e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private String getIccStateReason(State state) {
415e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        switch (state) {
416e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN;
417e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK;
418e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_LOCKED_NETWORK;
419e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED;
420e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            default: return null;
421e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka       }
422e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
423e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
424e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    /* IccCard interface implementation */
425e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
426e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public State getState() {
427e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
428e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return mExternalState;
429e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
430e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
431e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
432e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
433e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public IccRecords getIccRecords() {
434e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
435e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return mIccRecords;
436e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
437e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
438e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
439e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
440e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public IccFileHandler getIccFileHandler() {
441e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
442e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
443e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return mUiccApplication.getIccFileHandler();
444e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
445e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return null;
446e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
447e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
448e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
449e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    /**
450e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * Notifies handler of any transition into State.ABSENT
451e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     */
452e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
453e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void registerForAbsent(Handler h, int what, Object obj) {
454e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
455e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            Registrant r = new Registrant (h, what, obj);
456e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
457e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mAbsentRegistrants.add(r);
458e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
459e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (getState() == State.ABSENT) {
460e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                r.notifyRegistrant();
461e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
462e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
463e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
464e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
465e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
466e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void unregisterForAbsent(Handler h) {
467e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
468e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mAbsentRegistrants.remove(h);
469e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
470e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
471e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
472e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    /**
473e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * Notifies handler of any transition into State.NETWORK_LOCKED
474e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     */
475e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
476e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void registerForNetworkLocked(Handler h, int what, Object obj) {
477e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
478e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            Registrant r = new Registrant (h, what, obj);
479e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
480e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mNetworkLockedRegistrants.add(r);
481e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
482e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (getState() == State.NETWORK_LOCKED) {
483e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                r.notifyRegistrant();
484e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
485e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
486e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
487e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
488e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
489e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void unregisterForNetworkLocked(Handler h) {
490e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
491e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mNetworkLockedRegistrants.remove(h);
492e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
493e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
494e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
495e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    /**
496e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     * Notifies handler of any transition into State.isPinLocked()
497e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka     */
498e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
499e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void registerForLocked(Handler h, int what, Object obj) {
500e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
501e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            Registrant r = new Registrant (h, what, obj);
502e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
503e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mPinLockedRegistrants.add(r);
504e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
505e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (getState().isPinLocked()) {
506e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                r.notifyRegistrant();
507e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
508e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
509e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
510e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
511e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
512e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void unregisterForLocked(Handler h) {
513e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
514e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mPinLockedRegistrants.remove(h);
515e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
516e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
517e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
518e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
519e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void supplyPin(String pin, Message onComplete) {
520e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
521e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
522e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.supplyPin(pin, onComplete);
523e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
524e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
525e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
526e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
527e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
528e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
529e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
530e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
531e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
532e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
533e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void supplyPuk(String puk, String newPin, Message onComplete) {
534e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
535e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
536e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.supplyPuk(puk, newPin, onComplete);
537e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
538e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
539e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
540e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
541e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
542e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
543e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
544e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
545e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
546e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
547e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void supplyPin2(String pin2, Message onComplete) {
548e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
549e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
550e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.supplyPin2(pin2, onComplete);
551e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
552e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
553e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
554e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
555e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
556e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
557e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
558e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
559e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
560e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
561e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void supplyPuk2(String puk2, String newPin2, Message onComplete) {
562e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
563e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
564e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.supplyPuk2(puk2, newPin2, onComplete);
565e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
566e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
567e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
568e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
569e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
570e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
571e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
572e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
573e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
574e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
575e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void supplyNetworkDepersonalization(String pin, Message onComplete) {
576e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
577e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
578e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.supplyNetworkDepersonalization(pin, onComplete);
579e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
580e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("CommandsInterface is not set.");
581e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
582e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
583e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
584e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
585e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
586e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
587e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
588e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
589e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public boolean getIccLockEnabled() {
590e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
591e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            /* defaults to true, if ICC is absent */
592e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccLockEnabled() : true;
593e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return retValue;
594e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
595e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
596e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
597e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
598e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public boolean getIccFdnEnabled() {
599e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
600e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccFdnEnabled() : false;
601e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return retValue;
602e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
603e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
604e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
605e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
606e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void setIccLockEnabled(boolean enabled, String password, Message onComplete) {
607e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
608e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
609e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.setIccLockEnabled(enabled, password, onComplete);
610e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
611e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
612e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
613e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
614e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
615e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
616e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
617e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
618e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
619e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
620e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void setIccFdnEnabled(boolean enabled, String password, Message onComplete) {
621e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
622e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
623e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.setIccFdnEnabled(enabled, password, onComplete);
624e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
625e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
626e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
627e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
628e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
629e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
630e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
631e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
632e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
633e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
634e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void changeIccLockPassword(String oldPassword, String newPassword, Message onComplete) {
635e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
636e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
637e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.changeIccLockPassword(oldPassword, newPassword, onComplete);
638e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
639e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
640e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
641e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
642e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
643e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
644e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
645e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
646e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
647e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
648e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public void changeIccFdnPassword(String oldPassword, String newPassword, Message onComplete) {
649e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
650e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplication != null) {
651e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplication.changeIccFdnPassword(oldPassword, newPassword, onComplete);
652e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else if (onComplete != null) {
653e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                Exception e = new RuntimeException("ICC card is absent.");
654e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                AsyncResult.forMessage(onComplete).exception = e;
655e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onComplete.sendToTarget();
656e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
657e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
658e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
659e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
660e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
661e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
662e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public String getServiceProviderName() {
663e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
664e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mIccRecords != null) {
665e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return mIccRecords.getServiceProviderName();
666e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
667e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return null;
668e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
669e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
670e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
671e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
672e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) {
673e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
674e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            Boolean retValue = mUiccCard != null ? mUiccCard.isApplicationOnIcc(type) : false;
675e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return retValue;
676e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
677e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
678e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
679e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
680e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public boolean hasIccCard() {
681e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        synchronized (mLock) {
682e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccCard != null && mUiccCard.getCardState() != CardState.CARDSTATE_ABSENT) {
683e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return true;
684e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
685e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return false;
686e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
687e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
688e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
689e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void log(String s) {
690e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        Log.d(LOG_TAG, s);
691e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
692e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
693e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void loge(String msg) {
694e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        Log.e(LOG_TAG, msg);
695e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
696e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka}
697