CdmaMmiCode.java revision 3522c54a64f577f2b657a775dae9b4eb2d8003d5
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;
223522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Savilleimport com.android.internal.telephony.uicc.UiccCardApplication;
233522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Savilleimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.MmiCode;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
2999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.regex.Pattern;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.regex.Matcher;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This class can handle Puk code Mmi
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class CdmaMmiCode  extends Handler implements MmiCode {
41cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "CdmaMmiCode";
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Constants
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // From TS 22.030 6.5.2
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String ACTION_REGISTER = "**";
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
483522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    // Supplementary Service codes for PIN/PIN2/PUK/PUK2 from TS 22.030 Annex B
493522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    static final String SC_PIN          = "04";
503522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    static final String SC_PIN2         = "042";
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String SC_PUK          = "05";
523522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    static final String SC_PUK2         = "052";
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Event Constant
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_SET_COMPLETE = 1;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Instance Variables
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CDMAPhone mPhone;
6122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    Context mContext;
623522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    UiccCardApplication mUiccApplication;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mAction;              // ACTION_REGISTER
6522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mSc;                  // Service Code
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mSia, mSib, mSic;     // Service Info a,b,c
6722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPoundString;         // Entire MMI string up to and including #
6822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mDialingNumber;
6922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPwd;                 // For password registration
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    State mState = State.PENDING;
7222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CharSequence mMessage;
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Class Variables
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static Pattern sPatternSuppService = Pattern.compile(
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*       1  2                    3          4  5       6   7         8    9     10  11             12
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         1 = Full string up to and including #
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         2 = action
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         3 = service code
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         5 = SIA
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         7 = SIB
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         9 = SIC
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         10 = dialing number
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville*/
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_POUND_STRING = 1;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_ACTION = 2;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SERVICE_CODE = 3;
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIA = 5;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIB = 7;
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIC = 9;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_PWD_CONFIRM = 11;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_DIALING_NUMBER = 12;
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Public Class methods
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if provided string contains Mmi code in it and create corresponding
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mmi if it does
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static CdmaMmiCode
1073522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    newFromDialString(String dialString, CDMAPhone phone, UiccCardApplication app) {
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Matcher m;
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CdmaMmiCode ret = null;
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        m = sPatternSuppService.matcher(dialString);
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Is this formatted like a standard supplementary service code?
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (m.matches()) {
1153522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            ret = new CdmaMmiCode(phone,app);
11622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mPoundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mAction = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
11822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
11922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
12022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
12122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
12222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mPwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
12322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mDialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Private Class methods
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** make empty strings be null.
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Regexp returns empty strings for empty groups
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static String
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    makeEmptyNull (String s) {
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (s != null && s.length() == 0) return null;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return s;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Constructor
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1443522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    CdmaMmiCode (CDMAPhone phone, UiccCardApplication app) {
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super(phone.getHandler().getLooper());
14622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone = phone;
14722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mContext = phone.getContext();
1483522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville        mUiccApplication = app;
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // MmiCode implementation
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public State
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getState() {
15622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mState;
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public CharSequence
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getMessage() {
16222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mMessage;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // inherited javadoc suffices
166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    cancel() {
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Complete or failed cannot be cancelled
17022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState == State.COMPLETE || mState == State.FAILED) {
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mState = State.CANCELLED;
17522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone (this);
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isCancelable() {
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Instance Methods
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1883522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    boolean isPinPukCommand() {
1893522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville        return mSc != null && (mSc.equals(SC_PIN) || mSc.equals(SC_PIN2)
1903522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                              || mSc.equals(SC_PUK) || mSc.equals(SC_PUK2));
1913522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    }
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isRegister() {
19422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mAction != null && mAction.equals(ACTION_REGISTER);
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isUssdRequest() {
19999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode");
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Process a MMI PUK code */
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2053522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    processCode() {
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
2073522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            if (isPinPukCommand()) {
2083522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // TODO: This is the same as the code in GsmMmiCode.java,
2093522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // MmiCode should be an abstract or base class and this and
2103522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // other common variables and code should be promoted.
2113522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville
2123522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // sia = old PIN or PUK
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // sib = new PIN
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // sic = new PIN
21522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                String oldPinOrPuk = mSia;
2163522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                String newPinOrPuk = mSib;
2173522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                int pinLen = newPinOrPuk.length();
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isRegister()) {
2193522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    if (!newPinOrPuk.equals(mSic)) {
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // password mismatch; return error
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        handlePasswordError(com.android.internal.R.string.mismatchPin);
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else if (pinLen < 4 || pinLen > 8 ) {
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // invalid length
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        handlePasswordError(com.android.internal.R.string.invalidPin);
2253522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    } else if (mSc.equals(SC_PIN)
2263522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            && mUiccApplication != null
2273522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            && mUiccApplication.getState() == AppState.APPSTATE_PUK) {
2283522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // Sim is puk-locked
2293522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        handlePasswordError(com.android.internal.R.string.needPuk);
2303522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    } else if (mUiccApplication != null) {
2313522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        Rlog.d(LOG_TAG, "process mmi service code using UiccApp sc=" + mSc);
2323522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville
2333522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // We have an app and the pre-checks are OK
2343522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        if (mSc.equals(SC_PIN)) {
2353522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.changeIccLockPassword(oldPinOrPuk, newPinOrPuk,
2363522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2373522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else if (mSc.equals(SC_PIN2)) {
2383522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.changeIccFdnPassword(oldPinOrPuk, newPinOrPuk,
2393522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2403522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else if (mSc.equals(SC_PUK)) {
2413522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.supplyPuk(oldPinOrPuk, newPinOrPuk,
2423522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2433522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else if (mSc.equals(SC_PUK2)) {
2443522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.supplyPuk2(oldPinOrPuk, newPinOrPuk,
2453522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2463522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else {
2473522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            throw new RuntimeException("Unsupported service code=" + mSc);
2483522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        }
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
2503522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        throw new RuntimeException("No application mUiccApplicaiton is null");
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
2533522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    throw new RuntimeException ("Ivalid register/action=" + mAction);
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException exc) {
25722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
25822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mMessage = mContext.getText(com.android.internal.R.string.mmiError);
25922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.onMMIDone(this);
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handlePasswordError(int res) {
26422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mState = State.FAILED;
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder sb = new StringBuilder(getScString());
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append("\n");
26722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        sb.append(mContext.getText(res));
26822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMessage = sb;
26922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone(this);
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage (Message msg) {
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (msg.what == EVENT_SET_COMPLETE) {
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ar = (AsyncResult) (msg.obj);
2793522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            onSetComplete(msg, ar);
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
28199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.e(LOG_TAG, "Unexpected reply");
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Private instance methods
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CharSequence getScString() {
28722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSc != null) {
2883522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            if (isPinPukCommand()) {
28922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                return mContext.getText(com.android.internal.R.string.PinMmi);
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return "";
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
2973522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    onSetComplete(Message msg, AsyncResult ar){
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder sb = new StringBuilder(getScString());
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append("\n");
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
30222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ar.exception instanceof CommandException) {
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (err == CommandException.Error.PASSWORD_INCORRECT) {
3063522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    if (isPinPukCommand()) {
3073522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // look specifically for the PUK commands and adjust
3083522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // the message accordingly.
3093522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        if (mSc.equals(SC_PUK) || mSc.equals(SC_PUK2)) {
3103522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            sb.append(mContext.getText(
3113522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    com.android.internal.R.string.badPuk));
3123522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else {
3133522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            sb.append(mContext.getText(
3143522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    com.android.internal.R.string.badPin));
3153522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        }
3163522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // Get the No. of retries remaining to unlock PUK/PUK2
3173522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        int attemptsRemaining = msg.arg1;
3183522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        if (attemptsRemaining >= 0) {
3193522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            Rlog.d(LOG_TAG, "onSetComplete: attemptsRemaining="+attemptsRemaining);
3203522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            sb.append(mContext.getResources().getQuantityString(
3213522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    com.android.internal.R.plurals.pinpuk_attempts,
3223522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    attemptsRemaining, attemptsRemaining));
3233522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        }
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
32522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sb.append(mContext.getText(
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                com.android.internal.R.string.passwordIncorrect));
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
3283522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                } else if (err == CommandException.Error.SIM_PUK2) {
3293522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    sb.append(mContext.getText(
3303522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            com.android.internal.R.string.badPin));
3313522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    sb.append("\n");
3323522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    sb.append(mContext.getText(
3333522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            com.android.internal.R.string.needPuk2));
3343522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                } else if (err == CommandException.Error.REQUEST_NOT_SUPPORTED) {
3353522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    if (mSc.equals(SC_PIN)) {
3363522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        sb.append(mContext.getText(com.android.internal.R.string.enablePin));
3373522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    }
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
33922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sb.append(mContext.getText(
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            com.android.internal.R.string.mmiError));
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
34322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sb.append(mContext.getText(
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        com.android.internal.R.string.mmiError));
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isRegister()) {
34722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.COMPLETE;
34822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            sb.append(mContext.getText(
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    com.android.internal.R.string.serviceRegistered));
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
35122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
35222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            sb.append(mContext.getText(
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    com.android.internal.R.string.mmiError));
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
35622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMessage = sb;
35722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone(this);
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
361