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