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