Home | History | Annotate | Download | only in keyguard
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.keyguard;
     18 
     19 import android.content.Context;
     20 import android.graphics.Rect;
     21 import android.util.AttributeSet;
     22 import android.view.KeyEvent;
     23 import android.view.View;
     24 
     25 /**
     26  * A Pin based Keyguard input view
     27  */
     28 public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
     29         implements View.OnKeyListener {
     30 
     31     protected PasswordTextView mPasswordEntry;
     32     private View mOkButton;
     33     private View mDeleteButton;
     34     private View mButton0;
     35     private View mButton1;
     36     private View mButton2;
     37     private View mButton3;
     38     private View mButton4;
     39     private View mButton5;
     40     private View mButton6;
     41     private View mButton7;
     42     private View mButton8;
     43     private View mButton9;
     44 
     45     public KeyguardPinBasedInputView(Context context) {
     46         this(context, null);
     47     }
     48 
     49     public KeyguardPinBasedInputView(Context context, AttributeSet attrs) {
     50         super(context, attrs);
     51     }
     52 
     53     @Override
     54     public void reset() {
     55         mPasswordEntry.requestFocus();
     56         super.reset();
     57     }
     58 
     59     @Override
     60     protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
     61         // send focus to the password field
     62         return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
     63     }
     64 
     65     @Override
     66     protected void resetState() {
     67         setPasswordEntryEnabled(true);
     68     }
     69 
     70     @Override
     71     protected void setPasswordEntryEnabled(boolean enabled) {
     72         mPasswordEntry.setEnabled(enabled);
     73         mOkButton.setEnabled(enabled);
     74     }
     75 
     76     @Override
     77     protected void setPasswordEntryInputEnabled(boolean enabled) {
     78         mPasswordEntry.setEnabled(enabled);
     79         mOkButton.setEnabled(enabled);
     80     }
     81 
     82     @Override
     83     public boolean onKeyDown(int keyCode, KeyEvent event) {
     84         if (KeyEvent.isConfirmKey(keyCode)) {
     85             performClick(mOkButton);
     86             return true;
     87         } else if (keyCode == KeyEvent.KEYCODE_DEL) {
     88             performClick(mDeleteButton);
     89             return true;
     90         }
     91         if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
     92             int number = keyCode - KeyEvent.KEYCODE_0;
     93             performNumberClick(number);
     94             return true;
     95         }
     96         if (keyCode >= KeyEvent.KEYCODE_NUMPAD_0 && keyCode <= KeyEvent.KEYCODE_NUMPAD_9) {
     97             int number = keyCode - KeyEvent.KEYCODE_NUMPAD_0;
     98             performNumberClick(number);
     99             return true;
    100         }
    101         return super.onKeyDown(keyCode, event);
    102     }
    103 
    104     @Override
    105     protected int getPromtReasonStringRes(int reason) {
    106         switch (reason) {
    107             case PROMPT_REASON_RESTART:
    108                 return R.string.kg_prompt_reason_restart_pin;
    109             case PROMPT_REASON_TIMEOUT:
    110                 return R.string.kg_prompt_reason_timeout_pin;
    111             case PROMPT_REASON_DEVICE_ADMIN:
    112                 return R.string.kg_prompt_reason_device_admin;
    113             case PROMPT_REASON_USER_REQUEST:
    114                 return R.string.kg_prompt_reason_user_request;
    115             case PROMPT_REASON_NONE:
    116                 return 0;
    117             default:
    118                 return R.string.kg_prompt_reason_timeout_pin;
    119         }
    120     }
    121 
    122     private void performClick(View view) {
    123         view.performClick();
    124     }
    125 
    126     private void performNumberClick(int number) {
    127         switch (number) {
    128             case 0:
    129                 performClick(mButton0);
    130                 break;
    131             case 1:
    132                 performClick(mButton1);
    133                 break;
    134             case 2:
    135                 performClick(mButton2);
    136                 break;
    137             case 3:
    138                 performClick(mButton3);
    139                 break;
    140             case 4:
    141                 performClick(mButton4);
    142                 break;
    143             case 5:
    144                 performClick(mButton5);
    145                 break;
    146             case 6:
    147                 performClick(mButton6);
    148                 break;
    149             case 7:
    150                 performClick(mButton7);
    151                 break;
    152             case 8:
    153                 performClick(mButton8);
    154                 break;
    155             case 9:
    156                 performClick(mButton9);
    157                 break;
    158         }
    159     }
    160 
    161     @Override
    162     protected void resetPasswordText(boolean animate, boolean announce) {
    163         mPasswordEntry.reset(animate, announce);
    164     }
    165 
    166     @Override
    167     protected String getPasswordText() {
    168         return mPasswordEntry.getText();
    169     }
    170 
    171     @Override
    172     protected void onFinishInflate() {
    173         mPasswordEntry = (PasswordTextView) findViewById(getPasswordTextViewId());
    174         mPasswordEntry.setOnKeyListener(this);
    175 
    176         // Set selected property on so the view can send accessibility events.
    177         mPasswordEntry.setSelected(true);
    178 
    179         mPasswordEntry.setUserActivityListener(new PasswordTextView.UserActivityListener() {
    180             @Override
    181             public void onUserActivity() {
    182                 onUserInput();
    183             }
    184         });
    185 
    186         mOkButton = findViewById(R.id.key_enter);
    187         if (mOkButton != null) {
    188             mOkButton.setOnClickListener(new View.OnClickListener() {
    189                 @Override
    190                 public void onClick(View v) {
    191                     doHapticKeyClick();
    192                     if (mPasswordEntry.isEnabled()) {
    193                         verifyPasswordAndUnlock();
    194                     }
    195                 }
    196             });
    197             mOkButton.setOnHoverListener(new LiftToActivateListener(getContext()));
    198         }
    199 
    200         mDeleteButton = findViewById(R.id.delete_button);
    201         mDeleteButton.setVisibility(View.VISIBLE);
    202         mDeleteButton.setOnClickListener(new OnClickListener() {
    203             @Override
    204             public void onClick(View v) {
    205                 // check for time-based lockouts
    206                 if (mPasswordEntry.isEnabled()) {
    207                     mPasswordEntry.deleteLastChar();
    208                 }
    209                 doHapticKeyClick();
    210             }
    211         });
    212         mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() {
    213             @Override
    214             public boolean onLongClick(View v) {
    215                 // check for time-based lockouts
    216                 if (mPasswordEntry.isEnabled()) {
    217                     resetPasswordText(true /* animate */, true /* announce */);
    218                 }
    219                 doHapticKeyClick();
    220                 return true;
    221             }
    222         });
    223 
    224         mButton0 = findViewById(R.id.key0);
    225         mButton1 = findViewById(R.id.key1);
    226         mButton2 = findViewById(R.id.key2);
    227         mButton3 = findViewById(R.id.key3);
    228         mButton4 = findViewById(R.id.key4);
    229         mButton5 = findViewById(R.id.key5);
    230         mButton6 = findViewById(R.id.key6);
    231         mButton7 = findViewById(R.id.key7);
    232         mButton8 = findViewById(R.id.key8);
    233         mButton9 = findViewById(R.id.key9);
    234 
    235         mPasswordEntry.requestFocus();
    236         super.onFinishInflate();
    237     }
    238 
    239     @Override
    240     public boolean onKey(View v, int keyCode, KeyEvent event) {
    241         if (event.getAction() == KeyEvent.ACTION_DOWN) {
    242             return onKeyDown(keyCode, event);
    243         }
    244         return false;
    245     }
    246 }
    247