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