19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.telephony.gsm;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.*;
21767a662ecde33c3979bf02b793d392aca0403162Wink Saville
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.*;
23767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.telephony.PhoneNumberUtils;
24767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.text.SpannableStringBuilder;
25767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.text.TextUtils;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
27767a662ecde33c3979bf02b793d392aca0403162Wink Saville
28767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport static com.android.internal.telephony.CommandsInterface.*;
29767a662ecde33c3979bf02b793d392aca0403162Wink Saville
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Matcher;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The motto for this file is:
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
36767a662ecde33c3979bf02b793d392aca0403162Wink Saville * "NOTE:    By using the # as a separator, most cases are expected to be unambiguous."
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   -- TS 22.030 6.5.2
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
42390de220248d05ccb9dc10a197700ad3c1595937Jake Hambypublic final class GsmMmiCode extends Handler implements MmiCode {
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String LOG_TAG = "GSM";
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Constants
46767a662ecde33c3979bf02b793d392aca0403162Wink Saville
470b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2)
480b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    static final int MAX_LENGTH_SHORT_CODE = 2;
490b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros
500b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    // TS 22.030 6.5.2 Every Short String USSD command will end with #-key
510b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    // (known as #-String)
520b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    static final char END_OF_USSD_COMMAND = '#';
530b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // From TS 22.030 6.5.2
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String ACTION_ACTIVATE = "*";
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String ACTION_DEACTIVATE = "#";
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String ACTION_INTERROGATE = "*#";
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String ACTION_REGISTER = "**";
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String ACTION_ERASURE = "##";
60767a662ecde33c3979bf02b793d392aca0403162Wink Saville
61390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby    // Supp Service codes from TS 22.030 Annex B
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //Called line presentation
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CLIP    = "30";
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CLIR    = "31";
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Call Forwarding
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CFU     = "21";
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CFB     = "67";
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CFNRy   = "61";
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CFNR    = "62";
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CF_All = "002";
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_CF_All_Conditional = "004";
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Call Waiting
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_WAIT     = "43";
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Call Barring
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BAOC         = "33";
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BAOIC        = "331";
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BAOICxH      = "332";
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BAIC         = "35";
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BAICr        = "351";
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BA_ALL       = "330";
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BA_MO        = "333";
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_BA_MT        = "353";
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Supp Service Password registration
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_PWD          = "03";
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // PIN/PIN2/PUK/PUK2
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_PIN          = "04";
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_PIN2         = "042";
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_PUK          = "05";
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String SC_PUK2         = "052";
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Event Constants
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_SET_COMPLETE         = 1;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_GET_CLIR_COMPLETE    = 2;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_QUERY_CF_COMPLETE    = 3;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_USSD_COMPLETE        = 4;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_QUERY_COMPLETE       = 5;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_SET_CFF_COMPLETE     = 6;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_USSD_CANCEL_COMPLETE = 7;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Instance Variables
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GSMPhone phone;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Context context;
113767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String action;              // One of ACTION_*
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String sc;                  // Service Code
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String sia, sib, sic;       // Service Info a,b,c
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String poundString;         // Entire MMI string up to and including #
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String dialingNumber;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String pwd;                 // For password registration
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
121767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /** Set to true in processCode, not at newFromDialString time */
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean isPendingUSSD;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean isUssdRequest;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
126767a662ecde33c3979bf02b793d392aca0403162Wink Saville    State state = State.PENDING;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CharSequence message;
128767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Class Variables
130767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // See TS 22.030 6.5.2 "Structure of the MMI"
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static Pattern sPatternSuppService = Pattern.compile(
135269081781573ac6f830c00b24efe3cf8af80bd32John Wang        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)([^#]*)");
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*       1  2                    3          4  5       6   7         8    9     10  11             12
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         1 = Full string up to and including #
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         2 = action (activation/interrogation/registration/erasure)
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         3 = service code
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         5 = SIA
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         7 = SIB
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         9 = SIC
144269081781573ac6f830c00b24efe3cf8af80bd32John Wang         10 = dialing number which must not include #, e.g. *SCn*SI#DN format
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
147767a662ecde33c3979bf02b793d392aca0403162Wink Saville    static final int MATCH_GROUP_POUND_STRING = 1;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
149767a662ecde33c3979bf02b793d392aca0403162Wink Saville    static final int MATCH_GROUP_ACTION = 2;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        //(activation/interrogation/registration/erasure)
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MATCH_GROUP_SERVICE_CODE = 3;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MATCH_GROUP_SIA = 5;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MATCH_GROUP_SIB = 7;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MATCH_GROUP_SIC = 9;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MATCH_GROUP_PWD_CONFIRM = 11;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MATCH_GROUP_DIALING_NUMBER = 12;
1580a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff    static private String[] sTwoDigitNumberPattern;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Public Class methods
161767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Some dial strings in GSM are defined to do non-call setup
164390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby     * things, such as modify or query supplementary service settings (eg, call
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * forwarding). These are generally referred to as "MMI codes".
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * We look to see if the dial string contains a valid MMI code (potentially
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with a dial string at the end as well) and return info here.
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If the dial string contains no MMI code, we return an instance with
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * only "dialingNumber" set
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Please see flow chart in TS 22.030 6.5.3.2
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
175767a662ecde33c3979bf02b793d392aca0403162Wink Saville    static GsmMmiCode
176767a662ecde33c3979bf02b793d392aca0403162Wink Saville    newFromDialString(String dialString, GSMPhone phone) {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Matcher m;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GsmMmiCode ret = null;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        m = sPatternSuppService.matcher(dialString);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Is this formatted like a standard supplementary service code?
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (m.matches()) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret = new GsmMmiCode(phone);
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (dialString.endsWith("#")) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // TS 22.030 sec 6.5.3.2
196767a662ecde33c3979bf02b793d392aca0403162Wink Saville            // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND".
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret = new GsmMmiCode(phone);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.poundString = dialString;
2010a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        } else if (isTwoDigitShortCode(phone.getContext(), dialString)) {
2020a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff            //Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2
2030a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff            ret = null;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (isShortCode(dialString, phone)) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this may be a short code, as defined in TS 22.030, 6.5.3.2
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret = new GsmMmiCode(phone);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.dialingNumber = dialString;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static GsmMmiCode
214767a662ecde33c3979bf02b793d392aca0403162Wink Saville    newNetworkInitiatedUssd (String ussdMessage,
215767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                boolean isUssdRequest, GSMPhone phone) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GsmMmiCode ret;
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ret = new GsmMmiCode(phone);
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ret.message = ussdMessage;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ret.isUssdRequest = isUssdRequest;
222767a662ecde33c3979bf02b793d392aca0403162Wink Saville
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If it's a request, set to PENDING so that it's cancelable.
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isUssdRequest) {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.isPendingUSSD = true;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.state = State.PENDING;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret.state = State.COMPLETE;
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static GsmMmiCode newFromUssdUserInput(String ussdMessge, GSMPhone phone) {
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GsmMmiCode ret = new GsmMmiCode(phone);
236767a662ecde33c3979bf02b793d392aca0403162Wink Saville
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ret.message = ussdMessge;
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ret.state = State.PENDING;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ret.isPendingUSSD = true;
240767a662ecde33c3979bf02b793d392aca0403162Wink Saville
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Private Class methods
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
246767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /** make empty strings be null.
247767a662ecde33c3979bf02b793d392aca0403162Wink Saville     *  Regexp returns empty strings for empty groups
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static String
250767a662ecde33c3979bf02b793d392aca0403162Wink Saville    makeEmptyNull (String s) {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (s != null && s.length() == 0) return null;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return s;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** returns true of the string is empty or null */
257767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private static boolean
258767a662ecde33c3979bf02b793d392aca0403162Wink Saville    isEmptyOrNull(CharSequence s) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return s == null || (s.length() == 0);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static int
264767a662ecde33c3979bf02b793d392aca0403162Wink Saville    scToCallForwardReason(String sc) {
265767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (sc == null) {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException ("invalid call forward sc");
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
268767a662ecde33c3979bf02b793d392aca0403162Wink Saville
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sc.equals(SC_CF_All)) {
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           return CommandsInterface.CF_REASON_ALL;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_CFU)) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CF_REASON_UNCONDITIONAL;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_CFB)) {
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CF_REASON_BUSY;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_CFNR)) {
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CF_REASON_NOT_REACHABLE;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_CFNRy)) {
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CF_REASON_NO_REPLY;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_CF_All_Conditional)) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           return CommandsInterface.CF_REASON_ALL_CONDITIONAL;
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException ("invalid call forward sc");
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static int
287767a662ecde33c3979bf02b793d392aca0403162Wink Saville    siToServiceClass(String si) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (si == null || si.length() == 0) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return  SERVICE_CLASS_NONE;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // NumberFormatException should cause MMI fail
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int serviceCode = Integer.parseInt(si, 10);
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (serviceCode) {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 10: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX  + SERVICE_CLASS_VOICE;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 11: return SERVICE_CLASS_VOICE;
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 12: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 13: return SERVICE_CLASS_FAX;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 16: return SERVICE_CLASS_SMS;
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 19: return SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Note for code 20:
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     From TS 22.030 Annex C:
306767a662ecde33c3979bf02b793d392aca0403162Wink Saville                "All GPRS bearer services" are not included in "All tele and bearer services"
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    and "All bearer services"."
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project....so SERVICE_CLASS_DATA, which (according to 27.007) includes GPRS
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 20: return SERVICE_CLASS_DATA_ASYNC + SERVICE_CLASS_DATA_SYNC;
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 21: return SERVICE_CLASS_PAD + SERVICE_CLASS_DATA_ASYNC;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 22: return SERVICE_CLASS_PACKET + SERVICE_CLASS_DATA_SYNC;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 24: return SERVICE_CLASS_DATA_SYNC;
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 25: return SERVICE_CLASS_DATA_ASYNC;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 26: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 99: return SERVICE_CLASS_PACKET;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException("unsupported MMI service code " + si);
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static int
326767a662ecde33c3979bf02b793d392aca0403162Wink Saville    siToTime (String si) {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (si == null || si.length() == 0) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // NumberFormatException should cause MMI fail
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return Integer.parseInt(si, 10);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static boolean
336767a662ecde33c3979bf02b793d392aca0403162Wink Saville    isServiceCodeCallForwarding(String sc) {
337767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return sc != null &&
338767a662ecde33c3979bf02b793d392aca0403162Wink Saville                (sc.equals(SC_CFU)
339767a662ecde33c3979bf02b793d392aca0403162Wink Saville                || sc.equals(SC_CFB) || sc.equals(SC_CFNRy)
340767a662ecde33c3979bf02b793d392aca0403162Wink Saville                || sc.equals(SC_CFNR) || sc.equals(SC_CF_All)
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || sc.equals(SC_CF_All_Conditional));
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static boolean
345767a662ecde33c3979bf02b793d392aca0403162Wink Saville    isServiceCodeCallBarring(String sc) {
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sc != null &&
347767a662ecde33c3979bf02b793d392aca0403162Wink Saville                (sc.equals(SC_BAOC)
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || sc.equals(SC_BAOIC)
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || sc.equals(SC_BAOICxH)
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || sc.equals(SC_BAIC)
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || sc.equals(SC_BAICr)
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || sc.equals(SC_BA_ALL)
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || sc.equals(SC_BA_MO)
354767a662ecde33c3979bf02b793d392aca0403162Wink Saville                || sc.equals(SC_BA_MT));
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static String
358767a662ecde33c3979bf02b793d392aca0403162Wink Saville    scToBarringFacility(String sc) {
359767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (sc == null) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException ("invalid call barring sc");
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sc.equals(SC_BAOC)) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BAOC;
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_BAOIC)) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BAOIC;
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_BAOICxH)) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BAOICxH;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_BAIC)) {
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BAIC;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_BAICr)) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BAICr;
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_BA_ALL)) {
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BA_ALL;
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_BA_MO)) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BA_MO;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (sc.equals(SC_BA_MT)) {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return CommandsInterface.CB_FACILITY_BA_MT;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException ("invalid call barring sc");
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Constructor
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
386767a662ecde33c3979bf02b793d392aca0403162Wink Saville    GsmMmiCode (GSMPhone phone) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The telephony unit-test cases may create GsmMmiCode's
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // in secondary threads
389767a662ecde33c3979bf02b793d392aca0403162Wink Saville        super(phone.getHandler().getLooper());
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.phone = phone;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.context = phone.getContext();
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** MmiCode implementation
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public State
397767a662ecde33c3979bf02b793d392aca0403162Wink Saville    getState() {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return state;
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence
402767a662ecde33c3979bf02b793d392aca0403162Wink Saville    getMessage() {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return message;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // inherited javadoc suffices
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void
408767a662ecde33c3979bf02b793d392aca0403162Wink Saville    cancel() {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Complete or failed cannot be cancelled
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state == State.COMPLETE || state == State.FAILED) {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        state = State.CANCELLED;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isPendingUSSD) {
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * There can only be one pending USSD session, so tell the radio to
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * cancel it.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             */
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.mCM.cancelPendingUssd(obtainMessage(EVENT_USSD_CANCEL_COMPLETE, this));
422767a662ecde33c3979bf02b793d392aca0403162Wink Saville
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * Don't call phone.onMMIDone here; wait for CANCEL_COMPLETE notice
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * from RIL.
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             */
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // TODO in cases other than USSD, it would be nice to cancel
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // the pending radio operation. This requires RIL cancellation
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // support, which does not presently exist.
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.onMMIDone (this);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isCancelable() {
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* Can only cancel pending USSD sessions. */
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return isPendingUSSD;
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Instance Methods
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Does this dial string contain a structured or unstructured MMI code? */
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
446767a662ecde33c3979bf02b793d392aca0403162Wink Saville    isMMI() {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return poundString != null;
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Is this a 1 or 2 digit "short code" as defined in TS 22.030 sec 6.5.3.2? */
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
452767a662ecde33c3979bf02b793d392aca0403162Wink Saville    isShortCode() {
453767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return poundString == null
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && dialingNumber != null && dialingNumber.length() <= 2;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4580a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff    static private boolean
4590a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff    isTwoDigitShortCode(Context context, String dialString) {
4600a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        Log.d(LOG_TAG, "isTwoDigitShortCode");
4610a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff
4620a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        if (dialString == null || dialString.length() != 2) return false;
4630a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff
4640a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        if (sTwoDigitNumberPattern == null) {
4650a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff            sTwoDigitNumberPattern = context.getResources().getStringArray(
4660a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff                    com.android.internal.R.array.config_twoDigitNumberPattern);
4670a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        }
4680a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff
4690a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        for (String dialnumber : sTwoDigitNumberPattern) {
4700a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff            Log.d(LOG_TAG, "Two Digit Number Pattern " + dialnumber);
4710a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff            if (dialString.equals(dialnumber)) {
4720a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff                Log.d(LOG_TAG, "Two Digit Number Pattern -true");
4730a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff                return true;
4740a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff            }
4750a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        }
4760a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        Log.d(LOG_TAG, "Two Digit Number Pattern -false");
4770a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff        return false;
4780a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff    }
4790a4b3fd93b2de21de0684a8291663920d9099170Irfan Sheriff
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4810b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * Helper function for newFromDialString. Returns true if dialString appears
4820b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * to be a short code AND conditions are correct for it to be treated as
4830b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * such.
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private boolean isShortCode(String dialString, GSMPhone phone) {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Refer to TS 22.030 Figure 3.5.3.2:
4870b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        if (dialString == null) {
4880b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            return false;
4890b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        }
4900b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros
4910b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        // Illegal dial string characters will give a ZERO length.
4920b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        // At this point we do not want to crash as any application with
4930b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        // call privileges may send a non dial string.
4940b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        // It return false as when the dialString is equal to NULL.
4950b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        if (dialString.length() == 0) {
4960b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            return false;
4970b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        }
4980b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros
4996b7c3f8a1cd8b638defc28a3249746e99b8039aeShaopeng Jia        if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
5000b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            return false;
5010b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        } else {
5020b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            return isShortCodeUSSD(dialString, phone);
5030b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        }
5040b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    }
5050b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros
5060b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    /**
5070b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * Helper function for isShortCode. Returns true if dialString appears to be
5080b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * a short code and it is a USSD structure
5090b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     *
5100b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2
5110b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * digit "short code" is treated as USSD if it is entered while on a call or
5120b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * does not satisfy the condition (exactly 2 digits && starts with '1'), there
5130b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * are however exceptions to this rule (see below)
5140b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     *
5150b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * Exception (1) to Call initiation is: If the user of the device is already in a call
5160b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * and enters a Short String without any #-key at the end and the length of the Short String is
5170b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2]
5180b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     *
5190b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * The phone shall initiate a USSD/SS commands.
5200b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     *
5210b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * Exception (2) to Call initiation is: If the user of the device enters one
5220b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * Digit followed by the #-key. This rule defines this String as the
5230b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * #-String which is a USSD/SS command.
5240b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     *
5250b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     * The phone shall initiate a USSD/SS command.
5260b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros     */
5270b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros    static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) {
5280b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        if (dialString != null) {
5290b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            if (phone.isInCall()) {
5300b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros                // The maximum length of a Short Code (aka Short String) is 2
5310b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros                if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
5320b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros                    return true;
5330b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros                }
5340b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            }
5350b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros
5360b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            // The maximum length of a Short Code (aka Short String) is 2
5370b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
5380b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros                if (dialString.charAt(dialString.length() - 1) == END_OF_USSD_COMMAND) {
5390b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros                    return true;
5400b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros                }
5410b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros            }
5420b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        }
5430b2bbacd9b648f013c2f898b1d57e37f502325c9Georgios Katsaros        return false;
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
545390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean isPinCommand() {
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sc != null && (sc.equals(SC_PIN) || sc.equals(SC_PIN2)
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              || sc.equals(SC_PUK) || sc.equals(SC_PUK2));
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     }
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
554767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
555390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby     * See TS 22.030 Annex B.
556767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * In temporary mode, to suppress CLIR for a single call, enter:
557390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby     *      " * 31 # [called number] SEND "
558767a662ecde33c3979bf02b793d392aca0403162Wink Saville     *  In temporary mode, to invoke CLIR for a single call enter:
559390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby     *       " # 31 # [called number] SEND "
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
561767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean
562767a662ecde33c3979bf02b793d392aca0403162Wink Saville    isTemporaryModeCLIR() {
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sc != null && sc.equals(SC_CLIR) && dialingNumber != null
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (isActivate() || isDeactivate());
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns CommandsInterface.CLIR_*
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * See also isTemporaryModeCLIR()
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int
572767a662ecde33c3979bf02b793d392aca0403162Wink Saville    getCLIRMode() {
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sc != null && sc.equals(SC_CLIR)) {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isActivate()) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return CommandsInterface.CLIR_SUPPRESSION;
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (isDeactivate()) {
577767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return CommandsInterface.CLIR_INVOCATION;
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
580767a662ecde33c3979bf02b793d392aca0403162Wink Saville
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return CommandsInterface.CLIR_DEFAULT;
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
583767a662ecde33c3979bf02b793d392aca0403162Wink Saville
584767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean isActivate() {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return action != null && action.equals(ACTION_ACTIVATE);
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
588767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean isDeactivate() {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return action != null && action.equals(ACTION_DEACTIVATE);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
591767a662ecde33c3979bf02b793d392aca0403162Wink Saville
592767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean isInterrogate() {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return action != null && action.equals(ACTION_INTERROGATE);
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
596767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean isRegister() {
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return action != null && action.equals(ACTION_REGISTER);
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
600767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean isErasure() {
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return action != null && action.equals(ACTION_ERASURE);
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
604767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this is a USSD code that's been submitted to the
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * network...eg, after processCode() is called
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
608767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public boolean isPendingUSSD() {
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return isPendingUSSD;
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isUssdRequest() {
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return isUssdRequest;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Process a MMI code or short code...anything that isn't a dialing number */
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
618767a662ecde33c3979bf02b793d392aca0403162Wink Saville    processCode () {
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isShortCode()) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.d(LOG_TAG, "isShortCode");
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // These just get treated as USSD.
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sendUssd(dialingNumber);
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (dialingNumber != null) {
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // We should have no dialing numbers here
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException ("Invalid or Unsupported MMI Code");
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc != null && sc.equals(SC_CLIP)) {
628767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.d(LOG_TAG, "is CLIP");
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (isInterrogate()) {
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.queryCLIP(
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            obtainMessage(EVENT_QUERY_COMPLETE, this));
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc != null && sc.equals(SC_CLIR)) {
636767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.d(LOG_TAG, "is CLIR");
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (isActivate()) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.setCLIR(CommandsInterface.CLIR_INVOCATION,
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        obtainMessage(EVENT_SET_COMPLETE, this));
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (isDeactivate()) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.setCLIR(CommandsInterface.CLIR_SUPPRESSION,
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        obtainMessage(EVENT_SET_COMPLETE, this));
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (isInterrogate()) {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.getCLIR(
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        obtainMessage(EVENT_GET_CLIR_COMPLETE, this));
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (isServiceCodeCallForwarding(sc)) {
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.d(LOG_TAG, "is CF");
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String dialingNumber = sia;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int serviceClass = siToServiceClass(sib);
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int reason = scToCallForwardReason(sc);
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int time = siToTime(sic);
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (isInterrogate()) {
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.queryCallForwardStatus(
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reason, serviceClass,  dialingNumber,
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                obtainMessage(EVENT_QUERY_CF_COMPLETE, this));
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int cfAction;
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (isActivate()) {
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        cfAction = CommandsInterface.CF_ACTION_ENABLE;
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (isDeactivate()) {
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        cfAction = CommandsInterface.CF_ACTION_DISABLE;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (isRegister()) {
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        cfAction = CommandsInterface.CF_ACTION_REGISTRATION;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (isErasure()) {
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        cfAction = CommandsInterface.CF_ACTION_ERASURE;
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        throw new RuntimeException ("invalid action");
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int isSettingUnconditionalVoice =
67751d412304f41e0d553c7e401e288e9394dbca950jsh                        (((reason == CommandsInterface.CF_REASON_UNCONDITIONAL) ||
67851d412304f41e0d553c7e401e288e9394dbca950jsh                                (reason == CommandsInterface.CF_REASON_ALL)) &&
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                (((serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) ||
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 (serviceClass == CommandsInterface.SERVICE_CLASS_NONE))) ? 1 : 0;
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int isEnableDesired =
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ((cfAction == CommandsInterface.CF_ACTION_ENABLE) ||
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                (cfAction == CommandsInterface.CF_ACTION_REGISTRATION)) ? 1 : 0;
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.d(LOG_TAG, "is CF setCallForward");
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.setCallForward(cfAction, reason, serviceClass,
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            dialingNumber, time, obtainMessage(
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    EVENT_SET_CFF_COMPLETE,
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    isSettingUnconditionalVoice,
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    isEnableDesired, this));
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (isServiceCodeCallBarring(sc)) {
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sia = password
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sib = basic service group
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String password = sia;
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int serviceClass = siToServiceClass(sib);
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String facility = scToBarringFacility(sc);
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (isInterrogate()) {
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.queryFacilityLock(facility, password,
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this));
7042563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                } else if (isActivate() || isDeactivate()) {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.setFacilityLock(facility, isActivate(), password,
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            serviceClass, obtainMessage(EVENT_SET_COMPLETE, this));
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc != null && sc.equals(SC_PWD)) {
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sia = fac
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sib = old pwd
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sic = new pwd
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // pwd = new pwd
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String facility;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String oldPwd = sib;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String newPwd = sic;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (isActivate() || isRegister()) {
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Even though ACTIVATE is acceptable, this is really termed a REGISTER
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    action = ACTION_REGISTER;
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (sia == null) {
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // If sc was not specified, treat it as BA_ALL.
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        facility = CommandsInterface.CB_FACILITY_BA_ALL;
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        facility = scToBarringFacility(sia);
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (newPwd.equals(pwd)) {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        phone.mCM.changeBarringPassword(facility, oldPwd,
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                newPwd, obtainMessage(EVENT_SET_COMPLETE, this));
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // password mismatch; return error
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handlePasswordError(com.android.internal.R.string.passwordIncorrect);
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc != null && sc.equals(SC_WAIT)) {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sia = basic service group
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int serviceClass = siToServiceClass(sia);
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
744767a662ecde33c3979bf02b793d392aca0403162Wink Saville                if (isActivate() || isDeactivate()) {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.setCallWaiting(isActivate(), serviceClass,
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            obtainMessage(EVENT_SET_COMPLETE, this));
747767a662ecde33c3979bf02b793d392aca0403162Wink Saville                } else if (isInterrogate()) {
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mCM.queryCallWaiting(serviceClass,
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            obtainMessage(EVENT_QUERY_COMPLETE, this));
750767a662ecde33c3979bf02b793d392aca0403162Wink Saville                } else {
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (isPinCommand()) {
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sia = old PIN or PUK
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sib = new PIN
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // sic = new PIN
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String oldPinOrPuk = sia;
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String newPin = sib;
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int pinLen = newPin.length();
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (isRegister()) {
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!newPin.equals(sic)) {
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // password mismatch; return error
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handlePasswordError(com.android.internal.R.string.mismatchPin);
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (pinLen < 4 || pinLen > 8 ) {
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // invalid length
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handlePasswordError(com.android.internal.R.string.invalidPin);
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (sc.equals(SC_PIN) &&
76812ef0981be95a074443edcc600abce692e80d3d0Alex Yakavenka                               phone.getIccCard().getState() == IccCard.State.PUK_REQUIRED ) {
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Sim is puk-locked
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handlePasswordError(com.android.internal.R.string.needPuk);
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // pre-checks OK
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (sc.equals(SC_PIN)) {
774767a662ecde33c3979bf02b793d392aca0403162Wink Saville                            phone.mCM.changeIccPin(oldPinOrPuk, newPin,
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    obtainMessage(EVENT_SET_COMPLETE, this));
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (sc.equals(SC_PIN2)) {
777767a662ecde33c3979bf02b793d392aca0403162Wink Saville                            phone.mCM.changeIccPin2(oldPinOrPuk, newPin,
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    obtainMessage(EVENT_SET_COMPLETE, this));
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (sc.equals(SC_PUK)) {
780767a662ecde33c3979bf02b793d392aca0403162Wink Saville                            phone.mCM.supplyIccPuk(oldPinOrPuk, newPin,
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    obtainMessage(EVENT_SET_COMPLETE, this));
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (sc.equals(SC_PUK2)) {
783767a662ecde33c3979bf02b793d392aca0403162Wink Saville                            phone.mCM.supplyIccPuk2(oldPinOrPuk, newPin,
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    obtainMessage(EVENT_SET_COMPLETE, this));
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (poundString != null) {
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sendUssd(poundString);
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException ("Invalid or Unsupported MMI Code");
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RuntimeException exc) {
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.FAILED;
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            message = context.getText(com.android.internal.R.string.mmiError);
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.onMMIDone(this);
799767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handlePasswordError(int res) {
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        state = State.FAILED;
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringBuilder sb = new StringBuilder(getScString());
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sb.append("\n");
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sb.append(context.getText(res));
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        message = sb;
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.onMMIDone(this);
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
811767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
812767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * Called from GSMPhone
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An unsolicited USSD NOTIFY or REQUEST has come in matching
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * up with this pending USSD request
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Note: If REQUEST, this exchange is complete, but the session remains
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *       active (ie, the network expects user input).
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
821767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onUssdFinished(String ussdMessage, boolean isUssdRequest) {
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state == State.PENDING) {
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ussdMessage == null) {
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                message = context.getText(com.android.internal.R.string.mmiComplete);
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                message = ussdMessage;
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.isUssdRequest = isUssdRequest;
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If it's a request, leave it PENDING so that it's cancelable.
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isUssdRequest) {
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                state = State.COMPLETE;
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.onMMIDone(this);
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
838767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
839767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * Called from GSMPhone
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The radio has reset, and this is still pending
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
845767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onUssdFinishedError() {
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state == State.PENDING) {
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.FAILED;
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            message = context.getText(com.android.internal.R.string.mmiError);
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.onMMIDone(this);
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void sendUssd(String ussdMessage) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Treat this as a USSD string
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        isPendingUSSD = true;
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Note that unlike most everything else, the USSD complete
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // response does not complete this MMI code...we wait for
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // an unsolicited USSD "Notify" or "Request".
861390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby        // The matching up of this is done in GSMPhone.
862767a662ecde33c3979bf02b793d392aca0403162Wink Saville
863767a662ecde33c3979bf02b793d392aca0403162Wink Saville        phone.mCM.sendUSSD(ussdMessage,
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            obtainMessage(EVENT_USSD_COMPLETE, this));
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Called from GSMPhone.handleMessage; not a Handler subclass */
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void
869767a662ecde33c3979bf02b793d392aca0403162Wink Saville    handleMessage (Message msg) {
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AsyncResult ar;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SET_COMPLETE:
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) (msg.obj);
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onSetComplete(ar);
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SET_CFF_COMPLETE:
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) (msg.obj);
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /*
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                * msg.arg1 = 1 means to set unconditional voice call forwarding
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                * msg.arg2 = 1 means to enable voice call forwarding
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                */
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((ar.exception == null) && (msg.arg1 == 1)) {
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    boolean cffEnabled = (msg.arg2 == 1);
888ecd302259a66aaf5abd49407c379c066e2542e95Wink Saville                    phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onSetComplete(ar);
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_GET_CLIR_COMPLETE:
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) (msg.obj);
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onGetClirComplete(ar);
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_QUERY_CF_COMPLETE:
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) (msg.obj);
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onQueryCfComplete(ar);
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_QUERY_COMPLETE:
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) (msg.obj);
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onQueryComplete(ar);
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_USSD_COMPLETE:
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) (msg.obj);
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ar.exception != null) {
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    state = State.FAILED;
91418573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla                    message = getErrorMessage(ar);
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.onMMIDone(this);
917767a662ecde33c3979bf02b793d392aca0403162Wink Saville                }
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Note that unlike most everything else, the USSD complete
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // response does not complete this MMI code...we wait for
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // an unsolicited USSD "Notify" or "Request".
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The matching up of this is done in GSMPhone.
923767a662ecde33c3979bf02b793d392aca0403162Wink Saville
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_USSD_CANCEL_COMPLETE:
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                phone.onMMIDone(this);
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Private instance methods
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
93318573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla    private CharSequence getErrorMessage(AsyncResult ar) {
93418573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla
93518573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla        if (ar.exception instanceof CommandException) {
93618573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla            CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
93718573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla            if (err == CommandException.Error.FDN_CHECK_FAILURE) {
93818573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla                Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
93918573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla                return context.getText(com.android.internal.R.string.mmiFdnError);
94018573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla            }
94118573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla        }
94218573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla
94318573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla        return context.getText(com.android.internal.R.string.mmiError);
94418573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla    }
94518573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CharSequence getScString() {
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sc != null) {
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isServiceCodeCallBarring(sc)) {
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return context.getText(com.android.internal.R.string.BaMmi);
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (isServiceCodeCallForwarding(sc)) {
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return context.getText(com.android.internal.R.string.CfMmi);
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc.equals(SC_CLIP)) {
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return context.getText(com.android.internal.R.string.ClipMmi);
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc.equals(SC_CLIR)) {
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return context.getText(com.android.internal.R.string.ClirMmi);
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc.equals(SC_PWD)) {
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return context.getText(com.android.internal.R.string.PwdMmi);
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sc.equals(SC_WAIT)) {
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return context.getText(com.android.internal.R.string.CwMmi);
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (isPinCommand()) {
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return context.getText(com.android.internal.R.string.PinMmi);
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return "";
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    onSetComplete(AsyncResult ar){
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringBuilder sb = new StringBuilder(getScString());
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sb.append("\n");
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception != null) {
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.FAILED;
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ar.exception instanceof CommandException) {
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err == CommandException.Error.PASSWORD_INCORRECT) {
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (isPinCommand()) {
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // look specifically for the PUK commands and adjust
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // the message accordingly.
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (sc.equals(SC_PUK) || sc.equals(SC_PUK2)) {
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    com.android.internal.R.string.badPuk));
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    com.android.internal.R.string.badPin));
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        sb.append(context.getText(
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                com.android.internal.R.string.passwordIncorrect));
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (err == CommandException.Error.SIM_PUK2) {
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            com.android.internal.R.string.badPin));
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append("\n");
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            com.android.internal.R.string.needPuk2));
99818573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla                } else if (err == CommandException.Error.FDN_CHECK_FAILURE) {
99918573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla                    Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
100018573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla                    sb.append(context.getText(com.android.internal.R.string.mmiFdnError));
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            com.android.internal.R.string.mmiError));
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(context.getText(
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.string.mmiError));
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (isActivate()) {
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.COMPLETE;
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append(context.getText(
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.string.serviceEnabled));
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Record CLIR setting
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (sc.equals(SC_CLIR)) {
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                phone.saveClirSetting(CommandsInterface.CLIR_INVOCATION);
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (isDeactivate()) {
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.COMPLETE;
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append(context.getText(
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.string.serviceDisabled));
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Record CLIR setting
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (sc.equals(SC_CLIR)) {
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                phone.saveClirSetting(CommandsInterface.CLIR_SUPPRESSION);
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (isRegister()) {
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.COMPLETE;
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append(context.getText(
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.string.serviceRegistered));
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (isErasure()) {
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.COMPLETE;
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append(context.getText(
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.string.serviceErased));
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.FAILED;
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append(context.getText(
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.string.mmiError));
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        message = sb;
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.onMMIDone(this);
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
1044767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onGetClirComplete(AsyncResult ar) {
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringBuilder sb = new StringBuilder(getScString());
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sb.append("\n");
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception != null) {
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.FAILED;
105018573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla            sb.append(getErrorMessage(ar));
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int clirArgs[];
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            clirArgs = (int[])ar.result;
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // the 'm' parameter from TS 27.007 7.7
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (clirArgs[1]) {
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 0: // CLIR not provisioned
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                com.android.internal.R.string.serviceNotProvisioned));
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    state = State.COMPLETE;
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1063767a662ecde33c3979bf02b793d392aca0403162Wink Saville
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 1: // CLIR provisioned in permanent mode
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                com.android.internal.R.string.CLIRPermanent));
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    state = State.COMPLETE;
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1070767a662ecde33c3979bf02b793d392aca0403162Wink Saville                case 2: // unknown (e.g. no network, etc.)
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                com.android.internal.R.string.mmiError));
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    state = State.FAILED;
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1076767a662ecde33c3979bf02b793d392aca0403162Wink Saville                case 3: // CLIR temporary mode presentation restricted
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // the 'n' parameter from TS 27.007 7.7
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (clirArgs[0]) {
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        default:
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case 0: // Default
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
1083767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    com.android.internal.R.string.CLIRDefaultOnNextCallOn));
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case 1: // CLIR invocation
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
1087767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    com.android.internal.R.string.CLIRDefaultOnNextCallOn));
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case 2: // CLIR suppression
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
1091767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    com.android.internal.R.string.CLIRDefaultOnNextCallOff));
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    state = State.COMPLETE;
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 4: // CLIR temporary mode presentation allowed
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // the 'n' parameter from TS 27.007 7.7
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (clirArgs[0]) {
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        default:
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case 0: // Default
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
1103767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    com.android.internal.R.string.CLIRDefaultOffNextCallOff));
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case 1: // CLIR invocation
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
1107767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    com.android.internal.R.string.CLIRDefaultOffNextCallOn));
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case 2: // CLIR suppression
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sb.append(context.getText(
1111767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    com.android.internal.R.string.CLIRDefaultOffNextCallOff));
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    state = State.COMPLETE;
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1117767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        message = sb;
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.onMMIDone(this);
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param serviceClass 1 bit of the service class bit vectory
1126767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @return String to be used for call forward query MMI response text.
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        Returns null if unrecognized
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CharSequence
1131767a662ecde33c3979bf02b793d392aca0403162Wink Saville    serviceClassToCFString (int serviceClass) {
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (serviceClass) {
1133767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_VOICE:
1134767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassVoice);
1135767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_DATA:
1136767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassData);
1137767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_FAX:
1138767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassFAX);
1139767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_SMS:
1140767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassSMS);
1141767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_DATA_SYNC:
1142767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassDataSync);
1143767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_DATA_ASYNC:
1144767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassDataAsync);
1145767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_PACKET:
1146767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassPacket);
1147767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case SERVICE_CLASS_PAD:
1148767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return context.getText(com.android.internal.R.string.serviceClassPAD);
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** one CallForwardInfo + serviceClassMask -> one line of text */
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CharSequence
1157767a662ecde33c3979bf02b793d392aca0403162Wink Saville    makeCFQueryResultMessage(CallForwardInfo info, int serviceClassMask) {
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence template;
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String sources[] = {"{0}", "{1}", "{2}"};
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence destinations[] = new CharSequence[3];
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean needTimeTemplate;
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // CF_REASON_NO_REPLY also has a time value associated with
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // it. All others don't.
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1166767a662ecde33c3979bf02b793d392aca0403162Wink Saville        needTimeTemplate =
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (info.reason == CommandsInterface.CF_REASON_NO_REPLY);
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.status == 1) {
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (needTimeTemplate) {
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                template = context.getText(
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.string.cfTemplateForwardedTime);
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                template = context.getText(
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.string.cfTemplateForwarded);
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (info.status == 0 && isEmptyOrNull(info.number)) {
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            template = context.getText(
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.string.cfTemplateNotForwarded);
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else { /* (info.status == 0) && !isEmptyOrNull(info.number) */
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // A call forward record that is not active but contains
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // a phone number is considered "registered"
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (needTimeTemplate) {
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                template = context.getText(
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.string.cfTemplateRegisteredTime);
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                template = context.getText(
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.string.cfTemplateRegistered);
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // In the template (from strings.xmls)
1194767a662ecde33c3979bf02b793d392aca0403162Wink Saville        //         {0} is one of "bearerServiceCode*"
1195767a662ecde33c3979bf02b793d392aca0403162Wink Saville        //        {1} is dialing number
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //      {2} is time in seconds
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        destinations[0] = serviceClassToCFString(info.serviceClass & serviceClassMask);
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        destinations[1] = PhoneNumberUtils.stringFromStringAndTOA(info.number, info.toa);
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        destinations[2] = Integer.toString(info.timeSeconds);
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.reason == CommandsInterface.CF_REASON_UNCONDITIONAL &&
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (info.serviceClass & serviceClassMask)
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        == CommandsInterface.SERVICE_CLASS_VOICE) {
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean cffEnabled = (info.status == 1);
1206ecd302259a66aaf5abd49407c379c066e2542e95Wink Saville            phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return TextUtils.replace(template, sources, destinations);
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
1214767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onQueryCfComplete(AsyncResult ar) {
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringBuilder sb = new StringBuilder(getScString());
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sb.append("\n");
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception != null) {
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.FAILED;
122018573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla            sb.append(getErrorMessage(ar));
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            CallForwardInfo infos[];
1223767a662ecde33c3979bf02b793d392aca0403162Wink Saville
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            infos = (CallForwardInfo[]) ar.result;
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (infos.length == 0) {
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Assume the default is not active
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Set unconditional CFF in SIM to false
1231ecd302259a66aaf5abd49407c379c066e2542e95Wink Saville                phone.mIccRecords.setVoiceCallForwardingFlag(1, false);
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SpannableStringBuilder tb = new SpannableStringBuilder();
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Each bit in the service class gets its own result line
1237767a662ecde33c3979bf02b793d392aca0403162Wink Saville                // The service classes may be split up over multiple
1238390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby                // CallForwardInfos. So, for each service class, find out
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // which CallForwardInfo represents it and then build
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the response text based on that
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1242767a662ecde33c3979bf02b793d392aca0403162Wink Saville                for (int serviceClassMask = 1
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ; serviceClassMask <= SERVICE_CLASS_MAX
1244767a662ecde33c3979bf02b793d392aca0403162Wink Saville                            ; serviceClassMask <<= 1
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ) {
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (int i = 0, s = infos.length; i < s ; i++) {
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if ((serviceClassMask & infos[i].serviceClass) != 0) {
1248767a662ecde33c3979bf02b793d392aca0403162Wink Saville                            tb.append(makeCFQueryResultMessage(infos[i],
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            serviceClassMask));
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            tb.append("\n");
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(tb);
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.COMPLETE;
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        message = sb;
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.onMMIDone(this);
1262767a662ecde33c3979bf02b793d392aca0403162Wink Saville
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
1266767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onQueryComplete(AsyncResult ar) {
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringBuilder sb = new StringBuilder(getScString());
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sb.append("\n");
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception != null) {
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.FAILED;
127218573e9281d6e5621fa1663dac29b558291913d7Naveen Kalla            sb.append(getErrorMessage(ar));
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int[] ints = (int[])ar.result;
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ints.length != 0) {
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ints[0] == 0) {
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (sc.equals(SC_WAIT)) {
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Call Waiting includes additional data in the response.
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(createQueryCallWaitingResultMessage(ints[1]));
128238e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang                } else if (isServiceCodeCallBarring(sc)) {
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // ints[0] for Call Barring is a bit vector of services
12842563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    sb.append(createQueryCallBarringResultMessage(ints[0]));
128538e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang                } else if (ints[0] == 1) {
12862563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    // for all other services, treat it as a boolean
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(com.android.internal.R.string.serviceEnabled));
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sb.append(context.getText(com.android.internal.R.string.mmiError));
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(context.getText(com.android.internal.R.string.mmiError));
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = State.COMPLETE;
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        message = sb;
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.onMMIDone(this);
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1300767a662ecde33c3979bf02b793d392aca0403162Wink Saville
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CharSequence
1302767a662ecde33c3979bf02b793d392aca0403162Wink Saville    createQueryCallWaitingResultMessage(int serviceClass) {
1303767a662ecde33c3979bf02b793d392aca0403162Wink Saville        StringBuilder sb =
1304767a662ecde33c3979bf02b793d392aca0403162Wink Saville                new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1306767a662ecde33c3979bf02b793d392aca0403162Wink Saville        for (int classMask = 1
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ; classMask <= SERVICE_CLASS_MAX
1308767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    ; classMask <<= 1
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ) {
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((classMask & serviceClass) != 0) {
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append("\n");
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(serviceClassToCFString(classMask & serviceClass));
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sb;
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
131738e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang    private CharSequence
131838e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang    createQueryCallBarringResultMessage(int serviceClass)
131938e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang    {
132038e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang        StringBuilder sb = new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
132138e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang
13222563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville        for (int classMask = 1
132338e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang                    ; classMask <= SERVICE_CLASS_MAX
13242563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    ; classMask <<= 1
132538e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang        ) {
132638e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang            if ((classMask & serviceClass) != 0) {
132738e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang                sb.append("\n");
132838e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang                sb.append(serviceClassToCFString(classMask & serviceClass));
132938e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang            }
133038e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang        }
133138e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang        return sb;
133238e260a62020af0e6ca45d5a9cc3f8e8c9a2842cJohn Wang    }
13332563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /***
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * TODO: It would be nice to have a method here that can take in a dialstring and
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * figure out if there is an MMI code embedded within it.  This code would replace
1337767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * some of the string parsing functionality in the Phone App's
1338767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * SpecialCharSequenceMgr class.
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1341269081781573ac6f830c00b24efe3cf8af80bd32John Wang    @Override
1342269081781573ac6f830c00b24efe3cf8af80bd32John Wang    public String toString() {
1343269081781573ac6f830c00b24efe3cf8af80bd32John Wang        StringBuilder sb = new StringBuilder("GsmMmiCode {");
1344269081781573ac6f830c00b24efe3cf8af80bd32John Wang
1345269081781573ac6f830c00b24efe3cf8af80bd32John Wang        sb.append("State=" + getState());
1346269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (action != null) sb.append(" action=" + action);
1347269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (sc != null) sb.append(" sc=" + sc);
1348269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (sia != null) sb.append(" sia=" + sia);
1349269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (sib != null) sb.append(" sib=" + sib);
1350269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (sic != null) sb.append(" sic=" + sic);
1351269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (poundString != null) sb.append(" poundString=" + poundString);
1352269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (dialingNumber != null) sb.append(" dialingNumber=" + dialingNumber);
1353269081781573ac6f830c00b24efe3cf8af80bd32John Wang        if (pwd != null) sb.append(" pwd=" + pwd);
1354269081781573ac6f830c00b24efe3cf8af80bd32John Wang        sb.append("}");
1355269081781573ac6f830c00b24efe3cf8af80bd32John Wang        return sb.toString();
1356269081781573ac6f830c00b24efe3cf8af80bd32John Wang    }
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1358