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