Fix QS Edit scrolling in Split shade.

When in customizer Swiping up should not transition to a different
scene. Maybe it should if swiping on the notifications side or from the
bottom, but this is not supported (along with the nested scrolling).

Also, fix the scrolling on the QS side in split shade. The footer should
be fixed and not scroll with the rest of the content.

Test: manual
Test: atest ShadeSceneViewModelTest
Fixes: 329662922
Bug: 330200163
Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT
Change-Id: Ic69e15fbd402b75dccc75fa7812bcd7dc23412db
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index e1b56f1..03e83a0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -55,6 +55,7 @@
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.LowestZIndexScenePicker
 import com.android.compose.animation.scene.SceneScope
+import com.android.compose.animation.scene.TransitionState
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.compose.animation.scene.animateSceneFloatAsState
@@ -294,6 +295,7 @@
     }
 
     val quickSettingsScrollState = rememberScrollState()
+    val isScrollable = layoutState.transitionState is TransitionState.Idle
     LaunchedEffect(isCustomizing, quickSettingsScrollState) {
         if (isCustomizing) {
             quickSettingsScrollState.scrollTo(0)
@@ -322,36 +324,41 @@
                 Column(
                     verticalArrangement = Arrangement.Top,
                     modifier =
-                        Modifier.weight(1f).fillMaxHeight().thenIf(!isCustomizing) {
-                            Modifier.verticalNestedScrollToScene()
-                                .verticalScroll(quickSettingsScrollState)
-                                .clipScrollableContainer(Orientation.Horizontal)
-                                .padding(bottom = navBarBottomHeight)
-                        }
+                        Modifier.weight(1f).fillMaxSize().thenIf(!isCustomizing) {
+                            Modifier.padding(bottom = navBarBottomHeight)
+                        },
                 ) {
-                    Box(
-                        modifier = Modifier.element(QuickSettings.Elements.SplitShadeQuickSettings)
+                    Column(
+                        modifier =
+                            Modifier.fillMaxSize().weight(1f).thenIf(!isCustomizing) {
+                                Modifier.verticalNestedScrollToScene()
+                                    .verticalScroll(
+                                        quickSettingsScrollState,
+                                        enabled = isScrollable
+                                    )
+                                    .clipScrollableContainer(Orientation.Horizontal)
+                            }
                     ) {
-                        QuickSettings(
-                            qsSceneAdapter = viewModel.qsSceneAdapter,
-                            heightProvider = { viewModel.qsSceneAdapter.qsHeight },
-                            isSplitShade = true,
+                        Box(
+                            modifier =
+                                Modifier.element(QuickSettings.Elements.SplitShadeQuickSettings)
+                        ) {
+                            QuickSettings(
+                                qsSceneAdapter = viewModel.qsSceneAdapter,
+                                heightProvider = { viewModel.qsSceneAdapter.qsHeight },
+                                isSplitShade = true,
+                                modifier = Modifier.fillMaxWidth(),
+                                squishiness = tileSquishiness,
+                            )
+                        }
+
+                        MediaIfVisible(
+                            viewModel = viewModel,
+                            mediaCarouselController = mediaCarouselController,
+                            mediaHost = mediaHost,
                             modifier = Modifier.fillMaxWidth(),
-                            squishiness = tileSquishiness,
                         )
                     }
-
-                    MediaIfVisible(
-                        viewModel = viewModel,
-                        mediaCarouselController = mediaCarouselController,
-                        mediaHost = mediaHost,
-                        modifier = Modifier.fillMaxWidth(),
-                    )
-
-                    Spacer(
-                        modifier = Modifier.weight(1f),
-                    )
-
                     FooterActionsWithAnimatedVisibility(
                         viewModel = footerActionsViewModel,
                         isCustomizing = isCustomizing,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 1c54961..d1c4ec3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -95,7 +95,7 @@
             scope = testScope.backgroundScope,
         )
 
-    private val qsFlexiglassAdapter = FakeQSSceneAdapter({ mock() })
+    private val qsSceneAdapter = FakeQSSceneAdapter({ mock() })
 
     private lateinit var shadeHeaderViewModel: ShadeHeaderViewModel
 
@@ -122,7 +122,7 @@
                 applicationScope = testScope.backgroundScope,
                 deviceEntryInteractor = deviceEntryInteractor,
                 shadeHeaderViewModel = shadeHeaderViewModel,
-                qsSceneAdapter = qsFlexiglassAdapter,
+                qsSceneAdapter = qsSceneAdapter,
                 notifications = kosmos.notificationsPlaceholderViewModel,
                 mediaDataManager = mediaDataManager,
                 shadeInteractor = kosmos.shadeInteractor,
@@ -279,6 +279,20 @@
         }
 
     @Test
+    fun upTransitionSceneKey_customizing_noTransition() =
+            testScope.runTest {
+                val destinationScenes by collectLastValue(underTest.destinationScenes)
+
+                qsSceneAdapter.setCustomizing(true)
+                assertThat(
+                        destinationScenes!!
+                                .keys
+                                .filterIsInstance<Swipe>()
+                                .filter { it.direction == SwipeDirection.Up }
+                ).isEmpty()
+            }
+
+    @Test
     fun shadeMode() =
         testScope.runTest {
             val shadeMode by collectLastValue(underTest.shadeMode)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 34f66b8..c695d4c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -48,6 +48,8 @@
         qsSceneAdapter.isCustomizing.map { customizing ->
             if (customizing) {
                 mapOf<UserAction, UserActionResult>(Back to UserActionResult(Scenes.QuickSettings))
+                // TODO(b/330200163) Add an Up from Bottom to be able to collapse the shade
+                // while customizing
             } else {
                 mapOf(
                     Back to UserActionResult(Scenes.Shade),
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index ea549f2..24b7533 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -66,11 +66,13 @@
                 deviceEntryInteractor.isUnlocked,
                 deviceEntryInteractor.canSwipeToEnter,
                 shadeInteractor.shadeMode,
-            ) { isUnlocked, canSwipeToDismiss, shadeMode ->
+                qsSceneAdapter.isCustomizing
+            ) { isUnlocked, canSwipeToDismiss, shadeMode, isCustomizing ->
                 destinationScenes(
                     isUnlocked = isUnlocked,
                     canSwipeToDismiss = canSwipeToDismiss,
                     shadeMode = shadeMode,
+                    isCustomizing = isCustomizing
                 )
             }
             .stateIn(
@@ -81,6 +83,7 @@
                         isUnlocked = deviceEntryInteractor.isUnlocked.value,
                         canSwipeToDismiss = deviceEntryInteractor.canSwipeToEnter.value,
                         shadeMode = shadeInteractor.shadeMode.value,
+                        isCustomizing = qsSceneAdapter.isCustomizing.value,
                     ),
             )
 
@@ -120,6 +123,7 @@
         isUnlocked: Boolean,
         canSwipeToDismiss: Boolean?,
         shadeMode: ShadeMode,
+        isCustomizing: Boolean,
     ): Map<UserAction, UserActionResult> {
         val up =
             when {
@@ -131,7 +135,9 @@
         val down = Scenes.QuickSettings.takeIf { shadeMode is ShadeMode.Single }
 
         return buildMap {
-            this[Swipe(SwipeDirection.Up)] = UserActionResult(up)
+            if (!isCustomizing) {
+                this[Swipe(SwipeDirection.Up)] = UserActionResult(up)
+            } // TODO(b/330200163) Add an else to be able to collapse the shade while customizing
             down?.let { this[Swipe(SwipeDirection.Down)] = UserActionResult(down) }
         }
     }