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