Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2012 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 | |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 17 | package com.android.keyguard; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 18 | |
Jason Monk | ea03be1 | 2017-12-04 11:08:41 -0500 | [diff] [blame] | 19 | import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL; |
| 20 | import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL_UNLOCKED; |
Jorim Jaggi | d056517 | 2016-09-15 16:31:14 -0700 | [diff] [blame] | 21 | |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 22 | import android.content.Context; |
Jason Chang | 1e4a4bd | 2018-05-22 17:30:19 +0800 | [diff] [blame] | 23 | import android.content.res.ColorStateList; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 24 | import android.os.AsyncTask; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 25 | import android.os.CountDownTimer; |
| 26 | import android.os.SystemClock; |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 27 | import android.util.AttributeSet; |
| 28 | import android.view.HapticFeedbackConstants; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 29 | import android.view.KeyEvent; |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 30 | import android.view.View; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 31 | import android.widget.LinearLayout; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 32 | |
Jason Monk | ea03be1 | 2017-12-04 11:08:41 -0500 | [diff] [blame] | 33 | import com.android.internal.util.LatencyTracker; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 34 | import com.android.internal.widget.LockPatternChecker; |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 35 | import com.android.internal.widget.LockPatternUtils; |
Sunny Goyal | 87fccf0 | 2019-08-13 17:39:10 -0700 | [diff] [blame] | 36 | import com.android.systemui.R; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 37 | |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 38 | import java.util.Arrays; |
| 39 | |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 40 | /** |
| 41 | * Base class for PIN and password unlock screens. |
| 42 | */ |
| 43 | public abstract class KeyguardAbsKeyInputView extends LinearLayout |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 44 | implements KeyguardSecurityView, EmergencyButton.EmergencyButtonCallback { |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 45 | protected KeyguardSecurityCallback mCallback; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 46 | protected LockPatternUtils mLockPatternUtils; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 47 | protected AsyncTask<?, ?, ?> mPendingLockCheck; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 48 | protected SecurityMessageDisplay mSecurityMessageDisplay; |
Chris Wren | c0ae9e6 | 2012-11-05 13:16:31 -0500 | [diff] [blame] | 49 | protected View mEcaView; |
Daniel Sandler | acb60fb | 2012-10-25 10:46:37 -0400 | [diff] [blame] | 50 | protected boolean mEnableHaptics; |
Jim Miller | ed7dcc2 | 2015-08-25 19:36:22 -0700 | [diff] [blame] | 51 | private boolean mDismissing; |
lumark | d62bfd2 | 2019-01-10 15:29:11 +0800 | [diff] [blame] | 52 | protected boolean mResumed; |
Hidenari Koshimae | 5be868c | 2014-08-21 11:27:33 +0200 | [diff] [blame] | 53 | private CountDownTimer mCountdownTimer = null; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 54 | |
| 55 | // To avoid accidental lockout due to events while the device in in the pocket, ignore |
| 56 | // any passwords with length less than or equal to this length. |
| 57 | protected static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3; |
| 58 | |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 59 | public KeyguardAbsKeyInputView(Context context) { |
| 60 | this(context, null); |
| 61 | } |
| 62 | |
| 63 | public KeyguardAbsKeyInputView(Context context, AttributeSet attrs) { |
| 64 | super(context, attrs); |
| 65 | } |
| 66 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 67 | @Override |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 68 | public void setKeyguardCallback(KeyguardSecurityCallback callback) { |
| 69 | mCallback = callback; |
| 70 | } |
| 71 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 72 | @Override |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 73 | public void setLockPatternUtils(LockPatternUtils utils) { |
| 74 | mLockPatternUtils = utils; |
Daniel Sandler | acb60fb | 2012-10-25 10:46:37 -0400 | [diff] [blame] | 75 | mEnableHaptics = mLockPatternUtils.isTactileFeedbackEnabled(); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 76 | } |
| 77 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 78 | @Override |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 79 | public void reset() { |
| 80 | // start fresh |
Jim Miller | ed7dcc2 | 2015-08-25 19:36:22 -0700 | [diff] [blame] | 81 | mDismissing = false; |
Jim Miller | 4db942c | 2016-05-16 18:06:50 -0700 | [diff] [blame] | 82 | resetPasswordText(false /* animate */, false /* announce */); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 83 | // if the user is currently locked out, enforce it. |
Adrian Roos | 8150d2a | 2015-04-16 17:11:20 -0700 | [diff] [blame] | 84 | long deadline = mLockPatternUtils.getLockoutAttemptDeadline( |
Adrian Roos | d6aa6cb | 2015-04-16 19:31:29 -0700 | [diff] [blame] | 85 | KeyguardUpdateMonitor.getCurrentUser()); |
Jim Miller | 7d5e00a | 2013-10-11 22:45:57 -0700 | [diff] [blame] | 86 | if (shouldLockout(deadline)) { |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 87 | handleAttemptLockout(deadline); |
| 88 | } else { |
| 89 | resetState(); |
| 90 | } |
| 91 | } |
| 92 | |
Jim Miller | 7d5e00a | 2013-10-11 22:45:57 -0700 | [diff] [blame] | 93 | // Allow subclasses to override this behavior |
| 94 | protected boolean shouldLockout(long deadline) { |
| 95 | return deadline != 0; |
| 96 | } |
| 97 | |
Daniel Sandler | 8a26bf5 | 2012-10-30 13:29:50 -0400 | [diff] [blame] | 98 | protected abstract int getPasswordTextViewId(); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 99 | protected abstract void resetState(); |
| 100 | |
| 101 | @Override |
| 102 | protected void onFinishInflate() { |
Daniel Sandler | acb60fb | 2012-10-25 10:46:37 -0400 | [diff] [blame] | 103 | mLockPatternUtils = new LockPatternUtils(mContext); |
Chris Wren | c0ae9e6 | 2012-11-05 13:16:31 -0500 | [diff] [blame] | 104 | mEcaView = findViewById(R.id.keyguard_selector_fade_container); |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 105 | |
Alan Viverette | 51efddb | 2017-04-05 10:00:01 -0400 | [diff] [blame] | 106 | EmergencyButton button = findViewById(R.id.emergency_call_button); |
Andrew Lee | f98f7b9 | 2015-02-02 15:50:29 -0800 | [diff] [blame] | 107 | if (button != null) { |
| 108 | button.setCallback(this); |
| 109 | } |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 110 | } |
| 111 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 112 | @Override |
Lucas Dupin | 2e838ac | 2019-04-17 16:50:58 -0700 | [diff] [blame] | 113 | protected void onAttachedToWindow() { |
| 114 | super.onAttachedToWindow(); |
| 115 | mSecurityMessageDisplay = KeyguardMessageArea.findSecurityMessageDisplay(this); |
| 116 | } |
| 117 | |
| 118 | @Override |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 119 | public void onEmergencyButtonClickedWhenInCall() { |
| 120 | mCallback.reset(); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 121 | } |
| 122 | |
Daniel Sandler | 261b18a | 2012-11-01 23:54:03 -0400 | [diff] [blame] | 123 | /* |
| 124 | * Override this if you have a different string for "wrong password" |
| 125 | * |
| 126 | * Note that PIN/PUK have their own implementation of verifyPasswordAndUnlock and so don't need this |
| 127 | */ |
| 128 | protected int getWrongPasswordStringId() { |
| 129 | return R.string.kg_wrong_password; |
| 130 | } |
| 131 | |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 132 | protected void verifyPasswordAndUnlock() { |
Jim Miller | ed7dcc2 | 2015-08-25 19:36:22 -0700 | [diff] [blame] | 133 | if (mDismissing) return; // already verified but haven't been dismissed; don't do it again. |
| 134 | |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 135 | final byte[] entry = getPasswordText(); |
Xiyuan Xia | de26ea6 | 2015-05-19 15:00:41 -0700 | [diff] [blame] | 136 | setPasswordEntryInputEnabled(false); |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 137 | if (mPendingLockCheck != null) { |
| 138 | mPendingLockCheck.cancel(false); |
| 139 | } |
Andres Morales | 2397427 | 2015-05-14 22:42:26 -0700 | [diff] [blame] | 140 | |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 141 | final int userId = KeyguardUpdateMonitor.getCurrentUser(); |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 142 | if (entry.length <= MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) { |
Andres Morales | 2397427 | 2015-05-14 22:42:26 -0700 | [diff] [blame] | 143 | // to avoid accidental lockout, only count attempts that are long enough to be a |
| 144 | // real password. This may require some tweaking. |
| 145 | setPasswordEntryInputEnabled(true); |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 146 | onPasswordChecked(userId, false /* matched */, 0, false /* not valid - too short */); |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 147 | Arrays.fill(entry, (byte) 0); |
Andres Morales | 2397427 | 2015-05-14 22:42:26 -0700 | [diff] [blame] | 148 | return; |
| 149 | } |
| 150 | |
Jorim Jaggi | d056517 | 2016-09-15 16:31:14 -0700 | [diff] [blame] | 151 | if (LatencyTracker.isEnabled(mContext)) { |
| 152 | LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL); |
| 153 | LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL_UNLOCKED); |
| 154 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 155 | mPendingLockCheck = LockPatternChecker.checkPassword( |
| 156 | mLockPatternUtils, |
| 157 | entry, |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 158 | userId, |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 159 | new LockPatternChecker.OnCheckCallback() { |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 160 | |
| 161 | @Override |
| 162 | public void onEarlyMatched() { |
Jorim Jaggi | d056517 | 2016-09-15 16:31:14 -0700 | [diff] [blame] | 163 | if (LatencyTracker.isEnabled(mContext)) { |
| 164 | LatencyTracker.getInstance(mContext).onActionEnd( |
| 165 | ACTION_CHECK_CREDENTIAL); |
| 166 | } |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 167 | onPasswordChecked(userId, true /* matched */, 0 /* timeoutMs */, |
| 168 | true /* isValidPassword */); |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 169 | Arrays.fill(entry, (byte) 0); |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 170 | } |
| 171 | |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 172 | @Override |
Andres Morales | 2397427 | 2015-05-14 22:42:26 -0700 | [diff] [blame] | 173 | public void onChecked(boolean matched, int timeoutMs) { |
Jorim Jaggi | d056517 | 2016-09-15 16:31:14 -0700 | [diff] [blame] | 174 | if (LatencyTracker.isEnabled(mContext)) { |
| 175 | LatencyTracker.getInstance(mContext).onActionEnd( |
| 176 | ACTION_CHECK_CREDENTIAL_UNLOCKED); |
| 177 | } |
Xiyuan Xia | de26ea6 | 2015-05-19 15:00:41 -0700 | [diff] [blame] | 178 | setPasswordEntryInputEnabled(true); |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 179 | mPendingLockCheck = null; |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 180 | if (!matched) { |
| 181 | onPasswordChecked(userId, false /* matched */, timeoutMs, |
| 182 | true /* isValidPassword */); |
| 183 | } |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 184 | Arrays.fill(entry, (byte) 0); |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 185 | } |
Jorim Jaggi | ed3032b | 2016-10-07 16:49:34 +0200 | [diff] [blame] | 186 | |
| 187 | @Override |
| 188 | public void onCancelled() { |
| 189 | // We already got dismissed with the early matched callback, so we cancelled |
| 190 | // the check. However, we still need to note down the latency. |
| 191 | if (LatencyTracker.isEnabled(mContext)) { |
| 192 | LatencyTracker.getInstance(mContext).onActionEnd( |
| 193 | ACTION_CHECK_CREDENTIAL_UNLOCKED); |
| 194 | } |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 195 | Arrays.fill(entry, (byte) 0); |
Jorim Jaggi | ed3032b | 2016-10-07 16:49:34 +0200 | [diff] [blame] | 196 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 197 | }); |
| 198 | } |
| 199 | |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 200 | private void onPasswordChecked(int userId, boolean matched, int timeoutMs, |
| 201 | boolean isValidPassword) { |
| 202 | boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 203 | if (matched) { |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 204 | mCallback.reportUnlockAttempt(userId, true, 0); |
| 205 | if (dismissKeyguard) { |
| 206 | mDismissing = true; |
Vadim Tryshev | 8702ca7 | 2016-04-22 08:14:12 -0700 | [diff] [blame] | 207 | mCallback.dismiss(true, userId); |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 208 | } |
Jim Miller | 526ed2d | 2014-05-19 11:28:32 -0700 | [diff] [blame] | 209 | } else { |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 210 | if (isValidPassword) { |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 211 | mCallback.reportUnlockAttempt(userId, false, timeoutMs); |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 212 | if (timeoutMs > 0) { |
| 213 | long deadline = mLockPatternUtils.setLockoutAttemptDeadline( |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 214 | userId, timeoutMs); |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 215 | handleAttemptLockout(deadline); |
| 216 | } |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 217 | } |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 218 | if (timeoutMs == 0) { |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 219 | mSecurityMessageDisplay.setMessage(getWrongPasswordStringId()); |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 220 | } |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 221 | } |
Jim Miller | 4db942c | 2016-05-16 18:06:50 -0700 | [diff] [blame] | 222 | resetPasswordText(true /* animate */, !matched /* announce deletion if no match */); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 223 | } |
| 224 | |
Jim Miller | 4db942c | 2016-05-16 18:06:50 -0700 | [diff] [blame] | 225 | protected abstract void resetPasswordText(boolean animate, boolean announce); |
Rich Cannings | f64ec63 | 2019-02-21 12:40:36 -0800 | [diff] [blame] | 226 | protected abstract byte[] getPasswordText(); |
Selim Cinek | 4e8b9ed | 2014-06-20 16:37:04 -0700 | [diff] [blame] | 227 | protected abstract void setPasswordEntryEnabled(boolean enabled); |
Xiyuan Xia | de26ea6 | 2015-05-19 15:00:41 -0700 | [diff] [blame] | 228 | protected abstract void setPasswordEntryInputEnabled(boolean enabled); |
Selim Cinek | 4e8b9ed | 2014-06-20 16:37:04 -0700 | [diff] [blame] | 229 | |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 230 | // Prevent user from using the PIN/Password entry until scheduled deadline. |
| 231 | protected void handleAttemptLockout(long elapsedRealtimeDeadline) { |
Selim Cinek | 4e8b9ed | 2014-06-20 16:37:04 -0700 | [diff] [blame] | 232 | setPasswordEntryEnabled(false); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 233 | long elapsedRealtime = SystemClock.elapsedRealtime(); |
Hidenari Koshimae | 5be868c | 2014-08-21 11:27:33 +0200 | [diff] [blame] | 234 | long secondsInFuture = (long) Math.ceil( |
| 235 | (elapsedRealtimeDeadline - elapsedRealtime) / 1000.0); |
| 236 | mCountdownTimer = new CountDownTimer(secondsInFuture * 1000, 1000) { |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 237 | |
| 238 | @Override |
| 239 | public void onTick(long millisUntilFinished) { |
Hidenari Koshimae | 5be868c | 2014-08-21 11:27:33 +0200 | [diff] [blame] | 240 | int secondsRemaining = (int) Math.round(millisUntilFinished / 1000.0); |
Kevin Chyn | e01c5e1 | 2017-08-29 19:04:25 -0700 | [diff] [blame] | 241 | mSecurityMessageDisplay.setMessage(mContext.getResources().getQuantityString( |
| 242 | R.plurals.kg_too_many_failed_attempts_countdown, |
| 243 | secondsRemaining, secondsRemaining)); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 244 | } |
| 245 | |
| 246 | @Override |
| 247 | public void onFinish() { |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 248 | mSecurityMessageDisplay.setMessage(""); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 249 | resetState(); |
| 250 | } |
| 251 | }.start(); |
| 252 | } |
| 253 | |
Xiyuan Xia | 09eb033 | 2015-05-13 15:29:42 -0700 | [diff] [blame] | 254 | protected void onUserInput() { |
| 255 | if (mCallback != null) { |
| 256 | mCallback.userActivity(); |
Lucas Dupin | ccf6721 | 2019-08-07 12:53:02 -0700 | [diff] [blame] | 257 | mCallback.onUserInput(); |
Xiyuan Xia | 09eb033 | 2015-05-13 15:29:42 -0700 | [diff] [blame] | 258 | } |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 259 | mSecurityMessageDisplay.setMessage(""); |
Xiyuan Xia | 09eb033 | 2015-05-13 15:29:42 -0700 | [diff] [blame] | 260 | } |
| 261 | |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 262 | @Override |
| 263 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
Lucas Dupin | 29e796d | 2018-05-10 15:31:20 -0700 | [diff] [blame] | 264 | // Fingerprint sensor sends a KeyEvent.KEYCODE_UNKNOWN. |
| 265 | // We don't want to consider it valid user input because the UI |
| 266 | // will already respond to the event. |
| 267 | if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { |
| 268 | onUserInput(); |
| 269 | } |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 270 | return false; |
| 271 | } |
| 272 | |
| 273 | @Override |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 274 | public boolean needsInput() { |
| 275 | return false; |
| 276 | } |
| 277 | |
| 278 | @Override |
| 279 | public void onPause() { |
lumark | d62bfd2 | 2019-01-10 15:29:11 +0800 | [diff] [blame] | 280 | mResumed = false; |
| 281 | |
Hidenari Koshimae | 5be868c | 2014-08-21 11:27:33 +0200 | [diff] [blame] | 282 | if (mCountdownTimer != null) { |
| 283 | mCountdownTimer.cancel(); |
| 284 | mCountdownTimer = null; |
| 285 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 286 | if (mPendingLockCheck != null) { |
| 287 | mPendingLockCheck.cancel(false); |
| 288 | mPendingLockCheck = null; |
| 289 | } |
Lucas Dupin | 2986c15 | 2018-04-09 20:49:41 -0700 | [diff] [blame] | 290 | reset(); |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 291 | } |
| 292 | |
| 293 | @Override |
Chris Wren | a042ac9 | 2012-11-07 11:37:06 -0500 | [diff] [blame] | 294 | public void onResume(int reason) { |
lumark | d62bfd2 | 2019-01-10 15:29:11 +0800 | [diff] [blame] | 295 | mResumed = true; |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | @Override |
| 299 | public KeyguardSecurityCallback getCallback() { |
| 300 | return mCallback; |
| 301 | } |
| 302 | |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 303 | @Override |
| 304 | public void showPromptReason(int reason) { |
| 305 | if (reason != PROMPT_REASON_NONE) { |
Lucas Dupin | c80c67e | 2017-12-04 14:29:10 -0800 | [diff] [blame] | 306 | int promtReasonStringRes = getPromptReasonStringRes(reason); |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 307 | if (promtReasonStringRes != 0) { |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 308 | mSecurityMessageDisplay.setMessage(promtReasonStringRes); |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 309 | } |
| 310 | } |
| 311 | } |
| 312 | |
Selim Cinek | cfafe4e | 2015-08-11 14:58:44 -0700 | [diff] [blame] | 313 | @Override |
Jason Chang | 1e4a4bd | 2018-05-22 17:30:19 +0800 | [diff] [blame] | 314 | public void showMessage(CharSequence message, ColorStateList colorState) { |
Lucas Dupin | 51996bb | 2019-05-16 17:56:43 -0700 | [diff] [blame] | 315 | if (colorState != null) { |
| 316 | mSecurityMessageDisplay.setNextMessageColor(colorState); |
| 317 | } |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 318 | mSecurityMessageDisplay.setMessage(message); |
Selim Cinek | cfafe4e | 2015-08-11 14:58:44 -0700 | [diff] [blame] | 319 | } |
| 320 | |
Lucas Dupin | c80c67e | 2017-12-04 14:29:10 -0800 | [diff] [blame] | 321 | protected abstract int getPromptReasonStringRes(int reason); |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 322 | |
Daniel Sandler | acb60fb | 2012-10-25 10:46:37 -0400 | [diff] [blame] | 323 | // Cause a VIRTUAL_KEY vibration |
| 324 | public void doHapticKeyClick() { |
| 325 | if (mEnableHaptics) { |
| 326 | performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, |
| 327 | HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING |
| 328 | | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); |
| 329 | } |
| 330 | } |
Chris Wren | c0ae9e6 | 2012-11-05 13:16:31 -0500 | [diff] [blame] | 331 | |
| 332 | @Override |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 333 | public boolean startDisappearAnimation(Runnable finishRunnable) { |
| 334 | return false; |
| 335 | } |
Daniel Sandler | 69bdee7 | 2012-10-23 16:45:50 -0400 | [diff] [blame] | 336 | } |
| 337 | |