Add helper methods to CommunalInteractor

These are helpful for external transitions to depend on in order to
know when the hub is fully showing and not in transition.

Bug: 315205216
Test: atest CommunalInteractorTest
Flag: ACONFIG com.android.systemui.communal_hub DEVELOPMENT
Change-Id: I3f746a2c6339c924113ef0f8fbd85adfe0fd5f08
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index 7769223..2119060 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -557,6 +557,43 @@
         }
 
     @Test
+    fun isIdleOnCommunal() =
+        testScope.runTest {
+            val transitionState =
+                MutableStateFlow<ObservableCommunalTransitionState>(
+                    ObservableCommunalTransitionState.Idle(CommunalSceneKey.Blank)
+                )
+            communalRepository.setTransitionState(transitionState)
+
+            // isIdleOnCommunal is false when not on communal.
+            val isIdleOnCommunal by collectLastValue(underTest.isIdleOnCommunal)
+            runCurrent()
+            assertThat(isIdleOnCommunal).isEqualTo(false)
+
+            // Transition to communal.
+            transitionState.value =
+                ObservableCommunalTransitionState.Idle(CommunalSceneKey.Communal)
+            runCurrent()
+
+            // isIdleOnCommunal is now true since we're on communal.
+            assertThat(isIdleOnCommunal).isEqualTo(true)
+
+            // Start transition away from communal.
+            transitionState.value =
+                ObservableCommunalTransitionState.Transition(
+                    fromScene = CommunalSceneKey.Communal,
+                    toScene = CommunalSceneKey.Blank,
+                    progress = flowOf(0f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            runCurrent()
+
+            // isIdleOnCommunal turns false as soon as transition away starts.
+            assertThat(isIdleOnCommunal).isEqualTo(false)
+        }
+
+    @Test
     fun testShowWidgetEditorStartsActivity() =
         testScope.runTest {
             underTest.showWidgetEditor()
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 71523b9..bef465b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -55,7 +55,7 @@
 class CommunalInteractor
 @Inject
 constructor(
-    @Application private val applicationScope: CoroutineScope,
+    @Application applicationScope: CoroutineScope,
     private val communalRepository: CommunalRepository,
     private val widgetRepository: CommunalWidgetRepository,
     private val communalPrefsRepository: CommunalPrefsRepository,
@@ -133,6 +133,17 @@
     val isCommunalShowing: Flow<Boolean> =
         communalRepository.desiredScene.map { it == CommunalSceneKey.Communal }
 
+    /**
+     * Flow that emits a boolean if the communal UI is fully visible and not in transition.
+     *
+     * This will not be true while transitioning to the hub and will turn false immediately when a
+     * swipe to exit the hub starts.
+     */
+    val isIdleOnCommunal: Flow<Boolean> =
+        communalRepository.transitionState.map {
+            it is ObservableCommunalTransitionState.Idle && it.scene == CommunalSceneKey.Communal
+        }
+
     val isKeyguardVisible: Flow<Boolean> = keyguardInteractor.isKeyguardVisible
 
     /** Callback received whenever the [SceneTransitionLayout] finishes a scene transition. */
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/CommunalInteractorKosmos.kt
index d8f0cec..92193fd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/CommunalInteractorKosmos.kt
@@ -24,14 +24,14 @@
 import com.android.systemui.communal.widgets.CommunalAppWidgetHost
 import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.smartspace.data.repository.smartspaceRepository
 import org.mockito.Mockito.mock
 
 val Kosmos.communalInteractor by
     Kosmos.Fixture {
         CommunalInteractor(
-            applicationScope = testScope.backgroundScope,
+            applicationScope = applicationCoroutineScope,
             communalRepository = communalRepository,
             widgetRepository = communalWidgetRepository,
             mediaRepository = communalMediaRepository,