10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cdma;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandException;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.MmiCode;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
2799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.regex.Pattern;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.regex.Matcher;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This class can handle Puk code Mmi
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class CdmaMmiCode  extends Handler implements MmiCode {
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "CdmaMmiCode";
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Constants
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // From TS 22.030 6.5.2
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String ACTION_REGISTER = "**";
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Supp Service codes from TS 22.030 Annex B
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String SC_PUK          = "05";
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Event Constant
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_SET_COMPLETE = 1;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Instance Variables
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CDMAPhone mPhone;
5622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    Context mContext;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mAction;              // ACTION_REGISTER
5922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mSc;                  // Service Code
6022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mSia, mSib, mSic;     // Service Info a,b,c
6122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPoundString;         // Entire MMI string up to and including #
6222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mDialingNumber;
6322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPwd;                 // For password registration
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    State mState = State.PENDING;
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CharSequence mMessage;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Class Variables
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static Pattern sPatternSuppService = Pattern.compile(
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*       1  2                    3          4  5       6   7         8    9     10  11             12
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         1 = Full string up to and including #
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         2 = action
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         3 = service code
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         5 = SIA
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         7 = SIB
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         9 = SIC
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         10 = dialing number
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville*/
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_POUND_STRING = 1;
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_ACTION = 2;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SERVICE_CODE = 3;
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIA = 5;
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIB = 7;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIC = 9;
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_PWD_CONFIRM = 11;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_DIALING_NUMBER = 12;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Public Class methods
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if provided string contains Mmi code in it and create corresponding
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mmi if it does
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static CdmaMmiCode
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    newFromDialString(String dialString, CDMAPhone phone) {
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Matcher m;
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CdmaMmiCode ret = null;
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        m = sPatternSuppService.matcher(dialString);
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Is this formatted like a standard supplementary service code?
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (m.matches()) {
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ret = new CdmaMmiCode(phone);
11022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mPoundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
11122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mAction = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
11222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
11322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
11422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
11522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
11622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mPwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mDialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Private Class methods
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** make empty strings be null.
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Regexp returns empty strings for empty groups
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static String
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    makeEmptyNull (String s) {
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (s != null && s.length() == 0) return null;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return s;
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Constructor
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaMmiCode (CDMAPhone phone) {
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super(phone.getHandler().getLooper());
14022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone = phone;
14122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mContext = phone.getContext();
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // MmiCode implementation
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public State
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getState() {
14922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mState;
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public CharSequence
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getMessage() {
15522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mMessage;
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // inherited javadoc suffices
159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    cancel() {
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Complete or failed cannot be cancelled
16322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState == State.COMPLETE || mState == State.FAILED) {
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mState = State.CANCELLED;
16822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone (this);
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isCancelable() {
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Instance Methods
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isPukCommand() {
18222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSc != null && mSc.equals(SC_PUK);
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isRegister() {
18622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mAction != null && mAction.equals(ACTION_REGISTER);
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isUssdRequest() {
19199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode");
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Process a MMI PUK code */
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    processCode () {
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (isPukCommand()) {
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // sia = old PUK
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // sib = new PIN
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // sic = new PIN
20322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                String oldPinOrPuk = mSia;
20422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                String newPin = mSib;
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int pinLen = newPin.length();
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isRegister()) {
20722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (!newPin.equals(mSic)) {
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // password mismatch; return error
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        handlePasswordError(com.android.internal.R.string.mismatchPin);
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else if (pinLen < 4 || pinLen > 8 ) {
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // invalid length
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        handlePasswordError(com.android.internal.R.string.invalidPin);
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
21422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mPhone.mCi.supplyIccPuk(oldPinOrPuk, newPin,
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                obtainMessage(EVENT_SET_COMPLETE, this));
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                throw new RuntimeException ("Invalid or Unsupported MMI Code");
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException exc) {
22422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
22522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mMessage = mContext.getText(com.android.internal.R.string.mmiError);
22622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.onMMIDone(this);
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handlePasswordError(int res) {
23122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mState = State.FAILED;
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder sb = new StringBuilder(getScString());
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append("\n");
23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        sb.append(mContext.getText(res));
23522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMessage = sb;
23622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone(this);
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage (Message msg) {
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (msg.what == EVENT_SET_COMPLETE) {
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ar = (AsyncResult) (msg.obj);
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            onSetComplete(ar);
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
24899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.e(LOG_TAG, "Unexpected reply");
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Private instance methods
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CharSequence getScString() {
25422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSc != null) {
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (isPukCommand()) {
25622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                return mContext.getText(com.android.internal.R.string.PinMmi);
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return "";
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onSetComplete(AsyncResult ar){
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder sb = new StringBuilder(getScString());
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append("\n");
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
26922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ar.exception instanceof CommandException) {
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (err == CommandException.Error.PASSWORD_INCORRECT) {
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (isPukCommand()) {
27422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sb.append(mContext.getText(
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                com.android.internal.R.string.badPuk));
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
27722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sb.append(mContext.getText(
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                com.android.internal.R.string.passwordIncorrect));
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
28122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sb.append(mContext.getText(
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            com.android.internal.R.string.mmiError));
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
28522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sb.append(mContext.getText(
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        com.android.internal.R.string.mmiError));
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isRegister()) {
28922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.COMPLETE;
29022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            sb.append(mContext.getText(
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    com.android.internal.R.string.serviceRegistered));
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
29322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
29422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            sb.append(mContext.getText(
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    com.android.internal.R.string.mmiError));
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
29822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMessage = sb;
29922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone(this);
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
303