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