Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 1 | /* |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 2 | * Copyright (C) 2012 The Android Open Source Project |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 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 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 17 | package com.android.internal.policy.impl.keyguard; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 18 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 19 | import android.content.Context; |
| 20 | import android.util.AttributeSet; |
| 21 | import android.view.View; |
| 22 | |
| 23 | import com.android.internal.R; |
| 24 | import com.android.internal.widget.LockPatternUtils; |
Jim Miller | 858f8ea | 2011-08-19 14:50:34 -0700 | [diff] [blame] | 25 | import java.util.List; |
| 26 | |
Jim Miller | f7c5d0e | 2010-03-25 18:37:48 -0700 | [diff] [blame] | 27 | import android.app.admin.DevicePolicyManager; |
Jim Miller | 5475906 | 2010-03-11 15:46:29 -0800 | [diff] [blame] | 28 | import android.content.res.Configuration; |
Jim Miller | 148e73e | 2010-02-11 15:39:45 -0800 | [diff] [blame] | 29 | import android.graphics.Rect; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 30 | |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 31 | import com.android.internal.widget.PasswordEntryKeyboardView; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 32 | |
Jim Miller | f1818ff | 2010-03-17 19:14:18 -0700 | [diff] [blame] | 33 | import android.os.CountDownTimer; |
| 34 | import android.os.SystemClock; |
Jim Miller | 8ecfac1 | 2011-07-08 19:15:51 -0700 | [diff] [blame] | 35 | import android.text.Editable; |
Jim Miller | da3ae8f | 2011-04-14 15:13:49 -0700 | [diff] [blame] | 36 | import android.text.InputType; |
Jim Miller | 8ecfac1 | 2011-07-08 19:15:51 -0700 | [diff] [blame] | 37 | import android.text.TextWatcher; |
Jim Miller | 8b9dda2 | 2010-03-02 17:24:48 -0800 | [diff] [blame] | 38 | import android.text.method.DigitsKeyListener; |
| 39 | import android.text.method.TextKeyListener; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 40 | import android.view.KeyEvent; |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 41 | import android.view.inputmethod.EditorInfo; |
Jim Miller | 858f8ea | 2011-08-19 14:50:34 -0700 | [diff] [blame] | 42 | import android.view.inputmethod.InputMethodInfo; |
| 43 | import android.view.inputmethod.InputMethodManager; |
| 44 | import android.view.inputmethod.InputMethodSubtype; |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 45 | import android.widget.EditText; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 46 | import android.widget.LinearLayout; |
| 47 | import android.widget.TextView; |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 48 | import android.widget.TextView.OnEditorActionListener; |
| 49 | |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 50 | import com.android.internal.widget.PasswordEntryKeyboardHelper; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 51 | /** |
| 52 | * Displays a dialer-like interface or alphanumeric (latin-1) key entry for the user to enter |
| 53 | * an unlock password |
| 54 | */ |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 55 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 56 | public class KeyguardPasswordView extends LinearLayout |
Jim Miller | 9cf2c52 | 2012-10-04 22:02:29 -0700 | [diff] [blame] | 57 | implements KeyguardSecurityView, OnEditorActionListener, TextWatcher { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 58 | private KeyguardSecurityCallback mCallback; |
| 59 | private EditText mPasswordEntry; |
| 60 | private LockPatternUtils mLockPatternUtils; |
| 61 | private PasswordEntryKeyboardView mKeyboardView; |
| 62 | private PasswordEntryKeyboardHelper mKeyboardHelper; |
| 63 | private boolean mIsAlpha; |
| 64 | private KeyguardNavigationManager mNavigationManager; |
Jim Miller | 5475906 | 2010-03-11 15:46:29 -0800 | [diff] [blame] | 65 | |
Jim Miller | 6fe0f0e | 2010-01-27 17:53:18 -0800 | [diff] [blame] | 66 | // To avoid accidental lockout due to events while the device in in the pocket, ignore |
| 67 | // any passwords with length less than or equal to this length. |
| 68 | private static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3; |
| 69 | |
Jim Miller | ac8f575 | 2012-09-07 16:48:41 -0700 | [diff] [blame] | 70 | // Enable this if we want to hide the on-screen PIN keyboard when a physical one is showing |
| 71 | private static final boolean ENABLE_HIDE_KEYBOARD = false; |
| 72 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 73 | public KeyguardPasswordView(Context context) { |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 74 | super(context); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 75 | } |
Jim Miller | 5475906 | 2010-03-11 15:46:29 -0800 | [diff] [blame] | 76 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 77 | public KeyguardPasswordView(Context context, AttributeSet attrs) { |
| 78 | super(context, attrs); |
| 79 | } |
| 80 | |
| 81 | public void setKeyguardCallback(KeyguardSecurityCallback callback) { |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 82 | mCallback = callback; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 83 | } |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 84 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 85 | public void setLockPatternUtils(LockPatternUtils utils) { |
| 86 | mLockPatternUtils = utils; |
| 87 | } |
| 88 | |
| 89 | public void reset() { |
| 90 | // start fresh |
| 91 | mPasswordEntry.setText(""); |
| 92 | mPasswordEntry.requestFocus(); |
| 93 | |
| 94 | // if the user is currently locked out, enforce it. |
| 95 | long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); |
| 96 | if (deadline != 0) { |
| 97 | handleAttemptLockout(deadline); |
Jim Miller | 42b432d | 2010-02-12 18:56:03 -0800 | [diff] [blame] | 98 | } else { |
Jim Miller | 08b2b6b | 2012-09-14 19:12:40 -0700 | [diff] [blame] | 99 | resetState(); |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 100 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 101 | } |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 102 | |
Jim Miller | 08b2b6b | 2012-09-14 19:12:40 -0700 | [diff] [blame] | 103 | private void resetState() { |
| 104 | mNavigationManager.setMessage( |
| 105 | mIsAlpha ? R.string.kg_password_instructions : R.string.kg_pin_instructions); |
| 106 | mPasswordEntry.setEnabled(true); |
| 107 | mKeyboardView.setEnabled(true); |
| 108 | } |
| 109 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 110 | @Override |
| 111 | protected void onFinishInflate() { |
| 112 | mLockPatternUtils = new LockPatternUtils(mContext); // TODO: use common one |
Jae Yong Sung | 8171b51 | 2010-08-05 10:44:27 -0700 | [diff] [blame] | 113 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 114 | mNavigationManager = new KeyguardNavigationManager(this); |
| 115 | |
| 116 | final int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(); |
Konstantin Lopyrev | f9a166a | 2010-06-01 16:47:05 -0700 | [diff] [blame] | 117 | mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality |
Konstantin Lopyrev | a15dcfa | 2010-05-24 17:10:56 -0700 | [diff] [blame] | 118 | || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality |
| 119 | || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality; |
Jim Miller | f7c5d0e | 2010-03-25 18:37:48 -0700 | [diff] [blame] | 120 | |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 121 | mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard); |
| 122 | mPasswordEntry = (EditText) findViewById(R.id.passwordEntry); |
| 123 | mPasswordEntry.setOnEditorActionListener(this); |
Jim Miller | 9cf2c52 | 2012-10-04 22:02:29 -0700 | [diff] [blame] | 124 | mPasswordEntry.addTextChangedListener(this); |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 125 | |
Jim Miller | 3af630c | 2012-09-26 14:29:18 -0700 | [diff] [blame] | 126 | mKeyboardHelper = new PasswordEntryKeyboardHelper(mContext, mKeyboardView, this, false, |
| 127 | new int[] { |
| 128 | R.xml.kg_password_kbd_numeric, |
| 129 | com.android.internal.R.xml.password_kbd_qwerty, |
| 130 | com.android.internal.R.xml.password_kbd_qwerty_shifted, |
| 131 | com.android.internal.R.xml.password_kbd_symbols, |
| 132 | com.android.internal.R.xml.password_kbd_symbols_shift |
| 133 | } |
| 134 | ); |
Jeff Sharkey | 3fb0af3 | 2012-05-15 12:37:33 -0700 | [diff] [blame] | 135 | mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled()); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 136 | |
Jim Miller | d9d0945 | 2011-11-02 18:32:16 -0700 | [diff] [blame] | 137 | boolean imeOrDeleteButtonVisible = false; |
Jim Miller | 6b05d58 | 2011-07-18 13:09:59 -0700 | [diff] [blame] | 138 | if (mIsAlpha) { |
| 139 | // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard |
| 140 | mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); |
Jae Yong Sung | 8171b51 | 2010-08-05 10:44:27 -0700 | [diff] [blame] | 141 | mKeyboardView.setVisibility(View.GONE); |
Jim Miller | 6b05d58 | 2011-07-18 13:09:59 -0700 | [diff] [blame] | 142 | } else { |
Jim Miller | 6b05d58 | 2011-07-18 13:09:59 -0700 | [diff] [blame] | 143 | mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); |
Jim Miller | ac8f575 | 2012-09-07 16:48:41 -0700 | [diff] [blame] | 144 | |
| 145 | // Use lockscreen's numeric keyboard if the physical keyboard isn't showing |
| 146 | boolean hardKeyboardVisible = getResources().getConfiguration().hardKeyboardHidden |
| 147 | == Configuration.HARDKEYBOARDHIDDEN_NO; |
| 148 | mKeyboardView.setVisibility( |
| 149 | (ENABLE_HIDE_KEYBOARD && hardKeyboardVisible) ? View.INVISIBLE : View.VISIBLE); |
Ben Komalo | 51ea88a | 2011-10-03 10:53:26 -0700 | [diff] [blame] | 150 | |
| 151 | // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts, |
| 152 | // not a separate view |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 153 | View pinDelete = findViewById(R.id.delete_button); |
Ben Komalo | 51ea88a | 2011-10-03 10:53:26 -0700 | [diff] [blame] | 154 | if (pinDelete != null) { |
| 155 | pinDelete.setVisibility(View.VISIBLE); |
Jim Miller | d9d0945 | 2011-11-02 18:32:16 -0700 | [diff] [blame] | 156 | imeOrDeleteButtonVisible = true; |
Ben Komalo | 51ea88a | 2011-10-03 10:53:26 -0700 | [diff] [blame] | 157 | pinDelete.setOnClickListener(new OnClickListener() { |
Ben Komalo | 51ea88a | 2011-10-03 10:53:26 -0700 | [diff] [blame] | 158 | public void onClick(View v) { |
| 159 | mKeyboardHelper.handleBackspace(); |
| 160 | } |
| 161 | }); |
| 162 | } |
Jae Yong Sung | 8171b51 | 2010-08-05 10:44:27 -0700 | [diff] [blame] | 163 | } |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 164 | |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 165 | mPasswordEntry.requestFocus(); |
Jim Miller | 966b126 | 2010-02-18 19:55:29 -0800 | [diff] [blame] | 166 | |
Jim Miller | 8ecfac1 | 2011-07-08 19:15:51 -0700 | [diff] [blame] | 167 | // This allows keyboards with overlapping qwerty/numeric keys to choose just numeric keys. |
Konstantin Lopyrev | f9a166a | 2010-06-01 16:47:05 -0700 | [diff] [blame] | 168 | if (mIsAlpha) { |
Jim Miller | 8b9dda2 | 2010-03-02 17:24:48 -0800 | [diff] [blame] | 169 | mPasswordEntry.setKeyListener(TextKeyListener.getInstance()); |
Jim Miller | 8ecfac1 | 2011-07-08 19:15:51 -0700 | [diff] [blame] | 170 | mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT |
| 171 | | InputType.TYPE_TEXT_VARIATION_PASSWORD); |
Jim Miller | 8b9dda2 | 2010-03-02 17:24:48 -0800 | [diff] [blame] | 172 | } else { |
| 173 | mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance()); |
Jim Miller | 8ecfac1 | 2011-07-08 19:15:51 -0700 | [diff] [blame] | 174 | mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER |
| 175 | | InputType.TYPE_NUMBER_VARIATION_PASSWORD); |
Jim Miller | 8b9dda2 | 2010-03-02 17:24:48 -0800 | [diff] [blame] | 176 | } |
| 177 | |
Jim Miller | 6b05d58 | 2011-07-18 13:09:59 -0700 | [diff] [blame] | 178 | // Poke the wakelock any time the text is selected or modified |
| 179 | mPasswordEntry.setOnClickListener(new OnClickListener() { |
| 180 | public void onClick(View v) { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 181 | mCallback.userActivity(0); // TODO: customize timeout for text? |
Jim Miller | 6b05d58 | 2011-07-18 13:09:59 -0700 | [diff] [blame] | 182 | } |
| 183 | }); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 184 | |
Jim Miller | 8ecfac1 | 2011-07-08 19:15:51 -0700 | [diff] [blame] | 185 | mPasswordEntry.addTextChangedListener(new TextWatcher() { |
| 186 | public void onTextChanged(CharSequence s, int start, int before, int count) { |
| 187 | } |
| 188 | |
| 189 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
| 190 | } |
| 191 | |
| 192 | public void afterTextChanged(Editable s) { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 193 | mCallback.userActivity(0); |
Jim Miller | 8ecfac1 | 2011-07-08 19:15:51 -0700 | [diff] [blame] | 194 | } |
| 195 | }); |
Jim Miller | 858f8ea | 2011-08-19 14:50:34 -0700 | [diff] [blame] | 196 | |
| 197 | // If there's more than one IME, enable the IME switcher button |
| 198 | View switchImeButton = findViewById(R.id.switch_ime_button); |
| 199 | final InputMethodManager imm = (InputMethodManager) getContext().getSystemService( |
| 200 | Context.INPUT_METHOD_SERVICE); |
Jim Miller | b0166bc | 2011-08-28 15:00:29 -0700 | [diff] [blame] | 201 | if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) { |
Jim Miller | 858f8ea | 2011-08-19 14:50:34 -0700 | [diff] [blame] | 202 | switchImeButton.setVisibility(View.VISIBLE); |
Jim Miller | d9d0945 | 2011-11-02 18:32:16 -0700 | [diff] [blame] | 203 | imeOrDeleteButtonVisible = true; |
Jim Miller | 858f8ea | 2011-08-19 14:50:34 -0700 | [diff] [blame] | 204 | switchImeButton.setOnClickListener(new OnClickListener() { |
| 205 | public void onClick(View v) { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 206 | mCallback.userActivity(0); // Leave the screen on a bit longer |
Jim Miller | 858f8ea | 2011-08-19 14:50:34 -0700 | [diff] [blame] | 207 | imm.showInputMethodPicker(); |
| 208 | } |
| 209 | }); |
| 210 | } |
Jim Miller | d9d0945 | 2011-11-02 18:32:16 -0700 | [diff] [blame] | 211 | |
| 212 | // If no icon is visible, reset the left margin on the password field so the text is |
| 213 | // still centered. |
| 214 | if (!imeOrDeleteButtonVisible) { |
| 215 | android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams(); |
| 216 | if (params instanceof MarginLayoutParams) { |
| 217 | ((MarginLayoutParams)params).leftMargin = 0; |
| 218 | mPasswordEntry.setLayoutParams(params); |
| 219 | } |
| 220 | } |
Jim Miller | 858f8ea | 2011-08-19 14:50:34 -0700 | [diff] [blame] | 221 | } |
| 222 | |
| 223 | /** |
| 224 | * Method adapted from com.android.inputmethod.latin.Utils |
| 225 | * |
| 226 | * @param imm The input method manager |
| 227 | * @param shouldIncludeAuxiliarySubtypes |
| 228 | * @return true if we have multiple IMEs to choose from |
| 229 | */ |
| 230 | private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm, |
| 231 | final boolean shouldIncludeAuxiliarySubtypes) { |
| 232 | final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); |
| 233 | |
| 234 | // Number of the filtered IMEs |
| 235 | int filteredImisCount = 0; |
| 236 | |
| 237 | for (InputMethodInfo imi : enabledImis) { |
| 238 | // We can return true immediately after we find two or more filtered IMEs. |
| 239 | if (filteredImisCount > 1) return true; |
| 240 | final List<InputMethodSubtype> subtypes = |
| 241 | imm.getEnabledInputMethodSubtypeList(imi, true); |
| 242 | // IMEs that have no subtypes should be counted. |
| 243 | if (subtypes.isEmpty()) { |
| 244 | ++filteredImisCount; |
| 245 | continue; |
| 246 | } |
| 247 | |
| 248 | int auxCount = 0; |
| 249 | for (InputMethodSubtype subtype : subtypes) { |
| 250 | if (subtype.isAuxiliary()) { |
| 251 | ++auxCount; |
| 252 | } |
| 253 | } |
| 254 | final int nonAuxCount = subtypes.size() - auxCount; |
| 255 | |
| 256 | // IMEs that have one or more non-auxiliary subtypes should be counted. |
| 257 | // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary |
| 258 | // subtypes should be counted as well. |
| 259 | if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) { |
| 260 | ++filteredImisCount; |
| 261 | continue; |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | return filteredImisCount > 1 |
| 266 | // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled |
| 267 | // input method subtype (The current IME should be LatinIME.) |
| 268 | || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 269 | } |
| 270 | |
Jim Miller | 148e73e | 2010-02-11 15:39:45 -0800 | [diff] [blame] | 271 | @Override |
| 272 | protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { |
| 273 | // send focus to the password field |
| 274 | return mPasswordEntry.requestFocus(direction, previouslyFocusedRect); |
| 275 | } |
| 276 | |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 277 | private void verifyPasswordAndUnlock() { |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 278 | String entry = mPasswordEntry.getText().toString(); |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 279 | if (mLockPatternUtils.checkPassword(entry)) { |
Jim Miller | 6fe0f0e | 2010-01-27 17:53:18 -0800 | [diff] [blame] | 280 | mCallback.reportSuccessfulUnlockAttempt(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 281 | mCallback.dismiss(true); |
Jim Miller | 6fe0f0e | 2010-01-27 17:53:18 -0800 | [diff] [blame] | 282 | } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) { |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 283 | // to avoid accidental lockout, only count attempts that are long enough to be a |
| 284 | // real password. This may require some tweaking. |
Jim Miller | 6fe0f0e | 2010-01-27 17:53:18 -0800 | [diff] [blame] | 285 | mCallback.reportFailedUnlockAttempt(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 286 | if (0 == (mCallback.getFailedAttempts() |
Jim Miller | f1818ff | 2010-03-17 19:14:18 -0700 | [diff] [blame] | 287 | % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) { |
| 288 | long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); |
| 289 | handleAttemptLockout(deadline); |
| 290 | } |
Jim Miller | d36ebe0 | 2012-08-31 17:42:42 -0700 | [diff] [blame] | 291 | mNavigationManager.setMessage( |
| 292 | mIsAlpha ? R.string.kg_wrong_password : R.string.kg_wrong_pin); |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 293 | } |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 294 | mPasswordEntry.setText(""); |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 295 | } |
| 296 | |
Jim Miller | f1818ff | 2010-03-17 19:14:18 -0700 | [diff] [blame] | 297 | // Prevent user from using the PIN/Password entry until scheduled deadline. |
| 298 | private void handleAttemptLockout(long elapsedRealtimeDeadline) { |
| 299 | mPasswordEntry.setEnabled(false); |
| 300 | mKeyboardView.setEnabled(false); |
| 301 | long elapsedRealtime = SystemClock.elapsedRealtime(); |
Ben Komalo | 51ea88a | 2011-10-03 10:53:26 -0700 | [diff] [blame] | 302 | new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) { |
Jim Miller | f1818ff | 2010-03-17 19:14:18 -0700 | [diff] [blame] | 303 | |
| 304 | @Override |
| 305 | public void onTick(long millisUntilFinished) { |
| 306 | int secondsRemaining = (int) (millisUntilFinished / 1000); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 307 | mNavigationManager.setMessage( |
| 308 | R.string.kg_too_many_failed_attempts_countdown, secondsRemaining); |
Jim Miller | f1818ff | 2010-03-17 19:14:18 -0700 | [diff] [blame] | 309 | } |
| 310 | |
| 311 | @Override |
| 312 | public void onFinish() { |
Jim Miller | 08b2b6b | 2012-09-14 19:12:40 -0700 | [diff] [blame] | 313 | resetState(); |
Jim Miller | f1818ff | 2010-03-17 19:14:18 -0700 | [diff] [blame] | 314 | } |
| 315 | }.start(); |
| 316 | } |
| 317 | |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 318 | @Override |
| 319 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 320 | mCallback.userActivity(0); |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 321 | return false; |
| 322 | } |
| 323 | |
Dianne Hackborn | 7578739 | 2010-03-18 01:04:37 -0700 | [diff] [blame] | 324 | @Override |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 325 | public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { |
| 326 | // Check if this was the result of hitting the enter key |
Jim Miller | 1c18828 | 2011-08-08 22:27:58 -0700 | [diff] [blame] | 327 | if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE |
| 328 | || actionId == EditorInfo.IME_ACTION_NEXT) { |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 329 | verifyPasswordAndUnlock(); |
| 330 | return true; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 331 | } |
Jim Miller | a781d01 | 2010-02-05 18:59:25 -0800 | [diff] [blame] | 332 | return false; |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 333 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 334 | |
| 335 | @Override |
| 336 | public boolean needsInput() { |
| 337 | return mIsAlpha; |
| 338 | } |
| 339 | |
| 340 | @Override |
| 341 | public void onPause() { |
| 342 | |
| 343 | } |
| 344 | |
| 345 | @Override |
| 346 | public void onResume() { |
| 347 | reset(); |
| 348 | } |
| 349 | |
| 350 | @Override |
| 351 | public KeyguardSecurityCallback getCallback() { |
| 352 | return mCallback; |
| 353 | } |
| 354 | |
Jim Miller | 9cf2c52 | 2012-10-04 22:02:29 -0700 | [diff] [blame] | 355 | @Override |
| 356 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
| 357 | if (mCallback != null) { |
| 358 | mCallback.userActivity(KeyguardViewManager.DIGIT_PRESS_WAKE_MILLIS); |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | @Override |
| 363 | public void onTextChanged(CharSequence s, int start, int before, int count) { |
| 364 | } |
| 365 | |
| 366 | @Override |
| 367 | public void afterTextChanged(Editable s) { |
| 368 | } |
| 369 | |
Jim Miller | 5e0f7ba | 2009-12-22 19:04:23 -0800 | [diff] [blame] | 370 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 371 | |