19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.telephony;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport static android.Manifest.permission.READ_PHONE_STATE;
20cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport android.app.ActivityManagerNative;
2110e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport android.app.AlertDialog;
2210e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport android.content.Context;
2310e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport android.content.DialogInterface;
24cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport android.content.Intent;
2510e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport android.content.res.Resources;
26cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport android.os.AsyncResult;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
28cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport android.os.Message;
2910e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport android.os.Power;
3010e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport android.os.PowerManager;
31cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport android.os.Registrant;
32cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport android.os.RegistrantList;
33cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport android.util.Log;
3410e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport android.view.WindowManager;
35cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
36cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport com.android.internal.telephony.PhoneBase;
37cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshimport com.android.internal.telephony.CommandsInterface.RadioState;
381f3278e111c8abadedf71a9bcdbbaffe154be738Wink Savilleimport com.android.internal.telephony.gsm.SIMRecords;
391f3278e111c8abadedf71a9bcdbbaffe154be738Wink Saville
409d7d62801ddb206d2ea96d74864a9edfe54d2eeeWink Savilleimport android.os.SystemProperties;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4210e9f668eec105699b8f10d544a418e5bf9605c5John Wangimport com.android.internal.R;
4310e9f668eec105699b8f10d544a418e5bf9605c5John Wang
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
47cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganeshpublic abstract class IccCard {
48cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected String mLogTag;
49cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected boolean mDbg;
50cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
51cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private IccCardStatus mIccCardStatus = null;
52cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected State mState = null;
53cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected PhoneBase mPhone;
54cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private RegistrantList mAbsentRegistrants = new RegistrantList();
55cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private RegistrantList mPinLockedRegistrants = new RegistrantList();
56cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
57cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
58cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private boolean mDesiredPinLocked;
59cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private boolean mDesiredFdnEnabled;
60cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private boolean mIccPinLocked = true; // Default to locked
61cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private boolean mIccFdnEnabled = false; // Default to disabled.
62cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                            // Will be updated when SIM_READY.
63cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
64cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
6504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
6604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    static public final String INTENT_KEY_ICC_STATE = "ss";
6704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */
6804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    static public final String INTENT_VALUE_ICC_NOT_READY = "NOT_READY";
6904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* ABSENT means ICC is missing */
7004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    static public final String INTENT_VALUE_ICC_ABSENT = "ABSENT";
7104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* LOCKED means ICC is locked by pin or by network */
7204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    static public final String INTENT_VALUE_ICC_LOCKED = "LOCKED";
7304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* READY means ICC is ready to access */
7404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    static public final String INTENT_VALUE_ICC_READY = "READY";
7504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* IMSI means ICC IMSI is ready in property */
7604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    static public final String INTENT_VALUE_ICC_IMSI = "IMSI";
7704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* LOADED means all ICC records, including IMSI, are loaded */
7804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    static public final String INTENT_VALUE_ICC_LOADED = "LOADED";
7904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static public final String INTENT_KEY_LOCKED_REASON = "reason";
8104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* PIN means ICC is locked on PIN1 */
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static public final String INTENT_VALUE_LOCKED_ON_PIN = "PIN";
8304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* PUK means ICC is locked on PUK1 */
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
8504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
87b0b24b3df50988d23f571b83d829fecc986ec497John Wang    /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
88b0b24b3df50988d23f571b83d829fecc986ec497John Wang    static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
89b0b24b3df50988d23f571b83d829fecc986ec497John Wang
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
91cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected static final int EVENT_ICC_LOCKED_OR_ABSENT = 1;
92cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_GET_ICC_STATUS_DONE = 2;
93cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
94cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_PINPUK_DONE = 4;
95cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_REPOLL_STATUS_DONE = 5;
96cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected static final int EVENT_ICC_READY = 6;
97cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
98cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
99cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_CHANGE_ICC_PASSWORD_DONE = 9;
100cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
101cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
1023ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini    private static final int EVENT_ICC_STATUS_CHANGED = 12;
10310e9f668eec105699b8f10d544a418e5bf9605c5John Wang    private static final int EVENT_CARD_REMOVED = 13;
10410e9f668eec105699b8f10d544a418e5bf9605c5John Wang    private static final int EVENT_CARD_ADDED = 14;
10510e9f668eec105699b8f10d544a418e5bf9605c5John Wang
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
10704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville      UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
10804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville      PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      turns to READY
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum State {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        UNKNOWN,
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ABSENT,
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PIN_REQUIRED,
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PUK_REQUIRED,
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NETWORK_LOCKED,
117cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        READY,
118b0b24b3df50988d23f571b83d829fecc986ec497John Wang        NOT_READY,
119b0b24b3df50988d23f571b83d829fecc986ec497John Wang        PERM_DISABLED;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isPinLocked() {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12410e9f668eec105699b8f10d544a418e5bf9605c5John Wang
12510e9f668eec105699b8f10d544a418e5bf9605c5John Wang        public boolean iccCardExist() {
12610e9f668eec105699b8f10d544a418e5bf9605c5John Wang            return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
127b0b24b3df50988d23f571b83d829fecc986ec497John Wang                    || (this == NETWORK_LOCKED) || (this == READY)
128b0b24b3df50988d23f571b83d829fecc986ec497John Wang                    || (this == PERM_DISABLED));
12910e9f668eec105699b8f10d544a418e5bf9605c5John Wang        }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
132cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public State getState() {
133cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (mState == null) {
134cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            switch(mPhone.mCM.getRadioState()) {
135cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                /* This switch block must not return anything in
136cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 * State.isLocked() or State.ABSENT.
137cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 * If it does, handleSimStatus() may break
138cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 */
139cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case RADIO_OFF:
140cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case RADIO_UNAVAILABLE:
141cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case SIM_NOT_READY:
142cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case RUIM_NOT_READY:
143cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    return State.UNKNOWN;
144cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case SIM_LOCKED_OR_ABSENT:
145cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case RUIM_LOCKED_OR_ABSENT:
146cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    //this should be transient-only
147cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    return State.UNKNOWN;
148cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case SIM_READY:
149cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case RUIM_READY:
150cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case NV_READY:
15105b301b9df83ee7aa7ac2a93e137bc1fd58d3fceWink Saville                    return State.READY;
152cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case NV_NOT_READY:
153cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    return State.ABSENT;
154cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            }
155cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        } else {
156cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            return mState;
157cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
158cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
159cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        Log.e(mLogTag, "IccCard.getState(): case should never be reached");
160cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        return State.UNKNOWN;
161cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
162cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
163cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public IccCard(PhoneBase phone, String logTag, Boolean dbg) {
164cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPhone = phone;
1653ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini        mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
166cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mLogTag = logTag;
167cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mDbg = dbg;
168cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
169cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
1703ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini    public void dispose() {
1713ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini        mPhone.mCM.unregisterForIccStatusChanged(mHandler);
1723ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini    }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
174cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected void finalize() {
175cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if(mDbg) Log.d(mLogTag, "IccCard finalized");
176cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Notifies handler of any transition into State.ABSENT
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
181cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void registerForAbsent(Handler h, int what, Object obj) {
182cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        Registrant r = new Registrant (h, what, obj);
183cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
184cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mAbsentRegistrants.add(r);
185cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
186cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (getState() == State.ABSENT) {
187cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            r.notifyRegistrant();
188cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
189cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
190cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
191cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void unregisterForAbsent(Handler h) {
192cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mAbsentRegistrants.remove(h);
193cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
196cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     * Notifies handler of any transition into State.NETWORK_LOCKED
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
198cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void registerForNetworkLocked(Handler h, int what, Object obj) {
199cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        Registrant r = new Registrant (h, what, obj);
200cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
201cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mNetworkLockedRegistrants.add(r);
202cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
203cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (getState() == State.NETWORK_LOCKED) {
204cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            r.notifyRegistrant();
205cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
206cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
207cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
208cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void unregisterForNetworkLocked(Handler h) {
209cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mNetworkLockedRegistrants.remove(h);
210cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
213cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     * Notifies handler of any transition into State.isPinLocked()
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
215cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void registerForLocked(Handler h, int what, Object obj) {
216cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        Registrant r = new Registrant (h, what, obj);
217cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
218cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPinLockedRegistrants.add(r);
219cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
220cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (getState().isPinLocked()) {
221cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            r.notifyRegistrant();
222cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
223cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
224cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
225cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void unregisterForLocked(Handler h) {
226cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPinLockedRegistrants.remove(h);
227cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
228cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
23104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * Supply the ICC PIN to the ICC
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2332e805b19cdb309ea6eeb6d2e8b0915681f831f5aBrad Fitzpatrick     * When the operation is complete, onComplete will be sent to its
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Handler.
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * onComplete.obj will be an AsyncResult
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ((AsyncResult)onComplete.obj).exception == null on success
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ((AsyncResult)onComplete.obj).exception != null on fail
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If the supplied PIN is incorrect:
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ((AsyncResult)onComplete.obj).exception != null
24304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * && ((AsyncResult)onComplete.obj).exception
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *       instanceof com.android.internal.telephony.gsm.CommandException)
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * && ((CommandException)(((AsyncResult)onComplete.obj).exception))
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *          .getCommandError() == CommandException.Error.PASSWORD_INCORRECT
24704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
251cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void supplyPin (String pin, Message onComplete) {
252cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
253cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
254cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
255cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void supplyPuk (String puk, String newPin, Message onComplete) {
256cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPhone.mCM.supplyIccPuk(puk, newPin,
257cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
258cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
259cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
260cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void supplyPin2 (String pin2, Message onComplete) {
261cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPhone.mCM.supplyIccPin2(pin2,
262cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
263cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
264cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
265cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
266cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPhone.mCM.supplyIccPuk2(puk2, newPin2,
267cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
268cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
269cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
270cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void supplyNetworkDepersonalization (String pin, Message onComplete) {
271cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPhone.mCM.supplyNetworkDepersonalization(pin,
272cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
273cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
27604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * Check whether ICC pin lock is enabled
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is a sync call which returns the cached pin enabled state
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
27904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @return true for ICC locked enabled
28004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *         false for ICC locked disabled
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
282cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public boolean getIccLockEnabled() {
283cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        return mIccPinLocked;
284cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
28704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * Check whether ICC fdn (fixed dialing number) is enabled
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is a sync call which returns the cached pin enabled state
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
29004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @return true for ICC fdn enabled
29104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *         false for ICC fdn disabled
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
293cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     public boolean getIccFdnEnabled() {
294cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        return mIccFdnEnabled;
295cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     }
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
297cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     /**
298cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * Set the ICC pin lock enabled or disabled
299cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * When the operation is complete, onComplete will be sent to its handler
300cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *
301cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param enabled "true" for locked "false" for unlocked.
302cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param password needed to change the ICC pin state, aka. Pin1
303cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param onComplete
304cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        onComplete.obj will be an AsyncResult
305cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception == null on success
306cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception != null on fail
307cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      */
308cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     public void setIccLockEnabled (boolean enabled,
309cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh             String password, Message onComplete) {
310cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         int serviceClassX;
311cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
312cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 CommandsInterface.SERVICE_CLASS_DATA +
313cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 CommandsInterface.SERVICE_CLASS_FAX;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
315cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         mDesiredPinLocked = enabled;
316cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
317cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM,
318cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 enabled, password, serviceClassX,
319cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete));
320cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     }
321cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
322cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     /**
323cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * Set the ICC fdn enabled or disabled
324cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * When the operation is complete, onComplete will be sent to its handler
325cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *
326cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param enabled "true" for locked "false" for unlocked.
327cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param password needed to change the ICC fdn enable, aka Pin2
328cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param onComplete
329cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        onComplete.obj will be an AsyncResult
330cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception == null on success
331cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception != null on fail
332cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      */
333cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     public void setIccFdnEnabled (boolean enabled,
334cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh             String password, Message onComplete) {
335cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         int serviceClassX;
336cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
337cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 CommandsInterface.SERVICE_CLASS_DATA +
338cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 CommandsInterface.SERVICE_CLASS_FAX +
339cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 CommandsInterface.SERVICE_CLASS_SMS;
340cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
341cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         mDesiredFdnEnabled = enabled;
342cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
343cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD,
344cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 enabled, password, serviceClassX,
345cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete));
346cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     }
347cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
348cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     /**
349cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * Change the ICC password used in ICC pin lock
350cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * When the operation is complete, onComplete will be sent to its handler
351cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *
352cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param oldPassword is the old password
353cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param newPassword is the new password
354cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param onComplete
355cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        onComplete.obj will be an AsyncResult
356cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception == null on success
357cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception != null on fail
358cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      */
359cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     public void changeIccLockPassword(String oldPassword, String newPassword,
360cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh             Message onComplete) {
361cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         mPhone.mCM.changeIccPin(oldPassword, newPassword,
362cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
363cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
364cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     }
365cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
366cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     /**
367cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * Change the ICC password used in ICC fdn enable
368cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * When the operation is complete, onComplete will be sent to its handler
369cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *
370cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param oldPassword is the old password
371cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param newPassword is the new password
372cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      * @param onComplete
373cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        onComplete.obj will be an AsyncResult
374cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception == null on success
375cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      *        ((AsyncResult)onComplete.obj).exception != null on fail
376cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh      */
377cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     public void changeIccFdnPassword(String oldPassword, String newPassword,
378cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh             Message onComplete) {
379cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh         mPhone.mCM.changeIccPin2(oldPassword, newPassword,
380cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
381cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
382cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
38604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * Returns service provider name stored in ICC card.
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If there is no service provider name associated or the record is not
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * yet available, null will be returned <p>
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Please use this value when display Service Provider Name in idle mode <p>
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Usage of this provider name in the UI is a common carrier requirement.
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Also available via Android property "gsm.sim.operator.alpha"
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
39604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @return Service Provider Name stored in ICC card
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         null if no service provider name associated or the record is not
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         yet available
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
401cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public abstract String getServiceProviderName();
402cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
403cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected void updateStateProperty() {
404cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString());
405cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
406cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
407cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private void getIccCardStatusDone(AsyncResult ar) {
408cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (ar.exception != null) {
409cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            Log.e(mLogTag,"Error getting ICC status. "
410cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    + "RIL_REQUEST_GET_ICC_STATUS should "
411cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    + "never return an error", ar.exception);
412cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            return;
413cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
414cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        handleIccCardStatus((IccCardStatus) ar.result);
415cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
416cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
417cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private void handleIccCardStatus(IccCardStatus newCardStatus) {
418cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        boolean transitionedIntoPinLocked;
419cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        boolean transitionedIntoAbsent;
420cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        boolean transitionedIntoNetworkLocked;
421b0b24b3df50988d23f571b83d829fecc986ec497John Wang        boolean transitionedIntoPermBlocked;
42210e9f668eec105699b8f10d544a418e5bf9605c5John Wang        boolean isIccCardRemoved;
42310e9f668eec105699b8f10d544a418e5bf9605c5John Wang        boolean isIccCardAdded;
424cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
425cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        State oldState, newState;
426cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
427cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        oldState = mState;
428cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mIccCardStatus = newCardStatus;
429cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        newState = getIccCardState();
430cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        mState = newState;
431cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
432cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        updateStateProperty();
433cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
434cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        transitionedIntoPinLocked = (
435cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                 (oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED)
436cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh              || (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED));
437cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
438cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
439cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                && newState == State.NETWORK_LOCKED);
440b0b24b3df50988d23f571b83d829fecc986ec497John Wang        transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED
441b0b24b3df50988d23f571b83d829fecc986ec497John Wang                && newState == State.PERM_DISABLED);
44210e9f668eec105699b8f10d544a418e5bf9605c5John Wang        isIccCardRemoved = (oldState != null &&
44310e9f668eec105699b8f10d544a418e5bf9605c5John Wang                        oldState.iccCardExist() && newState == State.ABSENT);
44410e9f668eec105699b8f10d544a418e5bf9605c5John Wang        isIccCardAdded = (oldState == State.ABSENT &&
44510e9f668eec105699b8f10d544a418e5bf9605c5John Wang                        newState != null && newState.iccCardExist());
446cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
447cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (transitionedIntoPinLocked) {
44810e9f668eec105699b8f10d544a418e5bf9605c5John Wang            if (mDbg) log("Notify SIM pin or puk locked.");
449cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            mPinLockedRegistrants.notifyRegistrants();
450cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
451cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    (newState == State.PIN_REQUIRED) ?
452cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                       INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
453cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        } else if (transitionedIntoAbsent) {
45410e9f668eec105699b8f10d544a418e5bf9605c5John Wang            if (mDbg) log("Notify SIM missing.");
455cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            mAbsentRegistrants.notifyRegistrants();
456cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, null);
457cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        } else if (transitionedIntoNetworkLocked) {
45810e9f668eec105699b8f10d544a418e5bf9605c5John Wang            if (mDbg) log("Notify SIM network locked.");
459cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            mNetworkLockedRegistrants.notifyRegistrants();
460cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
461cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                  INTENT_VALUE_LOCKED_NETWORK);
462b0b24b3df50988d23f571b83d829fecc986ec497John Wang        } else if (transitionedIntoPermBlocked) {
463b0b24b3df50988d23f571b83d829fecc986ec497John Wang            if (mDbg) log("Notify SIM permanently disabled.");
464b0b24b3df50988d23f571b83d829fecc986ec497John Wang            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT,
465b0b24b3df50988d23f571b83d829fecc986ec497John Wang                    INTENT_VALUE_ABSENT_ON_PERM_DISABLED);
466cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
4671f3278e111c8abadedf71a9bcdbbaffe154be738Wink Saville
46810e9f668eec105699b8f10d544a418e5bf9605c5John Wang        if (isIccCardRemoved) {
46910e9f668eec105699b8f10d544a418e5bf9605c5John Wang            mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null));
47010e9f668eec105699b8f10d544a418e5bf9605c5John Wang        } else if (isIccCardAdded) {
47110e9f668eec105699b8f10d544a418e5bf9605c5John Wang            mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null));
47210e9f668eec105699b8f10d544a418e5bf9605c5John Wang        }
47310e9f668eec105699b8f10d544a418e5bf9605c5John Wang    }
47410e9f668eec105699b8f10d544a418e5bf9605c5John Wang
47510e9f668eec105699b8f10d544a418e5bf9605c5John Wang    private void onIccSwap(boolean isAdded) {
47610e9f668eec105699b8f10d544a418e5bf9605c5John Wang        // TODO: Here we assume the device can't handle SIM hot-swap
47710e9f668eec105699b8f10d544a418e5bf9605c5John Wang        //      and has to reboot. We may want to add a property,
47810e9f668eec105699b8f10d544a418e5bf9605c5John Wang        //      e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support
47910e9f668eec105699b8f10d544a418e5bf9605c5John Wang        //      hot-swap.
48010e9f668eec105699b8f10d544a418e5bf9605c5John Wang        DialogInterface.OnClickListener listener = null;
48110e9f668eec105699b8f10d544a418e5bf9605c5John Wang
48210e9f668eec105699b8f10d544a418e5bf9605c5John Wang
48310e9f668eec105699b8f10d544a418e5bf9605c5John Wang        // TODO: SimRecords is not reset while SIM ABSENT (only reset while
48410e9f668eec105699b8f10d544a418e5bf9605c5John Wang        //       Radio_off_or_not_available). Have to reset in both both
48510e9f668eec105699b8f10d544a418e5bf9605c5John Wang        //       added or removed situation.
48610e9f668eec105699b8f10d544a418e5bf9605c5John Wang        listener = new DialogInterface.OnClickListener() {
48710e9f668eec105699b8f10d544a418e5bf9605c5John Wang            @Override
48810e9f668eec105699b8f10d544a418e5bf9605c5John Wang            public void onClick(DialogInterface dialog, int which) {
48910e9f668eec105699b8f10d544a418e5bf9605c5John Wang                if (which == DialogInterface.BUTTON_POSITIVE) {
49010e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    if (mDbg) log("Reboot due to SIM swap");
49110e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    PowerManager pm = (PowerManager) mPhone.getContext()
49210e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    .getSystemService(Context.POWER_SERVICE);
49310e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    pm.reboot("SIM is added.");
49410e9f668eec105699b8f10d544a418e5bf9605c5John Wang                }
49510e9f668eec105699b8f10d544a418e5bf9605c5John Wang            }
49610e9f668eec105699b8f10d544a418e5bf9605c5John Wang
49710e9f668eec105699b8f10d544a418e5bf9605c5John Wang        };
49810e9f668eec105699b8f10d544a418e5bf9605c5John Wang
49910e9f668eec105699b8f10d544a418e5bf9605c5John Wang        Resources r = Resources.getSystem();
50010e9f668eec105699b8f10d544a418e5bf9605c5John Wang
50110e9f668eec105699b8f10d544a418e5bf9605c5John Wang        String title = (isAdded) ? r.getString(R.string.sim_added_title) :
50210e9f668eec105699b8f10d544a418e5bf9605c5John Wang            r.getString(R.string.sim_removed_title);
50310e9f668eec105699b8f10d544a418e5bf9605c5John Wang        String message = (isAdded) ? r.getString(R.string.sim_added_message) :
50410e9f668eec105699b8f10d544a418e5bf9605c5John Wang            r.getString(R.string.sim_removed_message);
50510e9f668eec105699b8f10d544a418e5bf9605c5John Wang        String buttonTxt = r.getString(R.string.sim_restart_button);
50610e9f668eec105699b8f10d544a418e5bf9605c5John Wang
50710e9f668eec105699b8f10d544a418e5bf9605c5John Wang        AlertDialog dialog = new AlertDialog.Builder(mPhone.getContext())
50810e9f668eec105699b8f10d544a418e5bf9605c5John Wang            .setTitle(title)
50910e9f668eec105699b8f10d544a418e5bf9605c5John Wang            .setMessage(message)
51010e9f668eec105699b8f10d544a418e5bf9605c5John Wang            .setPositiveButton(buttonTxt, listener)
51110e9f668eec105699b8f10d544a418e5bf9605c5John Wang            .create();
51210e9f668eec105699b8f10d544a418e5bf9605c5John Wang        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
51310e9f668eec105699b8f10d544a418e5bf9605c5John Wang        dialog.show();
514cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
515cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
516cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    /**
517cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
518cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     * @param ar is asyncResult of Query_Facility_Locked
519cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     */
520cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private void onQueryFdnEnabled(AsyncResult ar) {
521cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if(ar.exception != null) {
522cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            if(mDbg) log("Error in querying facility lock:" + ar.exception);
523cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            return;
524cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
525cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
526cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        int[] ints = (int[])ar.result;
527cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if(ints.length != 0) {
528cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            mIccFdnEnabled = (0!=ints[0]);
529cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            if(mDbg) log("Query facility lock : "  + mIccFdnEnabled);
530cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        } else {
531cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            Log.e(mLogTag, "[IccCard] Bogus facility lock response");
532cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
533cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
534cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
535cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    /**
536cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
537cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     * @param ar is asyncResult of Query_Facility_Locked
538cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh     */
539cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private void onQueryFacilityLock(AsyncResult ar) {
540cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if(ar.exception != null) {
541cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            if (mDbg) log("Error in querying facility lock:" + ar.exception);
542cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            return;
543cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
544cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
545cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        int[] ints = (int[])ar.result;
546cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if(ints.length != 0) {
547cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            mIccPinLocked = (0!=ints[0]);
548cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            if(mDbg) log("Query facility lock : "  + mIccPinLocked);
549cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        } else {
550cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            Log.e(mLogTag, "[IccCard] Bogus facility lock response");
551cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
552cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
553cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
554cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public void broadcastIccStateChangedIntent(String value, String reason) {
555cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
5561c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
557cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        intent.putExtra(Phone.PHONE_NAME_KEY, mPhone.getPhoneName());
558cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        intent.putExtra(INTENT_KEY_ICC_STATE, value);
559cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        intent.putExtra(INTENT_KEY_LOCKED_REASON, reason);
560cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if(mDbg) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
561cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                + " reason " + reason);
562cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
563cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
564cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
565cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    protected Handler mHandler = new Handler() {
566cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        @Override
567cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        public void handleMessage(Message msg){
568cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            AsyncResult ar;
569cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            int serviceClassX;
570cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
571cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
572cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            CommandsInterface.SERVICE_CLASS_DATA +
573cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            CommandsInterface.SERVICE_CLASS_FAX;
574cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
575cc7605ce61c27e3688e33dbf2bcafd1c12788784Uma Maheswari Ramalingam            if (!mPhone.mIsTheCurrentActivePhone) {
576cc7605ce61c27e3688e33dbf2bcafd1c12788784Uma Maheswari Ramalingam                Log.e(mLogTag, "Received message " + msg + "[" + msg.what
577cc7605ce61c27e3688e33dbf2bcafd1c12788784Uma Maheswari Ramalingam                        + "] while being destroyed. Ignoring.");
578cc7605ce61c27e3688e33dbf2bcafd1c12788784Uma Maheswari Ramalingam                return;
579cc7605ce61c27e3688e33dbf2bcafd1c12788784Uma Maheswari Ramalingam            }
580cc7605ce61c27e3688e33dbf2bcafd1c12788784Uma Maheswari Ramalingam
581cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            switch (msg.what) {
582cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
583cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    mState = null;
584cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    updateStateProperty();
585cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    broadcastIccStateChangedIntent(INTENT_VALUE_ICC_NOT_READY, null);
586cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
587cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_ICC_READY:
588cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    //TODO: put facility read in SIM_READY now, maybe in REG_NW
589cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
590cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    mPhone.mCM.queryFacilityLock (
591cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
592cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
593cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    mPhone.mCM.queryFacilityLock (
594cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
595cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
596cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
597cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_ICC_LOCKED_OR_ABSENT:
598cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
599cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    mPhone.mCM.queryFacilityLock (
600cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
601cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
602cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
603cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_GET_ICC_STATUS_DONE:
604cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
605cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
606cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    getIccCardStatusDone(ar);
607cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
608cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_PINPUK_DONE:
609cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // a PIN/PUK/PIN2/PUK2/Network Personalization
610cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // request has completed. ar.userObj is the response Message
611cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // Repoll before returning
612cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
613cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // TODO should abstract these exceptions
614cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    AsyncResult.forMessage(((Message)ar.userObj)).exception
615cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                                        = ar.exception;
616cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    mPhone.mCM.getIccCardStatus(
617cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
618cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
619cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_REPOLL_STATUS_DONE:
620cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // Finished repolling status after PIN operation
621cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // ar.userObj is the response messaeg
622cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // ar.userObj.obj is already an AsyncResult with an
623cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    // appropriate exception filled in if applicable
624cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
625cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
626cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    getIccCardStatusDone(ar);
627cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ((Message)ar.userObj).sendToTarget();
628cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
629cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_QUERY_FACILITY_LOCK_DONE:
630cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
631cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    onQueryFacilityLock(ar);
632cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
633cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_QUERY_FACILITY_FDN_DONE:
634cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
635cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    onQueryFdnEnabled(ar);
636cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
637cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_CHANGE_FACILITY_LOCK_DONE:
638cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
639cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    if (ar.exception == null) {
640cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        mIccPinLocked = mDesiredPinLocked;
641cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        if (mDbg) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " +
642cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                "mIccPinLocked= " + mIccPinLocked);
643cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    } else {
644cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        Log.e(mLogTag, "Error change facility lock with exception "
645cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            + ar.exception);
646cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    }
647cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    AsyncResult.forMessage(((Message)ar.userObj)).exception
648cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                                        = ar.exception;
649cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ((Message)ar.userObj).sendToTarget();
650cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
651cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_CHANGE_FACILITY_FDN_DONE:
652cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
653cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
654cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    if (ar.exception == null) {
655cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        mIccFdnEnabled = mDesiredFdnEnabled;
656cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        if (mDbg) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
657cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                "mIccFdnEnabled=" + mIccFdnEnabled);
658cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    } else {
659cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        Log.e(mLogTag, "Error change facility fdn with exception "
660cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                + ar.exception);
661cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    }
662cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    AsyncResult.forMessage(((Message)ar.userObj)).exception
663cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                                        = ar.exception;
664cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ((Message)ar.userObj).sendToTarget();
665cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
666cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                case EVENT_CHANGE_ICC_PASSWORD_DONE:
667cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ar = (AsyncResult)msg.obj;
668cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    if(ar.exception != null) {
669cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                        Log.e(mLogTag, "Error in change sim password with exception"
670cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                            + ar.exception);
671cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    }
672cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    AsyncResult.forMessage(((Message)ar.userObj)).exception
673cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                                                        = ar.exception;
674cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    ((Message)ar.userObj).sendToTarget();
675cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    break;
6763ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini                case EVENT_ICC_STATUS_CHANGED:
6773ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini                    Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED");
6783ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
6793ce5de7fe2c2854f9a1d97d77fc6be98a029a04dRamesh Sudini                    break;
68010e9f668eec105699b8f10d544a418e5bf9605c5John Wang                case EVENT_CARD_REMOVED:
68110e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    onIccSwap(false);
68210e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    break;
68310e9f668eec105699b8f10d544a418e5bf9605c5John Wang                case EVENT_CARD_ADDED:
68410e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    onIccSwap(true);
68510e9f668eec105699b8f10d544a418e5bf9605c5John Wang                    break;
686cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                default:
687cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                    Log.e(mLogTag, "[IccCard] Unknown Event " + msg.what);
688cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            }
689cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
690cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    };
691cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
692cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    public State getIccCardState() {
693cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (mIccCardStatus == null) {
694cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            Log.e(mLogTag, "[IccCard] IccCardStatus is null");
695cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            return IccCard.State.ABSENT;
696cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
697cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
698cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        // this is common for all radio technologies
699cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (!mIccCardStatus.getCardState().isCardPresent()) {
70041e7363f98964a27e194f8cb6d3c2cb04e7ee090Jaikumar Ganesh            return IccCard.State.ABSENT;
701cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
702cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
703cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        RadioState currentRadioState = mPhone.mCM.getRadioState();
704cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        // check radio technology
705cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if( currentRadioState == RadioState.RADIO_OFF         ||
706cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            currentRadioState == RadioState.RADIO_UNAVAILABLE ||
707cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            currentRadioState == RadioState.SIM_NOT_READY     ||
708cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            currentRadioState == RadioState.RUIM_NOT_READY    ||
709cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            currentRadioState == RadioState.NV_NOT_READY      ||
710ef5acbc0d6176125c406d0d3448415d2cc699466Kazuhiro Ondo            currentRadioState == RadioState.NV_READY) {
711cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            return IccCard.State.NOT_READY;
712cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
713cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
714cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if( currentRadioState == RadioState.SIM_LOCKED_OR_ABSENT  ||
715cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            currentRadioState == RadioState.SIM_READY             ||
716cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
717ef5acbc0d6176125c406d0d3448415d2cc699466Kazuhiro Ondo            currentRadioState == RadioState.RUIM_READY) {
718e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo
719e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            State csimState =
720e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo                getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
721e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            State usimState =
722e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo                getAppState(mIccCardStatus.getGsmUmtsSubscriptionAppIndex());
723e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo
724e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            if(mDbg) log("USIM=" + usimState + " CSIM=" + csimState);
725e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo
726e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            if (mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
727e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo                // UICC card contains both USIM and CSIM
728e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo                // Return consolidated status
729e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo                return getConsolidatedState(csimState, usimState, csimState);
730e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            }
731cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
732cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            // check for CDMA radio technology
733cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            if (currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
734cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                currentRadioState == RadioState.RUIM_READY) {
735e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo                return csimState;
736cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            }
737e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return usimState;
738e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        }
739cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
740e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        return IccCard.State.ABSENT;
741e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo    }
742cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
743e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo    private State getAppState(int appIndex) {
744e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        IccCardApplication app;
745e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
746e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            app = mIccCardStatus.getApplication(appIndex);
747e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        } else {
748e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            Log.e(mLogTag, "[IccCard] Invalid Subscription Application index:" + appIndex);
749e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return IccCard.State.ABSENT;
750e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        }
751cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
752e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (app == null) {
753e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            Log.e(mLogTag, "[IccCard] Subscription Application in not present");
754e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return IccCard.State.ABSENT;
755cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
756cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
757e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        // check if PIN required
758b0b24b3df50988d23f571b83d829fecc986ec497John Wang        if (app.pin1.isPermBlocked()) {
759b0b24b3df50988d23f571b83d829fecc986ec497John Wang            return IccCard.State.PERM_DISABLED;
760b0b24b3df50988d23f571b83d829fecc986ec497John Wang        }
761e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (app.app_state.isPinRequired()) {
762e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return IccCard.State.PIN_REQUIRED;
763e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        }
764e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (app.app_state.isPukRequired()) {
765e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return IccCard.State.PUK_REQUIRED;
766e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        }
767e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (app.app_state.isSubscriptionPersoEnabled()) {
768e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return IccCard.State.NETWORK_LOCKED;
769e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        }
770e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (app.app_state.isAppReady()) {
771e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return IccCard.State.READY;
772e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        }
773e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (app.app_state.isAppNotReady()) {
774e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo            return IccCard.State.NOT_READY;
775e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        }
776e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        return IccCard.State.NOT_READY;
777cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
778cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
779e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo    private State getConsolidatedState(State left, State right, State preferredState) {
780e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        // Check if either is absent.
781e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (right == IccCard.State.ABSENT) return left;
782e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (left == IccCard.State.ABSENT) return right;
783e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo
78457675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo        // Only if both are ready, return ready
78557675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo        if ((left == IccCard.State.READY) && (right == IccCard.State.READY)) {
78657675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo            return State.READY;
78757675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo        }
78857675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo
78957675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo        // Case one is ready, but the other is not.
79057675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo        if (((right == IccCard.State.NOT_READY) && (left == IccCard.State.READY)) ||
79157675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo            ((left == IccCard.State.NOT_READY) && (right == IccCard.State.READY))) {
79257675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo            return IccCard.State.NOT_READY;
79357675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo        }
79457675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo
79557675037aa279e715a966e2888a31c97381a5fe4Kazuhiro Ondo        // At this point, the other state is assumed to be one of locked state
796e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (right == IccCard.State.NOT_READY) return left;
797e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        if (left == IccCard.State.NOT_READY) return right;
798e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo
799e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        // At this point, FW currently just assumes the status will be
800e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        // consistent across the applications...
801e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo        return preferredState;
802e14a59e96c2a4362a7d72685a0669a5c3338f421Kazuhiro Ondo    }
803cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
80434efc39f256d5833687c7bd7d83258d6394c9307Jaikumar Ganesh    public boolean isApplicationOnIcc(IccCardApplication.AppType type) {
805cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        if (mIccCardStatus == null) return false;
806cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
807cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        for (int i = 0 ; i < mIccCardStatus.getNumApplications(); i++) {
808cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            IccCardApplication app = mIccCardStatus.getApplication(i);
809cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            if (app != null && app.app_type == type) {
810cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh                return true;
811cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh            }
812cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        }
813cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        return false;
814cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
815cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh
81665d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville    /**
81765d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville     * @return true if a ICC card is present
81865d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville     */
81965d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville    public boolean hasIccCard() {
820213c853f40074633d61bb7705843a9f4a00513b3Naveen Kalla        if (mIccCardStatus == null) {
82165d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville            return false;
822213c853f40074633d61bb7705843a9f4a00513b3Naveen Kalla        } else {
823213c853f40074633d61bb7705843a9f4a00513b3Naveen Kalla            // Returns ICC card status for both GSM and CDMA mode
824213c853f40074633d61bb7705843a9f4a00513b3Naveen Kalla            return mIccCardStatus.getCardState().isCardPresent();
82565d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville        }
82665d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville    }
82765d62c774e42d8bf9a55ef50e153ffc9e277ef37Wink Saville
828cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    private void log(String msg) {
829cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh        Log.d(mLogTag, "[IccCard] " + msg);
830cdadaad0e4e76a69eba144d3501cca9765cee80cJaikumar Ganesh    }
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
832