Merge "Delete ShadeTransitionController" into main
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index a4b32a7..68e9cd8 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -169,7 +169,6 @@
 import com.android.systemui.shade.data.repository.FlingInfo;
 import com.android.systemui.shade.data.repository.ShadeRepository;
 import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor;
-import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.GestureRecorder;
@@ -746,7 +745,6 @@
             NotificationListContainer notificationListContainer,
             NotificationStackSizeCalculator notificationStackSizeCalculator,
             UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
-            ShadeTransitionController shadeTransitionController,
             SystemClock systemClock,
             KeyguardBottomAreaViewModel keyguardBottomAreaViewModel,
             KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
@@ -903,7 +901,6 @@
         mKeyguardBypassController = bypassController;
         mUpdateMonitor = keyguardUpdateMonitor;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
-        shadeTransitionController.setShadeViewController(this);
         dynamicPrivacyController.addListener(this::onDynamicPrivacyChanged);
         quickSettingsController.setExpansionHeightListener(this::onQsSetExpansionHeightCalled);
         quickSettingsController.setQsStateUpdateListener(this::onQsStateUpdated);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
index 3a0e167..7525184 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
@@ -62,7 +62,6 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.SystemBarUtils;
-import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.classifier.Classifier;
@@ -80,7 +79,6 @@
 import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.shade.data.repository.ShadeRepository;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
-import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -133,9 +131,7 @@
     private final FrameLayout mQsFrame;
 
     private final QsFrameTranslateController mQsFrameTranslateController;
-    private final ShadeTransitionController mShadeTransitionController;
     private final PulseExpansionHandler mPulseExpansionHandler;
-    private final ShadeExpansionStateManager mShadeExpansionStateManager;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final LightBarController mLightBarController;
     private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@@ -147,7 +143,6 @@
     private final KeyguardBypassController mKeyguardBypassController;
     private final NotificationRemoteInputManager mRemoteInputManager;
     private VelocityTracker mQsVelocityTracker;
-    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final ScrimController mScrimController;
     private final MediaDataManager mMediaDataManager;
     private final MediaHierarchyManager mMediaHierarchyManager;
@@ -309,10 +304,8 @@
             Lazy<NotificationPanelViewController> panelViewControllerLazy,
             NotificationPanelView panelView,
             QsFrameTranslateController qsFrameTranslateController,
-            ShadeTransitionController shadeTransitionController,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationRemoteInputManager remoteInputManager,
-            ShadeExpansionStateManager shadeExpansionStateManager,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             LightBarController lightBarController,
             NotificationStackScrollLayoutController notificationStackScrollLayoutController,
@@ -322,7 +315,6 @@
             StatusBarTouchableRegionManager statusBarTouchableRegionManager,
             KeyguardStateController keyguardStateController,
             KeyguardBypassController keyguardBypassController,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
             ScrimController scrimController,
             MediaDataManager mediaDataManager,
             MediaHierarchyManager mediaHierarchyManager,
@@ -353,7 +345,6 @@
         mSplitShadeStateController = splitShadeStateController;
         mSplitShadeEnabled = mSplitShadeStateController.shouldUseSplitNotificationShade(mResources);
         mQsFrameTranslateController = qsFrameTranslateController;
-        mShadeTransitionController = shadeTransitionController;
         mPulseExpansionHandler = pulseExpansionHandler;
         pulseExpansionHandler.setPulseExpandAbortListener(() -> {
             if (mQs != null) {
@@ -361,7 +352,6 @@
             }
         });
         mRemoteInputManager = remoteInputManager;
-        mShadeExpansionStateManager = shadeExpansionStateManager;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mLightBarController = lightBarController;
         mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
@@ -371,7 +361,6 @@
         mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
         mKeyguardStateController = keyguardStateController;
         mKeyguardBypassController = keyguardBypassController;
-        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mScrimController = scrimController;
         mMediaDataManager = mediaDataManager;
         mMediaHierarchyManager = mediaHierarchyManager;
@@ -2180,7 +2169,6 @@
                 }
             });
             mLockscreenShadeTransitionController.setQS(mQs);
-            mShadeTransitionController.setQs(mQs);
             mNotificationStackScrollLayoutController.setQsHeader((ViewGroup) mQs.getHeader());
             mQs.setScrollListener(mQsScrollListener);
             updateExpansion();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
index e40bcd5..df5ff5a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
@@ -56,11 +56,6 @@
         return ShadeExpansionChangeEvent(fraction, expanded, tracking, dragDownPxAmount)
     }
 
-    /** Removes an expansion listener. */
-    fun removeExpansionListener(listener: ShadeExpansionListener) {
-        expansionListeners.remove(listener)
-    }
-
     /** Adds a listener that will be notified when the panel state has changed. */
     @Deprecated("Use ShadeInteractor instead")
     fun addStateListener(listener: ShadeStateListener) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
index 1fb0fb6..60810a0 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.shade.TouchLogger.Companion.logTouchesTo
 import com.android.systemui.shade.data.repository.ShadeRepository
 import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.shade.transition.ScrimShadeTransitionController
 import com.android.systemui.statusbar.policy.SplitShadeStateController
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -47,12 +48,14 @@
     private val controller: SplitShadeStateController,
     private val shadeController: ShadeController,
     private val shadeHeaderController: ShadeHeaderController,
+    private val scrimShadeTransitionController: ScrimShadeTransitionController,
 ) : CoreStartable {
 
     override fun start() {
         hydrateShadeMode()
         logTouchesTo(touchLog)
         initHeaderController()
+        scrimShadeTransitionController.init()
     }
 
     private fun initHeaderController() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
index abb69f6..151e289 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
@@ -17,27 +17,55 @@
 package com.android.systemui.shade.transition
 
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.PanelState
 import com.android.systemui.shade.ShadeExpansionChangeEvent
+import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
 import com.android.systemui.statusbar.phone.ScrimController
+import dagger.Lazy
 import java.io.PrintWriter
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 /** Controls the scrim properties during the shade expansion transition on non-lockscreen. */
 @SysUISingleton
 class ScrimShadeTransitionController
 @Inject
 constructor(
-    dumpManager: DumpManager,
+    @Application private val applicationScope: CoroutineScope,
+    private val shadeExpansionStateManager: ShadeExpansionStateManager,
+    private val panelExpansionInteractor: Lazy<PanelExpansionInteractor>,
+    private val dumpManager: DumpManager,
     private val scrimController: ScrimController,
 ) {
-
     private var lastExpansionFraction: Float? = null
     private var lastExpansionEvent: ShadeExpansionChangeEvent? = null
     private var currentPanelState: Int? = null
 
-    init {
+    fun init() {
+        if (SceneContainerFlag.isEnabled) {
+            applicationScope.launch {
+                panelExpansionInteractor.get().legacyPanelExpansion.collect { panelExpansion ->
+                    onPanelExpansionChanged(
+                        ShadeExpansionChangeEvent(
+                            fraction = panelExpansion,
+                            expanded = panelExpansion > 0f,
+                            tracking = true,
+                            dragDownPxAmount = 0f,
+                        )
+                    )
+                }
+            }
+        } else {
+            val currentState =
+                shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
+            onPanelExpansionChanged(currentState)
+            shadeExpansionStateManager.addStateListener(this::onPanelStateChanged)
+        }
         dumpManager.registerDumpable(
             ScrimShadeTransitionController::class.java.simpleName,
             this::dump
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
deleted file mode 100644
index 3a5c5e1..0000000
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shade.transition
-
-import android.content.Context
-import android.content.res.Configuration
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.plugins.qs.QS
-import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.shade.PanelState
-import com.android.systemui.shade.ShadeExpansionChangeEvent
-import com.android.systemui.shade.ShadeExpansionStateManager
-import com.android.systemui.shade.ShadeViewController
-import com.android.systemui.shade.panelStateToString
-import com.android.systemui.statusbar.StatusBarState
-import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.statusbar.policy.SplitShadeStateController
-import dagger.Lazy
-import java.io.PrintWriter
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
-
-/** Controls the shade expansion transition on non-lockscreen. */
-@SysUISingleton
-class ShadeTransitionController
-@Inject
-constructor(
-    @Application private val applicationScope: CoroutineScope,
-    configurationController: ConfigurationController,
-    shadeExpansionStateManager: ShadeExpansionStateManager,
-    dumpManager: DumpManager,
-    private val context: Context,
-    private val scrimShadeTransitionController: ScrimShadeTransitionController,
-    private val statusBarStateController: SysuiStatusBarStateController,
-    private val splitShadeStateController: SplitShadeStateController,
-    private val panelExpansionInteractor: Lazy<PanelExpansionInteractor>,
-) {
-
-    lateinit var shadeViewController: ShadeViewController
-    lateinit var notificationStackScrollLayoutController: NotificationStackScrollLayoutController
-    lateinit var qs: QS
-
-    private var inSplitShade = false
-    private var currentPanelState: Int? = null
-    private var lastShadeExpansionChangeEvent: ShadeExpansionChangeEvent? = null
-
-    init {
-        updateResources()
-        configurationController.addCallback(
-            object : ConfigurationController.ConfigurationListener {
-                override fun onConfigChanged(newConfig: Configuration?) {
-                    updateResources()
-                }
-            }
-        )
-        if (SceneContainerFlag.isEnabled) {
-            applicationScope.launch {
-                panelExpansionInteractor.get().legacyPanelExpansion.collect { panelExpansion ->
-                    onPanelExpansionChanged(
-                        ShadeExpansionChangeEvent(
-                            fraction = panelExpansion,
-                            expanded = panelExpansion > 0f,
-                            tracking = true,
-                            dragDownPxAmount = 0f,
-                        )
-                    )
-                }
-            }
-        } else {
-            val currentState =
-                shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
-            onPanelExpansionChanged(currentState)
-            shadeExpansionStateManager.addStateListener(this::onPanelStateChanged)
-        }
-        dumpManager.registerCriticalDumpable("ShadeTransitionController") { printWriter, _ ->
-            dump(printWriter)
-        }
-    }
-
-    private fun updateResources() {
-        inSplitShade = splitShadeStateController.shouldUseSplitNotificationShade(context.resources)
-    }
-
-    private fun onPanelStateChanged(@PanelState state: Int) {
-        currentPanelState = state
-        scrimShadeTransitionController.onPanelStateChanged(state)
-    }
-
-    private fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
-        lastShadeExpansionChangeEvent = event
-        scrimShadeTransitionController.onPanelExpansionChanged(event)
-    }
-
-    private fun dump(pw: PrintWriter) {
-        pw.println(
-            """
-            ShadeTransitionController:
-                inSplitShade: $inSplitShade
-                isScreenUnlocked: ${isScreenUnlocked()}
-                currentPanelState: ${currentPanelState?.panelStateToString()}
-                lastPanelExpansionChangeEvent: $lastShadeExpansionChangeEvent
-                qs.isInitialized: ${this::qs.isInitialized}
-                npvc.isInitialized: ${this::shadeViewController.isInitialized}
-                nssl.isInitialized: ${this::notificationStackScrollLayoutController.isInitialized}
-            """
-                .trimIndent()
-        )
-    }
-
-    private fun isScreenUnlocked() =
-        statusBarStateController.currentOrUpcomingState == StatusBarState.SHADE
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 24c9d6b..56e61e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -136,7 +136,6 @@
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.shade.domain.interactor.ShadeInteractorImpl;
 import com.android.systemui.shade.domain.interactor.ShadeInteractorLegacyImpl;
-import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -307,7 +306,6 @@
     @Mock protected NotificationListContainer mNotificationListContainer;
     @Mock protected NotificationStackSizeCalculator mNotificationStackSizeCalculator;
     @Mock protected UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
-    @Mock protected ShadeTransitionController mShadeTransitionController;
     @Mock protected QS mQs;
     @Mock protected QSFragmentLegacy mQSFragment;
     @Mock protected ViewGroup mQsHeader;
@@ -725,7 +723,6 @@
                 mNotificationListContainer,
                 mNotificationStackSizeCalculator,
                 mUnlockedScreenOffAnimationController,
-                mShadeTransitionController,
                 systemClock,
                 mKeyguardBottomAreaViewModel,
                 mKeyguardBottomAreaInteractor,
@@ -792,10 +789,8 @@
                 mNotificationPanelViewControllerLazy,
                 mView,
                 mQsFrameTranslateController,
-                mShadeTransitionController,
                 expansionHandler,
                 mNotificationRemoteInputManager,
-                mShadeExpansionStateManager,
                 mStatusBarKeyguardViewManager,
                 mLightBarController,
                 mNotificationStackScrollLayoutController,
@@ -805,7 +800,6 @@
                 mStatusBarTouchableRegionManager,
                 mKeyguardStateController,
                 mKeyguardBypassController,
-                mUpdateMonitor,
                 mScrimController,
                 mMediaDataManager,
                 mMediaHierarchyManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index ee279d8..20d877e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -69,7 +69,6 @@
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.shade.domain.interactor.ShadeInteractorImpl;
 import com.android.systemui.shade.domain.interactor.ShadeInteractorLegacyImpl;
-import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -134,7 +133,6 @@
     @Mock protected ViewGroup mQsHeader;
     @Mock protected ViewParent mPanelViewParent;
     @Mock protected QsFrameTranslateController mQsFrameTranslateController;
-    @Mock protected ShadeTransitionController mShadeTransitionController;
     @Mock protected PulseExpansionHandler mPulseExpansionHandler;
     @Mock protected NotificationRemoteInputManager mNotificationRemoteInputManager;
     @Mock protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -307,10 +305,8 @@
                 mPanelViewControllerLazy,
                 mPanelView,
                 mQsFrameTranslateController,
-                mShadeTransitionController,
                 mPulseExpansionHandler,
                 mNotificationRemoteInputManager,
-                mShadeExpansionStateManager,
                 mStatusBarKeyguardViewManager,
                 mLightBarController,
                 mNotificationStackScrollLayoutController,
@@ -320,7 +316,6 @@
                 mStatusBarTouchableRegionManager,
                 mKeyguardStateController,
                 mKeyguardBypassController,
-                mKeyguardUpdateMonitor,
                 mScrimController,
                 mMediaDataManager,
                 mMediaHierarchyManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
index a5bd2ae..dea905a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
@@ -1,12 +1,41 @@
 package com.android.systemui.shade.transition
 
+import android.platform.test.annotations.DisableFlags
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.shade.STATE_OPENING
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.FakeSceneDataSource
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.shade.ShadeExpansionChangeEvent
+import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
+import com.android.systemui.shade.domain.interactor.panelExpansionInteractor
 import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -21,26 +50,140 @@
     @Mock private lateinit var scrimController: ScrimController
     @Mock private lateinit var dumpManager: DumpManager
 
-    private lateinit var controller: ScrimShadeTransitionController
+    private val shadeExpansionStateManager = ShadeExpansionStateManager()
+    private val kosmos = testKosmos()
+    private lateinit var testScope: TestScope
+    private lateinit var applicationScope: CoroutineScope
+    private lateinit var panelExpansionInteractor: PanelExpansionInteractor
+    private lateinit var deviceEntryRepository: FakeDeviceEntryRepository
+    private lateinit var deviceUnlockedInteractor: DeviceUnlockedInteractor
+    private lateinit var sceneInteractor: SceneInteractor
+    private lateinit var fakeSceneDataSource: FakeSceneDataSource
+
+    private lateinit var underTest: ScrimShadeTransitionController
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         context.ensureTestableResources()
-        controller = ScrimShadeTransitionController(dumpManager, scrimController)
-
-        controller.onPanelStateChanged(STATE_OPENING)
+        testScope = kosmos.testScope
+        applicationScope = kosmos.applicationCoroutineScope
+        panelExpansionInteractor = kosmos.panelExpansionInteractor
+        deviceEntryRepository = kosmos.fakeDeviceEntryRepository
+        deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor
+        sceneInteractor = kosmos.sceneInteractor
+        fakeSceneDataSource = kosmos.fakeSceneDataSource
+        underTest = ScrimShadeTransitionController(
+            applicationScope,
+            shadeExpansionStateManager,
+            { panelExpansionInteractor },
+            dumpManager,
+            scrimController,
+            )
+        underTest.init()
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
     fun onPanelExpansionChanged_setsFractionEqualToEventFraction() {
-        controller.onPanelExpansionChanged(EXPANSION_EVENT)
+        underTest.onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT)
 
-        verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction)
+        verify(scrimController).setRawPanelExpansionFraction(DEFAULT_EXPANSION_EVENT.fraction)
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
+    fun onPanelStateChanged_forwardsToScrimTransitionController() {
+        startLegacyPanelExpansion()
+
+        verify(scrimController).setRawPanelExpansionFraction(DEFAULT_EXPANSION_EVENT.fraction)
+    }
+
+    @Test
+    @EnableSceneContainer
+    fun sceneChanges_forwardsToScrimTransitionController() =
+        testScope.runTest {
+            var rawExpansion: Float? = null
+            whenever(scrimController.setRawPanelExpansionFraction(any())).then {
+                (it.arguments[0] as Float?).also { rawExp -> rawExpansion = rawExp }
+            }
+            setUnlocked(true)
+            val transitionState =
+                MutableStateFlow<ObservableTransitionState>(
+                    ObservableTransitionState.Idle(Scenes.Gone)
+                )
+            sceneInteractor.setTransitionState(transitionState)
+
+            changeScene(Scenes.Gone, transitionState)
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            Truth.assertThat(currentScene).isEqualTo(Scenes.Gone)
+
+            Truth.assertThat(rawExpansion)
+                    .isEqualTo(0f)
+
+            changeScene(Scenes.Shade, transitionState) { progress ->
+                Truth.assertThat(rawExpansion)
+                        .isEqualTo(progress)
+            }
+        }
+
+    private fun startLegacyPanelExpansion() {
+        shadeExpansionStateManager.onPanelExpansionChanged(
+            DEFAULT_EXPANSION_EVENT.fraction,
+            DEFAULT_EXPANSION_EVENT.expanded,
+            DEFAULT_EXPANSION_EVENT.tracking,
+            DEFAULT_EXPANSION_EVENT.dragDownPxAmount,
+        )
+    }
+
+    private fun TestScope.setUnlocked(isUnlocked: Boolean) {
+        val isDeviceUnlocked by collectLastValue(deviceUnlockedInteractor.isDeviceUnlocked)
+        deviceEntryRepository.setUnlocked(isUnlocked)
+        runCurrent()
+
+        Truth.assertThat(isDeviceUnlocked).isEqualTo(isUnlocked)
+    }
+
+    private fun TestScope.changeScene(
+        toScene: SceneKey,
+        transitionState: MutableStateFlow<ObservableTransitionState>,
+        assertDuringProgress: ((progress: Float) -> Unit) = {},
+    ) {
+        val currentScene by collectLastValue(sceneInteractor.currentScene)
+        val progressFlow = MutableStateFlow(0f)
+        transitionState.value =
+            ObservableTransitionState.Transition(
+                fromScene = checkNotNull(currentScene),
+                toScene = toScene,
+                progress = progressFlow,
+                isInitiatedByUserInput = true,
+                isUserInputOngoing = flowOf(true),
+            )
+        runCurrent()
+        assertDuringProgress(progressFlow.value)
+
+        progressFlow.value = 0.2f
+        runCurrent()
+        assertDuringProgress(progressFlow.value)
+
+        progressFlow.value = 0.6f
+        runCurrent()
+        assertDuringProgress(progressFlow.value)
+
+        progressFlow.value = 1f
+        runCurrent()
+        assertDuringProgress(progressFlow.value)
+
+        transitionState.value = ObservableTransitionState.Idle(toScene)
+        fakeSceneDataSource.changeScene(toScene)
+        runCurrent()
+        assertDuringProgress(progressFlow.value)
+
+        Truth.assertThat(currentScene).isEqualTo(toScene)
     }
 
     companion object {
-        val EXPANSION_EVENT =
+        val DEFAULT_EXPANSION_EVENT =
             ShadeExpansionChangeEvent(
                 fraction = 0.5f,
                 expanded = true,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
deleted file mode 100644
index 0a9541a..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
+++ /dev/null
@@ -1,217 +0,0 @@
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
-package com.android.systemui.shade.transition
-
-import android.platform.test.annotations.DisableFlags
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.compose.animation.scene.ObservableTransitionState
-import com.android.compose.animation.scene.SceneKey
-import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
-import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
-import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.EnableSceneContainer
-import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.model.FakeSceneDataSource
-import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.scene.shared.model.fakeSceneDataSource
-import com.android.systemui.shade.STATE_OPENING
-import com.android.systemui.shade.ShadeExpansionChangeEvent
-import com.android.systemui.shade.ShadeExpansionStateManager
-import com.android.systemui.shade.domain.interactor.panelExpansionInteractor
-import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.policy.FakeConfigurationController
-import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
-import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-class ShadeTransitionControllerTest : SysuiTestCase() {
-
-    @Mock private lateinit var scrimShadeTransitionController: ScrimShadeTransitionController
-    @Mock private lateinit var dumpManager: DumpManager
-    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
-
-    private lateinit var controller: ShadeTransitionController
-
-    private val configurationController = FakeConfigurationController()
-    private val shadeExpansionStateManager = ShadeExpansionStateManager()
-    private val kosmos = testKosmos()
-    private lateinit var testScope: TestScope
-    private lateinit var applicationScope: CoroutineScope
-    private lateinit var panelExpansionInteractor: PanelExpansionInteractor
-    private lateinit var deviceEntryRepository: FakeDeviceEntryRepository
-    private lateinit var deviceUnlockedInteractor: DeviceUnlockedInteractor
-    private lateinit var sceneInteractor: SceneInteractor
-    private lateinit var fakeSceneDataSource: FakeSceneDataSource
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        testScope = kosmos.testScope
-        applicationScope = kosmos.applicationCoroutineScope
-        panelExpansionInteractor = kosmos.panelExpansionInteractor
-        deviceEntryRepository = kosmos.fakeDeviceEntryRepository
-        deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor
-        sceneInteractor = kosmos.sceneInteractor
-        fakeSceneDataSource = kosmos.fakeSceneDataSource
-
-        controller =
-            ShadeTransitionController(
-                applicationScope,
-                configurationController,
-                shadeExpansionStateManager,
-                dumpManager,
-                context,
-                scrimShadeTransitionController,
-                statusBarStateController,
-                ResourcesSplitShadeStateController(),
-            ) {
-                panelExpansionInteractor
-            }
-    }
-
-    @Test
-    @DisableFlags(FLAG_SCENE_CONTAINER)
-    fun onPanelStateChanged_forwardsToScrimTransitionController() {
-        startLegacyPanelExpansion()
-
-        verify(scrimShadeTransitionController).onPanelStateChanged(STATE_OPENING)
-        verify(scrimShadeTransitionController).onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT)
-    }
-
-    @Test
-    @EnableSceneContainer
-    fun sceneChanges_forwardsToScrimTransitionController() =
-        testScope.runTest {
-            var latestChangeEvent: ShadeExpansionChangeEvent? = null
-            whenever(scrimShadeTransitionController.onPanelExpansionChanged(any())).thenAnswer {
-                latestChangeEvent = it.arguments[0] as ShadeExpansionChangeEvent
-                Unit
-            }
-            setUnlocked(true)
-            val transitionState =
-                MutableStateFlow<ObservableTransitionState>(
-                    ObservableTransitionState.Idle(Scenes.Gone)
-                )
-            sceneInteractor.setTransitionState(transitionState)
-
-            changeScene(Scenes.Gone, transitionState)
-            val currentScene by collectLastValue(sceneInteractor.currentScene)
-            assertThat(currentScene).isEqualTo(Scenes.Gone)
-
-            assertThat(latestChangeEvent)
-                .isEqualTo(
-                    ShadeExpansionChangeEvent(
-                        fraction = 0f,
-                        expanded = false,
-                        tracking = true,
-                        dragDownPxAmount = 0f,
-                    )
-                )
-
-            changeScene(Scenes.Shade, transitionState) { progress ->
-                assertThat(latestChangeEvent)
-                    .isEqualTo(
-                        ShadeExpansionChangeEvent(
-                            fraction = progress,
-                            expanded = progress > 0,
-                            tracking = true,
-                            dragDownPxAmount = 0f,
-                        )
-                    )
-            }
-        }
-
-    private fun startLegacyPanelExpansion() {
-        shadeExpansionStateManager.onPanelExpansionChanged(
-            DEFAULT_EXPANSION_EVENT.fraction,
-            DEFAULT_EXPANSION_EVENT.expanded,
-            DEFAULT_EXPANSION_EVENT.tracking,
-            DEFAULT_EXPANSION_EVENT.dragDownPxAmount,
-        )
-    }
-
-    private fun TestScope.setUnlocked(isUnlocked: Boolean) {
-        val isDeviceUnlocked by collectLastValue(deviceUnlockedInteractor.isDeviceUnlocked)
-        deviceEntryRepository.setUnlocked(isUnlocked)
-        runCurrent()
-
-        assertThat(isDeviceUnlocked).isEqualTo(isUnlocked)
-    }
-
-    private fun TestScope.changeScene(
-        toScene: SceneKey,
-        transitionState: MutableStateFlow<ObservableTransitionState>,
-        assertDuringProgress: ((progress: Float) -> Unit) = {},
-    ) {
-        val currentScene by collectLastValue(sceneInteractor.currentScene)
-        val progressFlow = MutableStateFlow(0f)
-        transitionState.value =
-            ObservableTransitionState.Transition(
-                fromScene = checkNotNull(currentScene),
-                toScene = toScene,
-                progress = progressFlow,
-                isInitiatedByUserInput = true,
-                isUserInputOngoing = flowOf(true),
-            )
-        runCurrent()
-        assertDuringProgress(progressFlow.value)
-
-        progressFlow.value = 0.2f
-        runCurrent()
-        assertDuringProgress(progressFlow.value)
-
-        progressFlow.value = 0.6f
-        runCurrent()
-        assertDuringProgress(progressFlow.value)
-
-        progressFlow.value = 1f
-        runCurrent()
-        assertDuringProgress(progressFlow.value)
-
-        transitionState.value = ObservableTransitionState.Idle(toScene)
-        fakeSceneDataSource.changeScene(toScene)
-        runCurrent()
-        assertDuringProgress(progressFlow.value)
-
-        assertThat(currentScene).isEqualTo(toScene)
-    }
-
-    companion object {
-        private const val DEFAULT_DRAG_DOWN_AMOUNT = 123f
-        private val DEFAULT_EXPANSION_EVENT =
-            ShadeExpansionChangeEvent(
-                fraction = 0.5f,
-                expanded = true,
-                tracking = true,
-                dragDownPxAmount = DEFAULT_DRAG_DOWN_AMOUNT
-            )
-    }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
index bbdb872..65e04f4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.shade.ShadeHeaderController
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.shadeController
+import com.android.systemui.shade.transition.ScrimShadeTransitionController
 import com.android.systemui.statusbar.policy.splitShadeStateController
 import com.android.systemui.util.mockito.mock
 
@@ -37,6 +38,7 @@
         shadeRepository = shadeRepository,
         controller = splitShadeStateController,
         shadeHeaderController = mock<ShadeHeaderController>(),
+        scrimShadeTransitionController = mock<ScrimShadeTransitionController>(),
         shadeController = shadeController
     )
 }