Merge changes I1bb8fdf7,Ie29334cd into main

* changes:
  Do not change scene when launching edit mode in STF
  Redirect communal scene interactor to scene interactor
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 777ddab..75ae414 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
@@ -664,22 +664,31 @@
         testScope.runTest {
             // Verify default is false
             val isCommunalShowing by collectLastValue(underTest.isCommunalShowing)
-            runCurrent()
-            assertThat(isCommunalShowing).isFalse()
-
-            // Verify scene changes without the flag doesn't have any impact
-            underTest.changeScene(CommunalScenes.Communal, "test")
-            runCurrent()
             assertThat(isCommunalShowing).isFalse()
 
             // Verify scene changes (with the flag) to communal sets the value to true
             sceneInteractor.changeScene(Scenes.Communal, loggingReason = "")
-            runCurrent()
             assertThat(isCommunalShowing).isTrue()
 
             // Verify scene changes (with the flag) to lockscreen sets the value to false
             sceneInteractor.changeScene(Scenes.Lockscreen, loggingReason = "")
-            runCurrent()
+            assertThat(isCommunalShowing).isFalse()
+        }
+
+    @Test
+    @EnableSceneContainer
+    fun isCommunalShowing_whenSceneContainerEnabledAndChangeToLegacyScene() =
+        testScope.runTest {
+            // Verify default is false
+            val isCommunalShowing by collectLastValue(underTest.isCommunalShowing)
+            assertThat(isCommunalShowing).isFalse()
+
+            // Verify legacy scene change still makes communal show
+            underTest.changeScene(CommunalScenes.Communal, "test")
+            assertThat(isCommunalShowing).isTrue()
+
+            // Verify legacy scene change to blank makes communal hidden
+            underTest.changeScene(CommunalScenes.Blank, "test")
             assertThat(isCommunalShowing).isFalse()
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
index dfb75ca..6a9b9be 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
@@ -16,18 +16,23 @@
 
 package com.android.systemui.communal.domain.interactor
 
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
 import androidx.test.filters.SmallTest
 import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.communal.data.repository.communalSceneRepository
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor.OnSceneAboutToChangeListener
 import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
 import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.communal.shared.model.EditModeState
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.initialSceneKey
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -42,10 +47,24 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @SmallTest
-@RunWith(AndroidJUnit4::class)
-class CommunalSceneInteractorTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class CommunalSceneInteractorTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+        }
+    }
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
@@ -53,6 +72,7 @@
     private val repository = kosmos.communalSceneRepository
     private val underTest by lazy { kosmos.communalSceneInteractor }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun changeScene() =
         testScope.runTest {
@@ -63,6 +83,7 @@
             assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
         }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun changeScene_callsSceneStateProcessor() =
         testScope.runTest {
@@ -78,6 +99,7 @@
             verify(callback).onSceneAboutToChange(CommunalScenes.Communal, null)
         }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun changeScene_doesNotCallSceneStateProcessorForDuplicateState() =
         testScope.runTest {
@@ -93,6 +115,7 @@
             verify(callback, never()).onSceneAboutToChange(any(), anyOrNull())
         }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun snapToScene() =
         testScope.runTest {
@@ -104,6 +127,7 @@
         }
 
     @OptIn(ExperimentalCoroutinesApi::class)
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun snapToSceneWithDelay() =
         testScope.runTest {
@@ -119,30 +143,7 @@
             assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
         }
 
-    @Test
-    fun changeSceneForActivityStartOnDismissKeyguard() =
-        testScope.runTest {
-            val currentScene by collectLastValue(underTest.currentScene)
-            underTest.snapToScene(CommunalScenes.Communal, "test")
-            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
-
-            underTest.changeSceneForActivityStartOnDismissKeyguard()
-            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
-        }
-
-    @Test
-    fun changeSceneForActivityStartOnDismissKeyguard_willNotChangeScene_forEditModeActivity() =
-        testScope.runTest {
-            val currentScene by collectLastValue(underTest.currentScene)
-            underTest.snapToScene(CommunalScenes.Communal, "test")
-            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
-
-            underTest.setEditModeState(EditModeState.STARTING)
-
-            underTest.changeSceneForActivityStartOnDismissKeyguard()
-            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
-        }
-
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun transitionProgress_fullProgress() =
         testScope.runTest {
@@ -161,6 +162,7 @@
                 .isEqualTo(CommunalTransitionProgressModel.Idle(CommunalScenes.Communal))
         }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun transitionProgress_transitioningAwayFromTrackedScene() =
         testScope.runTest {
@@ -201,6 +203,7 @@
                 .isEqualTo(CommunalTransitionProgressModel.Idle(CommunalScenes.Communal))
         }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun transitionProgress_transitioningToTrackedScene() =
         testScope.runTest {
@@ -238,6 +241,7 @@
                 .isEqualTo(CommunalTransitionProgressModel.Idle(CommunalScenes.Communal))
         }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun isIdleOnCommunal() =
         testScope.runTest {
@@ -265,6 +269,7 @@
             assertThat(isIdleOnCommunal).isEqualTo(false)
         }
 
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun isCommunalVisible() =
         testScope.runTest {
@@ -304,4 +309,206 @@
                 )
             assertThat(isCommunalVisible).isEqualTo(true)
         }
+
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    @Test
+    fun changeScene_legacyCommunalScene_mapToStfScene() =
+        testScope.runTest {
+            val currentScene by collectLastValue(underTest.currentScene)
+
+            // Verify that the current scene is the initial scene
+            assertThat(currentScene).isEqualTo(kosmos.initialSceneKey)
+
+            // Change to legacy communal scene
+            underTest.changeScene(CommunalScenes.Communal, loggingReason = "test")
+
+            // Verify that scene changed to communal scene in STF
+            assertThat(currentScene).isEqualTo(Scenes.Communal)
+
+            // Now change to legacy blank scene
+            underTest.changeScene(CommunalScenes.Blank, loggingReason = "test")
+
+            // Verify that scene changed to lock screen scene in STF
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    @Test
+    fun changeScene_stfScenes() =
+        testScope.runTest {
+            val currentScene by collectLastValue(underTest.currentScene)
+
+            // Verify that the current scene is the initial scene
+            assertThat(currentScene).isEqualTo(kosmos.initialSceneKey)
+
+            // Change to communal scene
+            underTest.changeScene(Scenes.Communal, loggingReason = "test")
+
+            // Verify changed to communal scene
+            assertThat(currentScene).isEqualTo(Scenes.Communal)
+
+            // Now change to lockscreen scene
+            underTest.changeScene(Scenes.Lockscreen, loggingReason = "test")
+
+            // Verify changed to lockscreen scene
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    @Test
+    fun snapToScene_legacyCommunalScene_mapToStfScene() =
+        testScope.runTest {
+            val currentScene by collectLastValue(underTest.currentScene)
+
+            // Verify that the current scene is the initial scene
+            assertThat(currentScene).isEqualTo(kosmos.initialSceneKey)
+
+            // Snap to legacy communal scene
+            underTest.snapToScene(CommunalScenes.Communal, loggingReason = "test")
+
+            // Verify that scene changed to communal scene in STF
+            assertThat(currentScene).isEqualTo(Scenes.Communal)
+
+            // Now snap to legacy blank scene
+            underTest.snapToScene(CommunalScenes.Blank, loggingReason = "test")
+
+            // Verify that scene changed to lock screen scene in STF
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    @Test
+    fun snapToScene_stfScenes() =
+        testScope.runTest {
+            val currentScene by collectLastValue(underTest.currentScene)
+
+            // Verify that the current scene is the initial scene
+            assertThat(currentScene).isEqualTo(kosmos.initialSceneKey)
+
+            // Snap to communal scene
+            underTest.snapToScene(Scenes.Communal, loggingReason = "test")
+
+            // Verify changed to communal scene
+            assertThat(currentScene).isEqualTo(Scenes.Communal)
+
+            // Now snap to lockscreen scene
+            underTest.snapToScene(Scenes.Lockscreen, loggingReason = "test")
+
+            // Verify changed to lockscreen scene
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    @Test
+    fun isIdleOnCommunal_sceneContainerEnabled() =
+        testScope.runTest {
+            val transitionState: MutableStateFlow<ObservableTransitionState> =
+                MutableStateFlow(ObservableTransitionState.Idle(Scenes.Lockscreen))
+            underTest.setTransitionState(transitionState)
+
+            // isIdleOnCommunal is initially false
+            val isIdleOnCommunal by collectLastValue(underTest.isIdleOnCommunal)
+            assertThat(isIdleOnCommunal).isEqualTo(false)
+
+            // Start transition to communal.
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Lockscreen,
+                    toScene = Scenes.Communal,
+                    currentScene = flowOf(Scenes.Lockscreen),
+                    progress = flowOf(0.1f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            assertThat(isIdleOnCommunal).isEqualTo(false)
+
+            // Finish transition to communal
+            transitionState.value = ObservableTransitionState.Idle(Scenes.Communal)
+            assertThat(isIdleOnCommunal).isEqualTo(true)
+
+            // Start transition away from communal
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Communal,
+                    toScene = Scenes.Lockscreen,
+                    currentScene = flowOf(Scenes.Communal),
+                    progress = flowOf(0.1f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            assertThat(isIdleOnCommunal).isEqualTo(false)
+
+            // Finish transition to lock screen
+            transitionState.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
+            assertThat(isIdleOnCommunal).isEqualTo(false)
+        }
+
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    @Test
+    fun isCommunalVisible_sceneContainerEnabled() =
+        testScope.runTest {
+            val transitionState: MutableStateFlow<ObservableTransitionState> =
+                MutableStateFlow(ObservableTransitionState.Idle(Scenes.Lockscreen))
+            underTest.setTransitionState(transitionState)
+
+            // isCommunalVisible is initially false
+            val isCommunalVisible by collectLastValue(underTest.isCommunalVisible)
+            assertThat(isCommunalVisible).isEqualTo(false)
+
+            // Start transition to communal.
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Lockscreen,
+                    toScene = Scenes.Communal,
+                    currentScene = flowOf(Scenes.Lockscreen),
+                    progress = flowOf(0.1f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            assertThat(isCommunalVisible).isEqualTo(true)
+
+            // Half-way transition to communal.
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Lockscreen,
+                    toScene = Scenes.Communal,
+                    currentScene = flowOf(Scenes.Lockscreen),
+                    progress = flowOf(0.5f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            assertThat(isCommunalVisible).isEqualTo(true)
+
+            // Finish transition to communal
+            transitionState.value = ObservableTransitionState.Idle(Scenes.Communal)
+            assertThat(isCommunalVisible).isEqualTo(true)
+
+            // Start transition away from communal
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Communal,
+                    toScene = Scenes.Lockscreen,
+                    currentScene = flowOf(Scenes.Communal),
+                    progress = flowOf(0.1f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            assertThat(isCommunalVisible).isEqualTo(true)
+
+            // Half-way transition away from communal
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Communal,
+                    toScene = Scenes.Lockscreen,
+                    currentScene = flowOf(Scenes.Communal),
+                    progress = flowOf(0.5f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            assertThat(isCommunalVisible).isEqualTo(true)
+
+            // Finish transition to lock screen
+            transitionState.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
+            assertThat(isCommunalVisible).isEqualTo(false)
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 3b2b12c..e4098ae 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -335,6 +335,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun alpha_idleOnHub_isZero() =
         testScope.runTest {
             val alpha by collectLastValue(underTest.alpha(viewState))
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
index ac496f0..3826fb4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
@@ -24,11 +24,14 @@
 import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
 import com.android.systemui.communal.shared.log.CommunalSceneLogger
 import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.communal.shared.model.CommunalTransitionKeys
+import com.android.systemui.communal.shared.model.CommunalScenes.toSceneContainerSceneKey
 import com.android.systemui.communal.shared.model.EditModeState
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.shared.model.KeyguardState
+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.util.kotlin.BooleanFlowOperators.allOf
 import com.android.systemui.util.kotlin.pairwiseBy
 import javax.inject.Inject
@@ -45,6 +48,7 @@
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
 
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -55,6 +59,7 @@
     @Application private val applicationScope: CoroutineScope,
     private val repository: CommunalSceneRepository,
     private val logger: CommunalSceneLogger,
+    private val sceneInteractor: SceneInteractor,
 ) {
     private val _isLaunchingWidget = MutableStateFlow(false)
 
@@ -72,8 +77,14 @@
 
     private val onSceneAboutToChangeListener = mutableSetOf<OnSceneAboutToChangeListener>()
 
-    /** Registers a listener which is called when the scene is about to change. */
+    /**
+     * Registers a listener which is called when the scene is about to change.
+     *
+     * This API is for legacy communal container scenes, and should not be used when
+     * [SceneContainerFlag] is enabled.
+     */
     fun registerSceneStateProcessor(processor: OnSceneAboutToChangeListener) {
+        SceneContainerFlag.assertInLegacyMode()
         onSceneAboutToChangeListener.add(processor)
     }
 
@@ -87,6 +98,15 @@
         transitionKey: TransitionKey? = null,
         keyguardState: KeyguardState? = null,
     ) {
+        if (SceneContainerFlag.isEnabled) {
+            return sceneInteractor.changeScene(
+                toScene = newScene.toSceneContainerSceneKey(),
+                loggingReason = loggingReason,
+                transitionKey = transitionKey,
+                sceneState = keyguardState,
+            )
+        }
+
         applicationScope.launch("$TAG#changeScene") {
             if (currentScene.value == newScene) return@launch
             logger.logSceneChangeRequested(
@@ -107,6 +127,13 @@
         delayMillis: Long = 0,
         keyguardState: KeyguardState? = null
     ) {
+        if (SceneContainerFlag.isEnabled) {
+            return sceneInteractor.snapToScene(
+                toScene = newScene.toSceneContainerSceneKey(),
+                loggingReason = loggingReason,
+            )
+        }
+
         applicationScope.launch("$TAG#snapToScene") {
             delay(delayMillis)
             if (currentScene.value == newScene) return@launch
@@ -125,37 +152,27 @@
         onSceneAboutToChangeListener.forEach { it.onSceneAboutToChange(newScene, keyguardState) }
     }
 
-    /** Changes to Blank scene when starting an activity after dismissing keyguard. */
-    fun changeSceneForActivityStartOnDismissKeyguard() {
-        // skip if we're starting edit mode activity, as it will be handled later by changeScene
-        // with transition key [CommunalTransitionKeys.ToEditMode].
-        if (_editModeState.value == EditModeState.STARTING) {
-            return
-        }
-        changeScene(
-            CommunalScenes.Blank,
-            "activity start dismissing keyguard",
-            CommunalTransitionKeys.SimpleFade,
-        )
-    }
-
     /**
      * Target scene as requested by the underlying [SceneTransitionLayout] or through [changeScene].
      */
     val currentScene: StateFlow<SceneKey> =
-        repository.currentScene
-            .pairwiseBy(initialValue = repository.currentScene.value) { from, to ->
-                logger.logSceneChangeCommitted(
-                    from = from,
-                    to = to,
+        if (SceneContainerFlag.isEnabled) {
+            sceneInteractor.currentScene
+        } else {
+            repository.currentScene
+                .pairwiseBy(initialValue = repository.currentScene.value) { from, to ->
+                    logger.logSceneChangeCommitted(
+                        from = from,
+                        to = to,
+                    )
+                    to
+                }
+                .stateIn(
+                    scope = applicationScope,
+                    started = SharingStarted.Eagerly,
+                    initialValue = repository.currentScene.value,
                 )
-                to
-            }
-            .stateIn(
-                scope = applicationScope,
-                started = SharingStarted.Eagerly,
-                initialValue = repository.currentScene.value,
-            )
+        }
 
     private val _editModeState = MutableStateFlow<EditModeState?>(null)
     /**
@@ -170,13 +187,17 @@
 
     /** Transition state of the hub mode. */
     val transitionState: StateFlow<ObservableTransitionState> =
-        repository.transitionState
-            .onEach { logger.logSceneTransition(it) }
-            .stateIn(
-                scope = applicationScope,
-                started = SharingStarted.Eagerly,
-                initialValue = repository.transitionState.value,
-            )
+        if (SceneContainerFlag.isEnabled) {
+            sceneInteractor.transitionState
+        } else {
+            repository.transitionState
+                .onEach { logger.logSceneTransition(it) }
+                .stateIn(
+                    scope = applicationScope,
+                    started = SharingStarted.Eagerly,
+                    initialValue = repository.transitionState.value,
+                )
+        }
 
     /**
      * Updates the transition state of the hub [SceneTransitionLayout].
@@ -184,10 +205,19 @@
      * Note that you must call is with `null` when the UI is done or risk a memory leak.
      */
     fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) {
-        repository.setTransitionState(transitionState)
+        if (SceneContainerFlag.isEnabled) {
+            sceneInteractor.setTransitionState(transitionState)
+        } else {
+            repository.setTransitionState(transitionState)
+        }
     }
 
-    /** Returns a flow that tracks the progress of transitions to the given scene from 0-1. */
+    /**
+     * Returns a flow that tracks the progress of transitions to the given scene from 0-1.
+     *
+     * This API is for legacy communal container scenes, and should not be used when
+     * [SceneContainerFlag] is enabled.
+     */
     fun transitionProgressToScene(targetScene: SceneKey) =
         transitionState
             .flatMapLatest { state ->
@@ -209,6 +239,7 @@
                 }
             }
             .distinctUntilChanged()
+            .onStart { SceneContainerFlag.assertInLegacyMode() }
 
     /**
      * Flow that emits a boolean if the communal UI is fully visible and not in transition.
@@ -219,7 +250,10 @@
     val isIdleOnCommunal: StateFlow<Boolean> =
         transitionState
             .map {
-                it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Communal
+                it is ObservableTransitionState.Idle &&
+                    (it.currentScene ==
+                        if (SceneContainerFlag.isEnabled) Scenes.Communal
+                        else CommunalScenes.Communal)
             }
             .stateIn(
                 scope = applicationScope,
@@ -239,7 +273,13 @@
     val isCommunalVisible: StateFlow<Boolean> =
         transitionState
             .map {
-                !(it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Blank)
+                if (SceneContainerFlag.isEnabled)
+                    it is ObservableTransitionState.Idle && it.currentScene == Scenes.Communal ||
+                        (it is ObservableTransitionState.Transition &&
+                            (it.fromContent == Scenes.Communal || it.toContent == Scenes.Communal))
+                else
+                    !(it is ObservableTransitionState.Idle &&
+                        it.currentScene == CommunalScenes.Blank)
             }
             .stateIn(
                 scope = applicationScope,
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
index d5a56c1..e562dfc 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.communal.shared.model
 
 import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
 
 /** Definition of the possible scenes for the communal UI. */
 object CommunalScenes {
@@ -27,4 +29,30 @@
     @JvmField val Communal = SceneKey("communal")
 
     @JvmField val Default = Blank
+
+    private fun SceneKey.isCommunalScene(): Boolean {
+        return this == Blank || this == Communal
+    }
+
+    /**
+     * Maps a legacy communal scene to a scene in the scene container.
+     *
+     * The rules are simple:
+     * - A legacy communal scene maps to a communal scene in the Scene Transition Framework (STF).
+     * - A legacy blank scene means that the communal scene layout does not render anything so
+     *   whatever is beneath the layout is shown. That usually means lockscreen or dream, both of
+     *   which are represented by the lockscreen scene in STF (but different keyguard states in
+     *   KTF).
+     */
+    fun SceneKey.toSceneContainerSceneKey(): SceneKey {
+        if (!isCommunalScene() || !SceneContainerFlag.isEnabled) {
+            return this
+        }
+
+        return when (this) {
+            Communal -> Scenes.Communal
+            Blank -> Scenes.Lockscreen
+            else -> throw Throwable("Unrecognized communal scene: $this")
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
index d84dc20..13b4aa9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.Logger
 import com.android.systemui.log.dagger.CommunalLog
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import javax.inject.Inject
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
@@ -244,15 +245,18 @@
     private fun listenForTransitionAndChangeScene() {
         lifecycleScope.launch {
             communalViewModel.canShowEditMode.collect {
-                communalViewModel.changeScene(
-                    scene = CommunalScenes.Blank,
-                    loggingReason = "edit mode opening",
-                    transitionKey = CommunalTransitionKeys.ToEditMode,
-                    keyguardState = KeyguardState.GONE,
-                )
-                // wait till transitioned to Blank scene, then animate in communal content in
-                // edit mode
-                communalViewModel.currentScene.first { it == CommunalScenes.Blank }
+                if (!SceneContainerFlag.isEnabled) {
+                    communalViewModel.changeScene(
+                        scene = CommunalScenes.Blank,
+                        loggingReason = "edit mode opening",
+                        transitionKey = CommunalTransitionKeys.ToEditMode,
+                        keyguardState = KeyguardState.GONE,
+                    )
+                    // wait till transitioned to Blank scene, then animate in communal content in
+                    // edit mode
+                    communalViewModel.currentScene.first { it == CommunalScenes.Blank }
+                }
+
                 communalViewModel.setEditModeState(EditModeState.SHOWING)
 
                 // Inform the ActivityController that we are now fully visible.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
index d4ef42c..5b37468 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
@@ -470,9 +470,6 @@
                     if (dismissShade) {
                         shadeControllerLazy.get().collapseShadeForActivityStart()
                     }
-                    if (Flags.communalHub()) {
-                        communalSceneInteractor.changeSceneForActivityStartOnDismissKeyguard()
-                    }
                     return deferred
                 }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorKosmos.kt
index 2ab8221..209d163 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.communal.shared.log.communalSceneLogger
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
 
 val Kosmos.communalSceneInteractor: CommunalSceneInteractor by
     Kosmos.Fixture {
@@ -27,5 +28,6 @@
             applicationScope = applicationCoroutineScope,
             repository = communalSceneRepository,
             logger = communalSceneLogger,
+            sceneInteractor = sceneInteractor,
         )
     }