[flexiglass] Hookup new source of truth for bouncer states in KeyguardUpdateMonitor

In legacy code, keyguardUpdateMonitor relies on bouncer states to be
passed to it via StatusBarKeyguardViewManager. Rather than relying
on SBKVM, rely on the SceneInteractor for primary bouncer states
and rely on the AlternateBouncerInteractor for the alternate
bouncer visibility state.

Test: atest KeyguardUpdateMonitorTest StatusBarKeyguardViewManagerTest
Bug: 353955910
Bug: 357649556
Flag: com.android.systemui.scene_container
Change-Id: I83a492a16ff5661110ba1af16ce9dcd2bd2ea082
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 0da252d..60fff28 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -104,6 +104,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.compose.animation.scene.ObservableTransitionState;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.foldables.FoldGracePeriodProvider;
 import com.android.internal.jank.InteractionJankMonitor;
@@ -119,6 +120,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -140,6 +142,9 @@
 import com.android.systemui.plugins.clocks.WeatherData;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -150,6 +155,7 @@
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
 import com.android.systemui.util.Assert;
+import com.android.systemui.util.kotlin.JavaAdapter;
 
 import dalvik.annotation.optimization.NeverCompile;
 
@@ -279,6 +285,9 @@
     private final UserTracker mUserTracker;
     private final KeyguardUpdateMonitorLogger mLogger;
     private final boolean mIsSystemUser;
+    private final Provider<JavaAdapter> mJavaAdapter;
+    private final Provider<SceneInteractor> mSceneInteractor;
+    private final Provider<AlternateBouncerInteractor> mAlternateBouncerInteractor;
     private final AuthController mAuthController;
     private final UiEventLogger mUiEventLogger;
     private final Set<String> mAllowFingerprintOnOccludingActivitiesFromPackage;
@@ -563,7 +572,7 @@
      */
     private boolean shouldDismissKeyguardOnTrustGrantedWithCurrentUser(TrustGrantFlags flags) {
         final boolean isBouncerShowing =
-                mPrimaryBouncerIsOrWillBeShowing || mAlternateBouncerShowing;
+                isPrimaryBouncerShowingOrWillBeShowing() || isAlternateBouncerShowing();
         return (flags.isInitiatedByUser() || flags.dismissKeyguardRequested())
                 && (mDeviceInteractive || flags.temporaryAndRenewable())
                 && (isBouncerShowing || flags.dismissKeyguardRequested());
@@ -1170,8 +1179,8 @@
         Assert.isMainThread();
         String reason =
                 mKeyguardBypassController.canBypass() ? "bypass"
-                        : mAlternateBouncerShowing ? "alternateBouncer"
-                                : mPrimaryBouncerFullyShown ? "bouncer"
+                        : isAlternateBouncerShowing() ? "alternateBouncer"
+                                : isPrimaryBouncerFullyShown() ? "bouncer"
                                         : "udfpsFpDown";
         requestActiveUnlock(
                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL,
@@ -2169,7 +2178,10 @@
             Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider,
             TaskStackChangeListeners taskStackChangeListeners,
             SelectedUserInteractor selectedUserInteractor,
-            IActivityTaskManager activityTaskManagerService) {
+            IActivityTaskManager activityTaskManagerService,
+            Provider<AlternateBouncerInteractor> alternateBouncerInteractor,
+            Provider<JavaAdapter> javaAdapter,
+            Provider<SceneInteractor> sceneInteractor) {
         mContext = context;
         mSubscriptionManager = subscriptionManager;
         mUserTracker = userTracker;
@@ -2214,6 +2226,9 @@
 
         mFingerprintInteractiveToAuthProvider = interactiveToAuthProvider.orElse(null);
         mIsSystemUser = mUserManager.isSystemUser();
+        mAlternateBouncerInteractor = alternateBouncerInteractor;
+        mJavaAdapter = javaAdapter;
+        mSceneInteractor = sceneInteractor;
 
         mHandler = new Handler(mainLooper) {
             @Override
@@ -2470,6 +2485,30 @@
         mContext.getContentResolver().registerContentObserver(
                 Settings.System.getUriFor(Settings.System.TIME_12_24),
                 false, mTimeFormatChangeObserver, UserHandle.USER_ALL);
+
+        if (SceneContainerFlag.isEnabled()) {
+            mJavaAdapter.get().alwaysCollectFlow(
+                    mAlternateBouncerInteractor.get().isVisible(),
+                    this::onAlternateBouncerVisibilityChange);
+            mJavaAdapter.get().alwaysCollectFlow(
+                    mSceneInteractor.get().getTransitionState(),
+                    this::onTransitionStateChanged
+            );
+        }
+    }
+
+    @VisibleForTesting
+    void onAlternateBouncerVisibilityChange(boolean isAlternateBouncerVisible) {
+        setAlternateBouncerShowing(isAlternateBouncerVisible);
+    }
+
+
+    @VisibleForTesting
+    void onTransitionStateChanged(ObservableTransitionState transitionState) {
+        int primaryBouncerFullyShown = isPrimaryBouncerFullyShown(transitionState) ? 1 : 0;
+        int primaryBouncerIsOrWillBeShowing =
+                  isPrimaryBouncerShowingOrWillBeShowing(transitionState) ? 1 : 0;
+        handlePrimaryBouncerChanged(primaryBouncerIsOrWillBeShowing, primaryBouncerFullyShown);
     }
 
     private void initializeSimState() {
@@ -2717,8 +2756,8 @@
         requestActiveUnlock(
                 requestOrigin,
                 extraReason, canFaceBypass
-                        || mAlternateBouncerShowing
-                        || mPrimaryBouncerFullyShown
+                        || isAlternateBouncerShowing()
+                        || isPrimaryBouncerFullyShown()
                         || mAuthController.isUdfpsFingerDown());
     }
 
@@ -2739,7 +2778,7 @@
      */
     public void setAlternateBouncerShowing(boolean showing) {
         mAlternateBouncerShowing = showing;
-        if (mAlternateBouncerShowing) {
+        if (isAlternateBouncerShowing()) {
             requestActiveUnlock(
                     ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
                     "alternateBouncer");
@@ -2747,6 +2786,45 @@
         updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
     }
 
+    private boolean isAlternateBouncerShowing() {
+        if (SceneContainerFlag.isEnabled()) {
+            return mAlternateBouncerInteractor.get().isVisibleState();
+        } else {
+            return mAlternateBouncerShowing;
+        }
+    }
+
+    private boolean isPrimaryBouncerShowingOrWillBeShowing() {
+        if (SceneContainerFlag.isEnabled()) {
+            return isPrimaryBouncerShowingOrWillBeShowing(
+                    mSceneInteractor.get().getTransitionState().getValue());
+        } else {
+            return mPrimaryBouncerIsOrWillBeShowing;
+        }
+    }
+
+    private boolean isPrimaryBouncerFullyShown() {
+        if (SceneContainerFlag.isEnabled()) {
+            return isPrimaryBouncerFullyShown(
+                    mSceneInteractor.get().getTransitionState().getValue());
+        } else {
+            return mPrimaryBouncerFullyShown;
+        }
+    }
+
+    private boolean isPrimaryBouncerShowingOrWillBeShowing(
+            ObservableTransitionState transitionState
+    ) {
+        SceneContainerFlag.assertInNewMode();
+        return isPrimaryBouncerFullyShown(transitionState)
+                || transitionState.isTransitioning(null, Scenes.Bouncer);
+    }
+
+    private boolean isPrimaryBouncerFullyShown(ObservableTransitionState transitionState) {
+        SceneContainerFlag.assertInNewMode();
+        return transitionState.isIdle(Scenes.Bouncer);
+    }
+
     /**
      * If the current state of the device allows for triggering active unlock. This does not
      * include active unlock availability.
@@ -2762,7 +2840,7 @@
     private boolean shouldTriggerActiveUnlock(boolean shouldLog) {
         // Triggers:
         final boolean triggerActiveUnlockForAssistant = shouldTriggerActiveUnlockForAssistant();
-        final boolean awakeKeyguard = mPrimaryBouncerFullyShown || mAlternateBouncerShowing
+        final boolean awakeKeyguard = isPrimaryBouncerFullyShown() || isAlternateBouncerShowing()
                 || (isKeyguardVisible() && !mGoingToSleep
                 && mStatusBarState != StatusBarState.SHADE_LOCKED);
 
@@ -2830,14 +2908,14 @@
         final boolean shouldListenKeyguardState =
                 isKeyguardVisible()
                         || !mDeviceInteractive
-                        || (mPrimaryBouncerIsOrWillBeShowing && !mKeyguardGoingAway)
+                        || (isPrimaryBouncerShowingOrWillBeShowing() && !mKeyguardGoingAway)
                         || mGoingToSleep
                         || shouldListenForFingerprintAssistant
                         || (mKeyguardOccluded && mIsDreaming)
                         || (mKeyguardOccluded && userDoesNotHaveTrust && mKeyguardShowing
                         && (mOccludingAppRequestingFp
                         || isUdfps
-                        || mAlternateBouncerShowing
+                        || isAlternateBouncerShowing()
                         || mAllowFingerprintOnCurrentOccludingActivity
                 )
             );
@@ -2856,7 +2934,7 @@
                         && !isUserInLockdown(user);
         final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed();
         final boolean shouldListenBouncerState =
-                !strongerAuthRequired || !mPrimaryBouncerIsOrWillBeShowing;
+                !strongerAuthRequired || !isPrimaryBouncerShowingOrWillBeShowing();
 
         final boolean shouldListenUdfpsState = !isUdfps
                 || (!userCanSkipBouncer
@@ -2872,10 +2950,10 @@
                     user,
                     shouldListen,
                     mAllowFingerprintOnCurrentOccludingActivity,
-                    mAlternateBouncerShowing,
+                    isAlternateBouncerShowing(),
                     biometricEnabledForUser,
                     mBiometricPromptShowing,
-                    mPrimaryBouncerIsOrWillBeShowing,
+                    isPrimaryBouncerShowingOrWillBeShowing(),
                     userCanSkipBouncer,
                     mCredentialAttempted,
                     mDeviceInteractive,
@@ -3614,6 +3692,7 @@
      */
     public void sendPrimaryBouncerChanged(boolean primaryBouncerIsOrWillBeShowing,
             boolean primaryBouncerFullyShown) {
+        SceneContainerFlag.assertInLegacyMode();
         mLogger.logSendPrimaryBouncerChanged(primaryBouncerIsOrWillBeShowing,
                 primaryBouncerFullyShown);
         Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
@@ -4031,10 +4110,10 @@
             if (isUdfpsSupported()) {
                 pw.println("        udfpsEnrolled=" + isUdfpsEnrolled());
                 pw.println("        shouldListenForUdfps=" + shouldListenForFingerprint(true));
-                pw.println("        mPrimaryBouncerIsOrWillBeShowing="
-                        + mPrimaryBouncerIsOrWillBeShowing);
+                pw.println("        isPrimaryBouncerShowingOrWillBeShowing="
+                        + isPrimaryBouncerShowingOrWillBeShowing());
                 pw.println("        mStatusBarState=" + StatusBarState.toString(mStatusBarState));
-                pw.println("        mAlternateBouncerShowing=" + mAlternateBouncerShowing);
+                pw.println("        isAlternateBouncerShowing=" + isAlternateBouncerShowing());
             } else if (isSfpsSupported()) {
                 pw.println("        sfpsEnrolled=" + isSfpsEnrolled());
                 pw.println("        shouldListenForSfps=" + shouldListenForFingerprint(false));
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 5486abb..de4d14d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -1007,7 +1007,9 @@
             mKeyguardMessageAreaController.setIsVisible(isShowingAlternateBouncer);
             mKeyguardMessageAreaController.setMessage("");
         }
-        mKeyguardUpdateManager.setAlternateBouncerShowing(isShowingAlternateBouncer);
+        if (!SceneContainerFlag.isEnabled()) {
+            mKeyguardUpdateManager.setAlternateBouncerShowing(isShowingAlternateBouncer);
+        }
 
         if (updateScrim) {
             mCentralSurfaces.updateScrimController();
@@ -1449,10 +1451,13 @@
             mNotificationShadeWindowController.setBouncerShowing(primaryBouncerShowing);
             mCentralSurfaces.setBouncerShowing(primaryBouncerShowing);
         }
-        if (primaryBouncerIsOrWillBeShowing != mLastPrimaryBouncerIsOrWillBeShowing || mFirstUpdate
-                || isPrimaryBouncerShowingChanged) {
-            mKeyguardUpdateManager.sendPrimaryBouncerChanged(primaryBouncerIsOrWillBeShowing,
-                    primaryBouncerShowing);
+        if (!SceneContainerFlag.isEnabled()) {
+            if (primaryBouncerIsOrWillBeShowing != mLastPrimaryBouncerIsOrWillBeShowing
+                    || mFirstUpdate
+                    || isPrimaryBouncerShowingChanged) {
+                mKeyguardUpdateManager.sendPrimaryBouncerChanged(primaryBouncerIsOrWillBeShowing,
+                        primaryBouncerShowing);
+            }
         }
 
         mFirstUpdate = false;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 075d8ae..c62b5e0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -114,6 +114,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.compose.animation.scene.ObservableTransitionState;
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.foldables.FoldGracePeriodProvider;
 import com.android.internal.jank.InteractionJankMonitor;
@@ -129,6 +130,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.deviceentry.data.repository.FaceWakeUpTriggersConfig;
 import com.android.systemui.deviceentry.data.repository.FaceWakeUpTriggersConfigImpl;
@@ -141,6 +143,9 @@
 import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.log.SessionTracker;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -149,6 +154,7 @@
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
+import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.settings.GlobalSettings;
 
 import org.junit.After;
@@ -277,6 +283,12 @@
     private SelectedUserInteractor mSelectedUserInteractor;
     @Mock
     private DeviceEntryFaceAuthInteractor mFaceAuthInteractor;
+    @Mock
+    private AlternateBouncerInteractor mAlternateBouncerInteractor;
+    @Mock
+    private JavaAdapter mJavaAdapter;
+    @Mock
+    private SceneInteractor mSceneInteractor;
     @Captor
     private ArgumentCaptor<FaceAuthenticationListener> mFaceAuthenticationListener;
 
@@ -993,7 +1005,7 @@
         verifyFingerprintAuthenticateNeverCalled();
         // WHEN alternate bouncer is shown
         mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
-        mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
+        mKeyguardUpdateMonitor.setAlternateBouncerVisibility(true);
 
         // THEN make sure FP listening begins
         verifyFingerprintAuthenticateCall();
@@ -1489,7 +1501,7 @@
     @Test
     public void testShouldNotListenForUdfps_whenInLockDown() {
         // GIVEN a "we should listen for udfps" state
-        setKeyguardBouncerVisibility(false /* isVisible */);
+        mKeyguardUpdateMonitor.setPrimaryBouncerVisibility(false /* isVisible */);
         mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
         when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
 
@@ -2124,7 +2136,7 @@
         verifyFingerprintAuthenticateNeverCalled();
 
         mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
-        mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
+        mKeyguardUpdateMonitor.setAlternateBouncerVisibility(true);
 
         verifyFingerprintAuthenticateCall();
     }
@@ -2323,12 +2335,7 @@
     }
 
     private void bouncerFullyVisible() {
-        setKeyguardBouncerVisibility(true);
-    }
-
-    private void setKeyguardBouncerVisibility(boolean isVisible) {
-        mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(isVisible, isVisible);
-        mTestableLooper.processAllMessages();
+        mKeyguardUpdateMonitor.setPrimaryBouncerVisibility(true);
     }
 
     private void setBroadcastReceiverPendingResult(BroadcastReceiver receiver) {
@@ -2434,7 +2441,12 @@
                     mPackageManager, mFingerprintManager, mBiometricManager,
                     mFaceWakeUpTriggersConfig, mDevicePostureController,
                     Optional.of(mInteractiveToAuthProvider),
-                    mTaskStackChangeListeners, mSelectedUserInteractor, mActivityTaskManager);
+                    mTaskStackChangeListeners, mSelectedUserInteractor, mActivityTaskManager,
+                    () -> mAlternateBouncerInteractor,
+                    () -> mJavaAdapter,
+                    () -> mSceneInteractor);
+            setAlternateBouncerVisibility(false);
+            setPrimaryBouncerVisibility(false);
             setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
             start();
         }
@@ -2458,5 +2470,25 @@
         protected int getBiometricLockoutDelay() {
             return 0;
         }
+
+        private void setPrimaryBouncerVisibility(boolean isVisible) {
+            if (SceneContainerFlag.isEnabled()) {
+                when(mSceneInteractor.getCurrentScene()).thenReturn(
+                        isVisible
+                                ? MutableStateFlow(Scenes.Bouncer)
+                                : MutableStateFlow(Scenes.Lockscreen));
+                onTransitionStateChanged(new ObservableTransitionState.Idle(Scenes.Bouncer));
+            } else {
+                sendPrimaryBouncerChanged(isVisible, isVisible);
+                mTestableLooper.processAllMessages();
+            }
+        }
+
+        private void setAlternateBouncerVisibility(boolean isVisible) {
+            if (SceneContainerFlag.isEnabled()) {
+                when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(isVisible);
+            }
+            onAlternateBouncerVisibilityChange(isVisible);
+        }
     }
 }