blob: 4d4818d51414d73f6d699c3f02d4c87b366fe403 [file] [log] [blame]
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar.phone;
18
19import android.content.Context;
Gus Prevasab336792018-11-14 13:52:20 -050020import android.hardware.biometrics.BiometricSourceType;
Steven Wue442acf2019-03-14 13:31:12 -040021import android.metrics.LogMaker;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070022import android.os.Handler;
23import android.os.PowerManager;
24import android.os.SystemClock;
Nick Desaulniers1d396752016-07-25 15:05:33 -070025import android.os.Trace;
Lucas Dupinc94963f2019-03-07 14:54:05 -080026import android.provider.Settings;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070027import android.util.Log;
28
Lucas Dupinc94963f2019-03-07 14:54:05 -080029import com.android.internal.annotations.VisibleForTesting;
Steven Wue442acf2019-03-14 13:31:12 -040030import com.android.internal.logging.MetricsLogger;
31import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Gus Prevasab336792018-11-14 13:52:20 -050032import com.android.internal.util.LatencyTracker;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070033import com.android.keyguard.KeyguardConstants;
34import com.android.keyguard.KeyguardUpdateMonitor;
35import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jason Monk421a9412017-02-06 09:15:21 -080036import com.android.systemui.Dependency;
Lucas Dupinc94963f2019-03-07 14:54:05 -080037import com.android.systemui.R;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070038import com.android.systemui.keyguard.KeyguardViewMediator;
Adrian Roos7a5e4c92017-07-31 16:40:19 +020039import com.android.systemui.keyguard.ScreenLifecycle;
Adrian Roos58ba6852017-07-18 17:10:29 +020040import com.android.systemui.keyguard.WakefulnessLifecycle;
Jason Monk297c04e2018-08-23 17:16:59 -040041import com.android.systemui.statusbar.NotificationMediaManager;
Lucas Dupinc94963f2019-03-07 14:54:05 -080042import com.android.systemui.tuner.TunerService;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070043
Adrian Roosba7ca592017-08-15 17:48:05 +020044import java.io.PrintWriter;
45
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070046/**
Gilad Brettercb51b8b2018-03-22 17:04:51 +020047 * Controller which coordinates all the biometric unlocking actions with the UI.
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070048 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +020049public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070050
Gilad Brettercb51b8b2018-03-22 17:04:51 +020051 private static final String TAG = "BiometricUnlockController";
52 private static final boolean DEBUG_BIO_WAKELOCK = KeyguardConstants.DEBUG_BIOMETRIC_WAKELOCK;
53 private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
54 private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070055
56 /**
Lucas Dupin3d053532019-01-29 12:35:22 -080057 * Mode in which we don't need to wake up the device when we authenticate.
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070058 */
59 public static final int MODE_NONE = 0;
60
61 /**
62 * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
63 * a fingerprint while the screen is off and the device was sleeping.
64 */
65 public static final int MODE_WAKE_AND_UNLOCK = 1;
66
67 /**
68 * Mode in which we wake the device up, and fade out the Keyguard contents because they were
69 * already visible while pulsing in doze mode.
70 */
71 public static final int MODE_WAKE_AND_UNLOCK_PULSING = 2;
72
73 /**
74 * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
75 * acquire a fingerprint pulsing in doze mode.
76 */
77 public static final int MODE_SHOW_BOUNCER = 3;
78
79 /**
Lucas Dupin3d053532019-01-29 12:35:22 -080080 * Mode in which we only wake up the device, and keyguard was not showing when we authenticated.
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070081 * */
82 public static final int MODE_ONLY_WAKE = 4;
83
84 /**
85 * Mode in which fingerprint unlocks the device.
86 */
87 public static final int MODE_UNLOCK = 5;
88
89 /**
90 * Mode in which fingerprint brings up the bouncer because fingerprint unlocking is currently
91 * not allowed.
92 */
93 public static final int MODE_DISMISS_BOUNCER = 6;
94
95 /**
Kevin Chyn36778ff2017-09-07 19:55:38 -070096 * Mode in which fingerprint wakes and unlocks the device from a dream.
97 */
98 public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 7;
99
100 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200101 * How much faster we collapse the lockscreen when authenticating with biometric.
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700102 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200103 private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700104
Lucas Dupinc94963f2019-03-07 14:54:05 -0800105 /**
106 * If face unlock dismisses the lock screen or keeps user on keyguard by default on this device.
107 */
108 private final boolean mFaceDismissesKeyguardByDefault;
109
110 /**
111 * If face unlock dismisses the lock screen or keeps user on keyguard for the current user.
112 */
113 @VisibleForTesting
114 protected boolean mFaceDismissesKeyguard;
115
Lucas Dupin3d053532019-01-29 12:35:22 -0800116 private final NotificationMediaManager mMediaManager;
117 private final PowerManager mPowerManager;
118 private final Handler mHandler;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700119 private PowerManager.WakeLock mWakeLock;
Lucas Dupin3d053532019-01-29 12:35:22 -0800120 private final KeyguardUpdateMonitor mUpdateMonitor;
121 private final UnlockMethodCache mUnlockMethodCache;
122 private final StatusBarWindowController mStatusBarWindowController;
123 private final Context mContext;
124 private final int mWakeUpDelay;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700125 private int mMode;
126 private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700127 private DozeScrimController mDozeScrimController;
128 private KeyguardViewMediator mKeyguardViewMediator;
129 private ScrimController mScrimController;
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500130 private StatusBar mStatusBar;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700131 private int mPendingAuthenticatedUserId = -1;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200132 private BiometricSourceType mPendingAuthenticatedBioSourceType = null;
Adrian Roos58ba6852017-07-18 17:10:29 +0200133 private boolean mPendingShowBouncer;
Adrian Roos7a5e4c92017-07-31 16:40:19 +0200134 private boolean mHasScreenTurnedOnSinceAuthenticating;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700135
Lucas Dupinc94963f2019-03-07 14:54:05 -0800136 private final TunerService.Tunable mFaceDismissedKeyguardTunable = new TunerService.Tunable() {
137 @Override
138 public void onTuningChanged(String key, String newValue) {
139 int defaultValue = mFaceDismissesKeyguardByDefault ? 1 : 0;
140 mFaceDismissesKeyguard = Settings.Secure.getIntForUser(mContext.getContentResolver(),
141 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
142 defaultValue, KeyguardUpdateMonitor.getCurrentUser()) != 0;
143 }
144 };
145
Steven Wue442acf2019-03-14 13:31:12 -0400146 private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
147
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200148 public BiometricUnlockController(Context context,
Lucas Dupinc94963f2019-03-07 14:54:05 -0800149 DozeScrimController dozeScrimController,
150 KeyguardViewMediator keyguardViewMediator,
151 ScrimController scrimController,
152 StatusBar statusBar,
153 UnlockMethodCache unlockMethodCache, Handler handler,
154 KeyguardUpdateMonitor keyguardUpdateMonitor,
155 TunerService tunerService) {
156 this(context, dozeScrimController, keyguardViewMediator, scrimController, statusBar,
157 unlockMethodCache, handler, keyguardUpdateMonitor, tunerService,
158 context.getResources()
159 .getInteger(com.android.internal.R.integer.config_wakeUpDelayDoze),
160 context.getResources().getBoolean(R.bool.config_faceAuthDismissesKeyguard));
161 }
162
163 @VisibleForTesting
164 protected BiometricUnlockController(Context context,
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200165 DozeScrimController dozeScrimController,
166 KeyguardViewMediator keyguardViewMediator,
167 ScrimController scrimController,
168 StatusBar statusBar,
Lucas Dupin3d053532019-01-29 12:35:22 -0800169 UnlockMethodCache unlockMethodCache, Handler handler,
170 KeyguardUpdateMonitor keyguardUpdateMonitor,
Lucas Dupinc94963f2019-03-07 14:54:05 -0800171 TunerService tunerService,
172 int wakeUpDelay,
173 boolean faceDismissesKeyguard) {
Jorim Jaggi8adb30c2016-09-13 15:02:22 -0700174 mContext = context;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700175 mPowerManager = context.getSystemService(PowerManager.class);
Lucas Dupin3d053532019-01-29 12:35:22 -0800176 mUpdateMonitor = keyguardUpdateMonitor;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700177 mUpdateMonitor.registerCallback(this);
Lucas Dupin3d053532019-01-29 12:35:22 -0800178 mMediaManager = Dependency.get(NotificationMediaManager.class);
Adrian Roos58ba6852017-07-18 17:10:29 +0200179 Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
Adrian Roos7a5e4c92017-07-31 16:40:19 +0200180 Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
Lucas Dupin1a8588d2018-08-21 12:18:47 -0700181 mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700182 mDozeScrimController = dozeScrimController;
183 mKeyguardViewMediator = keyguardViewMediator;
184 mScrimController = scrimController;
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500185 mStatusBar = statusBar;
Jorim Jaggi8adb30c2016-09-13 15:02:22 -0700186 mUnlockMethodCache = unlockMethodCache;
Lucas Dupin3d053532019-01-29 12:35:22 -0800187 mHandler = handler;
188 mWakeUpDelay = wakeUpDelay;
Lucas Dupinc94963f2019-03-07 14:54:05 -0800189 mFaceDismissesKeyguardByDefault = faceDismissesKeyguard;
190 tunerService.addTunable(mFaceDismissedKeyguardTunable,
191 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700192 }
193
194 public void setStatusBarKeyguardViewManager(
195 StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
196 mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
197 }
198
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200199 private final Runnable mReleaseBiometricWakeLockRunnable = new Runnable() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700200 @Override
201 public void run() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200202 if (DEBUG_BIO_WAKELOCK) {
203 Log.i(TAG, "biometric wakelock: TIMEOUT!!");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700204 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200205 releaseBiometricWakeLock();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700206 }
207 };
208
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200209 private void releaseBiometricWakeLock() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700210 if (mWakeLock != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200211 mHandler.removeCallbacks(mReleaseBiometricWakeLockRunnable);
212 if (DEBUG_BIO_WAKELOCK) {
213 Log.i(TAG, "releasing biometric wakelock");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700214 }
215 mWakeLock.release();
216 mWakeLock = null;
217 }
218 }
219
220 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200221 public void onBiometricAcquired(BiometricSourceType biometricSourceType) {
222 Trace.beginSection("BiometricUnlockController#onBiometricAcquired");
223 releaseBiometricWakeLock();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700224 if (!mUpdateMonitor.isDeviceInteractive()) {
Jorim Jaggi8adb30c2016-09-13 15:02:22 -0700225 if (LatencyTracker.isEnabled(mContext)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200226 int action = LatencyTracker.ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
227 if (biometricSourceType == BiometricSourceType.FACE) {
228 action = LatencyTracker.ACTION_FACE_WAKE_AND_UNLOCK;
229 }
230 LatencyTracker.getInstance(mContext).onActionStart(action);
Jorim Jaggi8adb30c2016-09-13 15:02:22 -0700231 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700232 mWakeLock = mPowerManager.newWakeLock(
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200233 PowerManager.PARTIAL_WAKE_LOCK, BIOMETRIC_WAKE_LOCK_NAME);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700234 Trace.beginSection("acquiring wake-and-unlock");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700235 mWakeLock.acquire();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700236 Trace.endSection();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200237 if (DEBUG_BIO_WAKELOCK) {
238 Log.i(TAG, "biometric acquired, grabbing biometric wakelock");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700239 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200240 mHandler.postDelayed(mReleaseBiometricWakeLockRunnable,
241 BIOMETRIC_WAKELOCK_TIMEOUT_MS);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700242 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700243 Trace.endSection();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700244 }
245
Adrian Roos3e23eb52017-07-07 15:58:57 +0200246 private boolean pulsingOrAod() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800247 final ScrimState scrimState = mScrimController.getState();
248 return scrimState == ScrimState.AOD
249 || scrimState == ScrimState.PULSING;
Adrian Roos3e23eb52017-07-07 15:58:57 +0200250 }
251
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700252 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200253 public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType) {
254 Trace.beginSection("BiometricUnlockController#onBiometricAuthenticated");
Jorim Jaggi95e40382015-09-16 15:53:42 -0700255 if (mUpdateMonitor.isGoingToSleep()) {
256 mPendingAuthenticatedUserId = userId;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200257 mPendingAuthenticatedBioSourceType = biometricSourceType;
Nick Desaulniers1d396752016-07-25 15:05:33 -0700258 Trace.endSection();
Jorim Jaggi95e40382015-09-16 15:53:42 -0700259 return;
260 }
Steven Wue442acf2019-03-14 13:31:12 -0400261 mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
262 .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
Lucas Dupin3d053532019-01-29 12:35:22 -0800263 startWakeAndUnlock(calculateMode(biometricSourceType));
Adrian Roos6d5ebb72017-08-03 15:10:22 +0200264 }
265
266 public void startWakeAndUnlock(int mode) {
Kevin Chyn0b508b42017-09-11 17:34:33 -0700267 // TODO(b/62444020): remove when this bug is fixed
268 Log.v(TAG, "startWakeAndUnlock(" + mode + ")");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700269 boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
Adrian Roos6d5ebb72017-08-03 15:10:22 +0200270 mMode = mode;
Adrian Roos7a5e4c92017-07-31 16:40:19 +0200271 mHasScreenTurnedOnSinceAuthenticating = false;
Adrian Roosb880afe72017-07-25 17:02:46 +0200272 if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) {
273 // If we are waking the device up while we are pulsing the clock and the
274 // notifications would light up first, creating an unpleasant animation.
275 // Defer changing the screen brightness by forcing doze brightness on our window
276 // until the clock and the notifications are faded out.
Lucas Dupin1a8588d2018-08-21 12:18:47 -0700277 mStatusBarWindowController.setForceDozeBrightness(true);
Adrian Roosb880afe72017-07-25 17:02:46 +0200278 }
Lucas Dupine63abf72018-07-02 11:17:14 -0700279 // During wake and unlock, we need to draw black before waking up to avoid abrupt
280 // brightness changes due to display state transitions.
281 boolean alwaysOnEnabled = DozeParameters.getInstance(mContext).getAlwaysOn();
Lucas Dupin2920eea2018-08-29 13:13:40 -0700282 boolean delayWakeUp = mode == MODE_WAKE_AND_UNLOCK && alwaysOnEnabled && mWakeUpDelay > 0;
Lucas Dupine63abf72018-07-02 11:17:14 -0700283 Runnable wakeUp = ()-> {
284 if (!wasDeviceInteractive) {
285 if (DEBUG_BIO_WAKELOCK) {
286 Log.i(TAG, "bio wakelock: Authenticated, waking up...");
287 }
Michael Wrighte3001042019-02-05 00:13:14 +0000288 mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
289 "android.policy:BIOMETRIC");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700290 }
Lucas Dupine63abf72018-07-02 11:17:14 -0700291 if (delayWakeUp) {
292 mKeyguardViewMediator.onWakeAndUnlocking();
293 }
294 Trace.beginSection("release wake-and-unlock");
295 releaseBiometricWakeLock();
296 Trace.endSection();
297 };
298
299 if (!delayWakeUp) {
300 wakeUp.run();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700301 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700302 switch (mMode) {
303 case MODE_DISMISS_BOUNCER:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700304 Trace.beginSection("MODE_DISMISS");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700305 mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
306 false /* strongAuth */);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700307 Trace.endSection();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700308 break;
309 case MODE_UNLOCK:
310 case MODE_SHOW_BOUNCER:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700311 Trace.beginSection("MODE_UNLOCK or MODE_SHOW_BOUNCER");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700312 if (!wasDeviceInteractive) {
Adrian Roos58ba6852017-07-18 17:10:29 +0200313 mPendingShowBouncer = true;
314 } else {
315 showBouncer();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700316 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700317 Trace.endSection();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700318 break;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700319 case MODE_WAKE_AND_UNLOCK_FROM_DREAM:
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700320 case MODE_WAKE_AND_UNLOCK_PULSING:
Jorim Jaggid94d3a22015-08-21 16:52:55 -0700321 case MODE_WAKE_AND_UNLOCK:
Adrian Roos88e61aa2017-05-23 16:16:50 -0700322 if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
323 Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
Jason Monk297c04e2018-08-23 17:16:59 -0400324 mMediaManager.updateMediaMetaData(false /* metaDataChanged */,
Adrian Roos88e61aa2017-05-23 16:16:50 -0700325 true /* allowEnterAnimation */);
Kevin Chyn36778ff2017-09-07 19:55:38 -0700326 } else if (mMode == MODE_WAKE_AND_UNLOCK){
Adrian Roos88e61aa2017-05-23 16:16:50 -0700327 Trace.beginSection("MODE_WAKE_AND_UNLOCK");
Kevin Chyn36778ff2017-09-07 19:55:38 -0700328 } else {
329 Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
330 mUpdateMonitor.awakenFromDream();
Adrian Roos88e61aa2017-05-23 16:16:50 -0700331 }
Lucas Dupin1a8588d2018-08-21 12:18:47 -0700332 mStatusBarWindowController.setStatusBarFocusable(false);
Lucas Dupine63abf72018-07-02 11:17:14 -0700333 if (delayWakeUp) {
Lucas Dupin2920eea2018-08-29 13:13:40 -0700334 mHandler.postDelayed(wakeUp, mWakeUpDelay);
Lucas Dupine63abf72018-07-02 11:17:14 -0700335 } else {
336 mKeyguardViewMediator.onWakeAndUnlocking();
337 }
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500338 if (mStatusBar.getNavigationBarView() != null) {
339 mStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700340 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700341 Trace.endSection();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700342 break;
343 case MODE_ONLY_WAKE:
344 case MODE_NONE:
345 break;
346 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200347 mStatusBar.notifyBiometricAuthModeChanged();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700348 Trace.endSection();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700349 }
350
Adrian Roos58ba6852017-07-18 17:10:29 +0200351 private void showBouncer() {
Lucas Dupin3d053532019-01-29 12:35:22 -0800352 if (mMode == MODE_SHOW_BOUNCER) {
felkachangefebbc2f72018-05-14 12:22:40 +0800353 mStatusBarKeyguardViewManager.showBouncer(false);
354 }
Adrian Roos58ba6852017-07-18 17:10:29 +0200355 mStatusBarKeyguardViewManager.animateCollapsePanels(
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200356 BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR);
Adrian Roos58ba6852017-07-18 17:10:29 +0200357 mPendingShowBouncer = false;
358 }
359
Jorim Jaggi95e40382015-09-16 15:53:42 -0700360 @Override
361 public void onStartedGoingToSleep(int why) {
Adrian Roosba7ca592017-08-15 17:48:05 +0200362 resetMode();
Jorim Jaggi95e40382015-09-16 15:53:42 -0700363 mPendingAuthenticatedUserId = -1;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200364 mPendingAuthenticatedBioSourceType = null;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700365 }
366
367 @Override
368 public void onFinishedGoingToSleep(int why) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200369 Trace.beginSection("BiometricUnlockController#onFinishedGoingToSleep");
Lucas Dupin45142ba2019-04-10 13:13:20 -0700370 BiometricSourceType pendingType = mPendingAuthenticatedBioSourceType;
371 int pendingUserId = mPendingAuthenticatedUserId;
372 if (pendingUserId != -1 && pendingType != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -0700373 // Post this to make sure it's executed after the device is fully locked.
Lucas Dupin45142ba2019-04-10 13:13:20 -0700374 mHandler.post(() -> onBiometricAuthenticated(pendingUserId, pendingType));
Jorim Jaggi95e40382015-09-16 15:53:42 -0700375 }
376 mPendingAuthenticatedUserId = -1;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200377 mPendingAuthenticatedBioSourceType = null;
Nick Desaulniers1d396752016-07-25 15:05:33 -0700378 Trace.endSection();
Jorim Jaggi95e40382015-09-16 15:53:42 -0700379 }
380
Adrian Roos710a0b12017-07-07 19:02:34 +0200381 public boolean hasPendingAuthentication() {
382 return mPendingAuthenticatedUserId != -1
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200383 && mUpdateMonitor.isUnlockingWithBiometricAllowed()
Adrian Roos710a0b12017-07-07 19:02:34 +0200384 && mPendingAuthenticatedUserId == KeyguardUpdateMonitor.getCurrentUser();
385 }
386
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700387 public int getMode() {
388 return mMode;
389 }
390
Lucas Dupin3d053532019-01-29 12:35:22 -0800391 private int calculateMode(BiometricSourceType biometricSourceType) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200392 boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
Kevin Chyn36778ff2017-09-07 19:55:38 -0700393 boolean deviceDreaming = mUpdateMonitor.isDreaming();
Lucas Dupinc94963f2019-03-07 14:54:05 -0800394 boolean faceStayingOnKeyguard = biometricSourceType == BiometricSourceType.FACE
395 && !mFaceDismissesKeyguard;
Adrian Roos02626662017-07-06 18:22:17 +0200396
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700397 if (!mUpdateMonitor.isDeviceInteractive()) {
398 if (!mStatusBarKeyguardViewManager.isShowing()) {
399 return MODE_ONLY_WAKE;
Adrian Roose4cb6c8a2017-07-19 18:08:07 +0200400 } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
Lucas Dupinc94963f2019-03-07 14:54:05 -0800401 return faceStayingOnKeyguard ? MODE_NONE : MODE_WAKE_AND_UNLOCK_PULSING;
Jorim Jaggi8adb30c2016-09-13 15:02:22 -0700402 } else if (unlockingAllowed || !mUnlockMethodCache.isMethodSecure()) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700403 return MODE_WAKE_AND_UNLOCK;
404 } else {
405 return MODE_SHOW_BOUNCER;
406 }
407 }
Lucas Dupinc94963f2019-03-07 14:54:05 -0800408 if (unlockingAllowed && deviceDreaming && !faceStayingOnKeyguard) {
Kevin Chyn36778ff2017-09-07 19:55:38 -0700409 return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
410 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700411 if (mStatusBarKeyguardViewManager.isShowing()) {
Lucas Dupind61974d2019-03-29 16:09:26 -0700412 if ((mStatusBarKeyguardViewManager.isBouncerShowing()
413 || mStatusBarKeyguardViewManager.isBouncerPartiallyVisible())
414 && unlockingAllowed) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700415 return MODE_DISMISS_BOUNCER;
416 } else if (unlockingAllowed) {
Lucas Dupinc94963f2019-03-07 14:54:05 -0800417 return faceStayingOnKeyguard ? MODE_ONLY_WAKE : MODE_UNLOCK;
Jorim Jaggibf04cf52015-09-02 11:53:02 -0700418 } else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700419 return MODE_SHOW_BOUNCER;
420 }
421 }
422 return MODE_NONE;
423 }
424
425 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200426 public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
Steven Wue442acf2019-03-14 13:31:12 -0400427 mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
428 .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType)));
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700429 cleanup();
430 }
431
432 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200433 public void onBiometricError(int msgId, String errString,
434 BiometricSourceType biometricSourceType) {
Steven Wue442acf2019-03-14 13:31:12 -0400435 mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
Steven Wu40cbada2019-05-16 10:56:40 -0400436 .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType))
437 .addTaggedData(MetricsEvent.FIELD_BIOMETRIC_AUTH_ERROR, msgId));
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700438 cleanup();
439 }
440
441 private void cleanup() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200442 releaseBiometricWakeLock();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700443 }
444
445 public void startKeyguardFadingAway() {
446
447 // Disable brightness override when the ambient contents are fully invisible.
448 mHandler.postDelayed(new Runnable() {
449 @Override
450 public void run() {
Lucas Dupin1a8588d2018-08-21 12:18:47 -0700451 mStatusBarWindowController.setForceDozeBrightness(false);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700452 }
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500453 }, StatusBar.FADE_KEYGUARD_DURATION_PULSING);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700454 }
455
456 public void finishKeyguardFadingAway() {
Adrian Roosba7ca592017-08-15 17:48:05 +0200457 resetMode();
458 }
459
460 private void resetMode() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700461 mMode = MODE_NONE;
Lucas Dupin1a8588d2018-08-21 12:18:47 -0700462 mStatusBarWindowController.setForceDozeBrightness(false);
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500463 if (mStatusBar.getNavigationBarView() != null) {
464 mStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700465 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200466 mStatusBar.notifyBiometricAuthModeChanged();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700467 }
Adrian Roos58ba6852017-07-18 17:10:29 +0200468
469 private final WakefulnessLifecycle.Observer mWakefulnessObserver =
470 new WakefulnessLifecycle.Observer() {
471 @Override
472 public void onFinishedWakingUp() {
473 if (mPendingShowBouncer) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200474 BiometricUnlockController.this.showBouncer();
Adrian Roos58ba6852017-07-18 17:10:29 +0200475 }
476 }
477 };
Adrian Roos7a5e4c92017-07-31 16:40:19 +0200478
479 private final ScreenLifecycle.Observer mScreenObserver =
480 new ScreenLifecycle.Observer() {
481 @Override
482 public void onScreenTurnedOn() {
483 mHasScreenTurnedOnSinceAuthenticating = true;
484 }
485 };
486
487 public boolean hasScreenTurnedOnSinceAuthenticating() {
488 return mHasScreenTurnedOnSinceAuthenticating;
489 }
Adrian Roosba7ca592017-08-15 17:48:05 +0200490
491 public void dump(PrintWriter pw) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200492 pw.println(" BiometricUnlockController:");
Adrian Roosba7ca592017-08-15 17:48:05 +0200493 pw.print(" mMode="); pw.println(mMode);
494 pw.print(" mWakeLock="); pw.println(mWakeLock);
495 }
Lucas Dupin067136c2018-03-27 18:03:25 -0700496
Lucas Dupin52c21c82018-06-04 19:03:20 -0700497 /**
Lucas Dupin3d053532019-01-29 12:35:22 -0800498 * Successful authentication with fingerprint, face, or iris that wakes up the device.
Lucas Dupin52c21c82018-06-04 19:03:20 -0700499 */
Lucas Dupin067136c2018-03-27 18:03:25 -0700500 public boolean isWakeAndUnlock() {
Lucas Dupin52c21c82018-06-04 19:03:20 -0700501 return mMode == MODE_WAKE_AND_UNLOCK
Lucas Dupin067136c2018-03-27 18:03:25 -0700502 || mMode == MODE_WAKE_AND_UNLOCK_PULSING
503 || mMode == MODE_WAKE_AND_UNLOCK_FROM_DREAM;
504 }
Lucas Dupin52c21c82018-06-04 19:03:20 -0700505
506 /**
Lucas Dupin3d053532019-01-29 12:35:22 -0800507 * Successful authentication with fingerprint, face, or iris when the screen was either
508 * on or off.
Lucas Dupin52c21c82018-06-04 19:03:20 -0700509 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200510 public boolean isBiometricUnlock() {
Lucas Dupin52c21c82018-06-04 19:03:20 -0700511 return isWakeAndUnlock() || mMode == MODE_UNLOCK;
512 }
Steven Wue442acf2019-03-14 13:31:12 -0400513
514 /**
515 * Translates biometric source type for logging purpose.
516 */
517 private int toSubtype(BiometricSourceType biometricSourceType) {
518 switch (biometricSourceType) {
519 case FINGERPRINT:
520 return 0;
521 case FACE:
522 return 1;
523 case IRIS:
524 return 2;
525 default:
526 return 3;
527 }
528 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700529}