Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [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 | */ |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 16 | package com.android.keyguard; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 17 | |
Jason Monk | ea03be1 | 2017-12-04 11:08:41 -0500 | [diff] [blame] | 18 | import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL; |
| 19 | import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL_UNLOCKED; |
Jorim Jaggi | ed3032b | 2016-10-07 16:49:34 +0200 | [diff] [blame] | 20 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 21 | import android.content.Context; |
Jim Miller | 5737534 | 2012-09-09 15:20:31 -0700 | [diff] [blame] | 22 | import android.graphics.Rect; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 23 | import android.os.AsyncTask; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 24 | import android.os.CountDownTimer; |
| 25 | import android.os.SystemClock; |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 26 | import android.text.TextUtils; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 27 | import android.util.AttributeSet; |
| 28 | import android.util.Log; |
| 29 | import android.view.MotionEvent; |
| 30 | import android.view.View; |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 31 | import android.view.ViewGroup; |
Jorim Jaggi | 98f8530 | 2014-08-07 17:45:04 +0200 | [diff] [blame] | 32 | import android.view.animation.AnimationUtils; |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 33 | import android.view.animation.Interpolator; |
Jim Miller | 3af630c | 2012-09-26 14:29:18 -0700 | [diff] [blame] | 34 | import android.widget.LinearLayout; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 35 | |
Jason Monk | ea03be1 | 2017-12-04 11:08:41 -0500 | [diff] [blame] | 36 | import com.android.internal.util.LatencyTracker; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 37 | import com.android.internal.widget.LockPatternChecker; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 38 | import com.android.internal.widget.LockPatternUtils; |
| 39 | import com.android.internal.widget.LockPatternView; |
Jorim Jaggi | 5673353 | 2015-06-09 15:25:40 -0700 | [diff] [blame] | 40 | import com.android.settingslib.animation.AppearAnimationCreator; |
| 41 | import com.android.settingslib.animation.AppearAnimationUtils; |
| 42 | import com.android.settingslib.animation.DisappearAnimationUtils; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 43 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 44 | import java.util.List; |
| 45 | |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 46 | public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView, |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 47 | AppearAnimationCreator<LockPatternView.CellState>, |
| 48 | EmergencyButton.EmergencyButtonCallback { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 49 | |
| 50 | private static final String TAG = "SecurityPatternView"; |
Jorim Jaggi | 5cf1787 | 2014-03-26 18:31:48 +0100 | [diff] [blame] | 51 | private static final boolean DEBUG = KeyguardConstants.DEBUG; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 52 | |
| 53 | // how long before we clear the wrong pattern |
| 54 | private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000; |
| 55 | |
| 56 | // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK |
| 57 | private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000; |
| 58 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 59 | // how many cells the user has to cross before we poke the wakelock |
| 60 | private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2; |
| 61 | |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 62 | // How much we scale up the duration of the disappear animation when the current user is locked |
| 63 | public static final float DISAPPEAR_MULTIPLIER_LOCKED = 1.5f; |
| 64 | |
Adrian Roos | 7c11f8b | 2014-03-10 17:00:11 +0100 | [diff] [blame] | 65 | private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 66 | private final AppearAnimationUtils mAppearAnimationUtils; |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 67 | private final DisappearAnimationUtils mDisappearAnimationUtils; |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 68 | private final DisappearAnimationUtils mDisappearAnimationUtilsLocked; |
Adrian Roos | 7c11f8b | 2014-03-10 17:00:11 +0100 | [diff] [blame] | 69 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 70 | private CountDownTimer mCountdownTimer = null; |
| 71 | private LockPatternUtils mLockPatternUtils; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 72 | private AsyncTask<?, ?, ?> mPendingLockCheck; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 73 | private LockPatternView mLockPatternView; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 74 | private KeyguardSecurityCallback mCallback; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 75 | |
| 76 | /** |
| 77 | * Keeps track of the last time we poked the wake lock during dispatching of the touch event. |
| 78 | * Initialized to something guaranteed to make us poke the wakelock when the user starts |
| 79 | * drawing the pattern. |
| 80 | * @see #dispatchTouchEvent(android.view.MotionEvent) |
| 81 | */ |
| 82 | private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS; |
| 83 | |
| 84 | /** |
| 85 | * Useful for clearing out the wrong pattern after a delay |
| 86 | */ |
| 87 | private Runnable mCancelPatternRunnable = new Runnable() { |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 88 | @Override |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 89 | public void run() { |
| 90 | mLockPatternView.clearPattern(); |
| 91 | } |
| 92 | }; |
Jim Miller | 5737534 | 2012-09-09 15:20:31 -0700 | [diff] [blame] | 93 | private Rect mTempRect = new Rect(); |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 94 | private KeyguardMessageArea mSecurityMessageDisplay; |
Chris Wren | c0ae9e6 | 2012-11-05 13:16:31 -0500 | [diff] [blame] | 95 | private View mEcaView; |
Jorim Jaggi | 6b88cdf | 2014-12-22 20:56:50 +0100 | [diff] [blame] | 96 | private ViewGroup mContainer; |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 97 | private int mDisappearYTranslation; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 98 | |
| 99 | enum FooterMode { |
| 100 | Normal, |
| 101 | ForgotLockPattern, |
| 102 | VerifyUnlocked |
| 103 | } |
| 104 | |
| 105 | public KeyguardPatternView(Context context) { |
| 106 | this(context, null); |
| 107 | } |
| 108 | |
| 109 | public KeyguardPatternView(Context context, AttributeSet attrs) { |
| 110 | super(context, attrs); |
Adrian Roos | 7c11f8b | 2014-03-10 17:00:11 +0100 | [diff] [blame] | 111 | mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); |
Jorim Jaggi | 98f8530 | 2014-08-07 17:45:04 +0200 | [diff] [blame] | 112 | mAppearAnimationUtils = new AppearAnimationUtils(context, |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 113 | AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 1.5f /* translationScale */, |
| 114 | 2.0f /* delayScale */, AnimationUtils.loadInterpolator( |
Jorim Jaggi | 98f8530 | 2014-08-07 17:45:04 +0200 | [diff] [blame] | 115 | mContext, android.R.interpolator.linear_out_slow_in)); |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 116 | mDisappearAnimationUtils = new DisappearAnimationUtils(context, |
| 117 | 125, 1.2f /* translationScale */, |
Jorim Jaggi | 94f6f061 | 2015-06-25 14:47:24 -0700 | [diff] [blame] | 118 | 0.6f /* delayScale */, AnimationUtils.loadInterpolator( |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 119 | mContext, android.R.interpolator.fast_out_linear_in)); |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 120 | mDisappearAnimationUtilsLocked = new DisappearAnimationUtils(context, |
| 121 | (long) (125 * DISAPPEAR_MULTIPLIER_LOCKED), 1.2f /* translationScale */, |
| 122 | 0.6f /* delayScale */, AnimationUtils.loadInterpolator( |
| 123 | mContext, android.R.interpolator.fast_out_linear_in)); |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 124 | mDisappearYTranslation = getResources().getDimensionPixelSize( |
| 125 | R.dimen.disappear_y_translation); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 126 | } |
| 127 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 128 | @Override |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 129 | public void setKeyguardCallback(KeyguardSecurityCallback callback) { |
| 130 | mCallback = callback; |
| 131 | } |
| 132 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 133 | @Override |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 134 | public void setLockPatternUtils(LockPatternUtils utils) { |
| 135 | mLockPatternUtils = utils; |
| 136 | } |
| 137 | |
| 138 | @Override |
| 139 | protected void onFinishInflate() { |
| 140 | super.onFinishInflate(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 141 | mLockPatternUtils = mLockPatternUtils == null |
| 142 | ? new LockPatternUtils(mContext) : mLockPatternUtils; |
| 143 | |
Alan Viverette | 51efddb | 2017-04-05 10:00:01 -0400 | [diff] [blame] | 144 | mLockPatternView = findViewById(R.id.lockPatternView); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 145 | mLockPatternView.setSaveEnabled(false); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 146 | mLockPatternView.setOnPatternListener(new UnlockPatternListener()); |
| 147 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 148 | // vibrate mode will be the same for the life of this screen |
| 149 | mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled()); |
| 150 | |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 151 | mSecurityMessageDisplay = |
| 152 | (KeyguardMessageArea) KeyguardMessageArea.findSecurityMessageDisplay(this); |
Chris Wren | c0ae9e6 | 2012-11-05 13:16:31 -0500 | [diff] [blame] | 153 | mEcaView = findViewById(R.id.keyguard_selector_fade_container); |
Alan Viverette | 51efddb | 2017-04-05 10:00:01 -0400 | [diff] [blame] | 154 | mContainer = findViewById(R.id.container); |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 155 | |
Alan Viverette | 51efddb | 2017-04-05 10:00:01 -0400 | [diff] [blame] | 156 | EmergencyButton button = findViewById(R.id.emergency_call_button); |
Andrew Lee | f98f7b9 | 2015-02-02 15:50:29 -0800 | [diff] [blame] | 157 | if (button != null) { |
| 158 | button.setCallback(this); |
| 159 | } |
Jian Jin | 44e4d82 | 2018-04-06 12:40:50 -0700 | [diff] [blame] | 160 | |
| 161 | View cancelBtn = findViewById(R.id.cancel_button); |
| 162 | if (cancelBtn != null) { |
| 163 | cancelBtn.setOnClickListener(view -> { |
| 164 | mCallback.reset(); |
| 165 | }); |
| 166 | } |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 167 | } |
| 168 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 169 | @Override |
Andrew Lee | 72b46d4 | 2015-01-30 13:23:21 -0800 | [diff] [blame] | 170 | public void onEmergencyButtonClickedWhenInCall() { |
| 171 | mCallback.reset(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 172 | } |
| 173 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 174 | @Override |
Jim Miller | d2b82f7 | 2012-09-18 20:52:55 -0700 | [diff] [blame] | 175 | public boolean onTouchEvent(MotionEvent ev) { |
| 176 | boolean result = super.onTouchEvent(ev); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 177 | // as long as the user is entering a pattern (i.e sending a touch event that was handled |
| 178 | // by this screen), keep poking the wake lock so that the screen will stay on. |
| 179 | final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime; |
| 180 | if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) { |
| 181 | mLastPokeTime = SystemClock.elapsedRealtime(); |
| 182 | } |
Jim Miller | 5737534 | 2012-09-09 15:20:31 -0700 | [diff] [blame] | 183 | mTempRect.set(0, 0, 0, 0); |
| 184 | offsetRectIntoDescendantCoords(mLockPatternView, mTempRect); |
| 185 | ev.offsetLocation(mTempRect.left, mTempRect.top); |
| 186 | result = mLockPatternView.dispatchTouchEvent(ev) || result; |
| 187 | ev.offsetLocation(-mTempRect.left, -mTempRect.top); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 188 | return result; |
| 189 | } |
| 190 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 191 | @Override |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 192 | public void reset() { |
| 193 | // reset lock pattern |
Toni Barzic | 17fdb13 | 2015-10-16 13:38:11 -0700 | [diff] [blame] | 194 | mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled( |
| 195 | KeyguardUpdateMonitor.getCurrentUser())); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 196 | mLockPatternView.enableInput(); |
| 197 | mLockPatternView.setEnabled(true); |
| 198 | mLockPatternView.clearPattern(); |
| 199 | |
| 200 | // if the user is currently locked out, enforce it. |
Adrian Roos | 8150d2a | 2015-04-16 17:11:20 -0700 | [diff] [blame] | 201 | long deadline = mLockPatternUtils.getLockoutAttemptDeadline( |
Adrian Roos | d6aa6cb | 2015-04-16 19:31:29 -0700 | [diff] [blame] | 202 | KeyguardUpdateMonitor.getCurrentUser()); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 203 | if (deadline != 0) { |
| 204 | handleAttemptLockout(deadline); |
| 205 | } else { |
Danielle Millett | 1625e87 | 2012-11-01 15:00:12 -0400 | [diff] [blame] | 206 | displayDefaultSecurityMessage(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 207 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 208 | } |
| 209 | |
Danielle Millett | 1625e87 | 2012-11-01 15:00:12 -0400 | [diff] [blame] | 210 | private void displayDefaultSecurityMessage() { |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 211 | mSecurityMessageDisplay.setMessage(""); |
Danielle Millett | 1625e87 | 2012-11-01 15:00:12 -0400 | [diff] [blame] | 212 | } |
| 213 | |
Adam Cohen | 6fb841f | 2012-10-24 13:15:38 -0700 | [diff] [blame] | 214 | @Override |
| 215 | public void showUsabilityHint() { |
| 216 | } |
| 217 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 218 | /** TODO: hook this up */ |
| 219 | public void cleanUp() { |
| 220 | if (DEBUG) Log.v(TAG, "Cleanup() called on " + this); |
| 221 | mLockPatternUtils = null; |
| 222 | mLockPatternView.setOnPatternListener(null); |
| 223 | } |
| 224 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 225 | private class UnlockPatternListener implements LockPatternView.OnPatternListener { |
| 226 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 227 | @Override |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 228 | public void onPatternStart() { |
| 229 | mLockPatternView.removeCallbacks(mCancelPatternRunnable); |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 230 | mSecurityMessageDisplay.setMessage(""); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 231 | } |
| 232 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 233 | @Override |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 234 | public void onPatternCleared() { |
| 235 | } |
| 236 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 237 | @Override |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 238 | public void onPatternCellAdded(List<LockPatternView.Cell> pattern) { |
Jorim Jaggi | b690f0d | 2014-07-03 23:25:44 +0200 | [diff] [blame] | 239 | mCallback.userActivity(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 240 | } |
| 241 | |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 242 | @Override |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 243 | public void onPatternDetected(final List<LockPatternView.Cell> pattern) { |
| 244 | mLockPatternView.disableInput(); |
| 245 | if (mPendingLockCheck != null) { |
| 246 | mPendingLockCheck.cancel(false); |
| 247 | } |
| 248 | |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 249 | final int userId = KeyguardUpdateMonitor.getCurrentUser(); |
Andres Morales | 2397427 | 2015-05-14 22:42:26 -0700 | [diff] [blame] | 250 | if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) { |
| 251 | mLockPatternView.enableInput(); |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 252 | onPatternChecked(userId, false, 0, false /* not valid - too short */); |
Andres Morales | 2397427 | 2015-05-14 22:42:26 -0700 | [diff] [blame] | 253 | return; |
| 254 | } |
| 255 | |
Jorim Jaggi | ed3032b | 2016-10-07 16:49:34 +0200 | [diff] [blame] | 256 | if (LatencyTracker.isEnabled(mContext)) { |
| 257 | LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL); |
| 258 | LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL_UNLOCKED); |
| 259 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 260 | mPendingLockCheck = LockPatternChecker.checkPattern( |
| 261 | mLockPatternUtils, |
| 262 | pattern, |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 263 | userId, |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 264 | new LockPatternChecker.OnCheckCallback() { |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 265 | |
| 266 | @Override |
| 267 | public void onEarlyMatched() { |
Jorim Jaggi | ed3032b | 2016-10-07 16:49:34 +0200 | [diff] [blame] | 268 | if (LatencyTracker.isEnabled(mContext)) { |
| 269 | LatencyTracker.getInstance(mContext).onActionEnd( |
| 270 | ACTION_CHECK_CREDENTIAL); |
| 271 | } |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 272 | onPatternChecked(userId, true /* matched */, 0 /* timeoutMs */, |
| 273 | true /* isValidPattern */); |
| 274 | } |
| 275 | |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 276 | @Override |
Andres Morales | 2397427 | 2015-05-14 22:42:26 -0700 | [diff] [blame] | 277 | public void onChecked(boolean matched, int timeoutMs) { |
Jorim Jaggi | ed3032b | 2016-10-07 16:49:34 +0200 | [diff] [blame] | 278 | if (LatencyTracker.isEnabled(mContext)) { |
| 279 | LatencyTracker.getInstance(mContext).onActionEnd( |
| 280 | ACTION_CHECK_CREDENTIAL_UNLOCKED); |
| 281 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 282 | mLockPatternView.enableInput(); |
| 283 | mPendingLockCheck = null; |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 284 | if (!matched) { |
| 285 | onPatternChecked(userId, false /* matched */, timeoutMs, |
| 286 | true /* isValidPattern */); |
| 287 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 288 | } |
Jorim Jaggi | ed3032b | 2016-10-07 16:49:34 +0200 | [diff] [blame] | 289 | |
| 290 | @Override |
| 291 | public void onCancelled() { |
| 292 | // We already got dismissed with the early matched callback, so we |
| 293 | // cancelled the check. However, we still need to note down the latency. |
| 294 | if (LatencyTracker.isEnabled(mContext)) { |
| 295 | LatencyTracker.getInstance(mContext).onActionEnd( |
| 296 | ACTION_CHECK_CREDENTIAL_UNLOCKED); |
| 297 | } |
| 298 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 299 | }); |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 300 | if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { |
| 301 | mCallback.userActivity(); |
| 302 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 303 | } |
| 304 | |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 305 | private void onPatternChecked(int userId, boolean matched, int timeoutMs, |
| 306 | boolean isValidPattern) { |
| 307 | boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId; |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 308 | if (matched) { |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 309 | mCallback.reportUnlockAttempt(userId, true, 0); |
| 310 | if (dismissKeyguard) { |
| 311 | mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct); |
Vadim Tryshev | 8702ca7 | 2016-04-22 08:14:12 -0700 | [diff] [blame] | 312 | mCallback.dismiss(true, userId); |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 313 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 314 | } else { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 315 | mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong); |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 316 | if (isValidPattern) { |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 317 | mCallback.reportUnlockAttempt(userId, false, timeoutMs); |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 318 | if (timeoutMs > 0) { |
| 319 | long deadline = mLockPatternUtils.setLockoutAttemptDeadline( |
Xiyuan Xia | ce64cea | 2016-01-06 08:51:16 -0800 | [diff] [blame] | 320 | userId, timeoutMs); |
Jim Miller | 51e3a67 | 2015-07-31 18:42:53 -0700 | [diff] [blame] | 321 | handleAttemptLockout(deadline); |
| 322 | } |
| 323 | } |
| 324 | if (timeoutMs == 0) { |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 325 | mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 326 | mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS); |
| 327 | } |
| 328 | } |
| 329 | } |
| 330 | } |
| 331 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 332 | private void handleAttemptLockout(long elapsedRealtimeDeadline) { |
| 333 | mLockPatternView.clearPattern(); |
| 334 | mLockPatternView.setEnabled(false); |
| 335 | final long elapsedRealtime = SystemClock.elapsedRealtime(); |
Hidenari Koshimae | 5be868c | 2014-08-21 11:27:33 +0200 | [diff] [blame] | 336 | final long secondsInFuture = (long) Math.ceil( |
| 337 | (elapsedRealtimeDeadline - elapsedRealtime) / 1000.0); |
| 338 | mCountdownTimer = new CountDownTimer(secondsInFuture * 1000, 1000) { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 339 | |
| 340 | @Override |
| 341 | public void onTick(long millisUntilFinished) { |
Hidenari Koshimae | 5be868c | 2014-08-21 11:27:33 +0200 | [diff] [blame] | 342 | final int secondsRemaining = (int) Math.round(millisUntilFinished / 1000.0); |
Kevin Chyn | e01c5e1 | 2017-08-29 19:04:25 -0700 | [diff] [blame] | 343 | mSecurityMessageDisplay.setMessage(mContext.getResources().getQuantityString( |
| 344 | R.plurals.kg_too_many_failed_attempts_countdown, |
| 345 | secondsRemaining, secondsRemaining)); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 346 | } |
| 347 | |
| 348 | @Override |
| 349 | public void onFinish() { |
| 350 | mLockPatternView.setEnabled(true); |
Danielle Millett | 1625e87 | 2012-11-01 15:00:12 -0400 | [diff] [blame] | 351 | displayDefaultSecurityMessage(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 352 | } |
| 353 | |
| 354 | }.start(); |
| 355 | } |
| 356 | |
| 357 | @Override |
| 358 | public boolean needsInput() { |
| 359 | return false; |
| 360 | } |
| 361 | |
| 362 | @Override |
| 363 | public void onPause() { |
| 364 | if (mCountdownTimer != null) { |
| 365 | mCountdownTimer.cancel(); |
| 366 | mCountdownTimer = null; |
| 367 | } |
Xiyuan Xia | 6e38058 | 2015-05-05 15:16:08 -0700 | [diff] [blame] | 368 | if (mPendingLockCheck != null) { |
| 369 | mPendingLockCheck.cancel(false); |
| 370 | mPendingLockCheck = null; |
| 371 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 372 | } |
| 373 | |
| 374 | @Override |
Chris Wren | a042ac9 | 2012-11-07 11:37:06 -0500 | [diff] [blame] | 375 | public void onResume(int reason) { |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 376 | } |
| 377 | |
| 378 | @Override |
| 379 | public KeyguardSecurityCallback getCallback() { |
| 380 | return mCallback; |
| 381 | } |
Chris Wren | c0ae9e6 | 2012-11-05 13:16:31 -0500 | [diff] [blame] | 382 | |
| 383 | @Override |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 384 | public void showPromptReason(int reason) { |
| 385 | switch (reason) { |
| 386 | case PROMPT_REASON_RESTART: |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 387 | mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_restart_pattern); |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 388 | break; |
Jorim Jaggi | 25b4d4b | 2015-08-11 15:54:06 -0700 | [diff] [blame] | 389 | case PROMPT_REASON_TIMEOUT: |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 390 | mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern); |
Jorim Jaggi | 25b4d4b | 2015-08-11 15:54:06 -0700 | [diff] [blame] | 391 | break; |
Adrian Roos | d6d253a | 2016-04-13 13:06:21 -0700 | [diff] [blame] | 392 | case PROMPT_REASON_DEVICE_ADMIN: |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 393 | mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_device_admin); |
Adrian Roos | d6d253a | 2016-04-13 13:06:21 -0700 | [diff] [blame] | 394 | break; |
| 395 | case PROMPT_REASON_USER_REQUEST: |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 396 | mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_user_request); |
Adrian Roos | d6d253a | 2016-04-13 13:06:21 -0700 | [diff] [blame] | 397 | break; |
Adrian Roos | c13723f | 2016-01-12 20:29:03 +0100 | [diff] [blame] | 398 | case PROMPT_REASON_NONE: |
| 399 | break; |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 400 | default: |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 401 | mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern); |
Jorim Jaggi | 25b4d4b | 2015-08-11 15:54:06 -0700 | [diff] [blame] | 402 | break; |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 403 | } |
| 404 | } |
| 405 | |
| 406 | @Override |
Lucas Dupin | c80c67e | 2017-12-04 14:29:10 -0800 | [diff] [blame] | 407 | public void showMessage(CharSequence message, int color) { |
Selim Cinek | cfafe4e | 2015-08-11 14:58:44 -0700 | [diff] [blame] | 408 | mSecurityMessageDisplay.setNextMessageColor(color); |
Adrian Roos | db327e9 | 2016-10-12 16:41:28 -0700 | [diff] [blame] | 409 | mSecurityMessageDisplay.setMessage(message); |
Selim Cinek | cfafe4e | 2015-08-11 14:58:44 -0700 | [diff] [blame] | 410 | } |
| 411 | |
| 412 | @Override |
Jorim Jaggi | c14f829 | 2014-05-27 02:25:45 +0200 | [diff] [blame] | 413 | public void startAppearAnimation() { |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 414 | enableClipping(false); |
Jorim Jaggi | fb28c0e | 2014-08-22 16:28:42 +0200 | [diff] [blame] | 415 | setAlpha(1f); |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 416 | setTranslationY(mAppearAnimationUtils.getStartTranslation()); |
Jorim Jaggi | 613f55f | 2015-07-16 15:30:10 -0700 | [diff] [blame] | 417 | AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */, |
| 418 | 0, mAppearAnimationUtils.getInterpolator()); |
Jorim Jaggi | 5673353 | 2015-06-09 15:25:40 -0700 | [diff] [blame] | 419 | mAppearAnimationUtils.startAnimation2d( |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 420 | mLockPatternView.getCellStates(), |
| 421 | new Runnable() { |
| 422 | @Override |
| 423 | public void run() { |
| 424 | enableClipping(true); |
| 425 | } |
| 426 | }, |
| 427 | this); |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 428 | if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) { |
| 429 | mAppearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0, |
Jorim Jaggi | 98f8530 | 2014-08-07 17:45:04 +0200 | [diff] [blame] | 430 | AppearAnimationUtils.DEFAULT_APPEAR_DURATION, |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 431 | mAppearAnimationUtils.getStartTranslation(), |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 432 | true /* appearing */, |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 433 | mAppearAnimationUtils.getInterpolator(), |
| 434 | null /* finishRunnable */); |
| 435 | } |
| 436 | } |
| 437 | |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 438 | @Override |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 439 | public boolean startDisappearAnimation(final Runnable finishRunnable) { |
Jorim Jaggi | 031f795 | 2016-09-01 16:39:26 -0700 | [diff] [blame] | 440 | float durationMultiplier = mKeyguardUpdateMonitor.needsSlowUnlockTransition() |
| 441 | ? DISAPPEAR_MULTIPLIER_LOCKED |
| 442 | : 1f; |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 443 | mLockPatternView.clearPattern(); |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 444 | enableClipping(false); |
| 445 | setTranslationY(0); |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 446 | AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, |
| 447 | (long) (300 * durationMultiplier), |
Jorim Jaggi | 613f55f | 2015-07-16 15:30:10 -0700 | [diff] [blame] | 448 | -mDisappearAnimationUtils.getStartTranslation(), |
| 449 | mDisappearAnimationUtils.getInterpolator()); |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 450 | |
Jorim Jaggi | 031f795 | 2016-09-01 16:39:26 -0700 | [diff] [blame] | 451 | DisappearAnimationUtils disappearAnimationUtils = mKeyguardUpdateMonitor |
| 452 | .needsSlowUnlockTransition() |
| 453 | ? mDisappearAnimationUtilsLocked |
| 454 | : mDisappearAnimationUtils; |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 455 | disappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(), |
| 456 | () -> { |
| 457 | enableClipping(true); |
| 458 | if (finishRunnable != null) { |
| 459 | finishRunnable.run(); |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 460 | } |
| 461 | }, KeyguardPatternView.this); |
Selim Cinek | 3122fa8 | 2015-06-18 01:38:59 -0700 | [diff] [blame] | 462 | if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) { |
| 463 | mDisappearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0, |
Jorim Jaggi | e8fde5d | 2016-06-30 23:41:37 -0700 | [diff] [blame] | 464 | (long) (200 * durationMultiplier), |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 465 | - mDisappearAnimationUtils.getStartTranslation() * 3, |
| 466 | false /* appearing */, |
| 467 | mDisappearAnimationUtils.getInterpolator(), |
| 468 | null /* finishRunnable */); |
| 469 | } |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 470 | return true; |
| 471 | } |
| 472 | |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 473 | private void enableClipping(boolean enable) { |
| 474 | setClipChildren(enable); |
Jorim Jaggi | 6b88cdf | 2014-12-22 20:56:50 +0100 | [diff] [blame] | 475 | mContainer.setClipToPadding(enable); |
| 476 | mContainer.setClipChildren(enable); |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 477 | } |
| 478 | |
| 479 | @Override |
| 480 | public void createAnimation(final LockPatternView.CellState animatedCell, long delay, |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 481 | long duration, float translationY, final boolean appearing, |
| 482 | Interpolator interpolator, |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 483 | final Runnable finishListener) { |
Jorim Jaggi | 613f55f | 2015-07-16 15:30:10 -0700 | [diff] [blame] | 484 | mLockPatternView.startCellStateAnimation(animatedCell, |
| 485 | 1f, appearing ? 1f : 0f, /* alpha */ |
| 486 | appearing ? translationY : 0f, appearing ? 0f : translationY, /* translation */ |
| 487 | appearing ? 0f : 1f, 1f /* scale */, |
| 488 | delay, duration, interpolator, finishListener); |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 489 | if (finishListener != null) { |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 490 | // Also animate the Emergency call |
Selim Cinek | f9c0e8f | 2014-11-11 13:41:02 +0100 | [diff] [blame] | 491 | mAppearAnimationUtils.createAnimation(mEcaView, delay, duration, translationY, |
| 492 | appearing, interpolator, null); |
Selim Cinek | 3018197 | 2014-05-30 03:33:06 +0200 | [diff] [blame] | 493 | } |
Jorim Jaggi | c14f829 | 2014-05-27 02:25:45 +0200 | [diff] [blame] | 494 | } |
Jorim Jaggi | 76a1623 | 2014-08-08 17:00:47 +0200 | [diff] [blame] | 495 | |
| 496 | @Override |
| 497 | public boolean hasOverlappingRendering() { |
| 498 | return false; |
| 499 | } |
Phil Weaver | 7d847b0 | 2018-02-13 16:02:35 -0800 | [diff] [blame] | 500 | |
| 501 | @Override |
| 502 | public CharSequence getTitle() { |
| 503 | return getContext().getString( |
| 504 | com.android.internal.R.string.keyguard_accessibility_pattern_unlock); |
| 505 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 506 | } |