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