1/* 2 * Copyright (C) 2012 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 17package com.android.internal.policy.impl.keyguard; 18 19import android.content.Context; 20import android.text.Editable; 21import android.text.InputType; 22import android.text.TextWatcher; 23import android.text.method.DigitsKeyListener; 24import android.util.AttributeSet; 25import android.view.View; 26import android.widget.TextView.OnEditorActionListener; 27 28import com.android.internal.R; 29 30/** 31 * Displays a PIN pad for unlocking. 32 */ 33public class KeyguardPINView extends KeyguardAbsKeyInputView 34 implements KeyguardSecurityView, OnEditorActionListener, TextWatcher { 35 36 public KeyguardPINView(Context context) { 37 this(context, null); 38 } 39 40 public KeyguardPINView(Context context, AttributeSet attrs) { 41 super(context, attrs); 42 } 43 44 protected void resetState() { 45 if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) { 46 mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true); 47 } else { 48 mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false); 49 } 50 mPasswordEntry.setEnabled(true); 51 } 52 53 @Override 54 protected int getPasswordTextViewId() { 55 return R.id.pinEntry; 56 } 57 58 @Override 59 protected void onFinishInflate() { 60 super.onFinishInflate(); 61 62 final View ok = findViewById(R.id.key_enter); 63 if (ok != null) { 64 ok.setOnClickListener(new View.OnClickListener() { 65 @Override 66 public void onClick(View v) { 67 doHapticKeyClick(); 68 if (mPasswordEntry.isEnabled()) { 69 verifyPasswordAndUnlock(); 70 } 71 } 72 }); 73 ok.setOnHoverListener(new LiftToActivateListener(getContext())); 74 } 75 76 // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts, 77 // not a separate view 78 View pinDelete = findViewById(R.id.delete_button); 79 if (pinDelete != null) { 80 pinDelete.setVisibility(View.VISIBLE); 81 pinDelete.setOnClickListener(new OnClickListener() { 82 public void onClick(View v) { 83 // check for time-based lockouts 84 if (mPasswordEntry.isEnabled()) { 85 CharSequence str = mPasswordEntry.getText(); 86 if (str.length() > 0) { 87 mPasswordEntry.setText(str.subSequence(0, str.length()-1)); 88 } 89 } 90 doHapticKeyClick(); 91 } 92 }); 93 pinDelete.setOnLongClickListener(new View.OnLongClickListener() { 94 public boolean onLongClick(View v) { 95 // check for time-based lockouts 96 if (mPasswordEntry.isEnabled()) { 97 mPasswordEntry.setText(""); 98 } 99 doHapticKeyClick(); 100 return true; 101 } 102 }); 103 } 104 105 mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance()); 106 mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER 107 | InputType.TYPE_NUMBER_VARIATION_PASSWORD); 108 109 mPasswordEntry.requestFocus(); 110 } 111 112 @Override 113 public void showUsabilityHint() { 114 } 115 116 @Override 117 public int getWrongPasswordStringId() { 118 return R.string.kg_wrong_pin; 119 } 120} 121