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
48734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahujaimport static com.android.internal.telephony.cat.CatCmdMessage.
493ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                   SetupEventListConstants.IDLE_SCREEN_AVAILABLE_EVENT;
503ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahujaimport static com.android.internal.telephony.cat.CatCmdMessage.
51734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                   SetupEventListConstants.LANGUAGE_SELECTION_EVENT;
52734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass RilMessage {
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int mId;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Object mData;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    ResultCode mResCode;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    RilMessage(int msgId, String rawData) {
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mId = msgId;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mData = rawData;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    RilMessage(RilMessage other) {
6422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mId = other.mId;
6522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mData = other.mData;
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mResCode = other.mResCode;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and application.
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class CatService extends Handler implements AppInterface {
77cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final boolean DBG = false;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Class members
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static IccRecords mIccRecords;
81e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static UiccCardApplication mUiccApplication;
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Service members.
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Protects singleton instance lazy initialization.
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final Object sInstanceLock = new Object();
86ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu    private static CatService[] sInstance = null;
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CommandsInterface mCmdIf;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Context mContext;
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CatCmdMessage mCurrntCmd = null;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CatCmdMessage mMenuCmd = null;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private RilMessageDecoder mMsgDecoder = null;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mStkAppInstalled = false;
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
95eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private UiccController mUiccController;
96eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private CardState mCardState = CardState.CARDSTATE_ABSENT;
97eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Service constants.
99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_SESSION_END              = 1;
100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_PROACTIVE_COMMAND        = 2;
101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_EVENT_NOTIFY             = 3;
102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_CALL_SETUP               = 4;
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_REFRESH                  = 5;
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_RESPONSE                 = 6;
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_SIM_READY                = 7;
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_ICC_CHANGED    = 8;
108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int MSG_ID_ALPHA_NOTIFY   = 9;
109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MSG_ID_RIL_MSG_DECODED          = 10;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Events to signal SIM presence or absent in the device.
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int MSG_ID_ICC_RECORDS_LOADED       = 20;
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
115eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    //Events to signal SIM REFRESH notificatations
116eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private static final int MSG_ID_ICC_REFRESH  = 30;
117eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_KEYPAD      = 0x01;
119734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    private static final int DEV_ID_DISPLAY     = 0x02;
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_UICC        = 0x81;
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_TERMINAL    = 0x82;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int DEV_ID_NETWORK     = 0x83;
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1242f48cebb0f3169da9d9325f7b4884872280599e5Nizar Haouati    static final String STK_DEFAULT = "Default Message";
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private HandlerThread mHandlerThread;
127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mSlotId;
128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* For multisim catservice should not be singleton */
130e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private CatService(CommandsInterface ci, UiccCardApplication ca, IccRecords ir,
131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Context context, IccFileHandler fh, UiccCard ic, int slotId) {
132e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (ci == null || ca == null || ir == null || context == null || fh == null
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                || ic == null) {
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new NullPointerException(
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "Service: Input parameters must not be null");
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf = ci;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext = context;
139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mSlotId = slotId;
140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandlerThread = new HandlerThread("Cat Telephony service" + slotId);
141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandlerThread.start();
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Get the RilMessagesDecoder for decoding the messages.
144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mMsgDecoder = RilMessageDecoder.getInstance(this, fh, slotId);
145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (null == mMsgDecoder) {
146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            CatLog.d(this, "Null RilMessageDecoder instance");
147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mMsgDecoder.start();
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Register ril events handling.
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null);
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
158eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mCmdIf.registerForIccRefresh(this, MSG_ID_ICC_REFRESH, null);
15909b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        mCmdIf.setOnCatCcAlphaNotify(this, MSG_ID_ALPHA_NOTIFY, null);
16009b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mIccRecords = ir;
162e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mUiccApplication = ca;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Register for SIM ready event.
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
166ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu        CatLog.d(this, "registerForRecordsLoaded slotid=" + mSlotId + " instance:" + this);
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
168eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
169eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mUiccController = UiccController.getInstance();
170eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mUiccController.registerForIccChanged(this, MSG_ID_ICC_CHANGED, null);
171eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
172ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu        // Check if STK application is available
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mStkAppInstalled = isStkAppInstalled();
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "Running CAT service on Slotid: " + mSlotId +
176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ". STK app installed:" + mStkAppInstalled);
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Used for instantiating the Service from the Card.
181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     *
182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param ci CommandsInterface object
183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param context phone app context
184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param ic Icc card
185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @param slotId to know the index of card
186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @return The only Service object in the system
187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static CatService getInstance(CommandsInterface ci,
189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Context context, UiccCard ic, int slotId) {
190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        UiccCardApplication ca = null;
191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccFileHandler fh = null;
192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords ir = null;
193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (ic != null) {
194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            /* Since Cat is not tied to any application, but rather is Uicc application
195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             * in itself - just get first FileHandler and IccRecords object
196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             */
197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ca = ic.getApplicationIndex(0);
198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (ca != null) {
199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                fh = ca.getIccFileHandler();
200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ir = ca.getIccRecords();
201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
204d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu        synchronized (sInstanceLock) {
205d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu            if (sInstance == null) {
206ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                int simCount = TelephonyManager.getDefault().getSimCount();
207ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                sInstance = new CatService[simCount];
208ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                for (int i = 0; i < simCount; i++) {
209ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    sInstance[i] = null;
210ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                }
211ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            }
212ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            if (sInstance[slotId] == null) {
213d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                if (ci == null || ca == null || ir == null || context == null || fh == null
214d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                        || ic == null) {
215d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                    return null;
216d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                }
217d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu
218ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                sInstance[slotId] = new CatService(ci, ca, ir, context, fh, ic, slotId);
219d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu            } else if ((ir != null) && (mIccRecords != ir)) {
220d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                if (mIccRecords != null) {
221ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    mIccRecords.unregisterForRecordsLoaded(sInstance[slotId]);
222d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                }
223d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu
224d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                mIccRecords = ir;
225d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu                mUiccApplication = ca;
226d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu
227ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                mIccRecords.registerForRecordsLoaded(sInstance[slotId],
228ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                        MSG_ID_ICC_RECORDS_LOADED, null);
229ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                CatLog.d(sInstance[slotId], "registerForRecordsLoaded slotid=" + slotId
230ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                        + " instance:" + sInstance[slotId]);
231d14886b2a393c8b3e844d38f5edee651e75c4f95Steven Liu            }
232ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            return sInstance[slotId];
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (sInstanceLock) {
238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            CatLog.d(this, "Disposing CatService object");
239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.unregisterForRecordsLoaded(this);
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
241eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            // Clean up stk icon if dispose is called
242eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            broadcastCardStateAndIccRefreshResp(CardState.CARDSTATE_ABSENT, null);
243eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatSessionEnd(this);
245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatProactiveCmd(this);
246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatEvent(this);
247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mCmdIf.unSetOnCatCallSetUp(this);
24809b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            mCmdIf.unSetOnCatCcAlphaNotify(this);
249eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
250eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mCmdIf.unregisterForIccRefresh(this);
251eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            if (mUiccController != null) {
252eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                mUiccController.unregisterForIccChanged(this);
253eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                mUiccController = null;
254eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            }
255eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mMsgDecoder.dispose();
256eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mMsgDecoder = null;
257eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mHandlerThread.quit();
258eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mHandlerThread = null;
259a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            removeCallbacksAndMessages(null);
260ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            if (sInstance != null) {
26182e8da62fe3f83f29d834636b8da5ce6803204e3Sanket Padawe                if (SubscriptionManager.isValidSlotIndex(mSlotId)) {
262ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    sInstance[mSlotId] = null;
263ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                } else {
264ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                    CatLog.d(this, "error: invaild slot id: " + mSlotId);
265ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                }
266ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu            }
267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CatLog.d(this, "Service finalized");
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleRilMsg(RilMessage rilMsg) {
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (rilMsg == null) {
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // dispatch messages
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandParams cmdParams = null;
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (rilMsg.mId) {
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_EVENT_NOTIFY:
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (rilMsg.mResCode == ResultCode.OK) {
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cmdParams = (CommandParams) rilMsg.mData;
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (cmdParams != null) {
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handleCommand(cmdParams, false);
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_PROACTIVE_COMMAND:
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cmdParams = (CommandParams) rilMsg.mData;
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (ClassCastException e) {
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // for error handling : cast exception
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "Fail to parse proactive command");
2971e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang                // Don't send Terminal Resp if command detail is not available
2989fdeecb4aa06552efcc535f21718cae45cc604e2Wink Saville                if (mCurrntCmd != null) {
2991e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang                    sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD,
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                     false, 0x00, null);
3011e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang                }
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cmdParams != null) {
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (rilMsg.mResCode == ResultCode.OK) {
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handleCommand(cmdParams, true);
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // for proactive commands that couldn't be decoded
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // successfully respond with the code generated by the
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // message decoder.
31122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sendTerminalResponse(cmdParams.mCmdDet, rilMsg.mResCode,
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            false, 0, null);
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_REFRESH:
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmdParams = (CommandParams) rilMsg.mData;
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cmdParams != null) {
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleCommand(cmdParams, false);
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_SESSION_END:
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleSessionEnd();
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_CALL_SETUP:
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // prior event notify command supplied all the information
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // needed for set up call processing.
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
333734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja     * This function validates the events in SETUP_EVENT_LIST which are currently
334734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja     * supported by the Android framework. In case of SETUP_EVENT_LIST has NULL events
335734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja     * or no events, all the events need to be reset.
336734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja     */
337734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    private boolean isSupportedSetupEventCommand(CatCmdMessage cmdMsg) {
338734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        boolean flag = true;
339734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
340734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        for (int eventVal: cmdMsg.getSetEventList().eventList) {
341734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            CatLog.d(this,"Event: " + eventVal);
342734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            switch (eventVal) {
343734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                /* Currently android is supporting only the below events in SetupEventList
344734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                 * Language Selection.  */
3453ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                case IDLE_SCREEN_AVAILABLE_EVENT:
346734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                case LANGUAGE_SELECTION_EVENT:
347734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                    break;
348734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                default:
349734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                    flag = false;
350734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            }
351734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        }
352734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        return flag;
353734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    }
354734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
355734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    /**
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * from RIL.
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sends valid proactive command data to the application using intents.
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * from RIL_UNSOL_STK_PROACTIVE_COMMAND.
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) {
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CatLog.d(this, cmdParams.getCommandType().name());
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3654cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal        // Log all proactive commands.
3664cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal        if (isProactiveCmd) {
3674cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal            if (mUiccController != null) {
3684cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal                mUiccController.addCardLog("ProactiveCommand mSlotId=" + mSlotId +
3694cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal                        " cmdParams=" + cmdParams);
3704cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal            }
3714cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal        }
3724cdf0a453fa3df6015032ec5cbb8d3253b6f81daShishir Agrawal
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence message;
3745767ae41f516736b666062091d4f1948eccca8f4Preeti Ahuja        ResultCode resultCode;
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (cmdParams.getCommandType()) {
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_MENU:
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (removeMenu(cmdMsg.getMenu())) {
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mMenuCmd = null;
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mMenuCmd = cmdMsg;
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3835767ae41f516736b666062091d4f1948eccca8f4Preeti Ahuja                resultCode = cmdParams.mLoadIconFailed ? ResultCode.PRFRMD_ICON_NOT_DISPLAYED
3845767ae41f516736b666062091d4f1948eccca8f4Preeti Ahuja                                                                            : ResultCode.OK;
3855767ae41f516736b666062091d4f1948eccca8f4Preeti Ahuja                sendTerminalResponse(cmdParams.mCmdDet, resultCode, false, 0, null);
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DISPLAY_TEXT:
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case REFRESH:
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // ME side only handles refresh commands which meant to remove IDLE
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // MODE TEXT.
39222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                cmdParams.mCmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_IDLE_MODE_TEXT:
3955767ae41f516736b666062091d4f1948eccca8f4Preeti Ahuja                resultCode = cmdParams.mLoadIconFailed ? ResultCode.PRFRMD_ICON_NOT_DISPLAYED
3965767ae41f516736b666062091d4f1948eccca8f4Preeti Ahuja                                                                            : ResultCode.OK;
3975767ae41f516736b666062091d4f1948eccca8f4Preeti Ahuja                sendTerminalResponse(cmdParams.mCmdDet,resultCode, false, 0, null);
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
399734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            case SET_UP_EVENT_LIST:
400734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                if (isSupportedSetupEventCommand(cmdMsg)) {
401734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
402734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                } else {
403734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.BEYOND_TERMINAL_CAPABILITY,
404734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                            false, 0, null);
405734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                }
406734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                break;
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case PROVIDE_LOCAL_INFORMATION:
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ResponseData resp;
40922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                switch (cmdParams.mCmdDet.commandQualifier) {
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    case CommandParamsFactory.DTTZ_SETTING:
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        resp = new DTTZResponseData(null);
41222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, resp);
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    case CommandParamsFactory.LANGUAGE_SETTING:
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        resp = new LanguageResponseData(Locale.getDefault().getLanguage());
41622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, resp);
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    default:
41922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // No need to start STK app here.
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case LAUNCH_BROWSER:
42422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if ((((LaunchBrowserParams) cmdParams).mConfirmMsg.text != null)
42522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && (((LaunchBrowserParams) cmdParams).mConfirmMsg.text.equals(STK_DEFAULT))) {
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    message = mContext.getText(com.android.internal.R.string.launchBrowserDefault);
42722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ((LaunchBrowserParams) cmdParams).mConfirmMsg.text = message.toString();
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SELECT_ITEM:
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INPUT:
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INKEY:
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_DTMF:
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_SMS:
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_SS:
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_USSD:
43822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if ((((DisplayTextParams)cmdParams).mTextMsg.text != null)
43922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && (((DisplayTextParams)cmdParams).mTextMsg.text.equals(STK_DEFAULT))) {
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    message = mContext.getText(com.android.internal.R.string.sending);
44122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ((DisplayTextParams)cmdParams).mTextMsg.text = message.toString();
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case PLAY_TONE:
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_CALL:
44722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if ((((CallSetupParams) cmdParams).mConfirmMsg.text != null)
44822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && (((CallSetupParams) cmdParams).mConfirmMsg.text.equals(STK_DEFAULT))) {
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    message = mContext.getText(com.android.internal.R.string.SetupCallDefault);
45022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ((CallSetupParams) cmdParams).mConfirmMsg.text = message.toString();
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case OPEN_CHANNEL:
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case CLOSE_CHANNEL:
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RECEIVE_DATA:
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SEND_DATA:
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                BIPClientParams cmd = (BIPClientParams) cmdParams;
458d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                /* Per 3GPP specification 102.223,
459d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 * if the alpha identifier is not provided by the UICC,
460d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 * the terminal MAY give information to the user
461d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 * noAlphaUsrCnf defines if you need to show user confirmation or not
462d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                 */
463d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                boolean noAlphaUsrCnf = false;
464d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                try {
465d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                    noAlphaUsrCnf = mContext.getResources().getBoolean(
466d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                            com.android.internal.R.bool.config_stkNoAlphaUsrCnf);
467d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                } catch (NotFoundException e) {
468d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                    noAlphaUsrCnf = false;
469d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                }
470d7e83ff0591580603e6d6adfca085140d1d53bd2duho.ro                if ((cmd.mTextMsg.text == null) && (cmd.mHasAlphaId || noAlphaUsrCnf)) {
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id");
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If alpha length is zero, we just respond with OK.
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (isProactiveCmd) {
474f2d28790a3f02c337d10592aa390cc8d4c75e978Ajay Dudani                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
475f2d28790a3f02c337d10592aa390cc8d4c75e978Ajay Dudani                    } else if (cmdParams.getCommandType() == CommandType.OPEN_CHANNEL) {
476f2d28790a3f02c337d10592aa390cc8d4c75e978Ajay Dudani                        mCmdIf.handleCallSetupRequestFromSim(true, null);
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Respond with permanent failure to avoid retry if STK app is not present.
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!mStkAppInstalled) {
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CatLog.d(this, "No STK application found.");
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (isProactiveCmd) {
48422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sendTerminalResponse(cmdParams.mCmdDet,
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                             ResultCode.BEYOND_TERMINAL_CAPABILITY,
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                             false, 0, null);
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                /*
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * either PROACTIVE_COMMAND or EVENT_NOTIFY.
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * If PROACTIVE_COMMAND is used for those commands, send terminal
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * response here.
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 */
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isProactiveCmd &&
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) ||
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                     (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) ||
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                     (cmdParams.getCommandType() == CommandType.SEND_DATA))) {
50022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "Unsupported command");
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = cmdMsg;
508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        broadcastCatCmdIntent(cmdMsg);
509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
510a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
511a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void broadcastCatCmdIntent(CatCmdMessage cmdMsg) {
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("STK CMD", cmdMsg);
515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra("SLOT_ID", mSlotId);
516685aaba80c3dee5daf0df761ed100221cf9f7cd4fionaxu        intent.setComponent(AppInterface.getDefaultSTKApplication());
517a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "Sending CmdMsg: " + cmdMsg+ " on slotid:" + mSlotId);
518d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL.
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleSessionEnd() {
526a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "SESSION END on "+ mSlotId);
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = mMenuCmd;
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra("SLOT_ID", mSlotId);
531685aaba80c3dee5daf0df761ed100221cf9f7cd4fionaxu        intent.setComponent(AppInterface.getDefaultSTKApplication());
532d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendTerminalResponse(CommandDetails cmdDet,
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResultCode resultCode, boolean includeAdditionalInfo,
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int additionalInfo, ResponseData resp) {
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdDet == null) {
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ByteArrayOutputStream buf = new ByteArrayOutputStream();
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Input cmdInput = null;
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mCurrntCmd != null) {
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmdInput = mCurrntCmd.geInput();
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // command details
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdDet.compRequired) {
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tag |= 0x80;
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x03); // length
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.commandNumber);
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.typeOfCommand);
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.commandQualifier);
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // device identities
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // According to TS102.223/TS31.111 section 6.8 Structure of
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the ME should set the CR(comprehension required) flag to
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // comprehension not required.(CR=0)"
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the CR flag is not set.
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_TERMINAL); // source device id
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_UICC); // destination device id
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // result
5758316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        tag = ComprehensionTlvTag.RESULT.value();
5768316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        if (cmdDet.compRequired) {
5778316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta            tag |= 0x80;
5788316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        }
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int length = includeAdditionalInfo ? 2 : 1;
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(length);
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(resultCode.value());
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // additional info
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (includeAdditionalInfo) {
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(additionalInfo);
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Fill optional data for each corresponding command
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (resp != null) {
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resp.format(buf);
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] rawData = buf.toByteArray();
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String hexString = IccUtils.bytesToHexString(rawData);
598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.sendTerminalResponse(hexString, null);
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void encodeOptionalTags(CommandDetails cmdDet,
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdType != null) {
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (cmdType) {
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case GET_INKEY:
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // ETSI TS 102 384,27.22.4.2.8.4.2.
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If it is a response for GET_INKEY command and the response timeout
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // occured, then add DURATION TLV for variable timeout case.
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (cmdInput != null) && (cmdInput.duration != null)) {
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getInKeyResponse(buf, cmdInput);
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case PROVIDE_LOCAL_INFORMATION:
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (resultCode.value() == ResultCode.OK.value())) {
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getPliResponse(buf);
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                default:
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CatLog.d(this, "encodeOptionalTags() Unsupported Cmd details=" + cmdDet);
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "encodeOptionalTags() bad Cmd details=" + cmdDet);
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = ComprehensionTlvTag.DURATION.value();
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdInput.duration.timeInterval); // Time Duration
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void getPliResponse(ByteArrayOutputStream buf) {
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Locale Language Setting
645595c172c6fec75d287716ad404622db8ddb554ddNarayan Kamath        final String lang = Locale.getDefault().getLanguage();
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (lang != null) {
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tag
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int tag = ComprehensionTlvTag.LANGUAGE.value();
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(tag);
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResponseData.writeLength(buf, lang.length());
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(lang.getBytes(), 0, lang.length());
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendMenuSelection(int menuId, boolean helpRequired) {
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ByteArrayOutputStream buf = new ByteArrayOutputStream();
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // tag
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = BerTlv.BER_MENU_SELECTION_TAG;
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // length
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x00); // place holder
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // device identities
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_KEYPAD); // source device id
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_UICC); // destination device id
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // item identifier
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value();
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x01); // length
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(menuId); // menu identifier chosen
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // help request
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (helpRequired) {
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tag = ComprehensionTlvTag.HELP_REQUEST.value();
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(tag);
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(0x00); // length
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] rawData = buf.toByteArray();
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // write real length
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int len = rawData.length - 2; // minus (tag + length)
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        rawData[1] = (byte) len;
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String hexString = IccUtils.bytesToHexString(rawData);
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.sendEnvelope(hexString, null);
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
698734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    private void eventDownload(int event, int sourceId, int destinationId,
699734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            byte[] additionalInfo, boolean oneShot) {
700734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
701734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        ByteArrayOutputStream buf = new ByteArrayOutputStream();
702734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
703734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // tag
704734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG;
705734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(tag);
706734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
707734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // length
708734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(0x00); // place holder, assume length < 128.
709734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
710734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // event list
711734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value();
712734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(tag);
713734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(0x01); // length
714734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(event); // event value
715734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
716734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // device identities
717734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
718734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(tag);
719734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(0x02); // length
720734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(sourceId); // source device id
721734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(destinationId); // destination device id
722734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
723734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        /*
724734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Check for type of event download to be sent to UICC - Browser
725734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * termination,Idle screen available, User activity, Language selection
726734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * etc as mentioned under ETSI TS 102 223 section 7.5
727734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         */
728734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
729734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        /*
730734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Currently the below events are supported:
731734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Language Selection Event.
732734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Other event download commands should be encoded similar way
733734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         */
734734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        /* TODO: eventDownload should be extended for other Envelope Commands */
735734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        switch (event) {
7363ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja            case IDLE_SCREEN_AVAILABLE_EVENT:
7373ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                CatLog.d(sInstance, " Sending Idle Screen Available event download to ICC");
7383ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                break;
739734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            case LANGUAGE_SELECTION_EVENT:
740734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                CatLog.d(sInstance, " Sending Language Selection event download to ICC");
741734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                tag = 0x80 | ComprehensionTlvTag.LANGUAGE.value();
742734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                buf.write(tag);
743734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                // Language length should be 2 byte
744734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                buf.write(0x02);
745734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                break;
746734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            default:
747734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                break;
748734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        }
749734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
750734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // additional information
751734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        if (additionalInfo != null) {
752734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            for (byte b : additionalInfo) {
753734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                buf.write(b);
754734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            }
755734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        }
756734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
757734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        byte[] rawData = buf.toByteArray();
758734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
759734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // write real length
760734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        int len = rawData.length - 2; // minus (tag + length)
761734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        rawData[1] = (byte) len;
762734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
763734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        String hexString = IccUtils.bytesToHexString(rawData);
764734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
765734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        CatLog.d(this, "ENVELOPE COMMAND: " + hexString);
766734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
767734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        mCmdIf.sendEnvelope(hexString, null);
768734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    }
769734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
771a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Used by application to get an AppInterface object.
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The only Service object in the system
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
775a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //TODO Need to take care for MSIM
776a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static AppInterface getInstance() {
777a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int slotId = PhoneConstants.DEFAULT_CARD_INDEX;
778a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        SubscriptionController sControl = SubscriptionController.getInstance();
779a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sControl != null) {
78082e8da62fe3f83f29d834636b8da5ce6803204e3Sanket Padawe            slotId = sControl.getSlotIndex(sControl.getDefaultSubId());
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
782a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return getInstance(null, null, null, slotId);
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Used by application to get an AppInterface object.
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The only Service object in the system
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
790a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static AppInterface getInstance(int slotId) {
791a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return getInstance(null, null, null, slotId);
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
796a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "handleMessage[" + msg.what + "]");
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_SESSION_END:
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_PROACTIVE_COMMAND:
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_EVENT_NOTIFY:
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_REFRESH:
803a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            CatLog.d(this, "ril message arrived,slotid:" + mSlotId);
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String data = null;
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (msg.obj != null) {
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar != null && ar.result != null) {
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    try {
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        data = (String) ar.result;
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } catch (ClassCastException e) {
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_CALL_SETUP:
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_ICC_RECORDS_LOADED:
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_RIL_MSG_DECODED:
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleRilMsg((RilMessage) msg.obj);
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_RESPONSE:
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleCmdResponse((CatResponseMessage) msg.obj);
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
828eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        case MSG_ID_ICC_CHANGED:
829eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            CatLog.d(this, "MSG_ID_ICC_CHANGED");
830eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            updateIccAvailability();
831eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            break;
832eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        case MSG_ID_ICC_REFRESH:
833eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            if (msg.obj != null) {
834eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                AsyncResult ar = (AsyncResult) msg.obj;
835eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                if (ar != null && ar.result != null) {
836eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    broadcastCardStateAndIccRefreshResp(CardState.CARDSTATE_PRESENT,
837eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                                  (IccRefreshResponse) ar.result);
838eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                } else {
839eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    CatLog.d(this,"Icc REFRESH with exception: " + ar.exception);
840eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                }
841eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            } else {
842eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                CatLog.d(this, "IccRefresh Message is null");
843eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            }
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
84509b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        case MSG_ID_ALPHA_NOTIFY:
84609b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            CatLog.d(this, "Received CAT CC Alpha message from card");
84709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            if (msg.obj != null) {
84809b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                AsyncResult ar = (AsyncResult) msg.obj;
84909b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                if (ar != null && ar.result != null) {
85009b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                    broadcastAlphaMessage((String)ar.result);
85109b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                } else {
85209b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                    CatLog.d(this, "CAT Alpha message: ar.result is null");
85309b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                }
85409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            } else {
85509b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                CatLog.d(this, "CAT Alpha message: msg.obj is null");
85609b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            }
85709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            break;
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new AssertionError("Unrecognized CAT command: " + msg.what);
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
863eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    /**
864eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** This function sends a CARD status (ABSENT, PRESENT, REFRESH) to STK_APP.
865eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** This is triggered during ICC_REFRESH or CARD STATE changes. In case
866eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** REFRESH, additional information is sent in 'refresh_result'
867eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     **
868eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     **/
869eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private void  broadcastCardStateAndIccRefreshResp(CardState cardState,
870eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            IccRefreshResponse iccRefreshState) {
871eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        Intent intent = new Intent(AppInterface.CAT_ICC_STATUS_CHANGE);
872eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        boolean cardPresent = (cardState == CardState.CARDSTATE_PRESENT);
873eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
874eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (iccRefreshState != null) {
875eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            //This case is when MSG_ID_ICC_REFRESH is received.
876eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            intent.putExtra(AppInterface.REFRESH_RESULT, iccRefreshState.refreshResult);
877eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            CatLog.d(this, "Sending IccResult with Result: "
878eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    + iccRefreshState.refreshResult);
879eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
880eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
881eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        // This sends an intent with CARD_ABSENT (0 - false) /CARD_PRESENT (1 - true).
882eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        intent.putExtra(AppInterface.CARD_STATUS, cardPresent);
883685aaba80c3dee5daf0df761ed100221cf9f7cd4fionaxu        intent.setComponent(AppInterface.getDefaultSTKApplication());
884eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CatLog.d(this, "Sending Card Status: "
885eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                + cardState + " " + "cardPresent: " + cardPresent);
886d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
88709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja    }
888eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
88909b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja    private void broadcastAlphaMessage(String alphaString) {
89009b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        CatLog.d(this, "Broadcasting CAT Alpha message from card: " + alphaString);
89109b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        Intent intent = new Intent(AppInterface.CAT_ALPHA_NOTIFY_ACTION);
89209b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
89309b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.putExtra(AppInterface.ALPHA_STRING, alphaString);
89409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.putExtra("SLOT_ID", mSlotId);
895685aaba80c3dee5daf0df761ed100221cf9f7cd4fionaxu        intent.setComponent(AppInterface.getDefaultSTKApplication());
896d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
897eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    }
898eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public synchronized void onCmdResponse(CatResponseMessage resMsg) {
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (resMsg == null) {
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // queue a response message.
90522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Message msg = obtainMessage(MSG_ID_RESPONSE, resMsg);
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.sendToTarget();
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean validateResponse(CatResponseMessage resMsg) {
910734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        boolean validResponse = false;
911734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        if ((resMsg.mCmdDet.typeOfCommand == CommandType.SET_UP_EVENT_LIST.value())
912734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                || (resMsg.mCmdDet.typeOfCommand == CommandType.SET_UP_MENU.value())) {
913734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            CatLog.d(this, "CmdType: " + resMsg.mCmdDet.typeOfCommand);
914734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            validResponse = true;
915734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        } else if (mCurrntCmd != null) {
916734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            validResponse = resMsg.mCmdDet.compareTo(mCurrntCmd.mCmdDet);
917734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            CatLog.d(this, "isResponse for last valid cmd: " + validResponse);
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
919734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        return validResponse;
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean removeMenu(Menu menu) {
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (menu.items.size() == 1 && menu.items.get(0) == null) {
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (NullPointerException e) {
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "Unable to get Menu's items size");
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleCmdResponse(CatResponseMessage resMsg) {
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Make sure the response details match the last valid command. An invalid
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // response is a one that doesn't have a corresponding proactive command
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // and sending it can "confuse" the baseband/ril.
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // One reason for out of order responses can be UI glitches. For example,
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if the application launch an activity, and that activity is stored
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // by the framework inside the history stack. That activity will be
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // available for relaunch using the latest application dialog
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // (long press on the home button). Relaunching that activity can send
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the same command's result again to the CatService and can cause it to
944734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // get out of sync with the SIM. This can happen in case of
945734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // non-interactive type Setup Event List and SETUP_MENU proactive commands.
946734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // Stk framework would have already sent Terminal Response to Setup Event
947734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // List and SETUP_MENU proactive commands. After sometime Stk app will send
948734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // Envelope Command/Event Download. In which case, the response details doesn't
949734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // match with last valid command (which are not related).
950734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // However, we should allow Stk framework to send the message to ICC.
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!validateResponse(resMsg)) {
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ResponseData resp = null;
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean helpRequired = false;
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandDetails cmdDet = resMsg.getCmdDetails();
95714957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        AppInterface.CommandType type = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
95922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch (resMsg.mResCode) {
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case HELP_INFO_REQUIRED:
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            helpRequired = true;
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // fall through
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case OK:
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_PARTIAL_COMPREHENSION:
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_MISSING_INFO:
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_ADDITIONAL_EFS_READ:
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_ICON_NOT_DISPLAYED:
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_MODIFIED_BY_NAA:
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_LIMITED_SERVICE:
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_MODIFICATION:
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_NAA_NOT_ACTIVE:
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_TONE_NOT_PLAYED:
9730bb8799f15d25a577bc271cb6e89ba5e43c4a672Preeti Ahuja        case LAUNCH_BROWSER_ERROR:
9742d7aad7791b92186dabc779b3ab43794aceebcdaGuillaume Lucas        case TERMINAL_CRNTLY_UNABLE_TO_PROCESS:
97514957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            switch (type) {
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_MENU:
97722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                helpRequired = resMsg.mResCode == ResultCode.HELP_INFO_REQUIRED;
97822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sendMenuSelection(resMsg.mUsersMenuSelection, helpRequired);
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SELECT_ITEM:
98122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                resp = new SelectItemResponseData(resMsg.mUsersMenuSelection);
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INPUT:
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INKEY:
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Input input = mCurrntCmd.geInput();
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!input.yesNo) {
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // when help is requested there is no need to send the text
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // string object.
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (!helpRequired) {
99022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        resp = new GetInkeyInputResponseData(resMsg.mUsersInput,
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                input.ucs2, input.packed);
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    resp = new GetInkeyInputResponseData(
99522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            resMsg.mUsersYesNoSelection);
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DISPLAY_TEXT:
9993ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                if (resMsg.mResCode == ResultCode.TERMINAL_CRNTLY_UNABLE_TO_PROCESS) {
10003ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    // For screenbusy case there will be addtional information in the terminal
10013ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    // response. And the value of the additional information byte is 0x01.
10023ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    resMsg.setAdditionalInfo(0x01);
10033ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                } else {
10043ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    resMsg.mIncludeAdditionalInfo = false;
10053ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    resMsg.mAdditionalInfo = 0;
10063ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                }
1007734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                break;
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case LAUNCH_BROWSER:
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
1010419f297bfb0cc21566d1d1110573dd9205e8f713Shriram Ganesh            // 3GPP TS.102.223: Open Channel alpha confirmation should not send TR
1011419f297bfb0cc21566d1d1110573dd9205e8f713Shriram Ganesh            case OPEN_CHANNEL:
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_CALL:
101322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCmdIf.handleCallSetupRequestFromSim(resMsg.mUsersConfirm, null);
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // No need to send terminal response for SET UP CALL. The user's
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // confirmation result is send back using a dedicated ril message
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // invoked by the CommandInterface call above.
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCurrntCmd = null;
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
1019734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            case SET_UP_EVENT_LIST:
10203ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                if (IDLE_SCREEN_AVAILABLE_EVENT == resMsg.mEventValue) {
10213ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    eventDownload(resMsg.mEventValue, DEV_ID_DISPLAY, DEV_ID_UICC,
10223ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                            resMsg.mAddedInfo, false);
10233ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                 } else {
10243ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                     eventDownload(resMsg.mEventValue, DEV_ID_TERMINAL, DEV_ID_UICC,
10253ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                            resMsg.mAddedInfo, false);
10263ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                 }
1027734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                // No need to send the terminal response after event download.
1028734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                return;
1029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            default:
1030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case BACKWARD_MOVE_BY_USER:
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case USER_NOT_ACCEPT:
103514957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // if the user dismissed the alert dialog for a
103614957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // setup call/open channel, consider that as the user
103714957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // rejecting the call. Use dedicated API for this, rather than
103814957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // sending a terminal response.
103914957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            if (type == CommandType.SET_UP_CALL || type == CommandType.OPEN_CHANNEL) {
104014957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                mCmdIf.handleCallSetupRequestFromSim(false, null);
104114957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                mCurrntCmd = null;
104214957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                return;
104314957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            } else {
104414957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                resp = null;
104514957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            }
104614957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            break;
104714957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        case NO_RESPONSE_FROM_USER:
104814957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        case UICC_SESSION_TERM_BY_USER:
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resp = null;
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
105422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        sendTerminalResponse(cmdDet, resMsg.mResCode, resMsg.mIncludeAdditionalInfo,
105522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                resMsg.mAdditionalInfo, resp);
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = null;
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean isStkAppInstalled() {
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PackageManager pm = mContext.getPackageManager();
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<ResolveInfo> broadcastReceivers =
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA);
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size();
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (numReceiver > 0);
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update(CommandsInterface ci,
1070a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Context context, UiccCard ic) {
1071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        UiccCardApplication ca = null;
1072a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords ir = null;
1073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1074a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (ic != null) {
1075a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            /* Since Cat is not tied to any application, but rather is Uicc application
1076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             * in itself - just get first FileHandler and IccRecords object
1077a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             */
1078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ca = ic.getApplicationIndex(0);
1079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (ca != null) {
1080a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ir = ca.getIccRecords();
1081a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1082a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1083a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1084a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (sInstanceLock) {
1085a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if ((ir != null) && (mIccRecords != ir)) {
1086a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mIccRecords != null) {
1087a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mIccRecords.unregisterForRecordsLoaded(this);
1088a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1089a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1090a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                CatLog.d(this,
1091a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        "Reinitialize the Service with SIMRecords and UiccCardApplication");
1092a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mIccRecords = ir;
1093a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUiccApplication = ca;
1094a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // re-Register for SIM ready event.
1096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
1097ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                CatLog.d(this, "registerForRecordsLoaded slotid=" + mSlotId + " instance:" + this);
1098a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1099a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1101eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
1102eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    void updateIccAvailability() {
1103eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (null == mUiccController) {
1104eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            return;
1105eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
1106eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
1107eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CardState newState = CardState.CARDSTATE_ABSENT;
11081f22d77839c35908113e4978a1431636be0786acduho.ro        UiccCard newCard = mUiccController.getUiccCard(mSlotId);
1109eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (newCard != null) {
1110eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            newState = newCard.getCardState();
1111eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
1112eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CardState oldState = mCardState;
1113eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mCardState = newState;
1114eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CatLog.d(this,"New Card State = " + newState + " " + "Old Card State = " + oldState);
1115eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (oldState == CardState.CARDSTATE_PRESENT &&
1116eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                newState != CardState.CARDSTATE_PRESENT) {
1117eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            broadcastCardStateAndIccRefreshResp(newState, null);
1118eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        } else if (oldState != CardState.CARDSTATE_PRESENT &&
1119eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                newState == CardState.CARDSTATE_PRESENT) {
1120eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            // Card moved to PRESENT STATE.
1121eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mCmdIf.reportStkServiceIsRunning(null);
1122eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
1123eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    }
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1125