Add logic for when to start the Udfps fp service

In general, the udfps overlay is shown whenever the fingerprint service
is running and there's a udfps fingerprint enrolled. However, unlike the
regular fingerprint, we don't want to start udfps fp service when:
- the bouncer is showing (ie: input pin/password/pattern)
- keyguard is showing the notification shade while locked
- on reboot, strong auth is required and udfps cannot be used to
authenticate

Test: manually checked:
 - udfps enrolled => pull down notification shade on LS => udfps overlay
 hidden
 - udfps enrolled => swipe up for bouncher => udfps overlay hidden
 - go to settings to enroll a new udfps fp => see overlay
Test: atest KeyguardUpdateMonitorTest AuthControllerTest KeyguardBouncerTest
Test: atest SystemUITests
Bug: 172050991
Change-Id: Id7e1b533d5b087dca24ac29a3323f2419d050da4
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 31b0701..42680e6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -238,6 +238,16 @@
     private final boolean mIsAutomotive;
     private final AuthController mAuthController;
     private final StatusBarStateController mStatusBarStateController;
+    private int mStatusBarState;
+    private final StatusBarStateController.StateListener mStatusBarStateControllerListener =
+            new StatusBarStateController.StateListener() {
+        @Override
+        public void onStateChanged(int newState) {
+            mStatusBarState = newState;
+            updateBiometricListeningState();
+        }
+    };
+
     HashMap<Integer, SimData> mSimDatas = new HashMap<>();
     HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
 
@@ -247,7 +257,7 @@
     private boolean mCredentialAttempted;
     private boolean mKeyguardGoingAway;
     private boolean mGoingToSleep;
-    private boolean mBouncer;
+    private boolean mBouncer; // true if bouncerIsOrWillBeShowing
     private boolean mAuthInterruptActive;
     private boolean mNeedsSlowUnlockTransition;
     private boolean mHasLockscreenWallpaper;
@@ -1595,6 +1605,8 @@
         mBroadcastDispatcher = broadcastDispatcher;
         mRingerModeTracker = ringerModeTracker;
         mStatusBarStateController = statusBarStateController;
+        mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
+        mStatusBarState = mStatusBarStateController.getState();
         mLockPatternUtils = lockPatternUtils;
         mAuthController = authController;
         dumpManager.registerDumpable(getClass().getName(), this);
@@ -1905,7 +1917,8 @@
             return;
         }
 
-        boolean shouldListenForFingerprint = shouldListenForFingerprint();
+        boolean shouldListenForFingerprint =
+                isUdfpsEnrolled() ? shouldListenForUdfps() : shouldListenForFingerprint();
         boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
                 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
         if (runningOrRestarting && !shouldListenForFingerprint) {
@@ -2002,12 +2015,20 @@
         return shouldListen;
     }
 
+    @VisibleForTesting
+    boolean shouldListenForUdfps() {
+        return shouldListenForFingerprint()
+                && !mBouncer
+                && mStatusBarState != StatusBarState.SHADE_LOCKED
+                && mStatusBarState != StatusBarState.FULLSCREEN_USER_SWITCHER
+                && mStrongAuthTracker.hasUserAuthenticatedSinceBoot();
+    }
+
     /**
      * If face auth is allows to scan on this exact moment.
      */
     public boolean shouldListenForFace() {
-        final boolean statusBarShadeLocked =
-                mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED;
+        final boolean statusBarShadeLocked = mStatusBarState == StatusBarState.SHADE_LOCKED;
         final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep
                 && !statusBarShadeLocked;
         final int user = getCurrentUser();
@@ -2593,13 +2614,12 @@
      *
      * @see #sendKeyguardBouncerChanged(boolean)
      */
-    private void handleKeyguardBouncerChanged(int bouncer) {
+    private void handleKeyguardBouncerChanged(int bouncerVisible) {
         Assert.isMainThread();
-        if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
-        boolean isBouncer = (bouncer == 1);
-        mBouncer = isBouncer;
+        if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncerVisible + ")");
+        mBouncer = bouncerVisible == 1;
 
-        if (isBouncer) {
+        if (mBouncer) {
             // If the bouncer is shown, always clear this flag. This can happen in the following
             // situations: 1) Default camera with SHOW_WHEN_LOCKED is not chosen yet. 2) Secure
             // camera requests dismiss keyguard (tapping on photos for example). When these happen,
@@ -2612,7 +2632,7 @@
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
-                cb.onKeyguardBouncerChanged(isBouncer);
+                cb.onKeyguardBouncerChanged(mBouncer);
             }
         }
         updateBiometricListeningState();
@@ -2745,10 +2765,10 @@
     /**
      * @see #handleKeyguardBouncerChanged(int)
      */
-    public void sendKeyguardBouncerChanged(boolean showingBouncer) {
-        if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
+    public void sendKeyguardBouncerChanged(boolean bouncerIsOrWillBeShowing) {
+        if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + bouncerIsOrWillBeShowing + ")");
         Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
-        message.arg1 = showingBouncer ? 1 : 0;
+        message.arg1 = bouncerIsOrWillBeShowing ? 1 : 0;
         message.sendToTarget();
     }
 
@@ -3081,6 +3101,12 @@
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
             pw.println("    udfpsEnrolled=" + isUdfpsEnrolled());
+            if (isUdfpsEnrolled()) {
+                pw.println("        shouldListenForUdfps=" + shouldListenForUdfps());
+                pw.println("        bouncerVisible=" + mBouncer);
+                pw.println("        mStatusBarState="
+                        + StatusBarState.toShortString(mStatusBarState));
+            }
         }
         if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
             final int userId = ActivityManager.getCurrentUser();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 3c5eceb..b722dea 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -94,7 +94,8 @@
 
     /**
      * Called when the keyguard enters or leaves bouncer mode.
-     * @param bouncer if true, keyguard is now in bouncer mode.
+     * @param bouncer if true, keyguard is showing the bouncer or transitioning from/to bouncer
+     *                mode.
      */
     public void onKeyguardBouncerChanged(boolean bouncer) { }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index a6b1b90..3f66c08 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -54,7 +54,6 @@
 import com.android.systemui.doze.DozeReceiver;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -68,7 +67,7 @@
  */
 @SysUISingleton
 public class AuthController extends SystemUI implements CommandQueue.Callbacks,
-        AuthDialogCallback, DozeReceiver, KeyguardBouncer.BouncerExpansionCallback {
+        AuthDialogCallback, DozeReceiver {
 
     private static final String TAG = "AuthController";
     private static final boolean DEBUG = true;
@@ -460,35 +459,6 @@
         mCurrentDialog = null;
     }
 
-    /** See {@link KeyguardBouncer.BouncerExpansionCallback#onFullyShown}. */
-    @Override
-    public void onFullyShown() {
-        if (mUdfpsController != null) {
-            mUdfpsController.setBouncerVisibility(true);
-        }
-    }
-
-    /** See {@link KeyguardBouncer.BouncerExpansionCallback#onStartingToHide}. */
-    @Override
-    public void onStartingToHide() {
-    }
-
-    /** See {@link KeyguardBouncer.BouncerExpansionCallback#onStartingToShow}. */
-    @Override
-    public void onStartingToShow() {
-        if (mUdfpsController != null) {
-            mUdfpsController.setBouncerVisibility(true);
-        }
-    }
-
-    /** See {@link KeyguardBouncer.BouncerExpansionCallback#onFullyHidden}. */
-    @Override
-    public void onFullyHidden() {
-        if (mUdfpsController != null) {
-            mUdfpsController.setBouncerVisibility(false);
-        }
-    }
-
    /**
      * Whether the passed userId has enrolled UDFPS.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index a4b407d..e437740 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -107,8 +107,6 @@
     private boolean mIsOverlayShowing;
     // Indicates whether the overlay has been requested.
     private boolean mIsOverlayRequested;
-    // Indicates whether the bouncer is showing. When it is showing, the overlay needs to be hidden.
-    private boolean mIsBouncerShowing;
 
     // The fingerprint AOD trigger doesn't provide an ACTION_UP/ACTION_CANCEL event to tell us when
     // to turn off high brightness mode. To get around this limitation, the state of the AOD
@@ -260,21 +258,8 @@
         updateOverlay();
     }
 
-    /**
-     * Call when the visibility of the bouncer changes.
-     *
-     * @param isShowing Whether or not the bouncer is showing
-     */
-    void setBouncerVisibility(boolean isShowing) {
-        if (isShowing == mIsBouncerShowing) {
-            return;
-        }
-        mIsBouncerShowing = isShowing;
-        updateOverlay();
-    }
-
     private void updateOverlay() {
-        if (mIsOverlayRequested && !mIsBouncerShowing) {
+        if (mIsOverlayRequested) {
             showUdfpsOverlay();
         } else {
             hideUdfpsOverlay();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 2767b7e..80cb289 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -39,7 +39,6 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.FalsingManager;
@@ -70,7 +69,6 @@
     private final DismissCallbackRegistry mDismissCallbackRegistry;
     private final Handler mHandler;
     private final List<BouncerExpansionCallback> mExpansionCallbacks = new ArrayList<>();
-    private final AuthController mAuthController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final KeyguardStateController mKeyguardStateController;
     private final KeyguardSecurityModel mKeyguardSecurityModel;
@@ -104,7 +102,6 @@
             ViewGroup container,
             DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager,
             BouncerExpansionCallback expansionCallback,
-            AuthController authController,
             KeyguardStateController keyguardStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             KeyguardBypassController keyguardBypassController, Handler handler,
@@ -123,8 +120,6 @@
         mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
         mKeyguardBypassController = keyguardBypassController;
         mExpansionCallbacks.add(expansionCallback);
-        mExpansionCallbacks.add(authController);
-        mAuthController = authController;
     }
 
     public void show(boolean resetSecuritySelection) {
@@ -297,11 +292,6 @@
         mIsScrimmed = false;
         mFalsingManager.onBouncerHidden();
         mCallback.onBouncerVisiblityChanged(false /* shown */);
-        // TODO(b/165257355): `mAuthController.onFullyHidden` should be `dispatchFullyHidden()`
-        // But, it is causing the UDFPS icon to disappear after SystemUI restarts. I guess the
-        // ExpansionCallback from StatusBarKeyguardViewManager can't handle the call to
-        // onFullyHidden after a restart.
-        mAuthController.onFullyHidden();
         cancelShowRunnable();
         if (mKeyguardViewController != null) {
             mKeyguardViewController.cancelDismissAction();
@@ -552,7 +542,6 @@
         private final ViewMediatorCallback mCallback;
         private final DismissCallbackRegistry mDismissCallbackRegistry;
         private final FalsingManager mFalsingManager;
-        private final AuthController mAuthController;
         private final KeyguardStateController mKeyguardStateController;
         private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
         private final KeyguardBypassController mKeyguardBypassController;
@@ -563,7 +552,6 @@
         @Inject
         public Factory(Context context, ViewMediatorCallback callback,
                 DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager,
-                AuthController authController,
                 KeyguardStateController keyguardStateController,
                 KeyguardUpdateMonitor keyguardUpdateMonitor,
                 KeyguardBypassController keyguardBypassController, Handler handler,
@@ -573,7 +561,6 @@
             mCallback = callback;
             mDismissCallbackRegistry = dismissCallbackRegistry;
             mFalsingManager = falsingManager;
-            mAuthController = authController;
             mKeyguardStateController = keyguardStateController;
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
             mKeyguardBypassController = keyguardBypassController;
@@ -586,7 +573,7 @@
                 BouncerExpansionCallback expansionCallback) {
             return new KeyguardBouncer(mContext, mCallback, container,
                     mDismissCallbackRegistry, mFalsingManager, expansionCallback,
-                    mAuthController, mKeyguardStateController, mKeyguardUpdateMonitor,
+                    mKeyguardStateController, mKeyguardUpdateMonitor,
                     mKeyguardBypassController, mHandler, mKeyguardSecurityModel,
                     mKeyguardBouncerComponentFactory);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 9e2e57e..f9dfd7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -117,6 +117,7 @@
 
         @Override
         public void onStartingToShow() {
+            updateStates();
             updateLockIcon();
         }
 
@@ -164,6 +165,7 @@
     protected boolean mLastShowing;
     protected boolean mLastOccluded;
     private boolean mLastBouncerShowing;
+    private boolean mLastBouncerIsOrWillBeShowing;
     private boolean mLastBouncerDismissible;
     protected boolean mLastRemoteInputActive;
     private boolean mLastDozing;
@@ -811,6 +813,7 @@
         boolean showing = mShowing;
         boolean occluded = mOccluded;
         boolean bouncerShowing = mBouncer.isShowing();
+        boolean bouncerIsOrWillBeShowing = bouncerIsOrWillBeShowing();
         boolean bouncerDismissible = !mBouncer.isFullscreenBouncer();
         boolean remoteInputActive = mRemoteInputActive;
 
@@ -839,8 +842,8 @@
         if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
             mKeyguardUpdateManager.onKeyguardVisibilityChanged(showing && !occluded);
         }
-        if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
-            mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerShowing);
+        if (bouncerIsOrWillBeShowing != mLastBouncerIsOrWillBeShowing || mFirstUpdate) {
+            mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerIsOrWillBeShowing);
         }
 
         mFirstUpdate = false;
@@ -848,6 +851,7 @@
         mLastGlobalActionsVisible = mGlobalActionsVisible;
         mLastOccluded = occluded;
         mLastBouncerShowing = bouncerShowing;
+        mLastBouncerIsOrWillBeShowing = bouncerIsOrWillBeShowing;
         mLastBouncerDismissible = bouncerDismissible;
         mLastRemoteInputActive = remoteInputActive;
         mLastDozing = mDozing;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index d78090a..51cbff8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -93,6 +93,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -102,7 +103,6 @@
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -159,12 +159,15 @@
     private StatusBarStateController mStatusBarStateController;
     @Mock
     private AuthController mAuthController;
+    @Captor
+    private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
     // Direct executor
     private Executor mBackgroundExecutor = Runnable::run;
     private TestableLooper mTestableLooper;
     private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private TestableContext mSpiedContext;
     private MockitoSession mMockitoSession;
+    private StatusBarStateController.StateListener mStatusBarStateListener;
 
     @Before
     public void setup() {
@@ -221,6 +224,9 @@
         mTestableLooper = TestableLooper.get(this);
         allowTestableLooperAsMainThread();
         mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mSpiedContext);
+
+        verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
+        mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
     }
 
     @After
@@ -475,8 +481,7 @@
 
     @Test
     public void testTriesToAuthenticate_whenBouncer() {
-        mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
-        mTestableLooper.processAllMessages();
+        setKeyguardBouncerVisibility(true);
 
         verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
         verify(mFaceManager).isHardwareDetected();
@@ -493,10 +498,10 @@
 
     @Test
     public void skipsAuthentication_whenStatusBarShadeLocked() {
-        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
-
+        mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
         mKeyguardUpdateMonitor.dispatchStartedWakingUp();
         mTestableLooper.processAllMessages();
+
         mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
         verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
     }
@@ -536,8 +541,7 @@
         verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
 
         // Stop scanning when bouncer becomes visible
-        mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true /* showingBouncer */);
-        mTestableLooper.processAllMessages();
+        setKeyguardBouncerVisibility(true);
         clearInvocations(mFaceManager);
         mKeyguardUpdateMonitor.requestFaceAuth();
         verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
@@ -768,6 +772,85 @@
         orderVerify.verify(callback).onRingerModeChanged(AudioManager.RINGER_MODE_VIBRATE);
     }
 
+    @Test
+    public void testStartUdfpsServiceBeginsOnKeyguard() {
+        // GIVEN
+        // - bouncer isn't showing
+        // - status bar state is on the keyguard
+        // - user has authenticated since boot
+        setKeyguardBouncerVisibility(false /* isVisible */);
+        mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
+        when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+
+        // THEN we should listen for udfps
+        assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(true);
+    }
+
+    @Test
+    public void testStartUdfpsServiceOnShadeLocked() {
+        // GIVEN
+        // - bouncer isn't showing
+        // - user has authenticated since boot
+        setKeyguardBouncerVisibility(false /* isVisible */);
+        when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+
+        // WHEN the status bar state changes to SHADE_LOCKED
+        mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
+
+        // THEN we shouldn't listen for udfps
+        assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
+    }
+
+    @Test
+    public void testStartUdfpsServiceOnFullscreenUserSwitcher() {
+        // GIVEN
+        // - bouncer isn't showing
+        // - user has authenticated since boot
+        setKeyguardBouncerVisibility(false /* isVisible */);
+        when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+
+        // WHEN the status bar state changes to FULLSCREEN_USER_SWITCHER
+        mStatusBarStateListener.onStateChanged(StatusBarState.FULLSCREEN_USER_SWITCHER);
+
+        // THEN we shouldn't listen for udfps
+        assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
+    }
+
+    @Test
+    public void testStartUdfpsServiceNoAuthenticationSinceLastBoot() {
+        // GIVEN
+        // - bouncer isn't showing
+        // - status bar state is on the keyguard
+        setKeyguardBouncerVisibility(false /* isVisible */);
+        mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
+
+        // WHEN user hasn't authenticated since last boot
+        when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(false);
+
+        // THEN we shouldn't listen for udfps
+        assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
+    }
+
+    @Test
+    public void testStartUdfpsServiceOnBouncerNotVisible() {
+        // GIVEN
+        // - status bar state is on the keyguard
+        // - user has authenticated since boot
+        mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
+        when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+
+        // WHEN the bouncer is showing
+        setKeyguardBouncerVisibility(true /* isVisible */);
+
+        // THEN we shouldn't listen for udfps
+        assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
+    }
+
+    private void setKeyguardBouncerVisibility(boolean isVisible) {
+        mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(isVisible);
+        mTestableLooper.processAllMessages();
+    }
+
     private void setBroadcastReceiverPendingResult(BroadcastReceiver receiver) {
         BroadcastReceiver.PendingResult pendingResult =
                 new BroadcastReceiver.PendingResult(Activity.RESULT_OK,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 42bb005..ec0aa4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -22,7 +22,6 @@
 import static junit.framework.Assert.assertNull;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -513,30 +512,6 @@
         verify(mUdfpsController).onCancelAodInterrupt();
     }
 
-    @Test
-    public void testOnFullyShown_DelegatesToUdfpsController() {
-        mAuthController.onFullyShown();
-        verify(mUdfpsController).setBouncerVisibility(eq(true));
-    }
-
-    @Test
-    public void testOnFullyHidden_DelegatesToUdfpsController() {
-        mAuthController.onFullyHidden();
-        verify(mUdfpsController).setBouncerVisibility(eq(false));
-    }
-
-    @Test
-    public void testOnStartingToShow_NeverDelegatesToUdfpsController() {
-        mAuthController.onStartingToShow();
-        verify(mUdfpsController).setBouncerVisibility(eq(true));
-    }
-
-    @Test
-    public void testOnStartingToHide_NeverDelegatesToUdfpsController() {
-        mAuthController.onStartingToHide();
-        verify(mUdfpsController, never()).setBouncerVisibility(anyBoolean());
-    }
-
     // Helpers
 
     private void showDialog(int[] sensorIds, boolean credentialAllowed) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 82ffd46..648c319 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -90,6 +89,7 @@
     private WindowManager mWindowManager;
     @Mock
     private StatusBarStateController mStatusBarStateController;
+
     private FakeSettings mSystemSettings;
     private FakeExecutor mFgExecutor;
 
@@ -173,41 +173,6 @@
     }
 
     @Test
-    public void showUdfpsOverlay_bouncerShowing() throws RemoteException {
-        // GIVEN that the bouncer is showing
-        mUdfpsController.setBouncerVisibility(/* isShowing */ true);
-        // WHEN a request to show the overlay is received
-        mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
-        mFgExecutor.runAllReady();
-        // THEN the overlay is not attached
-        verify(mWindowManager, never()).addView(eq(mUdfpsView), any());
-    }
-
-    @Test
-    public void setBouncerVisibility_overlayDetached() throws RemoteException {
-        // GIVEN that the overlay has been requested
-        mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
-        // WHEN the bouncer becomes visible
-        mUdfpsController.setBouncerVisibility(/* isShowing */ true);
-        mFgExecutor.runAllReady();
-        // THEN the overlay is detached
-        verify(mWindowManager).removeView(eq(mUdfpsView));
-    }
-
-    @Test
-    public void setBouncerVisibility_overlayAttached() throws RemoteException {
-        // GIVEN that the bouncer is visible
-        mUdfpsController.setBouncerVisibility(/* isShowing */ true);
-        // AND the overlay has been requested
-        mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
-        // WHEN the bouncer is closed
-        mUdfpsController.setBouncerVisibility(/* isShowing */ false);
-        mFgExecutor.runAllReady();
-        // THEN the overlay is attached
-        verify(mWindowManager).addView(eq(mUdfpsView), any());
-    }
-
-    @Test
     public void fingerDown() throws RemoteException {
         // Configure UdfpsView to accept the ACTION_DOWN event
         when(mUdfpsView.isScrimShowing()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 4fb45ec..1b05ad7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -50,7 +50,6 @@
 import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.FalsingManager;
@@ -79,8 +78,6 @@
     @Mock
     private DismissCallbackRegistry mDismissCallbackRegistry;
     @Mock
-    private AuthController mAuthController;
-    @Mock
     private KeyguardHostViewController mKeyguardHostViewController;
     @Mock
     private KeyguardBouncer.BouncerExpansionCallback mExpansionCallback;
@@ -131,7 +128,7 @@
 
         final ViewGroup container = new FrameLayout(getContext());
         mBouncer = new KeyguardBouncer.Factory(getContext(), mViewMediatorCallback,
-                mDismissCallbackRegistry, mFalsingManager, mAuthController,
+                mDismissCallbackRegistry, mFalsingManager,
                 mKeyguardStateController, mKeyguardUpdateMonitor,
                 mKeyguardBypassController, mHandler, mKeyguardSecurityModel,
                 mKeyguardBouncerComponentFactory)
@@ -210,12 +207,6 @@
     }
 
     @Test
-    public void testShow_notifiesAuthControllerStartingToShow() {
-        mBouncer.show(/* resetSecuritySelection */ false);
-        verify(mAuthController).onStartingToShow();
-    }
-
-    @Test
     public void testSetExpansion_notifiesFalsingManager() {
         mBouncer.ensureView();
         mBouncer.setExpansion(0.5f);
@@ -246,38 +237,6 @@
     }
 
     @Test
-    public void testSetExpansion_notifiesAuthControllerFullyShown() {
-        mBouncer.ensureView();
-        mBouncer.setExpansion(0.1f);
-        mBouncer.setExpansion(0f);
-        verify(mAuthController).onFullyShown();
-    }
-
-    @Test
-    public void testSetExpansion_notifiesAuthControllerStartingToHide() {
-        mBouncer.ensureView();
-        mBouncer.setExpansion(0f);
-        mBouncer.setExpansion(0.1f);
-        verify(mAuthController).onStartingToHide();
-    }
-
-    @Test
-    public void testSetExpansion_notifiesAuthControllerFullyHidden() {
-        mBouncer.ensureView();
-        mBouncer.setExpansion(0.9f);
-        mBouncer.setExpansion(1f);
-        verify(mAuthController).onFullyHidden();
-    }
-
-    @Test
-    public void testSetExpansion_negativeAuthControllerStartingToShow() {
-        mBouncer.ensureView();
-        mBouncer.setExpansion(1f);
-        mBouncer.setExpansion(0.9f);
-        verify(mAuthController, never()).onStartingToShow();
-    }
-
-    @Test
     public void testHide_notifiesFalsingManager() {
         mBouncer.hide(false);
         verify(mFalsingManager).onBouncerHidden();