• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.MotionEvent;
24 import android.view.View;
25 
26 /**
27  * A Pin based Keyguard input view
28  */
29 public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
30         implements View.OnKeyListener, View.OnTouchListener {
31 
32     protected PasswordTextView mPasswordEntry;
33     private View mOkButton;
34     private View mDeleteButton;
35     private View mButton0;
36     private View mButton1;
37     private View mButton2;
38     private View mButton3;
39     private View mButton4;
40     private View mButton5;
41     private View mButton6;
42     private View mButton7;
43     private View mButton8;
44     private View mButton9;
45 
KeyguardPinBasedInputView(Context context)46     public KeyguardPinBasedInputView(Context context) {
47         this(context, null);
48     }
49 
KeyguardPinBasedInputView(Context context, AttributeSet attrs)50     public KeyguardPinBasedInputView(Context context, AttributeSet attrs) {
51         super(context, attrs);
52     }
53 
54     @Override
reset()55     public void reset() {
56         mPasswordEntry.requestFocus();
57         super.reset();
58     }
59 
60     @Override
onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect)61     protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
62         // send focus to the password field
63         return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
64     }
65 
66     @Override
resetState()67     protected void resetState() {
68         setPasswordEntryEnabled(true);
69     }
70 
71     @Override
setPasswordEntryEnabled(boolean enabled)72     protected void setPasswordEntryEnabled(boolean enabled) {
73         mPasswordEntry.setEnabled(enabled);
74         mOkButton.setEnabled(enabled);
75     }
76 
77     @Override
setPasswordEntryInputEnabled(boolean enabled)78     protected void setPasswordEntryInputEnabled(boolean enabled) {
79         mPasswordEntry.setEnabled(enabled);
80         mOkButton.setEnabled(enabled);
81     }
82 
83     @Override
onKeyDown(int keyCode, KeyEvent event)84     public boolean onKeyDown(int keyCode, KeyEvent event) {
85         if (KeyEvent.isConfirmKey(keyCode)) {
86             performClick(mOkButton);
87             return true;
88         } else if (keyCode == KeyEvent.KEYCODE_DEL) {
89             performClick(mDeleteButton);
90             return true;
91         }
92         if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
93             int number = keyCode - KeyEvent.KEYCODE_0;
94             performNumberClick(number);
95             return true;
96         }
97         if (keyCode >= KeyEvent.KEYCODE_NUMPAD_0 && keyCode <= KeyEvent.KEYCODE_NUMPAD_9) {
98             int number = keyCode - KeyEvent.KEYCODE_NUMPAD_0;
99             performNumberClick(number);
100             return true;
101         }
102         return super.onKeyDown(keyCode, event);
103     }
104 
105     @Override
getPromtReasonStringRes(int reason)106     protected int getPromtReasonStringRes(int reason) {
107         switch (reason) {
108             case PROMPT_REASON_RESTART:
109                 return R.string.kg_prompt_reason_restart_pin;
110             case PROMPT_REASON_TIMEOUT:
111                 return R.string.kg_prompt_reason_timeout_pin;
112             case PROMPT_REASON_DEVICE_ADMIN:
113                 return R.string.kg_prompt_reason_device_admin;
114             case PROMPT_REASON_USER_REQUEST:
115                 return R.string.kg_prompt_reason_user_request;
116             case PROMPT_REASON_NONE:
117                 return 0;
118             default:
119                 return R.string.kg_prompt_reason_timeout_pin;
120         }
121     }
122 
performClick(View view)123     private void performClick(View view) {
124         view.performClick();
125     }
126 
performNumberClick(int number)127     private void performNumberClick(int number) {
128         switch (number) {
129             case 0:
130                 performClick(mButton0);
131                 break;
132             case 1:
133                 performClick(mButton1);
134                 break;
135             case 2:
136                 performClick(mButton2);
137                 break;
138             case 3:
139                 performClick(mButton3);
140                 break;
141             case 4:
142                 performClick(mButton4);
143                 break;
144             case 5:
145                 performClick(mButton5);
146                 break;
147             case 6:
148                 performClick(mButton6);
149                 break;
150             case 7:
151                 performClick(mButton7);
152                 break;
153             case 8:
154                 performClick(mButton8);
155                 break;
156             case 9:
157                 performClick(mButton9);
158                 break;
159         }
160     }
161 
162     @Override
resetPasswordText(boolean animate, boolean announce)163     protected void resetPasswordText(boolean animate, boolean announce) {
164         mPasswordEntry.reset(animate, announce);
165     }
166 
167     @Override
getPasswordText()168     protected String getPasswordText() {
169         return mPasswordEntry.getText();
170     }
171 
172     @Override
onFinishInflate()173     protected void onFinishInflate() {
174         mPasswordEntry = findViewById(getPasswordTextViewId());
175         mPasswordEntry.setOnKeyListener(this);
176 
177         // Set selected property on so the view can send accessibility events.
178         mPasswordEntry.setSelected(true);
179 
180         mPasswordEntry.setUserActivityListener(new PasswordTextView.UserActivityListener() {
181             @Override
182             public void onUserActivity() {
183                 onUserInput();
184             }
185         });
186 
187         mOkButton = findViewById(R.id.key_enter);
188         if (mOkButton != null) {
189             mOkButton.setOnTouchListener(this);
190             mOkButton.setOnClickListener(new View.OnClickListener() {
191                 @Override
192                 public void onClick(View v) {
193                     if (mPasswordEntry.isEnabled()) {
194                         verifyPasswordAndUnlock();
195                     }
196                 }
197             });
198             mOkButton.setOnHoverListener(new LiftToActivateListener(getContext()));
199         }
200 
201         mDeleteButton = findViewById(R.id.delete_button);
202         mDeleteButton.setVisibility(View.VISIBLE);
203         mDeleteButton.setOnTouchListener(this);
204         mDeleteButton.setOnClickListener(new OnClickListener() {
205             @Override
206             public void onClick(View v) {
207                 // check for time-based lockouts
208                 if (mPasswordEntry.isEnabled()) {
209                     mPasswordEntry.deleteLastChar();
210                 }
211             }
212         });
213         mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() {
214             @Override
215             public boolean onLongClick(View v) {
216                 // check for time-based lockouts
217                 if (mPasswordEntry.isEnabled()) {
218                     resetPasswordText(true /* animate */, true /* announce */);
219                 }
220                 doHapticKeyClick();
221                 return true;
222             }
223         });
224 
225         mButton0 = findViewById(R.id.key0);
226         mButton1 = findViewById(R.id.key1);
227         mButton2 = findViewById(R.id.key2);
228         mButton3 = findViewById(R.id.key3);
229         mButton4 = findViewById(R.id.key4);
230         mButton5 = findViewById(R.id.key5);
231         mButton6 = findViewById(R.id.key6);
232         mButton7 = findViewById(R.id.key7);
233         mButton8 = findViewById(R.id.key8);
234         mButton9 = findViewById(R.id.key9);
235 
236         mPasswordEntry.requestFocus();
237         super.onFinishInflate();
238     }
239 
240     @Override
onTouch(View v, MotionEvent event)241     public boolean onTouch(View v, MotionEvent event) {
242         if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
243             doHapticKeyClick();
244         }
245         return false;
246     }
247 
248     @Override
onKey(View v, int keyCode, KeyEvent event)249     public boolean onKey(View v, int keyCode, KeyEvent event) {
250         if (event.getAction() == KeyEvent.ACTION_DOWN) {
251             return onKeyDown(keyCode, event);
252         }
253         return false;
254     }
255 }
256