CatService.java revision 09b65da3b46e18c8acc146d722047ba2fb161bfe
10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2007 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cat;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.pm.PackageManager;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.pm.ResolveInfo;
23d7e83ff0591580603e6d6adfca085140d1d53bd2duho.roimport android.content.res.Resources.NotFoundException;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.HandlerThread;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
29ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wuimport android.telephony.SubscriptionManager;
30ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wuimport android.telephony.TelephonyManager;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface;
33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneConstants;
34a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.SubscriptionController;
35d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccFileHandler;
36d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
37d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils;
38d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccCard;
39d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccCardApplication;
40eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Guttaimport com.android.internal.telephony.uicc.IccCardStatus.CardState;
41eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Guttaimport com.android.internal.telephony.uicc.IccRefreshResponse;
42eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Guttaimport com.android.internal.telephony.uicc.UiccController;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.ByteArrayOutputStream;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Locale;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass RilMessage {
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int mId;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Object mData;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    ResultCode mResCode;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    RilMessage(int msgId, String rawData) {
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mId = msgId;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mData = rawData;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    RilMessage(RilMessage other) {
5922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mId = other.mId;
6022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mData = other.mData;
6122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mResCode = other.mResCode;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and application.
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class CatService extends Handler implements AppInterface {
72cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final boolean DBG = false;
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Class members
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static IccRecords mIccRecords;
76e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static UiccCardApplication mUiccApplication;
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Service members.
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Protects singleton instance lazy initialization.
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final Object sInstanceLock = new Object();
81ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu    private static CatService[] sInstance = null;
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CommandsInterface mCmdIf;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Context mContext;
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CatCmdMessage mCurrntCmd = null;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CatCmdMessage mMenuCmd = null;
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private RilMessageDecoder mMsgDecoder = null;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mStkAppInstalled = false;
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
90eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private UiccController mUiccController;
91eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private CardState mCardState = CardState.CARDSTATE_ABSENT;
92eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Service constants.
94a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_SESSION_END              = 1;
95a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_PROACTIVE_COMMAND        = 2;
96a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_EVENT_NOTIFY             = 3;
97a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_CALL_SETUP               = 4;
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_REFRESH                  = 5;
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_RESPONSE                 = 6;
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_SIM_READY                = 7;
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_ICC_CHANGED    = 8;
103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_ALPHA_NOTIFY   = 9;
104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_RIL_MSG_DECODED          = 10;
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Events to signal SIM presence or absent in the device.
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int MSG_ID_ICC_RECORDS_LOADED       = 20;
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
110eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    //Events to signal SIM REFRESH notificatations
111eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private static final int MSG_ID_ICC_REFRESH  = 30;
112eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_KEYPAD      = 0x01;
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_UICC        = 0x81;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_TERMINAL    = 0x82;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_NETWORK     = 0x83;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1182f48cebb0f3169da9d9325f7b4884872280599e5Nizar Haouati    static final String STK_DEFAULT = "Default Message";
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private HandlerThread mHandlerThread;
121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mSlotId;
122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* For multisim catservice should not be singleton */
124e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private CatService(CommandsInterface ci, UiccCardApplication ca, IccRecords ir,
125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Context context, IccFileHandler fh, UiccCard ic, int slotId) {
126e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (ci == null || ca == null || ir == null || context == null || fh == null
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                || ic == null) {
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new NullPointerException(
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "Service: Input parameters must not be null");
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf = ci;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext = context;
133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mSlotId = slotId;
134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandlerThread = new HandlerThread("Cat Telephony service" + slotId);
135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandlerThread.start();
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Get the RilMessagesDecoder for decoding the messages.
138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mMsgDecoder = RilMessageDecoder.getInstance(this, fh, slotId);
139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (null == mMsgDecoder) {
140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            CatLog.d(this, "Null RilMessageDecoder instance");
141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mMsgDecoder.start();
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Register ril events handling.
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null);
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
152eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mCmdIf.registerForIccRefresh(this, MSG_ID_ICC_REFRESH, null);
15309b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        mCmdIf.setOnCatCcAlphaNotify(this, MSG_ID_ALPHA_NOTIFY, null);
15409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mIccRecords = ir;
156e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mUiccApplication = ca;
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Register for SIM ready event.
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
160ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu        CatLog.d(this, "registerForRecordsLoaded slotid=" + mSlotId + " instance:" + this);
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
162eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
163eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mUiccController = UiccController.getInstance();
164eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mUiccController.registerForIccChanged(this, MSG_ID_ICC_CHANGED, null);
165eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
166ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu        // Check if STK application is available
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mStkAppInstalled = isStkAppInstalled();
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "Running CAT service on Slotid: " + mSlotId +
170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ". STK app installed:" + mStkAppInstalled);
171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Used for instantiating the Service from the Card.
175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     *
176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param ci CommandsInterface object
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param context phone app context
178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param ic Icc card
179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param slotId to know the index of card
180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @return The only Service object in the system
181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static CatService getInstance(CommandsInterface ci,
183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Context context, UiccCard ic, int slotId) {
184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        UiccCardApplication ca = null;
185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccFileHandler fh = null;
186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords ir = null;
187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (ic != null) {
188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            /* Since Cat is not tied to any application, but rather is Uicc application
189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             * in itself - just get first FileHandler and IccRecords object
190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             */
191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ca = ic.getApplicationIndex(0);
192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (ca != null) {
193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                fh = ca.getIccFileHandler();
194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ir = ca.getIccRecords();
195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
198d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu        synchronized (sInstanceLock) {
199d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu            if (sInstance == null) {
200ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                int simCount = TelephonyManager.getDefault().getSimCount();
201ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                sInstance = new CatService[simCount];
202ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                for (int i = 0; i < simCount; i++) {
203ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    sInstance[i] = null;
204ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                }
205ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            }
206ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            if (sInstance[slotId] == null) {
207d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                if (ci == null || ca == null || ir == null || context == null || fh == null
208d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                        || ic == null) {
209d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                    return null;
210d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                }
211d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu
212ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                sInstance[slotId] = new CatService(ci, ca, ir, context, fh, ic, slotId);
213d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu            } else if ((ir != null) && (mIccRecords != ir)) {
214d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                if (mIccRecords != null) {
215ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    mIccRecords.unregisterForRecordsLoaded(sInstance[slotId]);
216d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                }
217d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu
218d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                mIccRecords = ir;
219d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                mUiccApplication = ca;
220d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu
221ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                mIccRecords.registerForRecordsLoaded(sInstance[slotId],
222ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                        MSG_ID_ICC_RECORDS_LOADED, null);
223ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                CatLog.d(sInstance[slotId], "registerForRecordsLoaded slotid=" + slotId
224ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                        + " instance:" + sInstance[slotId]);
225d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu            }
226ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            return sInstance[slotId];
227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (sInstanceLock) {
232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            CatLog.d(this, "Disposing CatService object");
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.unregisterForRecordsLoaded(this);
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
235eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            // Clean up stk icon if dispose is called
236eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            broadcastCardStateAndIccRefreshResp(CardState.CARDSTATE_ABSENT, null);
237eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatSessionEnd(this);
239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatProactiveCmd(this);
240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatEvent(this);
241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatCallSetUp(this);
24209b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            mCmdIf.unSetOnCatCcAlphaNotify(this);
243eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
244eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mCmdIf.unregisterForIccRefresh(this);
245eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            if (mUiccController != null) {
246eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                mUiccController.unregisterForIccChanged(this);
247eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                mUiccController = null;
248eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            }
249eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mMsgDecoder.dispose();
250eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mMsgDecoder = null;
251eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mHandlerThread.quit();
252eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mHandlerThread = null;
253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            removeCallbacksAndMessages(null);
254ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            if (sInstance != null) {
255ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                if (SubscriptionManager.isValidSlotId(mSlotId)) {
256ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    sInstance[mSlotId] = null;
257ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                } else {
258ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    CatLog.d(this, "error: invaild slot id: " + mSlotId);
259ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                }
260ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            }
261a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CatLog.d(this, "Service finalized");
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleRilMsg(RilMessage rilMsg) {
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (rilMsg == null) {
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // dispatch messages
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandParams cmdParams = null;
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (rilMsg.mId) {
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_EVENT_NOTIFY:
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (rilMsg.mResCode == ResultCode.OK) {
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cmdParams = (CommandParams) rilMsg.mData;
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (cmdParams != null) {
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handleCommand(cmdParams, false);
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_PROACTIVE_COMMAND:
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cmdParams = (CommandParams) rilMsg.mData;
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (ClassCastException e) {
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // for error handling : cast exception
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "Fail to parse proactive command");
2911e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang                // Don't send Terminal Resp if command detail is not available
2929fdeecb4aa06552efcc535f21718cae45cc604e2Wink Saville                if (mCurrntCmd != null) {
2931e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang                    sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD,
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                     false, 0x00, null);
2951e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang                }
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cmdParams != null) {
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (rilMsg.mResCode == ResultCode.OK) {
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handleCommand(cmdParams, true);
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // for proactive commands that couldn't be decoded
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // successfully respond with the code generated by the
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // message decoder.
30522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sendTerminalResponse(cmdParams.mCmdDet, rilMsg.mResCode,
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            false, 0, null);
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_REFRESH:
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmdParams = (CommandParams) rilMsg.mData;
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cmdParams != null) {
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleCommand(cmdParams, false);
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_SESSION_END:
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleSessionEnd();
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_CALL_SETUP:
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // prior event notify command supplied all the information
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // needed for set up call processing.
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * from RIL.
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sends valid proactive command data to the application using intents.
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * from RIL_UNSOL_STK_PROACTIVE_COMMAND.
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) {
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CatLog.d(this, cmdParams.getCommandType().name());
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence message;
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (cmdParams.getCommandType()) {
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_MENU:
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (removeMenu(cmdMsg.getMenu())) {
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mMenuCmd = null;
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mMenuCmd = cmdMsg;
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
34522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DISPLAY_TEXT:
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // when application is not required to respond, send an immediate response.
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!cmdMsg.geTextMessage().responseNeeded) {
35022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case REFRESH:
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // ME side only handles refresh commands which meant to remove IDLE
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // MODE TEXT.
35622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                cmdParams.mCmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_IDLE_MODE_TEXT:
35922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case PROVIDE_LOCAL_INFORMATION:
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ResponseData resp;
36322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                switch (cmdParams.mCmdDet.commandQualifier) {
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    case CommandParamsFactory.DTTZ_SETTING:
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        resp = new DTTZResponseData(null);
36622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, resp);
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    case CommandParamsFactory.LANGUAGE_SETTING:
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        resp = new LanguageResponseData(Locale.getDefault().getLanguage());
37022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, resp);
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    default:
37322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // No need to start STK app here.
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case LAUNCH_BROWSER:
37822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if ((((LaunchBrowserParams) cmdParams).mConfirmMsg.text != null)
37922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && (((LaunchBrowserParams) cmdParams).mConfirmMsg.text.equals(STK_DEFAULT))) {
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    message = mContext.getText(com.android.internal.R.string.launchBrowserDefault);
38122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ((LaunchBrowserParams) cmdParams).mConfirmMsg.text = message.toString();
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SELECT_ITEM:
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INPUT:
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INKEY:
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_DTMF:
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_SMS:
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_SS:
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_USSD:
39222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if ((((DisplayTextParams)cmdParams).mTextMsg.text != null)
39322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && (((DisplayTextParams)cmdParams).mTextMsg.text.equals(STK_DEFAULT))) {
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    message = mContext.getText(com.android.internal.R.string.sending);
39522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ((DisplayTextParams)cmdParams).mTextMsg.text = message.toString();
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case PLAY_TONE:
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_CALL:
40122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if ((((CallSetupParams) cmdParams).mConfirmMsg.text != null)
40222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && (((CallSetupParams) cmdParams).mConfirmMsg.text.equals(STK_DEFAULT))) {
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    message = mContext.getText(com.android.internal.R.string.SetupCallDefault);
40422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ((CallSetupParams) cmdParams).mConfirmMsg.text = message.toString();
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case OPEN_CHANNEL:
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case CLOSE_CHANNEL:
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RECEIVE_DATA:
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_DATA:
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                BIPClientParams cmd = (BIPClientParams) cmdParams;
412d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                /* Per 3GPP specification 102.223,
413d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 * if the alpha identifier is not provided by the UICC,
414d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 * the terminal MAY give information to the user
415d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 * noAlphaUsrCnf defines if you need to show user confirmation or not
416d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 */
417d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                boolean noAlphaUsrCnf = false;
418d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                try {
419d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                    noAlphaUsrCnf = mContext.getResources().getBoolean(
420d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                            com.android.internal.R.bool.config_stkNoAlphaUsrCnf);
421d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                } catch (NotFoundException e) {
422d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                    noAlphaUsrCnf = false;
423d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                }
424d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                if ((cmd.mTextMsg.text == null) && (cmd.mHasAlphaId || noAlphaUsrCnf)) {
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id");
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If alpha length is zero, we just respond with OK.
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (isProactiveCmd) {
428f2d28790a3f02c337d10592aa390cc8d4c75e978Ajay Dudani                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
429f2d28790a3f02c337d10592aa390cc8d4c75e978Ajay Dudani                    } else if (cmdParams.getCommandType() == CommandType.OPEN_CHANNEL) {
430f2d28790a3f02c337d10592aa390cc8d4c75e978Ajay Dudani                        mCmdIf.handleCallSetupRequestFromSim(true, null);
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Respond with permanent failure to avoid retry if STK app is not present.
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!mStkAppInstalled) {
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CatLog.d(this, "No STK application found.");
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (isProactiveCmd) {
43822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet,
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                             ResultCode.BEYOND_TERMINAL_CAPABILITY,
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                             false, 0, null);
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                /*
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * either PROACTIVE_COMMAND or EVENT_NOTIFY.
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * If PROACTIVE_COMMAND is used for those commands, send terminal
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * response here.
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 */
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isProactiveCmd &&
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) ||
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                     (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) ||
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                     (cmdParams.getCommandType() == CommandType.SEND_DATA))) {
45422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "Unsupported command");
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = cmdMsg;
462a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        broadcastCatCmdIntent(cmdMsg);
463a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
464a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void broadcastCatCmdIntent(CatCmdMessage cmdMsg) {
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("STK CMD", cmdMsg);
469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra("SLOT_ID", mSlotId);
470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "Sending CmdMsg: " + cmdMsg+ " on slotid:" + mSlotId);
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext.sendBroadcast(intent);
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL.
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleSessionEnd() {
479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "SESSION END on "+ mSlotId);
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = mMenuCmd;
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra("SLOT_ID", mSlotId);
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext.sendBroadcast(intent);
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
487a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendTerminalResponse(CommandDetails cmdDet,
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResultCode resultCode, boolean includeAdditionalInfo,
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int additionalInfo, ResponseData resp) {
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdDet == null) {
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ByteArrayOutputStream buf = new ByteArrayOutputStream();
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Input cmdInput = null;
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mCurrntCmd != null) {
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmdInput = mCurrntCmd.geInput();
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // command details
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdDet.compRequired) {
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tag |= 0x80;
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x03); // length
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.commandNumber);
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.typeOfCommand);
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.commandQualifier);
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // device identities
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // According to TS102.223/TS31.111 section 6.8 Structure of
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the ME should set the CR(comprehension required) flag to
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // comprehension not required.(CR=0)"
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the CR flag is not set.
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_TERMINAL); // source device id
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_UICC); // destination device id
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // result
5278316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        tag = ComprehensionTlvTag.RESULT.value();
5288316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        if (cmdDet.compRequired) {
5298316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta            tag |= 0x80;
5308316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        }
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int length = includeAdditionalInfo ? 2 : 1;
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(length);
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(resultCode.value());
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // additional info
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (includeAdditionalInfo) {
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(additionalInfo);
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Fill optional data for each corresponding command
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (resp != null) {
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resp.format(buf);
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] rawData = buf.toByteArray();
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String hexString = IccUtils.bytesToHexString(rawData);
550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.sendTerminalResponse(hexString, null);
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void encodeOptionalTags(CommandDetails cmdDet,
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdType != null) {
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (cmdType) {
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case GET_INKEY:
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // ETSI TS 102 384,27.22.4.2.8.4.2.
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If it is a response for GET_INKEY command and the response timeout
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // occured, then add DURATION TLV for variable timeout case.
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (cmdInput != null) && (cmdInput.duration != null)) {
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getInKeyResponse(buf, cmdInput);
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case PROVIDE_LOCAL_INFORMATION:
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (resultCode.value() == ResultCode.OK.value())) {
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getPliResponse(buf);
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                default:
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CatLog.d(this, "encodeOptionalTags() Unsupported Cmd details=" + cmdDet);
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "encodeOptionalTags() bad Cmd details=" + cmdDet);
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = ComprehensionTlvTag.DURATION.value();
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdInput.duration.timeInterval); // Time Duration
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void getPliResponse(ByteArrayOutputStream buf) {
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Locale Language Setting
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String lang = SystemProperties.get("persist.sys.language");
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (lang != null) {
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tag
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int tag = ComprehensionTlvTag.LANGUAGE.value();
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(tag);
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResponseData.writeLength(buf, lang.length());
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(lang.getBytes(), 0, lang.length());
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendMenuSelection(int menuId, boolean helpRequired) {
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ByteArrayOutputStream buf = new ByteArrayOutputStream();
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // tag
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = BerTlv.BER_MENU_SELECTION_TAG;
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // length
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x00); // place holder
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // device identities
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_KEYPAD); // source device id
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_UICC); // destination device id
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // item identifier
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value();
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x01); // length
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(menuId); // menu identifier chosen
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // help request
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (helpRequired) {
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tag = ComprehensionTlvTag.HELP_REQUEST.value();
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(tag);
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(0x00); // length
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] rawData = buf.toByteArray();
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // write real length
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int len = rawData.length - 2; // minus (tag + length)
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        rawData[1] = (byte) len;
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String hexString = IccUtils.bytesToHexString(rawData);
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.sendEnvelope(hexString, null);
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
652a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Used by application to get an AppInterface object.
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The only Service object in the system
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //TODO Need to take care for MSIM
657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static AppInterface getInstance() {
658a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int slotId = PhoneConstants.DEFAULT_CARD_INDEX;
659a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        SubscriptionController sControl = SubscriptionController.getInstance();
660a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sControl != null) {
661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            slotId = sControl.getSlotId(sControl.getDefaultSubId());
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
663a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return getInstance(null, null, null, slotId);
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Used by application to get an AppInterface object.
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The only Service object in the system
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static AppInterface getInstance(int slotId) {
672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return getInstance(null, null, null, slotId);
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "handleMessage[" + msg.what + "]");
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_SESSION_END:
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_PROACTIVE_COMMAND:
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_EVENT_NOTIFY:
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_REFRESH:
684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            CatLog.d(this, "ril message arrived,slotid:" + mSlotId);
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String data = null;
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (msg.obj != null) {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar != null && ar.result != null) {
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    try {
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        data = (String) ar.result;
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } catch (ClassCastException e) {
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_CALL_SETUP:
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_ICC_RECORDS_LOADED:
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_RIL_MSG_DECODED:
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleRilMsg((RilMessage) msg.obj);
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_RESPONSE:
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleCmdResponse((CatResponseMessage) msg.obj);
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
709eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        case MSG_ID_ICC_CHANGED:
710eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            CatLog.d(this, "MSG_ID_ICC_CHANGED");
711eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            updateIccAvailability();
712eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            break;
713eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        case MSG_ID_ICC_REFRESH:
714eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            if (msg.obj != null) {
715eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                AsyncResult ar = (AsyncResult) msg.obj;
716eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                if (ar != null && ar.result != null) {
717eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    broadcastCardStateAndIccRefreshResp(CardState.CARDSTATE_PRESENT,
718eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                                  (IccRefreshResponse) ar.result);
719eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                } else {
720eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    CatLog.d(this,"Icc REFRESH with exception: " + ar.exception);
721eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                }
722eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            } else {
723eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                CatLog.d(this, "IccRefresh Message is null");
724eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            }
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
72609b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        case MSG_ID_ALPHA_NOTIFY:
72709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            CatLog.d(this, "Received CAT CC Alpha message from card");
72809b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            if (msg.obj != null) {
72909b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                AsyncResult ar = (AsyncResult) msg.obj;
73009b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                if (ar != null && ar.result != null) {
73109b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                    broadcastAlphaMessage((String)ar.result);
73209b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                } else {
73309b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                    CatLog.d(this, "CAT Alpha message: ar.result is null");
73409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                }
73509b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            } else {
73609b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                CatLog.d(this, "CAT Alpha message: msg.obj is null");
73709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            }
73809b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            break;
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new AssertionError("Unrecognized CAT command: " + msg.what);
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
744eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    /**
745eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** This function sends a CARD status (ABSENT, PRESENT, REFRESH) to STK_APP.
746eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** This is triggered during ICC_REFRESH or CARD STATE changes. In case
747eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** REFRESH, additional information is sent in 'refresh_result'
748eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     **
749eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     **/
750eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private void  broadcastCardStateAndIccRefreshResp(CardState cardState,
751eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            IccRefreshResponse iccRefreshState) {
752eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        Intent intent = new Intent(AppInterface.CAT_ICC_STATUS_CHANGE);
753eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        boolean cardPresent = (cardState == CardState.CARDSTATE_PRESENT);
754eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
755eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (iccRefreshState != null) {
756eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            //This case is when MSG_ID_ICC_REFRESH is received.
757eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            intent.putExtra(AppInterface.REFRESH_RESULT, iccRefreshState.refreshResult);
758eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            CatLog.d(this, "Sending IccResult with Result: "
759eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    + iccRefreshState.refreshResult);
760eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
761eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
762eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        // This sends an intent with CARD_ABSENT (0 - false) /CARD_PRESENT (1 - true).
763eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        intent.putExtra(AppInterface.CARD_STATUS, cardPresent);
764eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CatLog.d(this, "Sending Card Status: "
765eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                + cardState + " " + "cardPresent: " + cardPresent);
76609b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        mContext.sendBroadcast(intent);
76709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja    }
768eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
76909b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja    private void broadcastAlphaMessage(String alphaString) {
77009b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        CatLog.d(this, "Broadcasting CAT Alpha message from card: " + alphaString);
77109b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        Intent intent = new Intent(AppInterface.CAT_ALPHA_NOTIFY_ACTION);
77209b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
77309b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.putExtra(AppInterface.ALPHA_STRING, alphaString);
77409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.putExtra("SLOT_ID", mSlotId);
775eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mContext.sendBroadcast(intent);
776eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    }
777eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public synchronized void onCmdResponse(CatResponseMessage resMsg) {
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (resMsg == null) {
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // queue a response message.
78422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Message msg = obtainMessage(MSG_ID_RESPONSE, resMsg);
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.sendToTarget();
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean validateResponse(CatResponseMessage resMsg) {
789ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu        boolean ret = false;
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mCurrntCmd != null) {
791ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            ret = (resMsg.mCmdDet.compareTo(mCurrntCmd.mCmdDet));
792ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            CatLog.d(this, "SS-validateResponse: ret=" + ret +
793ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    " [" + resMsg.mCmdDet.toString()+
794ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    "/" + mCurrntCmd.mCmdDet.toString()+ "]");
795ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            return ret;
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean removeMenu(Menu menu) {
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (menu.items.size() == 1 && menu.items.get(0) == null) {
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (NullPointerException e) {
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "Unable to get Menu's items size");
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleCmdResponse(CatResponseMessage resMsg) {
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Make sure the response details match the last valid command. An invalid
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // response is a one that doesn't have a corresponding proactive command
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // and sending it can "confuse" the baseband/ril.
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // One reason for out of order responses can be UI glitches. For example,
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if the application launch an activity, and that activity is stored
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // by the framework inside the history stack. That activity will be
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // available for relaunch using the latest application dialog
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // (long press on the home button). Relaunching that activity can send
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the same command's result again to the CatService and can cause it to
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // get out of sync with the SIM.
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!validateResponse(resMsg)) {
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ResponseData resp = null;
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean helpRequired = false;
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandDetails cmdDet = resMsg.getCmdDetails();
82914957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        AppInterface.CommandType type = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
83122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch (resMsg.mResCode) {
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case HELP_INFO_REQUIRED:
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            helpRequired = true;
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // fall through
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case OK:
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_PARTIAL_COMPREHENSION:
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_MISSING_INFO:
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_ADDITIONAL_EFS_READ:
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_ICON_NOT_DISPLAYED:
8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_MODIFIED_BY_NAA:
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_LIMITED_SERVICE:
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_MODIFICATION:
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_NAA_NOT_ACTIVE:
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_TONE_NOT_PLAYED:
8452d7aad7791b92186dabc779b3ab43794aceebcdaGuillaume Lucas        case TERMINAL_CRNTLY_UNABLE_TO_PROCESS:
84614957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            switch (type) {
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_MENU:
84822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                helpRequired = resMsg.mResCode == ResultCode.HELP_INFO_REQUIRED;
84922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sendMenuSelection(resMsg.mUsersMenuSelection, helpRequired);
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SELECT_ITEM:
85222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                resp = new SelectItemResponseData(resMsg.mUsersMenuSelection);
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INPUT:
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INKEY:
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Input input = mCurrntCmd.geInput();
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!input.yesNo) {
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // when help is requested there is no need to send the text
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // string object.
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (!helpRequired) {
86122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        resp = new GetInkeyInputResponseData(resMsg.mUsersInput,
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                input.ucs2, input.packed);
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    resp = new GetInkeyInputResponseData(
86622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            resMsg.mUsersYesNoSelection);
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DISPLAY_TEXT:
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case LAUNCH_BROWSER:
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
872419f297bfb0cc21566d1d1110573dd9205e8f713Shriram Ganesh            // 3GPP TS.102.223: Open Channel alpha confirmation should not send TR
873419f297bfb0cc21566d1d1110573dd9205e8f713Shriram Ganesh            case OPEN_CHANNEL:
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_CALL:
87522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCmdIf.handleCallSetupRequestFromSim(resMsg.mUsersConfirm, null);
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // No need to send terminal response for SET UP CALL. The user's
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // confirmation result is send back using a dedicated ril message
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // invoked by the CommandInterface call above.
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCurrntCmd = null;
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            default:
882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case BACKWARD_MOVE_BY_USER:
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case USER_NOT_ACCEPT:
88714957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // if the user dismissed the alert dialog for a
88814957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // setup call/open channel, consider that as the user
88914957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // rejecting the call. Use dedicated API for this, rather than
89014957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // sending a terminal response.
89114957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            if (type == CommandType.SET_UP_CALL || type == CommandType.OPEN_CHANNEL) {
89214957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                mCmdIf.handleCallSetupRequestFromSim(false, null);
89314957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                mCurrntCmd = null;
89414957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                return;
89514957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            } else {
89614957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                resp = null;
89714957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            }
89814957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            break;
89914957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        case NO_RESPONSE_FROM_USER:
90014957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        case UICC_SESSION_TERM_BY_USER:
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resp = null;
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
90622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        sendTerminalResponse(cmdDet, resMsg.mResCode, resMsg.mIncludeAdditionalInfo,
90722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                resMsg.mAdditionalInfo, resp);
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = null;
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean isStkAppInstalled() {
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PackageManager pm = mContext.getPackageManager();
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<ResolveInfo> broadcastReceivers =
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA);
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size();
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (numReceiver > 0);
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
920a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
921a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update(CommandsInterface ci,
922a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Context context, UiccCard ic) {
923a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        UiccCardApplication ca = null;
924a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords ir = null;
925a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
926a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (ic != null) {
927a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            /* Since Cat is not tied to any application, but rather is Uicc application
928a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             * in itself - just get first FileHandler and IccRecords object
929a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             */
930a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ca = ic.getApplicationIndex(0);
931a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (ca != null) {
932a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ir = ca.getIccRecords();
933a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
934a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
935a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
936a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (sInstanceLock) {
937a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if ((ir != null) && (mIccRecords != ir)) {
938a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mIccRecords != null) {
939a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mIccRecords.unregisterForRecordsLoaded(this);
940a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
941a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
942a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                CatLog.d(this,
943a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        "Reinitialize the Service with SIMRecords and UiccCardApplication");
944a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mIccRecords = ir;
945a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUiccApplication = ca;
946a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
947a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // re-Register for SIM ready event.
948a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
949ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                CatLog.d(this, "registerForRecordsLoaded slotid=" + mSlotId + " instance:" + this);
950a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
951a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
952a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
953eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
954eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    void updateIccAvailability() {
955eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (null == mUiccController) {
956eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            return;
957eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
958eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
959eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CardState newState = CardState.CARDSTATE_ABSENT;
9601f22d77839c35908113e4978a1431636be0786acduho.ro        UiccCard newCard = mUiccController.getUiccCard(mSlotId);
961eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (newCard != null) {
962eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            newState = newCard.getCardState();
963eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
964eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CardState oldState = mCardState;
965eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mCardState = newState;
966eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CatLog.d(this,"New Card State = " + newState + " " + "Old Card State = " + oldState);
967eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (oldState == CardState.CARDSTATE_PRESENT &&
968eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                newState != CardState.CARDSTATE_PRESENT) {
969eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            broadcastCardStateAndIccRefreshResp(newState, null);
970eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        } else if (oldState != CardState.CARDSTATE_PRESENT &&
971eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                newState == CardState.CARDSTATE_PRESENT) {
972eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            // Card moved to PRESENT STATE.
973eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mCmdIf.reportStkServiceIsRunning(null);
974eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
975eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    }
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
977