blob: ba0eaea9728a69337f09a61b191edb0ed84166fe [file] [log] [blame]
Jim Millerdcb3d842012-08-23 19:18:12 -07001/*
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 Miller5ecd8112013-01-09 18:50:26 -080016package com.android.keyguard;
Jim Millerdcb3d842012-08-23 19:18:12 -070017
Jason Monkea03be12017-12-04 11:08:41 -050018import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL;
19import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL_UNLOCKED;
Jorim Jaggied3032b2016-10-07 16:49:34 +020020
Jim Millerdcb3d842012-08-23 19:18:12 -070021import android.content.Context;
Jim Miller57375342012-09-09 15:20:31 -070022import android.graphics.Rect;
Xiyuan Xia6e380582015-05-05 15:16:08 -070023import android.os.AsyncTask;
Jim Millerdcb3d842012-08-23 19:18:12 -070024import android.os.CountDownTimer;
25import android.os.SystemClock;
Selim Cinek30181972014-05-30 03:33:06 +020026import android.text.TextUtils;
Jim Millerdcb3d842012-08-23 19:18:12 -070027import android.util.AttributeSet;
28import android.util.Log;
29import android.view.MotionEvent;
30import android.view.View;
Selim Cinek30181972014-05-30 03:33:06 +020031import android.view.ViewGroup;
Jorim Jaggi98f85302014-08-07 17:45:04 +020032import android.view.animation.AnimationUtils;
Selim Cinek30181972014-05-30 03:33:06 +020033import android.view.animation.Interpolator;
Jim Miller3af630c2012-09-26 14:29:18 -070034import android.widget.LinearLayout;
Jim Millerdcb3d842012-08-23 19:18:12 -070035
Jason Monkea03be12017-12-04 11:08:41 -050036import com.android.internal.util.LatencyTracker;
Xiyuan Xia6e380582015-05-05 15:16:08 -070037import com.android.internal.widget.LockPatternChecker;
Jim Millerdcb3d842012-08-23 19:18:12 -070038import com.android.internal.widget.LockPatternUtils;
39import com.android.internal.widget.LockPatternView;
Jorim Jaggi56733532015-06-09 15:25:40 -070040import com.android.settingslib.animation.AppearAnimationCreator;
41import com.android.settingslib.animation.AppearAnimationUtils;
42import com.android.settingslib.animation.DisappearAnimationUtils;
Jim Millerdcb3d842012-08-23 19:18:12 -070043
Jim Millerdcb3d842012-08-23 19:18:12 -070044import java.util.List;
45
Selim Cinek30181972014-05-30 03:33:06 +020046public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView,
Andrew Lee72b46d42015-01-30 13:23:21 -080047 AppearAnimationCreator<LockPatternView.CellState>,
48 EmergencyButton.EmergencyButtonCallback {
Jim Millerdcb3d842012-08-23 19:18:12 -070049
50 private static final String TAG = "SecurityPatternView";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010051 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Millerdcb3d842012-08-23 19:18:12 -070052
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 Millerdcb3d842012-08-23 19:18:12 -070059 // 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 Jaggie8fde5d2016-06-30 23:41:37 -070062 // 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 Roos7c11f8b2014-03-10 17:00:11 +010065 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
Selim Cinek30181972014-05-30 03:33:06 +020066 private final AppearAnimationUtils mAppearAnimationUtils;
Selim Cinekf9c0e8f2014-11-11 13:41:02 +010067 private final DisappearAnimationUtils mDisappearAnimationUtils;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070068 private final DisappearAnimationUtils mDisappearAnimationUtilsLocked;
Adrian Roos7c11f8b2014-03-10 17:00:11 +010069
Jim Millerdcb3d842012-08-23 19:18:12 -070070 private CountDownTimer mCountdownTimer = null;
71 private LockPatternUtils mLockPatternUtils;
Xiyuan Xia6e380582015-05-05 15:16:08 -070072 private AsyncTask<?, ?, ?> mPendingLockCheck;
Jim Millerdcb3d842012-08-23 19:18:12 -070073 private LockPatternView mLockPatternView;
Jim Millerdcb3d842012-08-23 19:18:12 -070074 private KeyguardSecurityCallback mCallback;
Jim Millerdcb3d842012-08-23 19:18:12 -070075
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 Miller51e3a672015-07-31 18:42:53 -070088 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -070089 public void run() {
90 mLockPatternView.clearPattern();
91 }
92 };
Jim Miller57375342012-09-09 15:20:31 -070093 private Rect mTempRect = new Rect();
Selim Cinek3122fa82015-06-18 01:38:59 -070094 private KeyguardMessageArea mSecurityMessageDisplay;
Chris Wrenc0ae9e62012-11-05 13:16:31 -050095 private View mEcaView;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010096 private ViewGroup mContainer;
Jorim Jaggi76a16232014-08-08 17:00:47 +020097 private int mDisappearYTranslation;
Jim Millerdcb3d842012-08-23 19:18:12 -070098
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 Roos7c11f8b2014-03-10 17:00:11 +0100111 mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
Jorim Jaggi98f85302014-08-07 17:45:04 +0200112 mAppearAnimationUtils = new AppearAnimationUtils(context,
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100113 AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 1.5f /* translationScale */,
114 2.0f /* delayScale */, AnimationUtils.loadInterpolator(
Jorim Jaggi98f85302014-08-07 17:45:04 +0200115 mContext, android.R.interpolator.linear_out_slow_in));
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100116 mDisappearAnimationUtils = new DisappearAnimationUtils(context,
117 125, 1.2f /* translationScale */,
Jorim Jaggi94f6f0612015-06-25 14:47:24 -0700118 0.6f /* delayScale */, AnimationUtils.loadInterpolator(
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100119 mContext, android.R.interpolator.fast_out_linear_in));
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700120 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 Jaggi76a16232014-08-08 17:00:47 +0200124 mDisappearYTranslation = getResources().getDimensionPixelSize(
125 R.dimen.disappear_y_translation);
Jim Millerdcb3d842012-08-23 19:18:12 -0700126 }
127
Jim Miller51e3a672015-07-31 18:42:53 -0700128 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700129 public void setKeyguardCallback(KeyguardSecurityCallback callback) {
130 mCallback = callback;
131 }
132
Jim Miller51e3a672015-07-31 18:42:53 -0700133 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700134 public void setLockPatternUtils(LockPatternUtils utils) {
135 mLockPatternUtils = utils;
136 }
137
138 @Override
139 protected void onFinishInflate() {
140 super.onFinishInflate();
Jim Millerdcb3d842012-08-23 19:18:12 -0700141 mLockPatternUtils = mLockPatternUtils == null
142 ? new LockPatternUtils(mContext) : mLockPatternUtils;
143
Alan Viverette51efddb2017-04-05 10:00:01 -0400144 mLockPatternView = findViewById(R.id.lockPatternView);
Jim Millerdcb3d842012-08-23 19:18:12 -0700145 mLockPatternView.setSaveEnabled(false);
Jim Millerdcb3d842012-08-23 19:18:12 -0700146 mLockPatternView.setOnPatternListener(new UnlockPatternListener());
Lucas Dupin01584832018-08-23 18:26:49 -0700147 mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(
148 KeyguardUpdateMonitor.getCurrentUser()));
Jim Millerdcb3d842012-08-23 19:18:12 -0700149
Jim Millerdcb3d842012-08-23 19:18:12 -0700150 // vibrate mode will be the same for the life of this screen
151 mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
152
Selim Cinek3122fa82015-06-18 01:38:59 -0700153 mSecurityMessageDisplay =
154 (KeyguardMessageArea) KeyguardMessageArea.findSecurityMessageDisplay(this);
Chris Wrenc0ae9e62012-11-05 13:16:31 -0500155 mEcaView = findViewById(R.id.keyguard_selector_fade_container);
Alan Viverette51efddb2017-04-05 10:00:01 -0400156 mContainer = findViewById(R.id.container);
Andrew Lee72b46d42015-01-30 13:23:21 -0800157
Alan Viverette51efddb2017-04-05 10:00:01 -0400158 EmergencyButton button = findViewById(R.id.emergency_call_button);
Andrew Leef98f7b92015-02-02 15:50:29 -0800159 if (button != null) {
160 button.setCallback(this);
161 }
Jian Jin44e4d822018-04-06 12:40:50 -0700162
163 View cancelBtn = findViewById(R.id.cancel_button);
164 if (cancelBtn != null) {
165 cancelBtn.setOnClickListener(view -> {
166 mCallback.reset();
167 });
168 }
Andrew Lee72b46d42015-01-30 13:23:21 -0800169 }
170
Jim Miller51e3a672015-07-31 18:42:53 -0700171 @Override
Andrew Lee72b46d42015-01-30 13:23:21 -0800172 public void onEmergencyButtonClickedWhenInCall() {
173 mCallback.reset();
Jim Millerdcb3d842012-08-23 19:18:12 -0700174 }
175
Jim Millerdcb3d842012-08-23 19:18:12 -0700176 @Override
Jim Millerd2b82f72012-09-18 20:52:55 -0700177 public boolean onTouchEvent(MotionEvent ev) {
178 boolean result = super.onTouchEvent(ev);
Jim Millerdcb3d842012-08-23 19:18:12 -0700179 // as long as the user is entering a pattern (i.e sending a touch event that was handled
180 // by this screen), keep poking the wake lock so that the screen will stay on.
181 final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime;
182 if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
183 mLastPokeTime = SystemClock.elapsedRealtime();
184 }
Jim Miller57375342012-09-09 15:20:31 -0700185 mTempRect.set(0, 0, 0, 0);
186 offsetRectIntoDescendantCoords(mLockPatternView, mTempRect);
187 ev.offsetLocation(mTempRect.left, mTempRect.top);
188 result = mLockPatternView.dispatchTouchEvent(ev) || result;
189 ev.offsetLocation(-mTempRect.left, -mTempRect.top);
Jim Millerdcb3d842012-08-23 19:18:12 -0700190 return result;
191 }
192
Jim Miller51e3a672015-07-31 18:42:53 -0700193 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700194 public void reset() {
195 // reset lock pattern
Toni Barzic17fdb132015-10-16 13:38:11 -0700196 mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(
197 KeyguardUpdateMonitor.getCurrentUser()));
Jim Millerdcb3d842012-08-23 19:18:12 -0700198 mLockPatternView.enableInput();
199 mLockPatternView.setEnabled(true);
200 mLockPatternView.clearPattern();
201
202 // if the user is currently locked out, enforce it.
Adrian Roos8150d2a2015-04-16 17:11:20 -0700203 long deadline = mLockPatternUtils.getLockoutAttemptDeadline(
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700204 KeyguardUpdateMonitor.getCurrentUser());
Jim Millerdcb3d842012-08-23 19:18:12 -0700205 if (deadline != 0) {
206 handleAttemptLockout(deadline);
207 } else {
Danielle Millett1625e872012-11-01 15:00:12 -0400208 displayDefaultSecurityMessage();
Jim Millerdcb3d842012-08-23 19:18:12 -0700209 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700210 }
211
Danielle Millett1625e872012-11-01 15:00:12 -0400212 private void displayDefaultSecurityMessage() {
Adrian Roosdb327e92016-10-12 16:41:28 -0700213 mSecurityMessageDisplay.setMessage("");
Danielle Millett1625e872012-11-01 15:00:12 -0400214 }
215
Adam Cohen6fb841f2012-10-24 13:15:38 -0700216 @Override
217 public void showUsabilityHint() {
218 }
219
Jim Millerdcb3d842012-08-23 19:18:12 -0700220 /** TODO: hook this up */
221 public void cleanUp() {
222 if (DEBUG) Log.v(TAG, "Cleanup() called on " + this);
223 mLockPatternUtils = null;
224 mLockPatternView.setOnPatternListener(null);
225 }
226
Jim Millerdcb3d842012-08-23 19:18:12 -0700227 private class UnlockPatternListener implements LockPatternView.OnPatternListener {
228
Jim Miller51e3a672015-07-31 18:42:53 -0700229 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700230 public void onPatternStart() {
231 mLockPatternView.removeCallbacks(mCancelPatternRunnable);
Adrian Roosdb327e92016-10-12 16:41:28 -0700232 mSecurityMessageDisplay.setMessage("");
Jim Millerdcb3d842012-08-23 19:18:12 -0700233 }
234
Jim Miller51e3a672015-07-31 18:42:53 -0700235 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700236 public void onPatternCleared() {
237 }
238
Jim Miller51e3a672015-07-31 18:42:53 -0700239 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700240 public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200241 mCallback.userActivity();
Jim Millerdcb3d842012-08-23 19:18:12 -0700242 }
243
Jim Miller51e3a672015-07-31 18:42:53 -0700244 @Override
Xiyuan Xia6e380582015-05-05 15:16:08 -0700245 public void onPatternDetected(final List<LockPatternView.Cell> pattern) {
246 mLockPatternView.disableInput();
247 if (mPendingLockCheck != null) {
248 mPendingLockCheck.cancel(false);
249 }
250
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800251 final int userId = KeyguardUpdateMonitor.getCurrentUser();
Andres Morales23974272015-05-14 22:42:26 -0700252 if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
253 mLockPatternView.enableInput();
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800254 onPatternChecked(userId, false, 0, false /* not valid - too short */);
Andres Morales23974272015-05-14 22:42:26 -0700255 return;
256 }
257
Jorim Jaggied3032b2016-10-07 16:49:34 +0200258 if (LatencyTracker.isEnabled(mContext)) {
259 LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL);
260 LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL_UNLOCKED);
261 }
Xiyuan Xia6e380582015-05-05 15:16:08 -0700262 mPendingLockCheck = LockPatternChecker.checkPattern(
263 mLockPatternUtils,
264 pattern,
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800265 userId,
Xiyuan Xia6e380582015-05-05 15:16:08 -0700266 new LockPatternChecker.OnCheckCallback() {
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700267
268 @Override
269 public void onEarlyMatched() {
Jorim Jaggied3032b2016-10-07 16:49:34 +0200270 if (LatencyTracker.isEnabled(mContext)) {
271 LatencyTracker.getInstance(mContext).onActionEnd(
272 ACTION_CHECK_CREDENTIAL);
273 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700274 onPatternChecked(userId, true /* matched */, 0 /* timeoutMs */,
275 true /* isValidPattern */);
276 }
277
Xiyuan Xia6e380582015-05-05 15:16:08 -0700278 @Override
Andres Morales23974272015-05-14 22:42:26 -0700279 public void onChecked(boolean matched, int timeoutMs) {
Jorim Jaggied3032b2016-10-07 16:49:34 +0200280 if (LatencyTracker.isEnabled(mContext)) {
281 LatencyTracker.getInstance(mContext).onActionEnd(
282 ACTION_CHECK_CREDENTIAL_UNLOCKED);
283 }
Xiyuan Xia6e380582015-05-05 15:16:08 -0700284 mLockPatternView.enableInput();
285 mPendingLockCheck = null;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700286 if (!matched) {
287 onPatternChecked(userId, false /* matched */, timeoutMs,
288 true /* isValidPattern */);
289 }
Xiyuan Xia6e380582015-05-05 15:16:08 -0700290 }
Jorim Jaggied3032b2016-10-07 16:49:34 +0200291
292 @Override
293 public void onCancelled() {
294 // We already got dismissed with the early matched callback, so we
295 // cancelled the check. However, we still need to note down the latency.
296 if (LatencyTracker.isEnabled(mContext)) {
297 LatencyTracker.getInstance(mContext).onActionEnd(
298 ACTION_CHECK_CREDENTIAL_UNLOCKED);
299 }
300 }
Xiyuan Xia6e380582015-05-05 15:16:08 -0700301 });
Jim Miller51e3a672015-07-31 18:42:53 -0700302 if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
303 mCallback.userActivity();
304 }
Xiyuan Xia6e380582015-05-05 15:16:08 -0700305 }
306
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800307 private void onPatternChecked(int userId, boolean matched, int timeoutMs,
308 boolean isValidPattern) {
309 boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
Xiyuan Xia6e380582015-05-05 15:16:08 -0700310 if (matched) {
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800311 mCallback.reportUnlockAttempt(userId, true, 0);
312 if (dismissKeyguard) {
313 mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700314 mCallback.dismiss(true, userId);
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800315 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700316 } else {
Jim Millerdcb3d842012-08-23 19:18:12 -0700317 mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
Jim Miller51e3a672015-07-31 18:42:53 -0700318 if (isValidPattern) {
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800319 mCallback.reportUnlockAttempt(userId, false, timeoutMs);
Jim Miller51e3a672015-07-31 18:42:53 -0700320 if (timeoutMs > 0) {
321 long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
Xiyuan Xiace64cea2016-01-06 08:51:16 -0800322 userId, timeoutMs);
Jim Miller51e3a672015-07-31 18:42:53 -0700323 handleAttemptLockout(deadline);
324 }
325 }
326 if (timeoutMs == 0) {
Adrian Roosdb327e92016-10-12 16:41:28 -0700327 mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern);
Jim Millerdcb3d842012-08-23 19:18:12 -0700328 mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS);
329 }
330 }
331 }
332 }
333
Jim Millerdcb3d842012-08-23 19:18:12 -0700334 private void handleAttemptLockout(long elapsedRealtimeDeadline) {
335 mLockPatternView.clearPattern();
336 mLockPatternView.setEnabled(false);
337 final long elapsedRealtime = SystemClock.elapsedRealtime();
Hidenari Koshimae5be868c2014-08-21 11:27:33 +0200338 final long secondsInFuture = (long) Math.ceil(
339 (elapsedRealtimeDeadline - elapsedRealtime) / 1000.0);
340 mCountdownTimer = new CountDownTimer(secondsInFuture * 1000, 1000) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700341
342 @Override
343 public void onTick(long millisUntilFinished) {
Hidenari Koshimae5be868c2014-08-21 11:27:33 +0200344 final int secondsRemaining = (int) Math.round(millisUntilFinished / 1000.0);
Kevin Chyne01c5e12017-08-29 19:04:25 -0700345 mSecurityMessageDisplay.setMessage(mContext.getResources().getQuantityString(
346 R.plurals.kg_too_many_failed_attempts_countdown,
347 secondsRemaining, secondsRemaining));
Jim Millerdcb3d842012-08-23 19:18:12 -0700348 }
349
350 @Override
351 public void onFinish() {
352 mLockPatternView.setEnabled(true);
Danielle Millett1625e872012-11-01 15:00:12 -0400353 displayDefaultSecurityMessage();
Jim Millerdcb3d842012-08-23 19:18:12 -0700354 }
355
356 }.start();
357 }
358
359 @Override
360 public boolean needsInput() {
361 return false;
362 }
363
364 @Override
365 public void onPause() {
366 if (mCountdownTimer != null) {
367 mCountdownTimer.cancel();
368 mCountdownTimer = null;
369 }
Xiyuan Xia6e380582015-05-05 15:16:08 -0700370 if (mPendingLockCheck != null) {
371 mPendingLockCheck.cancel(false);
372 mPendingLockCheck = null;
373 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700374 }
375
376 @Override
Chris Wrena042ac92012-11-07 11:37:06 -0500377 public void onResume(int reason) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700378 }
379
380 @Override
381 public KeyguardSecurityCallback getCallback() {
382 return mCallback;
383 }
Chris Wrenc0ae9e62012-11-05 13:16:31 -0500384
385 @Override
Selim Cinek3122fa82015-06-18 01:38:59 -0700386 public void showPromptReason(int reason) {
387 switch (reason) {
388 case PROMPT_REASON_RESTART:
Adrian Roosdb327e92016-10-12 16:41:28 -0700389 mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_restart_pattern);
Selim Cinek3122fa82015-06-18 01:38:59 -0700390 break;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700391 case PROMPT_REASON_TIMEOUT:
Adrian Roosdb327e92016-10-12 16:41:28 -0700392 mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700393 break;
Adrian Roosd6d253a2016-04-13 13:06:21 -0700394 case PROMPT_REASON_DEVICE_ADMIN:
Adrian Roosdb327e92016-10-12 16:41:28 -0700395 mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_device_admin);
Adrian Roosd6d253a2016-04-13 13:06:21 -0700396 break;
397 case PROMPT_REASON_USER_REQUEST:
Adrian Roosdb327e92016-10-12 16:41:28 -0700398 mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_user_request);
Adrian Roosd6d253a2016-04-13 13:06:21 -0700399 break;
Adrian Roosc13723f2016-01-12 20:29:03 +0100400 case PROMPT_REASON_NONE:
401 break;
Selim Cinek3122fa82015-06-18 01:38:59 -0700402 default:
Adrian Roosdb327e92016-10-12 16:41:28 -0700403 mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700404 break;
Selim Cinek3122fa82015-06-18 01:38:59 -0700405 }
406 }
407
408 @Override
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800409 public void showMessage(CharSequence message, int color) {
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700410 mSecurityMessageDisplay.setNextMessageColor(color);
Adrian Roosdb327e92016-10-12 16:41:28 -0700411 mSecurityMessageDisplay.setMessage(message);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700412 }
413
414 @Override
Jorim Jaggic14f8292014-05-27 02:25:45 +0200415 public void startAppearAnimation() {
Selim Cinek30181972014-05-30 03:33:06 +0200416 enableClipping(false);
Jorim Jaggifb28c0e2014-08-22 16:28:42 +0200417 setAlpha(1f);
Jorim Jaggi76a16232014-08-08 17:00:47 +0200418 setTranslationY(mAppearAnimationUtils.getStartTranslation());
Jorim Jaggi613f55f2015-07-16 15:30:10 -0700419 AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,
420 0, mAppearAnimationUtils.getInterpolator());
Jorim Jaggi56733532015-06-09 15:25:40 -0700421 mAppearAnimationUtils.startAnimation2d(
Selim Cinek30181972014-05-30 03:33:06 +0200422 mLockPatternView.getCellStates(),
423 new Runnable() {
424 @Override
425 public void run() {
426 enableClipping(true);
427 }
428 },
429 this);
Selim Cinek3122fa82015-06-18 01:38:59 -0700430 if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
431 mAppearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
Jorim Jaggi98f85302014-08-07 17:45:04 +0200432 AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
Selim Cinek30181972014-05-30 03:33:06 +0200433 mAppearAnimationUtils.getStartTranslation(),
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100434 true /* appearing */,
Selim Cinek30181972014-05-30 03:33:06 +0200435 mAppearAnimationUtils.getInterpolator(),
436 null /* finishRunnable */);
437 }
438 }
439
Jorim Jaggi76a16232014-08-08 17:00:47 +0200440 @Override
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100441 public boolean startDisappearAnimation(final Runnable finishRunnable) {
Jorim Jaggi031f7952016-09-01 16:39:26 -0700442 float durationMultiplier = mKeyguardUpdateMonitor.needsSlowUnlockTransition()
443 ? DISAPPEAR_MULTIPLIER_LOCKED
444 : 1f;
Jorim Jaggi76a16232014-08-08 17:00:47 +0200445 mLockPatternView.clearPattern();
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100446 enableClipping(false);
447 setTranslationY(0);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700448 AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */,
449 (long) (300 * durationMultiplier),
Jorim Jaggi613f55f2015-07-16 15:30:10 -0700450 -mDisappearAnimationUtils.getStartTranslation(),
451 mDisappearAnimationUtils.getInterpolator());
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700452
Jorim Jaggi031f7952016-09-01 16:39:26 -0700453 DisappearAnimationUtils disappearAnimationUtils = mKeyguardUpdateMonitor
454 .needsSlowUnlockTransition()
455 ? mDisappearAnimationUtilsLocked
456 : mDisappearAnimationUtils;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700457 disappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(),
458 () -> {
459 enableClipping(true);
460 if (finishRunnable != null) {
461 finishRunnable.run();
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100462 }
463 }, KeyguardPatternView.this);
Selim Cinek3122fa82015-06-18 01:38:59 -0700464 if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
465 mDisappearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700466 (long) (200 * durationMultiplier),
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100467 - mDisappearAnimationUtils.getStartTranslation() * 3,
468 false /* appearing */,
469 mDisappearAnimationUtils.getInterpolator(),
470 null /* finishRunnable */);
471 }
Jorim Jaggi76a16232014-08-08 17:00:47 +0200472 return true;
473 }
474
Selim Cinek30181972014-05-30 03:33:06 +0200475 private void enableClipping(boolean enable) {
476 setClipChildren(enable);
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100477 mContainer.setClipToPadding(enable);
478 mContainer.setClipChildren(enable);
Selim Cinek30181972014-05-30 03:33:06 +0200479 }
480
481 @Override
482 public void createAnimation(final LockPatternView.CellState animatedCell, long delay,
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100483 long duration, float translationY, final boolean appearing,
484 Interpolator interpolator,
Selim Cinek30181972014-05-30 03:33:06 +0200485 final Runnable finishListener) {
Jorim Jaggi613f55f2015-07-16 15:30:10 -0700486 mLockPatternView.startCellStateAnimation(animatedCell,
487 1f, appearing ? 1f : 0f, /* alpha */
488 appearing ? translationY : 0f, appearing ? 0f : translationY, /* translation */
489 appearing ? 0f : 1f, 1f /* scale */,
490 delay, duration, interpolator, finishListener);
Selim Cinek30181972014-05-30 03:33:06 +0200491 if (finishListener != null) {
Selim Cinek30181972014-05-30 03:33:06 +0200492 // Also animate the Emergency call
Selim Cinekf9c0e8f2014-11-11 13:41:02 +0100493 mAppearAnimationUtils.createAnimation(mEcaView, delay, duration, translationY,
494 appearing, interpolator, null);
Selim Cinek30181972014-05-30 03:33:06 +0200495 }
Jorim Jaggic14f8292014-05-27 02:25:45 +0200496 }
Jorim Jaggi76a16232014-08-08 17:00:47 +0200497
498 @Override
499 public boolean hasOverlappingRendering() {
500 return false;
501 }
Phil Weaver7d847b02018-02-13 16:02:35 -0800502
503 @Override
504 public CharSequence getTitle() {
505 return getContext().getString(
506 com.android.internal.R.string.keyguard_accessibility_pattern_unlock);
507 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700508}