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 android.annotation.IntDef;
20 import android.content.Context;
21 import android.content.res.Resources;
22 import android.hardware.biometrics.BiometricSourceType;
23 import android.metrics.LogMaker;
24 import android.os.Handler;
25 import android.os.PowerManager;
26 import android.os.SystemClock;
27 import android.os.Trace;
28 import android.util.Log;
29 
30 import com.android.internal.annotations.VisibleForTesting;
31 import com.android.internal.logging.MetricsLogger;
32 import com.android.internal.logging.UiEvent;
33 import com.android.internal.logging.UiEventLogger;
34 import com.android.internal.logging.UiEventLoggerImpl;
35 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
36 import com.android.internal.util.LatencyTracker;
37 import com.android.keyguard.KeyguardConstants;
38 import com.android.keyguard.KeyguardUpdateMonitor;
39 import com.android.keyguard.KeyguardUpdateMonitorCallback;
40 import com.android.keyguard.KeyguardViewController;
41 import com.android.systemui.Dependency;
42 import com.android.systemui.Dumpable;
43 import com.android.systemui.dagger.qualifiers.Main;
44 import com.android.systemui.dump.DumpManager;
45 import com.android.systemui.keyguard.KeyguardViewMediator;
46 import com.android.systemui.keyguard.ScreenLifecycle;
47 import com.android.systemui.keyguard.WakefulnessLifecycle;
48 import com.android.systemui.statusbar.CommandQueue;
49 import com.android.systemui.statusbar.NotificationMediaManager;
50 import com.android.systemui.statusbar.policy.KeyguardStateController;
51 
52 import java.io.FileDescriptor;
53 import java.io.PrintWriter;
54 import java.lang.annotation.Retention;
55 import java.lang.annotation.RetentionPolicy;
56 import java.util.Map;
57 import java.util.Optional;
58 
59 import javax.inject.Inject;
60 import javax.inject.Singleton;
61 
62 /**
63  * Controller which coordinates all the biometric unlocking actions with the UI.
64  */
65 @Singleton
66 public class BiometricUnlockController extends KeyguardUpdateMonitorCallback implements Dumpable {
67 
68     private static final String TAG = "BiometricUnlockCtrl";
69     private static final boolean DEBUG_BIO_WAKELOCK = KeyguardConstants.DEBUG_BIOMETRIC_WAKELOCK;
70     private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
71     private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
72     private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
73 
74     @IntDef(prefix = { "MODE_" }, value = {
75             MODE_NONE,
76             MODE_WAKE_AND_UNLOCK,
77             MODE_WAKE_AND_UNLOCK_PULSING,
78             MODE_SHOW_BOUNCER,
79             MODE_ONLY_WAKE,
80             MODE_UNLOCK_COLLAPSING,
81             MODE_UNLOCK_FADING,
82             MODE_DISMISS_BOUNCER,
83             MODE_WAKE_AND_UNLOCK_FROM_DREAM
84     })
85     @Retention(RetentionPolicy.SOURCE)
86     public @interface WakeAndUnlockMode {}
87 
88     /**
89      * Mode in which we don't need to wake up the device when we authenticate.
90      */
91     public static final int MODE_NONE = 0;
92 
93     /**
94      * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
95      * a fingerprint while the screen is off and the device was sleeping.
96      */
97     public static final int MODE_WAKE_AND_UNLOCK = 1;
98 
99     /**
100      * Mode in which we wake the device up, and fade out the Keyguard contents because they were
101      * already visible while pulsing in doze mode.
102      */
103     public static final int MODE_WAKE_AND_UNLOCK_PULSING = 2;
104 
105     /**
106      * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
107      * acquire a fingerprint pulsing in doze mode.
108      */
109     public static final int MODE_SHOW_BOUNCER = 3;
110 
111     /**
112      * Mode in which we only wake up the device, and keyguard was not showing when we authenticated.
113      * */
114     public static final int MODE_ONLY_WAKE = 4;
115 
116     /**
117      * Mode in which fingerprint unlocks the device.
118      */
119     public static final int MODE_UNLOCK_COLLAPSING = 5;
120 
121     /**
122      * Mode in which fingerprint wakes and unlocks the device from a dream.
123      */
124     public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 6;
125 
126     /**
127      * Faster mode of dismissing the lock screen when we cross fade to an app
128      * (used for keyguard bypass.)
129      */
130     public static final int MODE_UNLOCK_FADING = 7;
131 
132     /**
133      * When bouncer is visible and will be dismissed.
134      */
135     public static final int MODE_DISMISS_BOUNCER = 8;
136 
137     /**
138      * How much faster we collapse the lockscreen when authenticating with biometric.
139      */
140     private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
141 
142     private final NotificationMediaManager mMediaManager;
143     private final PowerManager mPowerManager;
144     private final Handler mHandler;
145     private final KeyguardBypassController mKeyguardBypassController;
146     private PowerManager.WakeLock mWakeLock;
147     private final ShadeController mShadeController;
148     private final KeyguardUpdateMonitor mUpdateMonitor;
149     private final DozeParameters mDozeParameters;
150     private final KeyguardStateController mKeyguardStateController;
151     private final NotificationShadeWindowController mNotificationShadeWindowController;
152     private final Context mContext;
153     private final int mWakeUpDelay;
154     private int mMode;
155     private KeyguardViewController mKeyguardViewController;
156     private DozeScrimController mDozeScrimController;
157     private KeyguardViewMediator mKeyguardViewMediator;
158     private ScrimController mScrimController;
159     private StatusBar mStatusBar;
160     private PendingAuthenticated mPendingAuthenticated = null;
161     private boolean mPendingShowBouncer;
162     private boolean mHasScreenTurnedOnSinceAuthenticating;
163     private boolean mFadedAwayAfterWakeAndUnlock;
164 
165     private final MetricsLogger mMetricsLogger;
166 
167     private static final class PendingAuthenticated {
168         public final int userId;
169         public final BiometricSourceType biometricSourceType;
170         public final boolean isStrongBiometric;
171 
PendingAuthenticated(int userId, BiometricSourceType biometricSourceType, boolean isStrongBiometric)172         PendingAuthenticated(int userId, BiometricSourceType biometricSourceType,
173                 boolean isStrongBiometric) {
174             this.userId = userId;
175             this.biometricSourceType = biometricSourceType;
176             this.isStrongBiometric = isStrongBiometric;
177         }
178     }
179 
180     @VisibleForTesting
181     public enum BiometricUiEvent implements UiEventLogger.UiEventEnum {
182 
183         @UiEvent(doc = "A biometric event of type fingerprint succeeded.")
184         BIOMETRIC_FINGERPRINT_SUCCESS(396),
185 
186         @UiEvent(doc = "A biometric event of type fingerprint failed.")
187         BIOMETRIC_FINGERPRINT_FAILURE(397),
188 
189         @UiEvent(doc = "A biometric event of type fingerprint errored.")
190         BIOMETRIC_FINGERPRINT_ERROR(398),
191 
192         @UiEvent(doc = "A biometric event of type face unlock succeeded.")
193         BIOMETRIC_FACE_SUCCESS(399),
194 
195         @UiEvent(doc = "A biometric event of type face unlock failed.")
196         BIOMETRIC_FACE_FAILURE(400),
197 
198         @UiEvent(doc = "A biometric event of type face unlock errored.")
199         BIOMETRIC_FACE_ERROR(401),
200 
201         @UiEvent(doc = "A biometric event of type iris succeeded.")
202         BIOMETRIC_IRIS_SUCCESS(402),
203 
204         @UiEvent(doc = "A biometric event of type iris failed.")
205         BIOMETRIC_IRIS_FAILURE(403),
206 
207         @UiEvent(doc = "A biometric event of type iris errored.")
208         BIOMETRIC_IRIS_ERROR(404);
209 
210         private final int mId;
211 
BiometricUiEvent(int id)212         BiometricUiEvent(int id) {
213             mId = id;
214         }
215 
216         @Override
getId()217         public int getId() {
218             return mId;
219         }
220 
221         static final Map<BiometricSourceType, BiometricUiEvent> ERROR_EVENT_BY_SOURCE_TYPE = Map.of(
222                 BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_ERROR,
223                 BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_ERROR,
224                 BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_ERROR
225         );
226 
227         static final Map<BiometricSourceType, BiometricUiEvent> SUCCESS_EVENT_BY_SOURCE_TYPE =
228                 Map.of(
229                     BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_SUCCESS,
230                     BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_SUCCESS,
231                     BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_SUCCESS
232                 );
233 
234         static final Map<BiometricSourceType, BiometricUiEvent> FAILURE_EVENT_BY_SOURCE_TYPE =
235                 Map.of(
236                     BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_FAILURE,
237                     BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_FAILURE,
238                     BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_FAILURE
239                 );
240     }
241 
242     @Inject
BiometricUnlockController(Context context, DozeScrimController dozeScrimController, KeyguardViewMediator keyguardViewMediator, ScrimController scrimController, StatusBar statusBar, ShadeController shadeController, NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, Handler handler, KeyguardUpdateMonitor keyguardUpdateMonitor, @Main Resources resources, KeyguardBypassController keyguardBypassController, DozeParameters dozeParameters, MetricsLogger metricsLogger, DumpManager dumpManager)243     public BiometricUnlockController(Context context, DozeScrimController dozeScrimController,
244             KeyguardViewMediator keyguardViewMediator, ScrimController scrimController,
245             StatusBar statusBar, ShadeController shadeController,
246             NotificationShadeWindowController notificationShadeWindowController,
247             KeyguardStateController keyguardStateController, Handler handler,
248             KeyguardUpdateMonitor keyguardUpdateMonitor,
249             @Main Resources resources,
250             KeyguardBypassController keyguardBypassController, DozeParameters dozeParameters,
251             MetricsLogger metricsLogger, DumpManager dumpManager) {
252         mContext = context;
253         mPowerManager = context.getSystemService(PowerManager.class);
254         mShadeController = shadeController;
255         mUpdateMonitor = keyguardUpdateMonitor;
256         mDozeParameters = dozeParameters;
257         mUpdateMonitor.registerCallback(this);
258         mMediaManager = Dependency.get(NotificationMediaManager.class);
259         Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
260         Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
261 
262         mNotificationShadeWindowController = notificationShadeWindowController;
263         mDozeScrimController = dozeScrimController;
264         mKeyguardViewMediator = keyguardViewMediator;
265         mScrimController = scrimController;
266         mStatusBar = statusBar;
267         mKeyguardStateController = keyguardStateController;
268         mHandler = handler;
269         mWakeUpDelay = resources.getInteger(com.android.internal.R.integer.config_wakeUpDelayDoze);
270         mKeyguardBypassController = keyguardBypassController;
271         mKeyguardBypassController.setUnlockController(this);
272         mMetricsLogger = metricsLogger;
273         dumpManager.registerDumpable(getClass().getName(), this);
274     }
275 
setKeyguardViewController(KeyguardViewController keyguardViewController)276     public void setKeyguardViewController(KeyguardViewController keyguardViewController) {
277         mKeyguardViewController = keyguardViewController;
278     }
279 
280     private final Runnable mReleaseBiometricWakeLockRunnable = new Runnable() {
281         @Override
282         public void run() {
283             if (DEBUG_BIO_WAKELOCK) {
284                 Log.i(TAG, "biometric wakelock: TIMEOUT!!");
285             }
286             releaseBiometricWakeLock();
287         }
288     };
289 
releaseBiometricWakeLock()290     private void releaseBiometricWakeLock() {
291         if (mWakeLock != null) {
292             mHandler.removeCallbacks(mReleaseBiometricWakeLockRunnable);
293             if (DEBUG_BIO_WAKELOCK) {
294                 Log.i(TAG, "releasing biometric wakelock");
295             }
296             mWakeLock.release();
297             mWakeLock = null;
298         }
299     }
300 
301     @Override
onBiometricAcquired(BiometricSourceType biometricSourceType)302     public void onBiometricAcquired(BiometricSourceType biometricSourceType) {
303         Trace.beginSection("BiometricUnlockController#onBiometricAcquired");
304         releaseBiometricWakeLock();
305         if (!mUpdateMonitor.isDeviceInteractive()) {
306             if (LatencyTracker.isEnabled(mContext)) {
307                 int action = LatencyTracker.ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
308                 if (biometricSourceType == BiometricSourceType.FACE) {
309                     action = LatencyTracker.ACTION_FACE_WAKE_AND_UNLOCK;
310                 }
311                 LatencyTracker.getInstance(mContext).onActionStart(action);
312             }
313             mWakeLock = mPowerManager.newWakeLock(
314                     PowerManager.PARTIAL_WAKE_LOCK, BIOMETRIC_WAKE_LOCK_NAME);
315             Trace.beginSection("acquiring wake-and-unlock");
316             mWakeLock.acquire();
317             Trace.endSection();
318             if (DEBUG_BIO_WAKELOCK) {
319                 Log.i(TAG, "biometric acquired, grabbing biometric wakelock");
320             }
321             mHandler.postDelayed(mReleaseBiometricWakeLockRunnable,
322                     BIOMETRIC_WAKELOCK_TIMEOUT_MS);
323         }
324         Trace.endSection();
325     }
326 
pulsingOrAod()327     private boolean pulsingOrAod() {
328         final ScrimState scrimState = mScrimController.getState();
329         return scrimState == ScrimState.AOD
330                 || scrimState == ScrimState.PULSING;
331     }
332 
333     @Override
onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType, boolean isStrongBiometric)334     public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
335             boolean isStrongBiometric) {
336         Trace.beginSection("BiometricUnlockController#onBiometricAuthenticated");
337         if (mUpdateMonitor.isGoingToSleep()) {
338             mPendingAuthenticated = new PendingAuthenticated(userId, biometricSourceType,
339                     isStrongBiometric);
340             Trace.endSection();
341             return;
342         }
343         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
344                 .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
345         Optional.ofNullable(BiometricUiEvent.SUCCESS_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
346                 .ifPresent(UI_EVENT_LOGGER::log);
347 
348         boolean unlockAllowed = mKeyguardBypassController.onBiometricAuthenticated(
349                 biometricSourceType, isStrongBiometric);
350         if (unlockAllowed) {
351             mKeyguardViewMediator.userActivity();
352             startWakeAndUnlock(biometricSourceType, isStrongBiometric);
353         } else {
354             Log.d(TAG, "onBiometricAuthenticated aborted by bypass controller");
355         }
356     }
357 
startWakeAndUnlock(BiometricSourceType biometricSourceType, boolean isStrongBiometric)358     public void startWakeAndUnlock(BiometricSourceType biometricSourceType,
359             boolean isStrongBiometric) {
360         startWakeAndUnlock(calculateMode(biometricSourceType, isStrongBiometric));
361     }
362 
startWakeAndUnlock(@akeAndUnlockMode int mode)363     public void startWakeAndUnlock(@WakeAndUnlockMode int mode) {
364         Log.v(TAG, "startWakeAndUnlock(" + mode + ")");
365         boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
366         mMode = mode;
367         mHasScreenTurnedOnSinceAuthenticating = false;
368         if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) {
369             // If we are waking the device up while we are pulsing the clock and the
370             // notifications would light up first, creating an unpleasant animation.
371             // Defer changing the screen brightness by forcing doze brightness on our window
372             // until the clock and the notifications are faded out.
373             mNotificationShadeWindowController.setForceDozeBrightness(true);
374         }
375         // During wake and unlock, we need to draw black before waking up to avoid abrupt
376         // brightness changes due to display state transitions.
377         boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
378         boolean delayWakeUp = mode == MODE_WAKE_AND_UNLOCK && alwaysOnEnabled && mWakeUpDelay > 0;
379         Runnable wakeUp = ()-> {
380             if (!wasDeviceInteractive) {
381                 if (DEBUG_BIO_WAKELOCK) {
382                     Log.i(TAG, "bio wakelock: Authenticated, waking up...");
383                 }
384                 mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
385                         "android.policy:BIOMETRIC");
386             }
387             if (delayWakeUp) {
388                 mKeyguardViewMediator.onWakeAndUnlocking();
389             }
390             Trace.beginSection("release wake-and-unlock");
391             releaseBiometricWakeLock();
392             Trace.endSection();
393         };
394 
395         if (!delayWakeUp && mMode != MODE_NONE) {
396             wakeUp.run();
397         }
398         switch (mMode) {
399             case MODE_DISMISS_BOUNCER:
400             case MODE_UNLOCK_FADING:
401                 Trace.beginSection("MODE_DISMISS_BOUNCER or MODE_UNLOCK_FADING");
402                 mKeyguardViewController.notifyKeyguardAuthenticated(
403                         false /* strongAuth */);
404                 Trace.endSection();
405                 break;
406             case MODE_UNLOCK_COLLAPSING:
407             case MODE_SHOW_BOUNCER:
408                 Trace.beginSection("MODE_UNLOCK_COLLAPSING or MODE_SHOW_BOUNCER");
409                 if (!wasDeviceInteractive) {
410                     mPendingShowBouncer = true;
411                 } else {
412                     showBouncer();
413                 }
414                 Trace.endSection();
415                 break;
416             case MODE_WAKE_AND_UNLOCK_FROM_DREAM:
417             case MODE_WAKE_AND_UNLOCK_PULSING:
418             case MODE_WAKE_AND_UNLOCK:
419                 if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
420                     Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
421                     mMediaManager.updateMediaMetaData(false /* metaDataChanged */,
422                             true /* allowEnterAnimation */);
423                 } else if (mMode == MODE_WAKE_AND_UNLOCK){
424                     Trace.beginSection("MODE_WAKE_AND_UNLOCK");
425                 } else {
426                     Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
427                     mUpdateMonitor.awakenFromDream();
428                 }
429                 mNotificationShadeWindowController.setNotificationShadeFocusable(false);
430                 if (delayWakeUp) {
431                     mHandler.postDelayed(wakeUp, mWakeUpDelay);
432                 } else {
433                     mKeyguardViewMediator.onWakeAndUnlocking();
434                 }
435                 if (mStatusBar.getNavigationBarView() != null) {
436                     mStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
437                 }
438                 Trace.endSection();
439                 break;
440             case MODE_ONLY_WAKE:
441             case MODE_NONE:
442                 break;
443         }
444         mStatusBar.notifyBiometricAuthModeChanged();
445         Trace.endSection();
446     }
447 
showBouncer()448     private void showBouncer() {
449         if (mMode == MODE_SHOW_BOUNCER) {
450             mKeyguardViewController.showBouncer(false);
451         }
452         mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */,
453                 false /* delayed */, BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR);
454         mPendingShowBouncer = false;
455     }
456 
457     @Override
onStartedGoingToSleep(int why)458     public void onStartedGoingToSleep(int why) {
459         resetMode();
460         mFadedAwayAfterWakeAndUnlock = false;
461         mPendingAuthenticated = null;
462     }
463 
464     @Override
onFinishedGoingToSleep(int why)465     public void onFinishedGoingToSleep(int why) {
466         Trace.beginSection("BiometricUnlockController#onFinishedGoingToSleep");
467         if (mPendingAuthenticated != null) {
468             PendingAuthenticated pendingAuthenticated = mPendingAuthenticated;
469             // Post this to make sure it's executed after the device is fully locked.
470             mHandler.post(() -> onBiometricAuthenticated(pendingAuthenticated.userId,
471                     pendingAuthenticated.biometricSourceType,
472                     pendingAuthenticated.isStrongBiometric));
473             mPendingAuthenticated = null;
474         }
475         Trace.endSection();
476     }
477 
hasPendingAuthentication()478     public boolean hasPendingAuthentication() {
479         return mPendingAuthenticated != null
480                 && mUpdateMonitor
481                     .isUnlockingWithBiometricAllowed(mPendingAuthenticated.isStrongBiometric)
482                 && mPendingAuthenticated.userId == KeyguardUpdateMonitor.getCurrentUser();
483     }
484 
getMode()485     public int getMode() {
486         return mMode;
487     }
488 
calculateMode(BiometricSourceType biometricSourceType, boolean isStrongBiometric)489     private @WakeAndUnlockMode int calculateMode(BiometricSourceType biometricSourceType,
490             boolean isStrongBiometric) {
491         if (biometricSourceType == BiometricSourceType.FACE
492                 || biometricSourceType == BiometricSourceType.IRIS) {
493             return calculateModeForPassiveAuth(isStrongBiometric);
494         } else {
495             return calculateModeForFingerprint(isStrongBiometric);
496         }
497     }
498 
calculateModeForFingerprint(boolean isStrongBiometric)499     private @WakeAndUnlockMode int calculateModeForFingerprint(boolean isStrongBiometric) {
500         boolean unlockingAllowed =
501                 mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
502         boolean deviceDreaming = mUpdateMonitor.isDreaming();
503 
504         if (!mUpdateMonitor.isDeviceInteractive()) {
505             if (!mKeyguardViewController.isShowing()) {
506                 return MODE_ONLY_WAKE;
507             } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
508                 return MODE_WAKE_AND_UNLOCK_PULSING;
509             } else if (unlockingAllowed || !mKeyguardStateController.isMethodSecure()) {
510                 return MODE_WAKE_AND_UNLOCK;
511             } else {
512                 return MODE_SHOW_BOUNCER;
513             }
514         }
515         if (unlockingAllowed && deviceDreaming) {
516             return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
517         }
518         if (mKeyguardViewController.isShowing()) {
519             if (mKeyguardViewController.bouncerIsOrWillBeShowing() && unlockingAllowed) {
520                 return MODE_DISMISS_BOUNCER;
521             } else if (unlockingAllowed) {
522                 return MODE_UNLOCK_COLLAPSING;
523             } else if (!mKeyguardViewController.isBouncerShowing()) {
524                 return MODE_SHOW_BOUNCER;
525             }
526         }
527         return MODE_NONE;
528     }
529 
calculateModeForPassiveAuth(boolean isStrongBiometric)530     private @WakeAndUnlockMode int calculateModeForPassiveAuth(boolean isStrongBiometric) {
531         boolean unlockingAllowed =
532                 mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
533         boolean deviceDreaming = mUpdateMonitor.isDreaming();
534         boolean bypass = mKeyguardBypassController.getBypassEnabled();
535 
536         if (!mUpdateMonitor.isDeviceInteractive()) {
537             if (!mKeyguardViewController.isShowing()) {
538                 return bypass ? MODE_WAKE_AND_UNLOCK : MODE_ONLY_WAKE;
539             } else if (!unlockingAllowed) {
540                 return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
541             } else if (mDozeScrimController.isPulsing()) {
542                 return bypass ? MODE_WAKE_AND_UNLOCK_PULSING : MODE_ONLY_WAKE;
543             } else {
544                 if (bypass) {
545                     // Wake-up fading out nicely
546                     return MODE_WAKE_AND_UNLOCK_PULSING;
547                 } else {
548                     // We could theoretically return MODE_NONE, but this means that the device
549                     // would be not interactive, unlocked, and the user would not see the device
550                     // state.
551                     return MODE_ONLY_WAKE;
552                 }
553             }
554         }
555         if (unlockingAllowed && deviceDreaming) {
556             return bypass ? MODE_WAKE_AND_UNLOCK_FROM_DREAM : MODE_ONLY_WAKE;
557         }
558         if (mKeyguardViewController.isShowing()) {
559             if (mKeyguardViewController.bouncerIsOrWillBeShowing() && unlockingAllowed) {
560                 if (bypass && mKeyguardBypassController.canPlaySubtleWindowAnimations()) {
561                     return MODE_UNLOCK_FADING;
562                 } else {
563                     return MODE_DISMISS_BOUNCER;
564                 }
565             } else if (unlockingAllowed) {
566                 return bypass ? MODE_UNLOCK_FADING : MODE_NONE;
567             } else {
568                 return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
569             }
570         }
571         return MODE_NONE;
572     }
573 
574     @Override
onBiometricAuthFailed(BiometricSourceType biometricSourceType)575     public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
576         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
577                 .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType)));
578         Optional.ofNullable(BiometricUiEvent.FAILURE_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
579                 .ifPresent(UI_EVENT_LOGGER::log);
580         cleanup();
581     }
582 
583     @Override
onBiometricError(int msgId, String errString, BiometricSourceType biometricSourceType)584     public void onBiometricError(int msgId, String errString,
585             BiometricSourceType biometricSourceType) {
586         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
587                 .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType))
588                 .addTaggedData(MetricsEvent.FIELD_BIOMETRIC_AUTH_ERROR, msgId));
589         Optional.ofNullable(BiometricUiEvent.ERROR_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
590                 .ifPresent(UI_EVENT_LOGGER::log);
591         cleanup();
592     }
593 
cleanup()594     private void cleanup() {
595         releaseBiometricWakeLock();
596     }
597 
startKeyguardFadingAway()598     public void startKeyguardFadingAway() {
599 
600         // Disable brightness override when the ambient contents are fully invisible.
601         mHandler.postDelayed(new Runnable() {
602             @Override
603             public void run() {
604                 mNotificationShadeWindowController.setForceDozeBrightness(false);
605             }
606         }, StatusBar.FADE_KEYGUARD_DURATION_PULSING);
607     }
608 
finishKeyguardFadingAway()609     public void finishKeyguardFadingAway() {
610         if (isWakeAndUnlock()) {
611             mFadedAwayAfterWakeAndUnlock = true;
612         }
613         resetMode();
614     }
615 
resetMode()616     private void resetMode() {
617         mMode = MODE_NONE;
618         mNotificationShadeWindowController.setForceDozeBrightness(false);
619         if (mStatusBar.getNavigationBarView() != null) {
620             mStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
621         }
622         mStatusBar.notifyBiometricAuthModeChanged();
623     }
624 
625     @VisibleForTesting
626     final WakefulnessLifecycle.Observer mWakefulnessObserver =
627             new WakefulnessLifecycle.Observer() {
628         @Override
629         public void onFinishedWakingUp() {
630             if (mPendingShowBouncer) {
631                 BiometricUnlockController.this.showBouncer();
632             }
633         }
634     };
635 
636     private final ScreenLifecycle.Observer mScreenObserver =
637             new ScreenLifecycle.Observer() {
638                 @Override
639                 public void onScreenTurnedOn() {
640                     mHasScreenTurnedOnSinceAuthenticating = true;
641                 }
642             };
643 
hasScreenTurnedOnSinceAuthenticating()644     public boolean hasScreenTurnedOnSinceAuthenticating() {
645         return mHasScreenTurnedOnSinceAuthenticating;
646     }
647 
648     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)649     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
650         pw.println(" BiometricUnlockController:");
651         pw.print("   mMode="); pw.println(mMode);
652         pw.print("   mWakeLock="); pw.println(mWakeLock);
653     }
654 
655     /**
656      * Successful authentication with fingerprint, face, or iris that wakes up the device.
657      */
isWakeAndUnlock()658     public boolean isWakeAndUnlock() {
659         return mMode == MODE_WAKE_AND_UNLOCK
660                 || mMode == MODE_WAKE_AND_UNLOCK_PULSING
661                 || mMode == MODE_WAKE_AND_UNLOCK_FROM_DREAM;
662     }
663 
664     /**
665      * Successful authentication with fingerprint, face, or iris that wakes up the device.
666      * This will return {@code true} even after the keyguard fades away.
667      */
unlockedByWakeAndUnlock()668     public boolean unlockedByWakeAndUnlock() {
669         return  isWakeAndUnlock() || mFadedAwayAfterWakeAndUnlock;
670     }
671 
672     /**
673      * Successful authentication with fingerprint, face, or iris when the screen was either
674      * on or off.
675      */
isBiometricUnlock()676     public boolean isBiometricUnlock() {
677         return isWakeAndUnlock() || mMode == MODE_UNLOCK_COLLAPSING || mMode == MODE_UNLOCK_FADING;
678     }
679 
680     /**
681      * Successful authentication with fingerprint, face, or iris when the lockscreen fades away
682      */
isUnlockFading()683     public boolean isUnlockFading() {
684         return mMode == MODE_UNLOCK_FADING;
685     }
686 
687     /**
688      * Translates biometric source type for logging purpose.
689      */
toSubtype(BiometricSourceType biometricSourceType)690     private int toSubtype(BiometricSourceType biometricSourceType) {
691         switch (biometricSourceType) {
692             case FINGERPRINT:
693                 return 0;
694             case FACE:
695                 return 1;
696             case IRIS:
697                 return 2;
698             default:
699                 return 3;
700         }
701     }
702 }
703