• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.systemui.statusbar.phone;
18 
19 import static android.app.StatusBarManager.SESSION_KEYGUARD;
20 import static android.service.dreams.Flags.dreamsV2;
21 
22 import android.annotation.IntDef;
23 import android.content.res.Resources;
24 import android.hardware.biometrics.BiometricFaceConstants;
25 import android.hardware.biometrics.BiometricFingerprintConstants;
26 import android.hardware.biometrics.BiometricSourceType;
27 import android.hardware.fingerprint.FingerprintManager;
28 import android.metrics.LogMaker;
29 import android.os.Handler;
30 import android.os.PowerManager;
31 import android.os.Trace;
32 
33 import androidx.annotation.Nullable;
34 
35 import com.android.internal.annotations.VisibleForTesting;
36 import com.android.internal.logging.InstanceId;
37 import com.android.internal.logging.MetricsLogger;
38 import com.android.internal.logging.UiEvent;
39 import com.android.internal.logging.UiEventLogger;
40 import com.android.internal.logging.UiEventLoggerImpl;
41 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
42 import com.android.internal.util.LatencyTracker;
43 import com.android.keyguard.KeyguardUpdateMonitor;
44 import com.android.keyguard.KeyguardUpdateMonitorCallback;
45 import com.android.keyguard.KeyguardViewController;
46 import com.android.keyguard.logging.BiometricUnlockLogger;
47 import com.android.systemui.Dumpable;
48 import com.android.systemui.biometrics.AuthController;
49 import com.android.systemui.dagger.SysUISingleton;
50 import com.android.systemui.dagger.qualifiers.Main;
51 import com.android.systemui.dump.DumpManager;
52 import com.android.systemui.keyguard.KeyguardViewMediator;
53 import com.android.systemui.keyguard.WakefulnessLifecycle;
54 import com.android.systemui.keyguard.domain.interactor.BiometricUnlockInteractor;
55 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
56 import com.android.systemui.keyguard.shared.model.BiometricUnlockSource;
57 import com.android.systemui.keyguard.shared.model.Edge;
58 import com.android.systemui.keyguard.shared.model.KeyguardState;
59 import com.android.systemui.keyguard.shared.model.TransitionState;
60 import com.android.systemui.keyguard.shared.model.TransitionStep;
61 import com.android.systemui.log.SessionTracker;
62 import com.android.systemui.media.NotificationMediaManager;
63 import com.android.systemui.plugins.statusbar.StatusBarStateController;
64 import com.android.systemui.res.R;
65 import com.android.systemui.scene.shared.model.Scenes;
66 import com.android.systemui.statusbar.NotificationShadeWindowController;
67 import com.android.systemui.statusbar.VibratorHelper;
68 import com.android.systemui.statusbar.policy.KeyguardStateController;
69 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
70 import com.android.systemui.util.kotlin.JavaAdapter;
71 import com.android.systemui.util.time.SystemClock;
72 
73 import dagger.Lazy;
74 
75 import java.io.PrintWriter;
76 import java.lang.annotation.Retention;
77 import java.lang.annotation.RetentionPolicy;
78 import java.util.HashSet;
79 import java.util.Map;
80 import java.util.Optional;
81 import java.util.Set;
82 
83 import javax.inject.Inject;
84 
85 /**
86  * Controller which coordinates all the biometric unlocking actions with the UI.
87  */
88 @SysUISingleton
89 public class BiometricUnlockController extends KeyguardUpdateMonitorCallback implements Dumpable {
90     private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
91     private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
92     private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
93     private static final int UDFPS_ATTEMPTS_BEFORE_SHOW_BOUNCER = 3;
94 
95     @IntDef(prefix = { "MODE_" }, value = {
96             MODE_NONE,
97             MODE_WAKE_AND_UNLOCK,
98             MODE_WAKE_AND_UNLOCK_PULSING,
99             MODE_SHOW_BOUNCER,
100             MODE_ONLY_WAKE,
101             MODE_UNLOCK_COLLAPSING,
102             MODE_DISMISS_BOUNCER,
103             MODE_WAKE_AND_UNLOCK_FROM_DREAM
104     })
105     @Retention(RetentionPolicy.SOURCE)
106     public @interface WakeAndUnlockMode {}
107 
108     /**
109      * Mode in which we don't need to wake up the device when we authenticate.
110      */
111     public static final int MODE_NONE = 0;
112 
113     /**
114      * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
115      * a fingerprint while the screen is off and the device was sleeping.
116      */
117     public static final int MODE_WAKE_AND_UNLOCK = 1;
118 
119     /**
120      * Mode in which we wake the device up, and fade out the Keyguard contents because they were
121      * already visible while pulsing in doze mode.
122      */
123     public static final int MODE_WAKE_AND_UNLOCK_PULSING = 2;
124 
125     /**
126      * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
127      * acquire a fingerprint pulsing in doze mode.
128      */
129     public static final int MODE_SHOW_BOUNCER = 3;
130 
131     /**
132      * Mode in which we only wake up the device, and keyguard was not showing when we authenticated.
133      * */
134     public static final int MODE_ONLY_WAKE = 4;
135 
136     /**
137      * Mode in which fingerprint unlocks the device or passive auth (ie face auth) unlocks the
138      * device while being requested when keyguard is occluded or showing.
139      */
140     public static final int MODE_UNLOCK_COLLAPSING = 5;
141 
142     /**
143      * Mode in which fingerprint wakes and unlocks the device from a dream.
144      */
145     public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 6;
146 
147     /**
148      * When bouncer is visible and will be dismissed.
149      */
150     public static final int MODE_DISMISS_BOUNCER = 7;
151 
152     /**
153      * How much faster we collapse the lockscreen when authenticating with biometric.
154      */
155     private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
156 
157     private final NotificationMediaManager mMediaManager;
158     private final PowerManager mPowerManager;
159     private final Handler mHandler;
160     private final KeyguardBypassController mKeyguardBypassController;
161     private PowerManager.WakeLock mWakeLock;
162     private final KeyguardUpdateMonitor mUpdateMonitor;
163     private final KeyguardStateController mKeyguardStateController;
164     private final NotificationShadeWindowController mNotificationShadeWindowController;
165     private final SessionTracker mSessionTracker;
166     private final int mConsecutiveFpFailureThreshold;
167     private int mMode;
168     private BiometricSourceType mBiometricType;
169     private KeyguardViewController mKeyguardViewController;
170     private DozeScrimController mDozeScrimController;
171     private KeyguardViewMediator mKeyguardViewMediator;
172     private PendingAuthenticated mPendingAuthenticated = null;
173     private boolean mHasScreenTurnedOnSinceAuthenticating;
174     private boolean mFadedAwayAfterWakeAndUnlock;
175     private Set<BiometricUnlockEventsListener> mBiometricUnlockEventsListeners = new HashSet<>();
176 
177     private final MetricsLogger mMetricsLogger;
178     private final AuthController mAuthController;
179     private final StatusBarStateController mStatusBarStateController;
180     private final WakefulnessLifecycle mWakefulnessLifecycle;
181     private final LatencyTracker mLatencyTracker;
182     private final VibratorHelper mVibratorHelper;
183     private final BiometricUnlockInteractor mBiometricUnlockInteractor;
184     private final BiometricUnlockLogger mLogger;
185     private final SystemClock mSystemClock;
186     private final boolean mOrderUnlockAndWake;
187     private final Lazy<SelectedUserInteractor> mSelectedUserInteractor;
188     private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
189     private long mLastFpFailureUptimeMillis;
190     private int mNumConsecutiveFpFailures;
191 
192     private static final class PendingAuthenticated {
193         public final int userId;
194         public final BiometricSourceType biometricSourceType;
195         public final boolean isStrongBiometric;
196 
PendingAuthenticated(int userId, BiometricSourceType biometricSourceType, boolean isStrongBiometric)197         PendingAuthenticated(int userId, BiometricSourceType biometricSourceType,
198                 boolean isStrongBiometric) {
199             this.userId = userId;
200             this.biometricSourceType = biometricSourceType;
201             this.isStrongBiometric = isStrongBiometric;
202         }
203     }
204 
205     public enum BiometricUiEvent implements UiEventLogger.UiEventEnum {
206 
207         @UiEvent(doc = "A biometric event of type fingerprint succeeded.")
208         BIOMETRIC_FINGERPRINT_SUCCESS(396),
209 
210         @UiEvent(doc = "A biometric event of type fingerprint failed.")
211         BIOMETRIC_FINGERPRINT_FAILURE(397),
212 
213         @UiEvent(doc = "A biometric event of type fingerprint errored.")
214         BIOMETRIC_FINGERPRINT_ERROR(398),
215 
216         @UiEvent(doc = "A biometric event of type face unlock succeeded.")
217         BIOMETRIC_FACE_SUCCESS(399),
218 
219         @UiEvent(doc = "A biometric event of type face unlock failed.")
220         BIOMETRIC_FACE_FAILURE(400),
221 
222         @UiEvent(doc = "A biometric event of type face unlock errored.")
223         BIOMETRIC_FACE_ERROR(401),
224 
225         @UiEvent(doc = "A biometric event of type iris succeeded.")
226         BIOMETRIC_IRIS_SUCCESS(402),
227 
228         @UiEvent(doc = "A biometric event of type iris failed.")
229         BIOMETRIC_IRIS_FAILURE(403),
230 
231         @UiEvent(doc = "A biometric event of type iris errored.")
232         BIOMETRIC_IRIS_ERROR(404),
233 
234         @UiEvent(doc = "Bouncer was shown as a result of consecutive failed UDFPS attempts.")
235         BIOMETRIC_BOUNCER_SHOWN(916),
236 
237         @UiEvent(doc = "Screen started waking up with the given PowerManager wake reason.")
238         STARTED_WAKING_UP(1378);
239 
240         private final int mId;
241 
BiometricUiEvent(int id)242         BiometricUiEvent(int id) {
243             mId = id;
244         }
245 
246         @Override
getId()247         public int getId() {
248             return mId;
249         }
250 
251         static final Map<BiometricSourceType, BiometricUiEvent> ERROR_EVENT_BY_SOURCE_TYPE = Map.of(
252                 BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_ERROR,
253                 BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_ERROR,
254                 BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_ERROR
255         );
256 
257         static final Map<BiometricSourceType, BiometricUiEvent> SUCCESS_EVENT_BY_SOURCE_TYPE =
258                 Map.of(
259                     BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_SUCCESS,
260                     BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_SUCCESS,
261                     BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_SUCCESS
262                 );
263 
264         static final Map<BiometricSourceType, BiometricUiEvent> FAILURE_EVENT_BY_SOURCE_TYPE =
265                 Map.of(
266                     BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_FAILURE,
267                     BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_FAILURE,
268                     BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_FAILURE
269                 );
270     }
271 
272     private final ScreenOffAnimationController mScreenOffAnimationController;
273 
274     @Inject
BiometricUnlockController( DozeScrimController dozeScrimController, KeyguardViewMediator keyguardViewMediator, NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, @Main Handler handler, KeyguardUpdateMonitor keyguardUpdateMonitor, @Main Resources resources, KeyguardBypassController keyguardBypassController, MetricsLogger metricsLogger, DumpManager dumpManager, PowerManager powerManager, BiometricUnlockLogger biometricUnlockLogger, NotificationMediaManager notificationMediaManager, WakefulnessLifecycle wakefulnessLifecycle, AuthController authController, StatusBarStateController statusBarStateController, SessionTracker sessionTracker, LatencyTracker latencyTracker, ScreenOffAnimationController screenOffAnimationController, VibratorHelper vibrator, SystemClock systemClock, Lazy<SelectedUserInteractor> selectedUserInteractor, BiometricUnlockInteractor biometricUnlockInteractor, JavaAdapter javaAdapter, KeyguardTransitionInteractor keyguardTransitionInteractor )275     public BiometricUnlockController(
276             DozeScrimController dozeScrimController,
277             KeyguardViewMediator keyguardViewMediator,
278             NotificationShadeWindowController notificationShadeWindowController,
279             KeyguardStateController keyguardStateController,
280             @Main Handler handler,
281             KeyguardUpdateMonitor keyguardUpdateMonitor,
282             @Main Resources resources,
283             KeyguardBypassController keyguardBypassController,
284             MetricsLogger metricsLogger, DumpManager dumpManager,
285             PowerManager powerManager,
286             BiometricUnlockLogger biometricUnlockLogger,
287             NotificationMediaManager notificationMediaManager,
288             WakefulnessLifecycle wakefulnessLifecycle,
289             AuthController authController,
290             StatusBarStateController statusBarStateController,
291             SessionTracker sessionTracker,
292             LatencyTracker latencyTracker,
293             ScreenOffAnimationController screenOffAnimationController,
294             VibratorHelper vibrator,
295             SystemClock systemClock,
296             Lazy<SelectedUserInteractor> selectedUserInteractor,
297             BiometricUnlockInteractor biometricUnlockInteractor,
298             JavaAdapter javaAdapter,
299             KeyguardTransitionInteractor keyguardTransitionInteractor
300     ) {
301         mPowerManager = powerManager;
302         mUpdateMonitor = keyguardUpdateMonitor;
303         mUpdateMonitor.registerCallback(this);
304         mMediaManager = notificationMediaManager;
305         mLatencyTracker = latencyTracker;
306         mWakefulnessLifecycle = wakefulnessLifecycle;
307         mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
308         mBiometricUnlockInteractor = biometricUnlockInteractor;
309 
310         mNotificationShadeWindowController = notificationShadeWindowController;
311         mDozeScrimController = dozeScrimController;
312         mKeyguardViewMediator = keyguardViewMediator;
313         mKeyguardStateController = keyguardStateController;
314         mHandler = handler;
315         mConsecutiveFpFailureThreshold = resources.getInteger(
316                 R.integer.fp_consecutive_failure_time_ms);
317         mKeyguardBypassController = keyguardBypassController;
318         mKeyguardBypassController.setUnlockController(this);
319         mMetricsLogger = metricsLogger;
320         mAuthController = authController;
321         mStatusBarStateController = statusBarStateController;
322         mSessionTracker = sessionTracker;
323         mScreenOffAnimationController = screenOffAnimationController;
324         mVibratorHelper = vibrator;
325         mLogger = biometricUnlockLogger;
326         mSystemClock = systemClock;
327         mOrderUnlockAndWake = resources.getBoolean(
328                 com.android.internal.R.bool.config_orderUnlockAndWake);
329         mSelectedUserInteractor = selectedUserInteractor;
330         mKeyguardTransitionInteractor = keyguardTransitionInteractor;
331         javaAdapter.alwaysCollectFlow(
332                 keyguardTransitionInteractor.transition(
333                         /* edge */ Edge.create(Scenes.Gone, null),
334                         /* edgeWithoutSceneContainer */ Edge.create(
335                                 KeyguardState.GONE, (KeyguardState) null)),
336                 this::consumeFromGoneTransitions);
337         dumpManager.registerDumpable(this);
338     }
339 
340     @VisibleForTesting
consumeFromGoneTransitions(TransitionStep transitionStep)341     protected void consumeFromGoneTransitions(TransitionStep transitionStep) {
342         if (transitionStep.getTransitionState() == TransitionState.STARTED) {
343             mBiometricUnlockInteractor.setBiometricUnlockState(MODE_NONE, null);
344         }
345     }
346 
setKeyguardViewController(KeyguardViewController keyguardViewController)347     public void setKeyguardViewController(KeyguardViewController keyguardViewController) {
348         mKeyguardViewController = keyguardViewController;
349     }
350 
351     /** Adds a {@link BiometricUnlockEventsListener}. */
addListener(BiometricUnlockEventsListener listener)352     public void addListener(BiometricUnlockEventsListener listener) {
353         mBiometricUnlockEventsListeners.add(listener);
354     }
355 
356     /** Removes a {@link BiometricUnlockEventsListener}. */
removeListener(BiometricUnlockEventsListener listener)357     public void removeListener(BiometricUnlockEventsListener listener) {
358         mBiometricUnlockEventsListeners.remove(listener);
359     }
360 
361     private final Runnable mReleaseBiometricWakeLockRunnable = new Runnable() {
362         @Override
363         public void run() {
364             mLogger.i("biometric wakelock: TIMEOUT!!");
365             releaseBiometricWakeLock();
366         }
367     };
368 
releaseBiometricWakeLock()369     private void releaseBiometricWakeLock() {
370         if (mWakeLock != null) {
371             Trace.beginSection("release wake-and-unlock");
372             mHandler.removeCallbacks(mReleaseBiometricWakeLockRunnable);
373             mLogger.i("releasing biometric wakelock");
374             mWakeLock.release();
375             mWakeLock = null;
376             Trace.endSection();
377         }
378     }
379 
380     @Override
onBiometricAcquired(BiometricSourceType biometricSourceType, int acquireInfo)381     public void onBiometricAcquired(BiometricSourceType biometricSourceType,
382             int acquireInfo) {
383         if (BiometricSourceType.FINGERPRINT == biometricSourceType
384                 && acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
385             return;
386         } else if (BiometricSourceType.FACE == biometricSourceType
387                 && acquireInfo != BiometricFaceConstants.FACE_ACQUIRED_GOOD) {
388             return;
389         }
390         Trace.beginSection("BiometricUnlockController#onBiometricAcquired");
391         releaseBiometricWakeLock();
392         if (mStatusBarStateController.isDozing()) {
393             if (mLatencyTracker.isEnabled()) {
394                 int action = LatencyTracker.ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
395                 if (biometricSourceType == BiometricSourceType.FACE) {
396                     action = LatencyTracker.ACTION_FACE_WAKE_AND_UNLOCK;
397                 }
398                 mLatencyTracker.onActionStart(action);
399             }
400             mWakeLock = mPowerManager.newWakeLock(
401                     PowerManager.PARTIAL_WAKE_LOCK, BIOMETRIC_WAKE_LOCK_NAME);
402             Trace.beginSection("acquire wake-and-unlock");
403             mWakeLock.acquire();
404             Trace.endSection();
405             mLogger.i("biometric acquired, grabbing biometric wakelock");
406             mHandler.postDelayed(mReleaseBiometricWakeLockRunnable,
407                     BIOMETRIC_WAKELOCK_TIMEOUT_MS);
408         }
409         Trace.endSection();
410     }
411 
412     @Override
onBiometricDetected(int userId, BiometricSourceType biometricSourceType, boolean isStrongBiometric)413     public void onBiometricDetected(int userId, BiometricSourceType biometricSourceType,
414             boolean isStrongBiometric) {
415         Trace.beginSection("BiometricUnlockController#onBiometricDetected");
416         if (!mUpdateMonitor.isGoingToSleep()) {
417             startWakeAndUnlock(
418                     MODE_SHOW_BOUNCER,
419                     BiometricUnlockSource.Companion.fromBiometricSourceType(biometricSourceType)
420             );
421         }
422         Trace.endSection();
423     }
424 
425     @Override
onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType, boolean isStrongBiometric)426     public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
427             boolean isStrongBiometric) {
428         Trace.beginSection("BiometricUnlockController#onBiometricUnlocked");
429         if (mUpdateMonitor.isGoingToSleep()) {
430             mLogger.deferringAuthenticationDueToSleep(userId,
431                     biometricSourceType,
432                     mPendingAuthenticated != null);
433             mPendingAuthenticated = new PendingAuthenticated(userId, biometricSourceType,
434                     isStrongBiometric);
435             Trace.endSection();
436             return;
437         }
438         mBiometricType = biometricSourceType;
439         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
440                 .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
441         Optional.ofNullable(BiometricUiEvent.SUCCESS_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
442                 .ifPresent(event -> UI_EVENT_LOGGER.log(event, getSessionId()));
443 
444         boolean unlockAllowed =
445                 mKeyguardStateController.isOccluded()
446                         || mKeyguardBypassController.onBiometricAuthenticated(
447                                 biometricSourceType, isStrongBiometric);
448         if (unlockAllowed) {
449             mKeyguardViewMediator.userActivity();
450             startWakeAndUnlock(biometricSourceType, isStrongBiometric);
451         } else {
452             mLogger.d("onBiometricUnlocked aborted by bypass controller");
453         }
454         Trace.endSection();
455     }
456 
457     /**
458      * Wake and unlock the device in response to successful authentication using biometrics.
459      * @param biometricSourceType Biometric source that was used to authenticate.
460      * @param isStrongBiometric
461      */
startWakeAndUnlock(BiometricSourceType biometricSourceType, boolean isStrongBiometric)462     public void startWakeAndUnlock(BiometricSourceType biometricSourceType,
463                                    boolean isStrongBiometric) {
464         int mode = calculateMode(biometricSourceType, isStrongBiometric);
465         if (mode == MODE_WAKE_AND_UNLOCK
466                 || mode == MODE_WAKE_AND_UNLOCK_PULSING || mode == MODE_UNLOCK_COLLAPSING
467                 || mode == MODE_WAKE_AND_UNLOCK_FROM_DREAM || mode == MODE_DISMISS_BOUNCER) {
468             onBiometricUnlockedWithKeyguardDismissal(biometricSourceType);
469         }
470         startWakeAndUnlock(
471                 mode,
472                 BiometricUnlockSource.Companion.fromBiometricSourceType(biometricSourceType)
473         );
474     }
475 
476     /**
477      * Wake and unlock the device in response to successful authentication using biometrics.
478      */
startWakeAndUnlock( @akeAndUnlockMode int mode, BiometricUnlockSource biometricUnlockSource )479     public void startWakeAndUnlock(
480             @WakeAndUnlockMode int mode,
481             BiometricUnlockSource biometricUnlockSource
482     ) {
483         Trace.beginSection("BiometricUnlockController#startWakeAndUnlock");
484         mLogger.logStartWakeAndUnlock(mode);
485         boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
486         mMode = mode;
487         mHasScreenTurnedOnSinceAuthenticating = false;
488         if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
489             // If we are waking the device up while we are pulsing the clock and the
490             // notifications would light up first, creating an unpleasant animation.
491             // Defer changing the screen brightness by forcing doze brightness on our window
492             // until the clock and the notifications are faded out.
493             mNotificationShadeWindowController.setForceDozeBrightness(true);
494         }
495         // During wake and unlock, we need to draw black before waking up to avoid abrupt
496         // brightness changes due to display state transitions.
497         Runnable wakeUp = ()-> {
498             if (!wasDeviceInteractive || mUpdateMonitor.isDreaming()) {
499                 mLogger.i("bio wakelock: Authenticated, waking up...");
500                 mPowerManager.wakeUp(
501                         mSystemClock.uptimeMillis(),
502                         PowerManager.WAKE_REASON_BIOMETRIC,
503                         "android.policy:BIOMETRIC"
504                 );
505             }
506             releaseBiometricWakeLock();
507         };
508 
509         final boolean wakeInKeyguard = mMode == MODE_WAKE_AND_UNLOCK_FROM_DREAM
510                 && mPowerManager.isInteractive() && mOrderUnlockAndWake
511                 && mOrderUnlockAndWake;
512 
513         if (mMode != MODE_NONE && !wakeInKeyguard) {
514             wakeUp.run();
515         }
516         switch (mMode) {
517             case MODE_DISMISS_BOUNCER:
518                 Trace.beginSection("MODE_DISMISS_BOUNCER");
519                 mKeyguardViewController.notifyKeyguardAuthenticated(
520                         false /* primaryAuth */);
521                 Trace.endSection();
522                 break;
523             case MODE_UNLOCK_COLLAPSING:
524                 Trace.beginSection("MODE_UNLOCK_COLLAPSING");
525                 mKeyguardViewController.notifyKeyguardAuthenticated(
526                         false /* primaryAuth */);
527                 Trace.endSection();
528                 break;
529             case MODE_SHOW_BOUNCER:
530                 Trace.beginSection("MODE_SHOW_BOUNCER");
531                 mKeyguardViewController.showPrimaryBouncer(true,
532                         "BiometricUnlockController#MODE_SHOW_BOUNCER");
533                 Trace.endSection();
534                 break;
535             case MODE_WAKE_AND_UNLOCK_FROM_DREAM:
536             case MODE_WAKE_AND_UNLOCK_PULSING:
537             case MODE_WAKE_AND_UNLOCK:
538                 if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
539                     Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
540                 } else if (mMode == MODE_WAKE_AND_UNLOCK){
541                     Trace.beginSection("MODE_WAKE_AND_UNLOCK");
542                 } else {
543                     Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
544                     // Don't call awaken from Dream here. In order to avoid flickering, wait until
545                     // later to awaken.
546                 }
547                 mNotificationShadeWindowController.setNotificationShadeFocusable(false);
548                 // Notify the interactor first, to prevent race conditions with the screen waking up
549                 // that would show a flicker of the lockscreen on DOZING->GONE
550                 mBiometricUnlockInteractor.setBiometricUnlockState(mode, biometricUnlockSource);
551                 mKeyguardViewMediator.onWakeAndUnlocking(wakeInKeyguard);
552                 Trace.endSection();
553                 break;
554             case MODE_ONLY_WAKE:
555             case MODE_NONE:
556                 break;
557         }
558         onModeChanged(mMode, biometricUnlockSource);
559         Trace.endSection();
560     }
561 
onModeChanged( @akeAndUnlockMode int mode, BiometricUnlockSource biometricUnlockSource )562     private void onModeChanged(
563             @WakeAndUnlockMode int mode,
564             BiometricUnlockSource biometricUnlockSource
565     ) {
566         for (BiometricUnlockEventsListener listener : mBiometricUnlockEventsListeners) {
567             listener.onModeChanged(mode);
568         }
569         mBiometricUnlockInteractor.setBiometricUnlockState(mode, biometricUnlockSource);
570     }
571 
onBiometricUnlockedWithKeyguardDismissal(BiometricSourceType biometricSourceType)572     private void onBiometricUnlockedWithKeyguardDismissal(BiometricSourceType biometricSourceType) {
573         for (BiometricUnlockEventsListener listener : mBiometricUnlockEventsListeners) {
574             listener.onBiometricUnlockedWithKeyguardDismissal(biometricSourceType);
575         }
576     }
577 
hasPendingAuthentication()578     public boolean hasPendingAuthentication() {
579         return mPendingAuthenticated != null
580                 && mUpdateMonitor
581                     .isUnlockingWithBiometricAllowed(mPendingAuthenticated.isStrongBiometric)
582                 && mPendingAuthenticated.userId
583                     == mSelectedUserInteractor.get().getSelectedUserId();
584     }
585 
getMode()586     public @WakeAndUnlockMode int getMode() {
587         return mMode;
588     }
589 
calculateMode(BiometricSourceType biometricSourceType, boolean isStrongBiometric)590     private @WakeAndUnlockMode int calculateMode(BiometricSourceType biometricSourceType,
591             boolean isStrongBiometric) {
592         if (biometricSourceType == BiometricSourceType.FACE
593                 || biometricSourceType == BiometricSourceType.IRIS) {
594             return calculateModeForPassiveAuth(isStrongBiometric);
595         } else {
596             return calculateModeForFingerprint(isStrongBiometric);
597         }
598     }
599 
calculateModeForFingerprint(boolean isStrongBiometric)600     private @WakeAndUnlockMode int calculateModeForFingerprint(boolean isStrongBiometric) {
601         final boolean unlockingAllowed =
602                 mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
603         final boolean deviceInteractive = mUpdateMonitor.isDeviceInteractive();
604         final boolean keyguardShowing = mKeyguardStateController.isShowing();
605         final boolean deviceDreaming = mUpdateMonitor.isDreaming();
606 
607         logCalculateModeForFingerprint(unlockingAllowed, deviceInteractive,
608                 keyguardShowing, deviceDreaming, isStrongBiometric);
609         if (!deviceInteractive) {
610             if (!keyguardShowing && !mScreenOffAnimationController.isKeyguardShowDelayed()) {
611                 if (mKeyguardStateController.isUnlocked()) {
612                     return MODE_WAKE_AND_UNLOCK;
613                 }
614                 return MODE_ONLY_WAKE;
615             } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
616                 return MODE_WAKE_AND_UNLOCK_PULSING;
617             } else if (unlockingAllowed || !mKeyguardStateController.isMethodSecure()) {
618                 return MODE_WAKE_AND_UNLOCK;
619             } else {
620                 return MODE_SHOW_BOUNCER;
621             }
622         }
623         if (unlockingAllowed && deviceDreaming) {
624             return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
625         }
626         if (keyguardShowing) {
627             if (mKeyguardViewController.primaryBouncerIsOrWillBeShowing() && unlockingAllowed) {
628                 return MODE_DISMISS_BOUNCER;
629             } else if (unlockingAllowed) {
630                 return MODE_UNLOCK_COLLAPSING;
631             } else if (!mKeyguardViewController.isBouncerShowing()) {
632                 return MODE_SHOW_BOUNCER;
633             }
634         }
635         return MODE_NONE;
636     }
637 
logCalculateModeForFingerprint(boolean unlockingAllowed, boolean deviceInteractive, boolean keyguardShowing, boolean deviceDreaming, boolean strongBiometric)638     private void logCalculateModeForFingerprint(boolean unlockingAllowed, boolean deviceInteractive,
639             boolean keyguardShowing, boolean deviceDreaming, boolean strongBiometric) {
640         if (unlockingAllowed) {
641             mLogger.logCalculateModeForFingerprintUnlockingAllowed(deviceInteractive,
642                     keyguardShowing, deviceDreaming);
643         } else {
644             // if unlocking isn't allowed, log more information about why unlocking may not
645             // have been allowed
646             final int strongAuthFlags = mUpdateMonitor.getStrongAuthTracker().getStrongAuthForUser(
647                     mSelectedUserInteractor.get().getSelectedUserId());
648             final boolean nonStrongBiometricAllowed =
649                     mUpdateMonitor.getStrongAuthTracker()
650                             .isNonStrongBiometricAllowedAfterIdleTimeout(
651                                     mSelectedUserInteractor.get().getSelectedUserId());
652 
653             mLogger.logCalculateModeForFingerprintUnlockingNotAllowed(strongBiometric,
654                     strongAuthFlags, nonStrongBiometricAllowed, deviceInteractive, keyguardShowing);
655         }
656     }
657 
calculateModeForPassiveAuth(boolean isStrongBiometric)658     private @WakeAndUnlockMode int calculateModeForPassiveAuth(boolean isStrongBiometric) {
659         final boolean deviceInteractive = mUpdateMonitor.isDeviceInteractive();
660         final boolean isKeyguardShowing = mKeyguardStateController.isShowing();
661         final boolean unlockingAllowed =
662                 mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
663         final boolean deviceDreaming = mUpdateMonitor.isDreaming();
664         final boolean bypass = mKeyguardBypassController.getBypassEnabled()
665                 || mAuthController.isUdfpsFingerDown();
666         final boolean isBouncerShowing = mKeyguardViewController.primaryBouncerIsOrWillBeShowing()
667                 || mKeyguardTransitionInteractor.getCurrentState()
668                     == KeyguardState.ALTERNATE_BOUNCER;
669 
670         logCalculateModeForPassiveAuth(unlockingAllowed, deviceInteractive, isKeyguardShowing,
671                 deviceDreaming, bypass, isStrongBiometric);
672         if (!deviceInteractive) {
673             if (!isKeyguardShowing) {
674                 return bypass ? MODE_WAKE_AND_UNLOCK : MODE_ONLY_WAKE;
675             } else if (!unlockingAllowed) {
676                 return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
677             } else if (mDozeScrimController.isPulsing()) {
678                 return bypass ? MODE_WAKE_AND_UNLOCK_PULSING : MODE_ONLY_WAKE;
679             } else {
680                 if (bypass) {
681                     // Wake-up fading out nicely
682                     return MODE_WAKE_AND_UNLOCK_PULSING;
683                 } else {
684                     // We could theoretically return MODE_NONE, but this means that the device
685                     // would be not interactive, unlocked, and the user would not see the device
686                     // state.
687                     return MODE_ONLY_WAKE;
688                 }
689             }
690         }
691         if (unlockingAllowed && deviceDreaming) {
692             final boolean wakeAndUnlock = bypass || (dreamsV2() && isBouncerShowing);
693             return wakeAndUnlock ? MODE_WAKE_AND_UNLOCK_FROM_DREAM : MODE_ONLY_WAKE;
694         }
695         if (unlockingAllowed && mKeyguardStateController.isOccluded()) {
696             return MODE_UNLOCK_COLLAPSING;
697         }
698         if (isKeyguardShowing) {
699             if (isBouncerShowing && unlockingAllowed) {
700                 return MODE_DISMISS_BOUNCER;
701             } else if (unlockingAllowed && bypass) {
702                 return MODE_UNLOCK_COLLAPSING;
703             } else {
704                 return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
705             }
706         }
707         return MODE_NONE;
708     }
709 
logCalculateModeForPassiveAuth(boolean unlockingAllowed, boolean deviceInteractive, boolean keyguardShowing, boolean deviceDreaming, boolean bypass, boolean strongBiometric)710     private void logCalculateModeForPassiveAuth(boolean unlockingAllowed,
711             boolean deviceInteractive, boolean keyguardShowing, boolean deviceDreaming,
712             boolean bypass, boolean strongBiometric) {
713         if (unlockingAllowed) {
714             mLogger.logCalculateModeForPassiveAuthUnlockingAllowed(
715                     deviceInteractive, keyguardShowing, deviceDreaming, bypass);
716         } else {
717             // if unlocking isn't allowed, log more information about why unlocking may not
718             // have been allowed
719             final int strongAuthFlags = mUpdateMonitor.getStrongAuthTracker().getStrongAuthForUser(
720                     mSelectedUserInteractor.get().getSelectedUserId());
721             final boolean nonStrongBiometricAllowed =
722                     mUpdateMonitor.getStrongAuthTracker()
723                             .isNonStrongBiometricAllowedAfterIdleTimeout(
724                                     mSelectedUserInteractor.get().getSelectedUserId());
725 
726             mLogger.logCalculateModeForPassiveAuthUnlockingNotAllowed(
727                     strongBiometric, strongAuthFlags, nonStrongBiometricAllowed,
728                     deviceInteractive, keyguardShowing, bypass);
729         }
730     }
731 
732     @Override
onBiometricAuthFailed(BiometricSourceType biometricSourceType)733     public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
734         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
735                 .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType)));
736         Optional.ofNullable(BiometricUiEvent.FAILURE_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
737                 .ifPresent(event -> UI_EVENT_LOGGER.log(event, getSessionId()));
738 
739         if (mLatencyTracker.isEnabled()) {
740             int action = LatencyTracker.ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
741             if (biometricSourceType == BiometricSourceType.FACE) {
742                 action = LatencyTracker.ACTION_FACE_WAKE_AND_UNLOCK;
743             }
744             mLatencyTracker.onActionCancel(action);
745         }
746 
747         final boolean screenOff = !mUpdateMonitor.isDeviceInteractive();
748         if (!mVibratorHelper.hasVibrator() && screenOff) {
749             mLogger.d("wakeup device on authentication failure (device doesn't have a vibrator)");
750             startWakeAndUnlock(
751                     MODE_ONLY_WAKE,
752                     BiometricUnlockSource.Companion.fromBiometricSourceType(biometricSourceType)
753             );
754         } else if (biometricSourceType == BiometricSourceType.FINGERPRINT
755                 && mUpdateMonitor.isOpticalUdfpsSupported()) {
756             long currUptimeMillis = mSystemClock.uptimeMillis();
757             if (currUptimeMillis - mLastFpFailureUptimeMillis < mConsecutiveFpFailureThreshold) {
758                 mNumConsecutiveFpFailures += 1;
759             } else {
760                 mNumConsecutiveFpFailures = 1;
761             }
762             mLastFpFailureUptimeMillis = currUptimeMillis;
763 
764             if (mNumConsecutiveFpFailures >= UDFPS_ATTEMPTS_BEFORE_SHOW_BOUNCER) {
765                 mLogger.logUdfpsAttemptThresholdMet(mNumConsecutiveFpFailures);
766                 startWakeAndUnlock(
767                         MODE_SHOW_BOUNCER,
768                         BiometricUnlockSource.Companion.fromBiometricSourceType(biometricSourceType)
769                 );
770                 UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN, getSessionId());
771                 mNumConsecutiveFpFailures = 0;
772             }
773         }
774 
775         cleanup();
776     }
777 
778     @Override
onBiometricError(int msgId, String errString, BiometricSourceType biometricSourceType)779     public void onBiometricError(int msgId, String errString,
780             BiometricSourceType biometricSourceType) {
781         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
782                 .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType))
783                 .addTaggedData(MetricsEvent.FIELD_BIOMETRIC_AUTH_ERROR, msgId));
784         Optional.ofNullable(BiometricUiEvent.ERROR_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
785                 .ifPresent(event -> UI_EVENT_LOGGER.log(event, getSessionId()));
786 
787         final boolean fingerprintLockout = biometricSourceType == BiometricSourceType.FINGERPRINT
788                 && (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
789                 || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT);
790         if (fingerprintLockout) {
791             mLogger.d("fingerprint locked out");
792             startWakeAndUnlock(
793                     MODE_SHOW_BOUNCER,
794                     BiometricUnlockSource.Companion.fromBiometricSourceType(biometricSourceType)
795             );
796             UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN, getSessionId());
797         }
798 
799         cleanup();
800     }
801 
cleanup()802     private void cleanup() {
803         releaseBiometricWakeLock();
804     }
805 
startKeyguardFadingAway()806     public void startKeyguardFadingAway() {
807 
808         // Disable brightness override when the ambient contents are fully invisible.
809         mHandler.postDelayed(new Runnable() {
810             @Override
811             public void run() {
812                 mNotificationShadeWindowController.setForceDozeBrightness(false);
813             }
814         }, CentralSurfaces.FADE_KEYGUARD_DURATION_PULSING);
815     }
816 
finishKeyguardFadingAway()817     public void finishKeyguardFadingAway() {
818         if (isWakeAndUnlock()) {
819             mFadedAwayAfterWakeAndUnlock = true;
820         }
821         resetMode();
822     }
823 
resetMode()824     private void resetMode() {
825         mMode = MODE_NONE;
826         mBiometricType = null;
827         mNotificationShadeWindowController.setForceDozeBrightness(false);
828         for (BiometricUnlockEventsListener listener : mBiometricUnlockEventsListeners) {
829             listener.onResetMode();
830         }
831         mNumConsecutiveFpFailures = 0;
832         mLastFpFailureUptimeMillis = 0;
833     }
834 
835     @VisibleForTesting
836     final WakefulnessLifecycle.Observer mWakefulnessObserver =
837             new WakefulnessLifecycle.Observer() {
838                 @Override
839                 public void onStartedGoingToSleep() {
840                     resetMode();
841                     mFadedAwayAfterWakeAndUnlock = false;
842                     mPendingAuthenticated = null;
843                 }
844 
845                 @Override
846                 public void onFinishedGoingToSleep() {
847                     Trace.beginSection("BiometricUnlockController#onFinishedGoingToSleep");
848                     if (mPendingAuthenticated != null) {
849                         mLogger.finishedGoingToSleepWithPendingAuth();
850                         PendingAuthenticated pendingAuthenticated = mPendingAuthenticated;
851                         // Post this to make sure it's executed after the device is fully locked.
852                         mHandler.post(() -> onBiometricAuthenticated(pendingAuthenticated.userId,
853                                 pendingAuthenticated.biometricSourceType,
854                                 pendingAuthenticated.isStrongBiometric));
855                         mPendingAuthenticated = null;
856                     }
857                     Trace.endSection();
858                 }
859             };
860 
861     @Override
onKeyguardBouncerStateChanged(boolean bouncerIsOrWillBeShowing)862     public void onKeyguardBouncerStateChanged(boolean bouncerIsOrWillBeShowing) {
863         // When the bouncer is dismissed, treat this as a reset of the unlock mode. The user
864         // may have gone back instead of successfully unlocking
865         if (!bouncerIsOrWillBeShowing) {
866             resetMode();
867         }
868     }
869 
870     @Override
dump(PrintWriter pw, String[] args)871     public void dump(PrintWriter pw, String[] args) {
872         pw.println(" BiometricUnlockController:");
873         pw.print("   mMode="); pw.println(mMode);
874         pw.print("   mWakeLock="); pw.println(mWakeLock);
875         if (mUpdateMonitor.isUdfpsSupported()) {
876             pw.print("   mNumConsecutiveFpFailures="); pw.println(mNumConsecutiveFpFailures);
877             pw.print("   time since last failure=");
878             pw.println(mSystemClock.uptimeMillis() - mLastFpFailureUptimeMillis);
879         }
880     }
881 
882     /**
883      * Successful authentication with fingerprint, face, or iris that wakes up the device.
884      */
isWakeAndUnlock()885     public boolean isWakeAndUnlock() {
886         return mMode == MODE_WAKE_AND_UNLOCK
887                 || mMode == MODE_WAKE_AND_UNLOCK_PULSING
888                 || mMode == MODE_WAKE_AND_UNLOCK_FROM_DREAM;
889     }
890 
891     /**
892      * Successful authentication with fingerprint, face, or iris that wakes up the device.
893      * This will return {@code true} even after the keyguard fades away.
894      */
unlockedByWakeAndUnlock()895     public boolean unlockedByWakeAndUnlock() {
896         return  isWakeAndUnlock() || mFadedAwayAfterWakeAndUnlock;
897     }
898 
899     /**
900      * Successful authentication with fingerprint, face, or iris when the screen was either
901      * on or off.
902      */
isBiometricUnlock()903     public boolean isBiometricUnlock() {
904         return isWakeAndUnlock() || mMode == MODE_UNLOCK_COLLAPSING;
905     }
906 
907     /**
908      * Successful authentication with fingerprint, face, or iris when the lockscreen fades away
909      */
getBiometricType()910     public BiometricSourceType getBiometricType() {
911         return mBiometricType;
912     }
913 
getSessionId()914     private @Nullable InstanceId getSessionId() {
915         return mSessionTracker.getSessionId(SESSION_KEYGUARD);
916     }
917     /**
918      * Translates biometric source type for logging purpose.
919      */
toSubtype(BiometricSourceType biometricSourceType)920     private int toSubtype(BiometricSourceType biometricSourceType) {
921         switch (biometricSourceType) {
922             case FINGERPRINT:
923                 return 0;
924             case FACE:
925                 return 1;
926             case IRIS:
927                 return 2;
928             default:
929                 return 3;
930         }
931     }
932 
933     /** An interface to interact with the {@link BiometricUnlockController}. */
934     public interface BiometricUnlockEventsListener {
935         /** Called when {@code mMode} is reset to {@link #MODE_NONE}. */
onResetMode()936         default void onResetMode() {}
937         /** Called when {@code mMode} has changed in
938          *      {@link #startWakeAndUnlock(int, BiometricUnlockSource)}. */
onModeChanged(@akeAndUnlockMode int mode)939         default void onModeChanged(@WakeAndUnlockMode int mode) {}
940 
941         /**
942          * Called when the device is unlocked successfully using biometrics with the keyguard also
943          * being dismissed.
944          */
onBiometricUnlockedWithKeyguardDismissal( BiometricSourceType biometricSourceType)945         default void onBiometricUnlockedWithKeyguardDismissal(
946                 BiometricSourceType biometricSourceType) { }
947     }
948 }
949