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