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

Commit 53149e69 authored by Daniel Sandler's avatar Daniel Sandler
Browse files

SIM PIN support.

Bug: 7413109
Change-Id: Icc4157bd869c3661e7291fe8060c82d3f713445c
Proto-Id: I909ff4fdde82f3dc0c7a61d45c522844efcbe882
parent ed7a0262
Loading
Loading
Loading
Loading
+176 −76
Original line number Diff line number Diff line
@@ -19,89 +19,189 @@
<!-- This is the SIM PIN view that allows the user to enter a SIM PIN to unlock the device. -->
<com.android.internal.policy.impl.keyguard.KeyguardSimPinView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidprv="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyguard_sim_pin_view"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <LinearLayout
            android:layout_height="0dip"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_lockscreen_sim"/>

            <include layout="@layout/keyguard_message_area_large"
    <include layout="@layout/keyguard_message_area"
        android:layout_width="match_parent"
                android:layout_height="wrap_content" />

         </LinearLayout>

        <!-- Password entry field -->
        <!-- Note: the entire container is styled to look like the edit field,
             since the backspace/IME switcher looks better inside -->
        android:layout_height="wrap_content"
        />
    <LinearLayout
        android:layout_width="match_parent"
            android:layout_height="wrap_content"
        android:layout_height="0dp"
        android:orientation="horizontal"
            android:layout_marginEnd="4dip"
            android:layout_marginStart="4dip"
            android:gravity="center_vertical"
            android:background="#70000000">

            <!-- displays dots as user enters pin -->
            <EditText android:id="@+id/sim_pin_entry"
        android:layout_weight="1"
        >
        <TextView android:id="@+id/pinEntry"
            android:editable="true"
            android:layout_width="0dip"
                android:layout_height="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
                android:maxLines="1"
                android:singleLine="true"
                android:gravity="center_horizontal"
                android:layout_gravity="center_vertical"
            android:gravity="center"
            android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
                android:textStyle="normal"
                android:inputType="textPassword"
                android:textSize="36sp"
            android:singleLine="true"
            android:cursorVisible="false"
            android:background="@null"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="#ffffffff"
            android:textAppearance="@style/TextAppearance.NumPadKey"
            android:imeOptions="flagForceAscii|actionDone"
            />

        <ImageButton android:id="@+id/delete_button"
            android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:src="@android:drawable/ic_input_delete"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:src="@*android:drawable/ic_input_delete"
            android:clickable="true"
                android:padding="8dip"
            android:paddingTop="8dip"
            android:paddingBottom="8dip"
            android:paddingLeft="24dp"
            android:paddingRight="24dp"
            android:background="?android:attr/selectableItemBackground"
            />
    </LinearLayout>

        <!-- Numeric keyboard -->
        <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
    <View
        android:layout_width="wrap_content"
        android:layout_height="1dp"
        android:background="#55FFFFFF"
        />
    <LinearLayout
        android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="4dip"
            android:layout_marginEnd="4dip"
            android:paddingTop="4dip"
            android:paddingBottom="4dip"
            android:background="#40000000"
            android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
            android:clickable="true"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        >
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key1"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="1"
            />
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key2"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="2"
            />
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key3"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="3"
            />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        >
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key4"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="4"
            />
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key5"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="5"
            />
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key6"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="6"
            />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="1"
        >
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key7"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="7"
            />
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key8"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="8"
            />
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key9"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="9"
            />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        >
        <Space
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            />
        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
            android:id="@+id/key0"
            style="@style/Widget.Button.NumPadKey"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            androidprv:textView="@+id/pinEntry"
            androidprv:digit="0"
            />
        <ImageButton
            android:id="@+id/key_enter"
            style="@style/Widget.Button.NumPadKey"
            android:gravity="center"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:src="@drawable/sym_keyboard_return_holo"
            />
    </LinearLayout>

+66 −124
Original line number Diff line number Diff line
@@ -16,117 +16,104 @@

package com.android.internal.policy.impl.keyguard;

import com.android.internal.telephony.ITelephony;

import android.content.Context;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Rect;
import android.os.RemoteException;
import android.os.ServiceManager;

import com.android.internal.telephony.ITelephony;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.PasswordEntryKeyboardHelper;
import com.android.internal.widget.PasswordEntryKeyboardView;
import com.android.internal.R;

import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

import com.android.internal.R;

/**
 * Displays a dialer like interface to unlock the SIM PIN.
 * Displays a PIN pad for unlocking.
 */
public class KeyguardSimPinView extends LinearLayout
public class KeyguardSimPinView extends KeyguardAbsKeyInputView
          implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
  
    private EditText mPinEntry;
      private ProgressDialog mSimUnlockProgressDialog = null;
    private KeyguardSecurityCallback mCallback;
    private PasswordEntryKeyboardView mKeyboardView;
    private PasswordEntryKeyboardHelper mKeyboardHelper;
    private LockPatternUtils mLockPatternUtils;
    private SecurityMessageDisplay mSecurityMessageDisplay;

      private volatile boolean mSimCheckInProgress;
  
      public KeyguardSimPinView(Context context) {

        this(context, null);
    }

    public KeyguardSimPinView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mLockPatternUtils = new LockPatternUtils(getContext());
    }

    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
        mCallback = callback;
    public void resetState() {
        mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
        mPasswordEntry.setEnabled(true);
    }

    @Override
    protected int getPasswordTextViewId() {
        return R.id.pinEntry;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        mPinEntry = (EditText) findViewById(R.id.sim_pin_entry);
        mPinEntry.setOnEditorActionListener(this);
        mPinEntry.addTextChangedListener(this);

        mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
        mKeyboardHelper = new PasswordEntryKeyboardHelper(mContext, mKeyboardView, this, false,
                new int[] {
                R.xml.kg_password_kbd_numeric,
                com.android.internal.R.xml.password_kbd_qwerty,
                com.android.internal.R.xml.password_kbd_qwerty_shifted,
                com.android.internal.R.xml.password_kbd_symbols,
                com.android.internal.R.xml.password_kbd_symbols_shift
                });
        mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
        mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled());

        final View deleteButton = findViewById(R.id.delete_button);
        if (deleteButton != null) {
            deleteButton.setOnClickListener(new OnClickListener() {
        final View ok = findViewById(R.id.key_enter);
        if (ok != null) {
            ok.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mKeyboardHelper.handleBackspace();
                    doHapticKeyClick();
                    verifyPasswordAndUnlock();
                }
            });
        }

        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
        mSecurityMessageDisplay.setTimeout(0);
        reset();
        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
        // not a separate view
        View pinDelete = findViewById(R.id.delete_button);
        if (pinDelete != null) {
            pinDelete.setVisibility(View.VISIBLE);
            pinDelete.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    CharSequence str = mPasswordEntry.getText();
                    if (str.length() > 0) {
                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
                    }

    @Override
    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
        return mPinEntry.requestFocus(direction, previouslyFocusedRect);
                    doHapticKeyClick();
                }
            });
            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
                public boolean onLongClick(View v) {
                    mPasswordEntry.setText("");
                    doHapticKeyClick();
                    return true;
                }
            });
        }

    public void reset() {
        // start fresh
        mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);

        // make sure that the number of entered digits is consistent when we
        // erase the SIM unlock code, including orientation changes.
        mPinEntry.setText("");
        mPinEntry.requestFocus();
        mPasswordEntry.requestFocus();
    }

    @Override
    public void showUsabilityHint() {
    }

    /** {@inheritDoc} */
    public void cleanUp() {
    @Override
    public void onPause() {
        // dismiss the dialog.
        if (mSimUnlockProgressDialog != null) {
            mSimUnlockProgressDialog.dismiss();
@@ -167,19 +154,6 @@ public class KeyguardSimPinView extends LinearLayout
        }
    }

    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        // Check if this was the result of hitting the enter key
        mCallback.userActivity(KeyguardViewManager.DIGIT_PRESS_WAKE_MILLIS);
        if (event.getAction() == MotionEvent.ACTION_DOWN && (
                actionId == EditorInfo.IME_NULL
                || actionId == EditorInfo.IME_ACTION_DONE
                || actionId == EditorInfo.IME_ACTION_NEXT)) {
            checkPin();
            return true;
        }
        return false;
    }

    private Dialog getSimUnlockProgressDialog() {
        if (mSimUnlockProgressDialog == null) {
            mSimUnlockProgressDialog = new ProgressDialog(mContext);
@@ -195,11 +169,14 @@ public class KeyguardSimPinView extends LinearLayout
        return mSimUnlockProgressDialog;
    }

    private void checkPin() {
        if (mPinEntry.getText().length() < 4) {
    @Override
    protected void verifyPasswordAndUnlock() {
        String entry = mPasswordEntry.getText().toString();
        
        if (entry.length() < 4) {
            // otherwise, display a message to the user, and don't submit.
            mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint, true);
            mPinEntry.setText("");
            mPasswordEntry.setText("");
            mCallback.userActivity(0);
            return;
        }
@@ -208,7 +185,7 @@ public class KeyguardSimPinView extends LinearLayout

        if (!mSimCheckInProgress) {
            mSimCheckInProgress = true; // there should be only one
            new CheckSimPin(mPinEntry.getText().toString()) {
            new CheckSimPin(mPasswordEntry.getText().toString()) {
                void onSimCheckResponse(final boolean success) {
                    post(new Runnable() {
                        public void run() {
@@ -223,7 +200,7 @@ public class KeyguardSimPinView extends LinearLayout
                            } else {
                                mSecurityMessageDisplay.setMessage
                                    (R.string.kg_password_wrong_pin_code, true);
                                mPinEntry.setText("");
                                mPasswordEntry.setText("");
                            }
                            mCallback.userActivity(0);
                            mSimCheckInProgress = false;
@@ -233,40 +210,5 @@ public class KeyguardSimPinView extends LinearLayout
            }.start();
        }
    }

    public void setLockPatternUtils(LockPatternUtils utils) {
        mLockPatternUtils = utils;
}
    public boolean needsInput() {
        return false; // This view provides its own keypad
    }

    public void onPause() {

    }

    public void onResume() {
        reset();
    }

    public KeyguardSecurityCallback getCallback() {
        return mCallback;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if (mCallback != null) {
            mCallback.userActivity(KeyguardViewManager.DIGIT_PRESS_WAKE_MILLIS);
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }

    @Override
    public void afterTextChanged(Editable s) {
    }

}