Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3522c54a authored by Wink Saville's avatar Wink Saville
Browse files

Few PIN/PUK fixes

Following changes have been made as part of this:
-> Changes done to display retry counter on wrong entry of
   PIN1,and message to indicate Code accepted/PIN1 blocked
   during PIN1 verification as per certain carrier requirements.
-> The current APIs that are used to verify the PIN and PUK only convey
   whether the operation succeeded or failed. As a result on ANY failure
   clients ask the user to re-enter the PIN.
   Add 2 new APIs that report the actual error code and returns the
   number of attempts remaing in case of failure.
-> FDN Service state was derived based on the state of PIN2. Update the
   state of FDN service based on the FACILTY_LOCK messages instead.
-> Change the default value of function getIccLockEnabled to false.
   When sim is deactivated/absent & user navigates to
   Settings->Security->Set up SIM/RUIM card lock,
   checkbox for "Lock Sim Card" option should be
   unchecked by default.
-> PIN1 can be changed only after enabling SIM lock. RIL returns
   REQUEST_NOT_SUPPORTED error if user tries to change PIN1 without
   enabling SIM lock.
   Handle the error and display appropriate message when trying to
   change PIN1 using MMI code.
-> Added MMI support for change PIN1/PIN2 and unblocking PIN2

Bug: 9928717
Change-Id: I73718c9e6a8aa7244097e0dd4593a6226ff0ac08
parent 755e85a8
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -574,6 +574,9 @@ public interface CommandsInterface {
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC will be PUK locked.
     *
     * ar.exception and ar.result are null on success
     */

@@ -590,6 +593,9 @@ public interface CommandsInterface {
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC will be PUK locked.
     *
     * ar.exception and ar.result are null on success
     */

@@ -604,6 +610,9 @@ public interface CommandsInterface {
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC is permanently disabled.
     *
     * ar.exception and ar.result are null on success
     */

@@ -614,12 +623,14 @@ public interface CommandsInterface {
     *
     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
     *
     *  returned message
     *  retMsg.obj = AsyncResult ar
     *  ar.exception carries exception on failure
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC is permanently disabled.
     *
     * ar.exception and ar.result are null on success
     */

@@ -636,6 +647,9 @@ public interface CommandsInterface {
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC will be PUK locked.
     *
     * ar.exception and ar.result are null on success
     */

@@ -654,6 +668,9 @@ public interface CommandsInterface {
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC will be PUK locked.
     *
     * ar.exception and ar.result are null on success
     */

@@ -670,6 +687,9 @@ public interface CommandsInterface {
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC is permanently disabled.
     *
     * ar.exception and ar.result are null on success
     */

@@ -688,11 +708,15 @@ public interface CommandsInterface {
     *  This exception is CommandException with an error of PASSWORD_INCORRECT
     *  if the password is incorrect
     *
     *  ar.result is an optional array of integers where the first entry
     *  is the number of attempts remaining before the ICC is permanently disabled.
     *
     * ar.exception and ar.result are null on success
     */

    void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result);

    // TODO: Add java doc and indicate that msg.arg1 contains the number of attempts remaining.
    void changeIccPin(String oldPin, String newPin, Message result);
    void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result);
    void changeIccPin2(String oldPin2, String newPin2, Message result);
+17 −0
Original line number Diff line number Diff line
@@ -107,6 +107,13 @@ public interface IccCard {
     */
    public void supplyPuk2 (String puk2, String newPin2, Message onComplete);

    /**
     * Check whether fdn (fixed dialing number) service is available.
     * @return true if ICC fdn service available
     *         false if ICC fdn service not available
    */
    public boolean getIccFdnAvailable();

    /**
     * Supply Network depersonalization code to the RIL
     */
@@ -214,4 +221,14 @@ public interface IccCard {
     * @return true if a ICC card is present
     */
    public boolean hasIccCard();

    /**
     * @return true if ICC card is PIN2 blocked
     */
    public boolean getIccPin2Blocked();

    /**
     * @return true if ICC card is PUK2 blocked
     */
    public boolean getIccPuk2Blocked();
}
+2 −2
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ class RILRequest {

        if (RIL.RILJ_LOGD) Rlog.d(LOG_TAG, serialString() + "< "
            + RIL.requestToString(mRequest)
            + " error: " + ex);
            + " error: " + ex + " ret=" + RIL.retToString(mRequest, ret));

        if (mResult != null) {
            AsyncResult.forMessage(mResult, ret, ex);
@@ -2501,7 +2501,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
        return rr;
    }

    private String
    static String
    retToString(int req, Object ret) {
        if (ret == null) return "";
        switch (req) {
+2 −2
Original line number Diff line number Diff line
@@ -575,12 +575,12 @@ public class CDMAPhone extends PhoneBase {

    @Override
    public boolean handlePinMmi(String dialString) {
        CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this);
        CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this, mUiccApplication.get());

        if (mmi == null) {
            Rlog.e(LOG_TAG, "Mmi is NULL!");
            return false;
        } else if (mmi.isPukCommand()) {
        } else if (mmi.isPinPukCommand()) {
            mPendingMmis.add(mmi);
            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
            mmi.processCode();
+82 −24
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.internal.telephony.cdma;
import android.content.Context;

import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
import com.android.internal.telephony.MmiCode;

import android.os.AsyncResult;
@@ -43,8 +45,11 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
    // From TS 22.030 6.5.2
    static final String ACTION_REGISTER = "**";

    // Supp Service codes from TS 22.030 Annex B
    // Supplementary Service codes for PIN/PIN2/PUK/PUK2 from TS 22.030 Annex B
    static final String SC_PIN          = "04";
    static final String SC_PIN2         = "042";
    static final String SC_PUK          = "05";
    static final String SC_PUK2         = "052";

    // Event Constant

@@ -54,6 +59,7 @@ public final class CdmaMmiCode extends Handler implements MmiCode {

    CDMAPhone mPhone;
    Context mContext;
    UiccCardApplication mUiccApplication;

    String mAction;              // ACTION_REGISTER
    String mSc;                  // Service Code
@@ -98,7 +104,7 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
     */

    public static CdmaMmiCode
    newFromDialString(String dialString, CDMAPhone phone) {
    newFromDialString(String dialString, CDMAPhone phone, UiccCardApplication app) {
        Matcher m;
        CdmaMmiCode ret = null;

@@ -106,7 +112,7 @@ public final class CdmaMmiCode extends Handler implements MmiCode {

        // Is this formatted like a standard supplementary service code?
        if (m.matches()) {
            ret = new CdmaMmiCode(phone);
            ret = new CdmaMmiCode(phone,app);
            ret.mPoundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
            ret.mAction = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
            ret.mSc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
@@ -135,10 +141,11 @@ public final class CdmaMmiCode extends Handler implements MmiCode {

    // Constructor

    CdmaMmiCode (CDMAPhone phone) {
    CdmaMmiCode (CDMAPhone phone, UiccCardApplication app) {
        super(phone.getHandler().getLooper());
        mPhone = phone;
        mContext = phone.getContext();
        mUiccApplication = app;
    }

    // MmiCode implementation
@@ -178,8 +185,9 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
    /**
     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
     */
    boolean isPukCommand() {
        return mSc != null && mSc.equals(SC_PUK);
    boolean isPinPukCommand() {
        return mSc != null && (mSc.equals(SC_PIN) || mSc.equals(SC_PIN2)
                              || mSc.equals(SC_PUK) || mSc.equals(SC_PUK2));
    }

    boolean isRegister() {
@@ -196,29 +204,54 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
    void
    processCode() {
        try {
            if (isPukCommand()) {
                // sia = old PUK
            if (isPinPukCommand()) {
                // TODO: This is the same as the code in GsmMmiCode.java,
                // MmiCode should be an abstract or base class and this and
                // other common variables and code should be promoted.

                // sia = old PIN or PUK
                // sib = new PIN
                // sic = new PIN
                String oldPinOrPuk = mSia;
                String newPin = mSib;
                int pinLen = newPin.length();
                String newPinOrPuk = mSib;
                int pinLen = newPinOrPuk.length();
                if (isRegister()) {
                    if (!newPin.equals(mSic)) {
                    if (!newPinOrPuk.equals(mSic)) {
                        // password mismatch; return error
                        handlePasswordError(com.android.internal.R.string.mismatchPin);
                    } else if (pinLen < 4 || pinLen > 8 ) {
                        // invalid length
                        handlePasswordError(com.android.internal.R.string.invalidPin);
                    } else {
                        mPhone.mCi.supplyIccPuk(oldPinOrPuk, newPin,
                    } else if (mSc.equals(SC_PIN)
                            && mUiccApplication != null
                            && mUiccApplication.getState() == AppState.APPSTATE_PUK) {
                        // Sim is puk-locked
                        handlePasswordError(com.android.internal.R.string.needPuk);
                    } else if (mUiccApplication != null) {
                        Rlog.d(LOG_TAG, "process mmi service code using UiccApp sc=" + mSc);

                        // We have an app and the pre-checks are OK
                        if (mSc.equals(SC_PIN)) {
                            mUiccApplication.changeIccLockPassword(oldPinOrPuk, newPinOrPuk,
                                    obtainMessage(EVENT_SET_COMPLETE, this));
                        } else if (mSc.equals(SC_PIN2)) {
                            mUiccApplication.changeIccFdnPassword(oldPinOrPuk, newPinOrPuk,
                                    obtainMessage(EVENT_SET_COMPLETE, this));
                        } else if (mSc.equals(SC_PUK)) {
                            mUiccApplication.supplyPuk(oldPinOrPuk, newPinOrPuk,
                                    obtainMessage(EVENT_SET_COMPLETE, this));
                        } else if (mSc.equals(SC_PUK2)) {
                            mUiccApplication.supplyPuk2(oldPinOrPuk, newPinOrPuk,
                                    obtainMessage(EVENT_SET_COMPLETE, this));
                        } else {
                            throw new RuntimeException("Unsupported service code=" + mSc);
                        }
                    } else {
                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
                        throw new RuntimeException("No application mUiccApplicaiton is null");
                    }
                } else {
                throw new RuntimeException ("Invalid or Unsupported MMI Code");
                    throw new RuntimeException ("Ivalid register/action=" + mAction);
                }
            }
        } catch (RuntimeException exc) {
            mState = State.FAILED;
@@ -243,7 +276,7 @@ public final class CdmaMmiCode extends Handler implements MmiCode {

        if (msg.what == EVENT_SET_COMPLETE) {
            ar = (AsyncResult) (msg.obj);
            onSetComplete(ar);
            onSetComplete(msg, ar);
        } else {
            Rlog.e(LOG_TAG, "Unexpected reply");
        }
@@ -252,7 +285,7 @@ public final class CdmaMmiCode extends Handler implements MmiCode {

    private CharSequence getScString() {
        if (mSc != null) {
            if (isPukCommand()) {
            if (isPinPukCommand()) {
                return mContext.getText(com.android.internal.R.string.PinMmi);
            }
        }
@@ -261,7 +294,7 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
    }

    private void
    onSetComplete(AsyncResult ar){
    onSetComplete(Message msg, AsyncResult ar){
        StringBuilder sb = new StringBuilder(getScString());
        sb.append("\n");

@@ -270,13 +303,38 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
            if (ar.exception instanceof CommandException) {
                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
                if (err == CommandException.Error.PASSWORD_INCORRECT) {
                    if (isPukCommand()) {
                    if (isPinPukCommand()) {
                        // look specifically for the PUK commands and adjust
                        // the message accordingly.
                        if (mSc.equals(SC_PUK) || mSc.equals(SC_PUK2)) {
                            sb.append(mContext.getText(
                                    com.android.internal.R.string.badPuk));
                        } else {
                            sb.append(mContext.getText(
                                    com.android.internal.R.string.badPin));
                        }
                        // Get the No. of retries remaining to unlock PUK/PUK2
                        int attemptsRemaining = msg.arg1;
                        if (attemptsRemaining >= 0) {
                            Rlog.d(LOG_TAG, "onSetComplete: attemptsRemaining="+attemptsRemaining);
                            sb.append(mContext.getResources().getQuantityString(
                                    com.android.internal.R.plurals.pinpuk_attempts,
                                    attemptsRemaining, attemptsRemaining));
                        }
                    } else {
                        sb.append(mContext.getText(
                                com.android.internal.R.string.passwordIncorrect));
                    }
                } else if (err == CommandException.Error.SIM_PUK2) {
                    sb.append(mContext.getText(
                            com.android.internal.R.string.badPin));
                    sb.append("\n");
                    sb.append(mContext.getText(
                            com.android.internal.R.string.needPuk2));
                } else if (err == CommandException.Error.REQUEST_NOT_SUPPORTED) {
                    if (mSc.equals(SC_PIN)) {
                        sb.append(mContext.getText(com.android.internal.R.string.enablePin));
                    }
                } else {
                    sb.append(mContext.getText(
                            com.android.internal.R.string.mmiError));
Loading