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) {
261ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                if (SubscriptionManager.isValidSlotId(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);
516a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "Sending CmdMsg: " + cmdMsg+ " on slotid:" + mSlotId);
517d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL.
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleSessionEnd() {
525a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "SESSION END on "+ mSlotId);
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = mMenuCmd;
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
529a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra("SLOT_ID", mSlotId);
530d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendTerminalResponse(CommandDetails cmdDet,
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResultCode resultCode, boolean includeAdditionalInfo,
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int additionalInfo, ResponseData resp) {
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdDet == null) {
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ByteArrayOutputStream buf = new ByteArrayOutputStream();
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Input cmdInput = null;
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mCurrntCmd != null) {
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmdInput = mCurrntCmd.geInput();
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // command details
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdDet.compRequired) {
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tag |= 0x80;
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x03); // length
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.commandNumber);
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.typeOfCommand);
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdDet.commandQualifier);
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // device identities
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // According to TS102.223/TS31.111 section 6.8 Structure of
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the ME should set the CR(comprehension required) flag to
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // comprehension not required.(CR=0)"
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the CR flag is not set.
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_TERMINAL); // source device id
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_UICC); // destination device id
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // result
5738316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        tag = ComprehensionTlvTag.RESULT.value();
5748316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        if (cmdDet.compRequired) {
5758316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta            tag |= 0x80;
5768316a9897794e4b608e7917af701fafc34c9276eSandeep Kunta        }
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int length = includeAdditionalInfo ? 2 : 1;
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(length);
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(resultCode.value());
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // additional info
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (includeAdditionalInfo) {
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(additionalInfo);
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Fill optional data for each corresponding command
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (resp != null) {
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resp.format(buf);
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] rawData = buf.toByteArray();
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String hexString = IccUtils.bytesToHexString(rawData);
596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.sendTerminalResponse(hexString, null);
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void encodeOptionalTags(CommandDetails cmdDet,
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmdType != null) {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (cmdType) {
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case GET_INKEY:
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // ETSI TS 102 384,27.22.4.2.8.4.2.
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If it is a response for GET_INKEY command and the response timeout
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // occured, then add DURATION TLV for variable timeout case.
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (cmdInput != null) && (cmdInput.duration != null)) {
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getInKeyResponse(buf, cmdInput);
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case PROVIDE_LOCAL_INFORMATION:
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (resultCode.value() == ResultCode.OK.value())) {
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getPliResponse(buf);
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                default:
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CatLog.d(this, "encodeOptionalTags() Unsupported Cmd details=" + cmdDet);
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "encodeOptionalTags() bad Cmd details=" + cmdDet);
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = ComprehensionTlvTag.DURATION.value();
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(cmdInput.duration.timeInterval); // Time Duration
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void getPliResponse(ByteArrayOutputStream buf) {
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Locale Language Setting
643595c172c6fec75d287716ad404622db8ddb554ddNarayan Kamath        final String lang = Locale.getDefault().getLanguage();
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (lang != null) {
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tag
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int tag = ComprehensionTlvTag.LANGUAGE.value();
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(tag);
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ResponseData.writeLength(buf, lang.length());
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(lang.getBytes(), 0, lang.length());
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendMenuSelection(int menuId, boolean helpRequired) {
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ByteArrayOutputStream buf = new ByteArrayOutputStream();
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // tag
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int tag = BerTlv.BER_MENU_SELECTION_TAG;
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // length
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x00); // place holder
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // device identities
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x02); // length
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_KEYPAD); // source device id
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(DEV_ID_UICC); // destination device id
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // item identifier
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value();
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(tag);
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(0x01); // length
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf.write(menuId); // menu identifier chosen
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // help request
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (helpRequired) {
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tag = ComprehensionTlvTag.HELP_REQUEST.value();
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(tag);
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf.write(0x00); // length
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] rawData = buf.toByteArray();
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // write real length
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int len = rawData.length - 2; // minus (tag + length)
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        rawData[1] = (byte) len;
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String hexString = IccUtils.bytesToHexString(rawData);
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdIf.sendEnvelope(hexString, null);
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
696734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    private void eventDownload(int event, int sourceId, int destinationId,
697734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            byte[] additionalInfo, boolean oneShot) {
698734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
699734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        ByteArrayOutputStream buf = new ByteArrayOutputStream();
700734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
701734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // tag
702734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG;
703734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(tag);
704734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
705734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // length
706734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(0x00); // place holder, assume length < 128.
707734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
708734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // event list
709734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value();
710734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(tag);
711734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(0x01); // length
712734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(event); // event value
713734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
714734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // device identities
715734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
716734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(tag);
717734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(0x02); // length
718734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(sourceId); // source device id
719734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        buf.write(destinationId); // destination device id
720734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
721734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        /*
722734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Check for type of event download to be sent to UICC - Browser
723734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * termination,Idle screen available, User activity, Language selection
724734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * etc as mentioned under ETSI TS 102 223 section 7.5
725734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         */
726734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
727734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        /*
728734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Currently the below events are supported:
729734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Language Selection Event.
730734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         * Other event download commands should be encoded similar way
731734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja         */
732734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        /* TODO: eventDownload should be extended for other Envelope Commands */
733734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        switch (event) {
7343ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja            case IDLE_SCREEN_AVAILABLE_EVENT:
7353ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                CatLog.d(sInstance, " Sending Idle Screen Available event download to ICC");
7363ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                break;
737734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            case LANGUAGE_SELECTION_EVENT:
738734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                CatLog.d(sInstance, " Sending Language Selection event download to ICC");
739734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                tag = 0x80 | ComprehensionTlvTag.LANGUAGE.value();
740734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                buf.write(tag);
741734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                // Language length should be 2 byte
742734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                buf.write(0x02);
743734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                break;
744734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            default:
745734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                break;
746734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        }
747734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
748734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // additional information
749734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        if (additionalInfo != null) {
750734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            for (byte b : additionalInfo) {
751734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                buf.write(b);
752734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            }
753734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        }
754734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
755734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        byte[] rawData = buf.toByteArray();
756734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
757734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // write real length
758734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        int len = rawData.length - 2; // minus (tag + length)
759734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        rawData[1] = (byte) len;
760734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
761734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        String hexString = IccUtils.bytesToHexString(rawData);
762734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
763734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        CatLog.d(this, "ENVELOPE COMMAND: " + hexString);
764734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
765734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        mCmdIf.sendEnvelope(hexString, null);
766734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja    }
767734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
769a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Used by application to get an AppInterface object.
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The only Service object in the system
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
773a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //TODO Need to take care for MSIM
774a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static AppInterface getInstance() {
775a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int slotId = PhoneConstants.DEFAULT_CARD_INDEX;
776a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        SubscriptionController sControl = SubscriptionController.getInstance();
777a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sControl != null) {
778a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            slotId = sControl.getSlotId(sControl.getDefaultSubId());
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
780a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return getInstance(null, null, null, slotId);
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Used by application to get an AppInterface object.
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The only Service object in the system
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
788a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static AppInterface getInstance(int slotId) {
789a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return getInstance(null, null, null, slotId);
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
794a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        CatLog.d(this, "handleMessage[" + msg.what + "]");
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_SESSION_END:
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_PROACTIVE_COMMAND:
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_EVENT_NOTIFY:
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_REFRESH:
801a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            CatLog.d(this, "ril message arrived,slotid:" + mSlotId);
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String data = null;
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (msg.obj != null) {
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar != null && ar.result != null) {
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    try {
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        data = (String) ar.result;
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } catch (ClassCastException e) {
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_CALL_SETUP:
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_ICC_RECORDS_LOADED:
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_RIL_MSG_DECODED:
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleRilMsg((RilMessage) msg.obj);
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case MSG_ID_RESPONSE:
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleCmdResponse((CatResponseMessage) msg.obj);
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
826eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        case MSG_ID_ICC_CHANGED:
827eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            CatLog.d(this, "MSG_ID_ICC_CHANGED");
828eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            updateIccAvailability();
829eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            break;
830eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        case MSG_ID_ICC_REFRESH:
831eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            if (msg.obj != null) {
832eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                AsyncResult ar = (AsyncResult) msg.obj;
833eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                if (ar != null && ar.result != null) {
834eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    broadcastCardStateAndIccRefreshResp(CardState.CARDSTATE_PRESENT,
835eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                                  (IccRefreshResponse) ar.result);
836eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                } else {
837eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    CatLog.d(this,"Icc REFRESH with exception: " + ar.exception);
838eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                }
839eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            } else {
840eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                CatLog.d(this, "IccRefresh Message is null");
841eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            }
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
84309b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        case MSG_ID_ALPHA_NOTIFY:
84409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            CatLog.d(this, "Received CAT CC Alpha message from card");
84509b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            if (msg.obj != null) {
84609b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                AsyncResult ar = (AsyncResult) msg.obj;
84709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                if (ar != null && ar.result != null) {
84809b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                    broadcastAlphaMessage((String)ar.result);
84909b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                } else {
85009b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                    CatLog.d(this, "CAT Alpha message: ar.result is null");
85109b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                }
85209b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            } else {
85309b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja                CatLog.d(this, "CAT Alpha message: msg.obj is null");
85409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            }
85509b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja            break;
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new AssertionError("Unrecognized CAT command: " + msg.what);
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
861eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    /**
862eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** This function sends a CARD status (ABSENT, PRESENT, REFRESH) to STK_APP.
863eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** This is triggered during ICC_REFRESH or CARD STATE changes. In case
864eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     ** REFRESH, additional information is sent in 'refresh_result'
865eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     **
866eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta     **/
867eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    private void  broadcastCardStateAndIccRefreshResp(CardState cardState,
868eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            IccRefreshResponse iccRefreshState) {
869eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        Intent intent = new Intent(AppInterface.CAT_ICC_STATUS_CHANGE);
870eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        boolean cardPresent = (cardState == CardState.CARDSTATE_PRESENT);
871eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
872eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (iccRefreshState != null) {
873eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            //This case is when MSG_ID_ICC_REFRESH is received.
874eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            intent.putExtra(AppInterface.REFRESH_RESULT, iccRefreshState.refreshResult);
875eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            CatLog.d(this, "Sending IccResult with Result: "
876eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                    + iccRefreshState.refreshResult);
877eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
878eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
879eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        // This sends an intent with CARD_ABSENT (0 - false) /CARD_PRESENT (1 - true).
880eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        intent.putExtra(AppInterface.CARD_STATUS, cardPresent);
881eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CatLog.d(this, "Sending Card Status: "
882eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                + cardState + " " + "cardPresent: " + cardPresent);
883d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
88409b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja    }
885eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
88609b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja    private void broadcastAlphaMessage(String alphaString) {
88709b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        CatLog.d(this, "Broadcasting CAT Alpha message from card: " + alphaString);
88809b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        Intent intent = new Intent(AppInterface.CAT_ALPHA_NOTIFY_ACTION);
88909b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
89009b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.putExtra(AppInterface.ALPHA_STRING, alphaString);
89109b65da3b46e18c8acc146d722047ba2fb161bfePreeti Ahuja        intent.putExtra("SLOT_ID", mSlotId);
892d607cf3bc9ac43900dd4c87b86b2dbe5fabc3249Amit Mahajan        mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
893eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    }
894eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public synchronized void onCmdResponse(CatResponseMessage resMsg) {
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (resMsg == null) {
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // queue a response message.
90122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Message msg = obtainMessage(MSG_ID_RESPONSE, resMsg);
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.sendToTarget();
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean validateResponse(CatResponseMessage resMsg) {
906734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        boolean validResponse = false;
907734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        if ((resMsg.mCmdDet.typeOfCommand == CommandType.SET_UP_EVENT_LIST.value())
908734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                || (resMsg.mCmdDet.typeOfCommand == CommandType.SET_UP_MENU.value())) {
909734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            CatLog.d(this, "CmdType: " + resMsg.mCmdDet.typeOfCommand);
910734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            validResponse = true;
911734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        } else if (mCurrntCmd != null) {
912734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            validResponse = resMsg.mCmdDet.compareTo(mCurrntCmd.mCmdDet);
913734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            CatLog.d(this, "isResponse for last valid cmd: " + validResponse);
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
915734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        return validResponse;
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean removeMenu(Menu menu) {
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (menu.items.size() == 1 && menu.items.get(0) == null) {
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (NullPointerException e) {
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CatLog.d(this, "Unable to get Menu's items size");
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleCmdResponse(CatResponseMessage resMsg) {
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Make sure the response details match the last valid command. An invalid
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // response is a one that doesn't have a corresponding proactive command
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // and sending it can "confuse" the baseband/ril.
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // One reason for out of order responses can be UI glitches. For example,
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if the application launch an activity, and that activity is stored
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // by the framework inside the history stack. That activity will be
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // available for relaunch using the latest application dialog
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // (long press on the home button). Relaunching that activity can send
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the same command's result again to the CatService and can cause it to
940734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // get out of sync with the SIM. This can happen in case of
941734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // non-interactive type Setup Event List and SETUP_MENU proactive commands.
942734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // Stk framework would have already sent Terminal Response to Setup Event
943734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // List and SETUP_MENU proactive commands. After sometime Stk app will send
944734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // Envelope Command/Event Download. In which case, the response details doesn't
945734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // match with last valid command (which are not related).
946734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja        // However, we should allow Stk framework to send the message to ICC.
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!validateResponse(resMsg)) {
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ResponseData resp = null;
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean helpRequired = false;
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CommandDetails cmdDet = resMsg.getCmdDetails();
95314957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        AppInterface.CommandType type = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
95522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch (resMsg.mResCode) {
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case HELP_INFO_REQUIRED:
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            helpRequired = true;
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // fall through
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case OK:
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_PARTIAL_COMPREHENSION:
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_MISSING_INFO:
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_ADDITIONAL_EFS_READ:
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_ICON_NOT_DISPLAYED:
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_MODIFIED_BY_NAA:
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_LIMITED_SERVICE:
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_WITH_MODIFICATION:
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_NAA_NOT_ACTIVE:
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PRFRMD_TONE_NOT_PLAYED:
9690bb8799f15d25a577bc271cb6e89ba5e43c4a672Preeti Ahuja        case LAUNCH_BROWSER_ERROR:
9702d7aad7791b92186dabc779b3ab43794aceebcdaGuillaume Lucas        case TERMINAL_CRNTLY_UNABLE_TO_PROCESS:
97114957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            switch (type) {
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_MENU:
97322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                helpRequired = resMsg.mResCode == ResultCode.HELP_INFO_REQUIRED;
97422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sendMenuSelection(resMsg.mUsersMenuSelection, helpRequired);
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SELECT_ITEM:
97722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                resp = new SelectItemResponseData(resMsg.mUsersMenuSelection);
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INPUT:
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case GET_INKEY:
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Input input = mCurrntCmd.geInput();
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!input.yesNo) {
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // when help is requested there is no need to send the text
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // string object.
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (!helpRequired) {
98622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        resp = new GetInkeyInputResponseData(resMsg.mUsersInput,
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                input.ucs2, input.packed);
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    resp = new GetInkeyInputResponseData(
99122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            resMsg.mUsersYesNoSelection);
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DISPLAY_TEXT:
9953ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                if (resMsg.mResCode == ResultCode.TERMINAL_CRNTLY_UNABLE_TO_PROCESS) {
9963ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    // For screenbusy case there will be addtional information in the terminal
9973ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    // response. And the value of the additional information byte is 0x01.
9983ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    resMsg.setAdditionalInfo(0x01);
9993ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                } else {
10003ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    resMsg.mIncludeAdditionalInfo = false;
10013ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    resMsg.mAdditionalInfo = 0;
10023ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                }
1003734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                break;
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case LAUNCH_BROWSER:
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
1006419f297bfb0cc21566d1d1110573dd9205e8f713Shriram Ganesh            // 3GPP TS.102.223: Open Channel alpha confirmation should not send TR
1007419f297bfb0cc21566d1d1110573dd9205e8f713Shriram Ganesh            case OPEN_CHANNEL:
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SET_UP_CALL:
100922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCmdIf.handleCallSetupRequestFromSim(resMsg.mUsersConfirm, null);
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // No need to send terminal response for SET UP CALL. The user's
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // confirmation result is send back using a dedicated ril message
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // invoked by the CommandInterface call above.
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCurrntCmd = null;
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
1015734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja            case SET_UP_EVENT_LIST:
10163ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                if (IDLE_SCREEN_AVAILABLE_EVENT == resMsg.mEventValue) {
10173ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                    eventDownload(resMsg.mEventValue, DEV_ID_DISPLAY, DEV_ID_UICC,
10183ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                            resMsg.mAddedInfo, false);
10193ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                 } else {
10203ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                     eventDownload(resMsg.mEventValue, DEV_ID_TERMINAL, DEV_ID_UICC,
10213ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                            resMsg.mAddedInfo, false);
10223ffd9ad50690a7bdfb3c7df56fce27fb11bf7d7fPreeti Ahuja                 }
1023734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                // No need to send the terminal response after event download.
1024734900afa3a8e35d3a75786dc59f91b6f3136157Preeti Ahuja                return;
1025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            default:
1026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case BACKWARD_MOVE_BY_USER:
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case USER_NOT_ACCEPT:
103114957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // if the user dismissed the alert dialog for a
103214957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // setup call/open channel, consider that as the user
103314957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // rejecting the call. Use dedicated API for this, rather than
103414957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            // sending a terminal response.
103514957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            if (type == CommandType.SET_UP_CALL || type == CommandType.OPEN_CHANNEL) {
103614957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                mCmdIf.handleCallSetupRequestFromSim(false, null);
103714957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                mCurrntCmd = null;
103814957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                return;
103914957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            } else {
104014957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa                resp = null;
104114957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            }
104214957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa            break;
104314957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        case NO_RESPONSE_FROM_USER:
104414957f5b0b202fc80782944c962d282ed1866837Abhishek Adappa        case UICC_SESSION_TERM_BY_USER:
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resp = null;
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
105022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        sendTerminalResponse(cmdDet, resMsg.mResCode, resMsg.mIncludeAdditionalInfo,
105122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                resMsg.mAdditionalInfo, resp);
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrntCmd = null;
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean isStkAppInstalled() {
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PackageManager pm = mContext.getPackageManager();
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<ResolveInfo> broadcastReceivers =
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA);
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size();
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (numReceiver > 0);
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1064a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1065a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update(CommandsInterface ci,
1066a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Context context, UiccCard ic) {
1067a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        UiccCardApplication ca = null;
1068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords ir = null;
1069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1070a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (ic != null) {
1071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            /* Since Cat is not tied to any application, but rather is Uicc application
1072a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             * in itself - just get first FileHandler and IccRecords object
1073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville             */
1074a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ca = ic.getApplicationIndex(0);
1075a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (ca != null) {
1076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ir = ca.getIccRecords();
1077a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1080a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (sInstanceLock) {
1081a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if ((ir != null) && (mIccRecords != ir)) {
1082a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mIccRecords != null) {
1083a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mIccRecords.unregisterForRecordsLoaded(this);
1084a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1085a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1086a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                CatLog.d(this,
1087a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        "Reinitialize the Service with SIMRecords and UiccCardApplication");
1088a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mIccRecords = ir;
1089a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUiccApplication = ca;
1090a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1091a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // re-Register for SIM ready event.
1092a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
1093ae798a22222a7e6ee5c47cd789838b3e915d1f13Legler Wu                CatLog.d(this, "registerForRecordsLoaded slotid=" + mSlotId + " instance:" + this);
1094a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1097eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
1098eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    void updateIccAvailability() {
1099eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (null == mUiccController) {
1100eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            return;
1101eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
1102eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta
1103eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CardState newState = CardState.CARDSTATE_ABSENT;
11041f22d77839c35908113e4978a1431636be0786acduho.ro        UiccCard newCard = mUiccController.getUiccCard(mSlotId);
1105eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (newCard != null) {
1106eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            newState = newCard.getCardState();
1107eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
1108eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CardState oldState = mCardState;
1109eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        mCardState = newState;
1110eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        CatLog.d(this,"New Card State = " + newState + " " + "Old Card State = " + oldState);
1111eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        if (oldState == CardState.CARDSTATE_PRESENT &&
1112eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                newState != CardState.CARDSTATE_PRESENT) {
1113eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            broadcastCardStateAndIccRefreshResp(newState, null);
1114eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        } else if (oldState != CardState.CARDSTATE_PRESENT &&
1115eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta                newState == CardState.CARDSTATE_PRESENT) {
1116eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            // Card moved to PRESENT STATE.
1117eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta            mCmdIf.reportStkServiceIsRunning(null);
1118eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta        }
1119eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta    }
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1121