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