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