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 KeyguardPinBasedInputView(Context context)45 public KeyguardPinBasedInputView(Context context) { 46 this(context, null); 47 } 48 KeyguardPinBasedInputView(Context context, AttributeSet attrs)49 public KeyguardPinBasedInputView(Context context, AttributeSet attrs) { 50 super(context, attrs); 51 } 52 53 @Override reset()54 public void reset() { 55 mPasswordEntry.requestFocus(); 56 super.reset(); 57 } 58 59 @Override onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect)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 resetState()66 protected void resetState() { 67 setPasswordEntryEnabled(true); 68 } 69 70 @Override setPasswordEntryEnabled(boolean enabled)71 protected void setPasswordEntryEnabled(boolean enabled) { 72 mPasswordEntry.setEnabled(enabled); 73 mOkButton.setEnabled(enabled); 74 } 75 76 @Override setPasswordEntryInputEnabled(boolean enabled)77 protected void setPasswordEntryInputEnabled(boolean enabled) { 78 mPasswordEntry.setEnabled(enabled); 79 mOkButton.setEnabled(enabled); 80 } 81 82 @Override onKeyDown(int keyCode, KeyEvent event)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 return super.onKeyDown(keyCode, event); 97 } 98 99 @Override getPromtReasonStringRes(int reason)100 protected int getPromtReasonStringRes(int reason) { 101 switch (reason) { 102 case PROMPT_REASON_RESTART: 103 return R.string.kg_prompt_reason_restart_pin; 104 case PROMPT_REASON_TIMEOUT: 105 return R.string.kg_prompt_reason_timeout_pin; 106 default: 107 return 0; 108 } 109 } 110 performClick(View view)111 private void performClick(View view) { 112 view.performClick(); 113 } 114 performNumberClick(int number)115 private void performNumberClick(int number) { 116 switch (number) { 117 case 0: 118 performClick(mButton0); 119 break; 120 case 1: 121 performClick(mButton1); 122 break; 123 case 2: 124 performClick(mButton2); 125 break; 126 case 3: 127 performClick(mButton3); 128 break; 129 case 4: 130 performClick(mButton4); 131 break; 132 case 5: 133 performClick(mButton5); 134 break; 135 case 6: 136 performClick(mButton6); 137 break; 138 case 7: 139 performClick(mButton7); 140 break; 141 case 8: 142 performClick(mButton8); 143 break; 144 case 9: 145 performClick(mButton9); 146 break; 147 } 148 } 149 150 @Override resetPasswordText(boolean animate)151 protected void resetPasswordText(boolean animate) { 152 mPasswordEntry.reset(animate); 153 } 154 155 @Override getPasswordText()156 protected String getPasswordText() { 157 return mPasswordEntry.getText(); 158 } 159 160 @Override onFinishInflate()161 protected void onFinishInflate() { 162 mPasswordEntry = (PasswordTextView) findViewById(getPasswordTextViewId()); 163 mPasswordEntry.setOnKeyListener(this); 164 165 // Set selected property on so the view can send accessibility events. 166 mPasswordEntry.setSelected(true); 167 168 mPasswordEntry.setUserActivityListener(new PasswordTextView.UserActivityListener() { 169 @Override 170 public void onUserActivity() { 171 onUserInput(); 172 } 173 }); 174 175 mOkButton = findViewById(R.id.key_enter); 176 if (mOkButton != null) { 177 mOkButton.setOnClickListener(new View.OnClickListener() { 178 @Override 179 public void onClick(View v) { 180 doHapticKeyClick(); 181 if (mPasswordEntry.isEnabled()) { 182 verifyPasswordAndUnlock(); 183 } 184 } 185 }); 186 mOkButton.setOnHoverListener(new LiftToActivateListener(getContext())); 187 } 188 189 mDeleteButton = findViewById(R.id.delete_button); 190 mDeleteButton.setVisibility(View.VISIBLE); 191 mDeleteButton.setOnClickListener(new OnClickListener() { 192 @Override 193 public void onClick(View v) { 194 // check for time-based lockouts 195 if (mPasswordEntry.isEnabled()) { 196 mPasswordEntry.deleteLastChar(); 197 } 198 doHapticKeyClick(); 199 } 200 }); 201 mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() { 202 @Override 203 public boolean onLongClick(View v) { 204 // check for time-based lockouts 205 if (mPasswordEntry.isEnabled()) { 206 resetPasswordText(true /* animate */); 207 } 208 doHapticKeyClick(); 209 return true; 210 } 211 }); 212 213 mButton0 = findViewById(R.id.key0); 214 mButton1 = findViewById(R.id.key1); 215 mButton2 = findViewById(R.id.key2); 216 mButton3 = findViewById(R.id.key3); 217 mButton4 = findViewById(R.id.key4); 218 mButton5 = findViewById(R.id.key5); 219 mButton6 = findViewById(R.id.key6); 220 mButton7 = findViewById(R.id.key7); 221 mButton8 = findViewById(R.id.key8); 222 mButton9 = findViewById(R.id.key9); 223 224 mPasswordEntry.requestFocus(); 225 super.onFinishInflate(); 226 } 227 228 @Override onKey(View v, int keyCode, KeyEvent event)229 public boolean onKey(View v, int keyCode, KeyEvent event) { 230 if (event.getAction() == KeyEvent.ACTION_DOWN) { 231 onKeyDown(keyCode, event); 232 return true; 233 } 234 return false; 235 } 236 } 237