Use shared flow for transition animations

There was state incorrectly being shared between multiple
flows. Convert to a SharedFlow instead, to more efficiently reuse.

Also add optional animation logging in a new logbuffer.

Also convert all transition tests to use Kosmos.

Bug: 296373465
Test: atest com.android.keyguard.systemui.keyguard.ui.viewmodel
Flag: N/A
Change-Id: Ic0f507ad90b5c8a4643ab31cd24aa65a6686ecc0
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
index fd125e0..53bca48 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
@@ -19,14 +19,11 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import com.android.systemui.biometrics.shared.model.SensorStrength
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
 import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
 import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
@@ -38,16 +35,12 @@
 import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
 import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -55,223 +48,201 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: DreamingToLockscreenTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest =
-            DreamingToLockscreenTransitionViewModel(
-                interactor,
-                mock(),
-                DeviceEntryUdfpsInteractor(
-                    fingerprintPropertyRepository = fingerprintPropertyRepository,
-                    fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
-                    biometricSettingsRepository = FakeBiometricSettingsRepository(),
-                ),
-            )
-    }
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    private val underTest = kosmos.dreamingToLockscreenTransitionViewModel
 
     @Test
     fun dreamOverlayTranslationY() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
-
+        testScope.runTest {
             val pixels = 100
-            val job =
-                underTest.dreamOverlayTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+            val values by collectValues(underTest.dreamOverlayTranslationY(pixels))
 
-            repository.sendTransitionStep(step(0f, STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.5f))
-            repository.sendTransitionStep(step(0.6f))
-            repository.sendTransitionStep(step(0.8f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.3f),
+                    step(0.5f),
+                    step(0.6f),
+                    step(0.8f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(7)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 100f)) }
-
-            job.cancel()
         }
 
     @Test
     fun dreamOverlayFadeOut() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
+        testScope.runTest {
+            val values by collectValues(underTest.dreamOverlayAlpha)
 
-            val job = underTest.dreamOverlayAlpha.onEach { values.add(it) }.launchIn(this)
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    // Should start running here...
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.1f),
+                    step(0.5f),
+                    // ...up to here
+                    step(1f),
+                ),
+                testScope,
+            )
 
-            // Should start running here...
-            repository.sendTransitionStep(step(0f, STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.5f))
-            // ...up to here
-            repository.sendTransitionStep(step(1f))
-
-            // Only two values should be present, since the dream overlay runs for a small fraction
-            // of the overall animation time
             assertThat(values.size).isEqualTo(4)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
-
-            job.cancel()
         }
 
     @Test
     fun lockscreenFadeIn() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
+        testScope.runTest {
+            val values by collectValues(underTest.lockscreenAlpha)
 
-            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.2f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.1f),
+                    step(0.2f),
+                    step(0.3f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(4)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
-
-            job.cancel()
         }
 
     @Test
     fun deviceEntryParentViewFadeIn() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
+        testScope.runTest {
+            val values by collectValues(underTest.deviceEntryParentViewAlpha)
 
-            val job = underTest.deviceEntryParentViewAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.2f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.1f),
+                    step(0.2f),
+                    step(0.3f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(4)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
-
-            job.cancel()
         }
 
     @Test
     fun deviceEntryBackgroundViewAppear() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             fingerprintPropertyRepository.setProperties(
                 sensorId = 0,
                 strength = SensorStrength.STRONG,
                 sensorType = FingerprintSensorType.UDFPS_OPTICAL,
                 sensorLocations = emptyMap(),
             )
-            val values = mutableListOf<Float>()
+            val values by collectValues(underTest.deviceEntryBackgroundViewAlpha)
 
-            val job =
-                underTest.deviceEntryBackgroundViewAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.2f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.1f),
+                    step(0.2f),
+                    step(0.3f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             values.forEach { assertThat(it).isEqualTo(1f) }
-
-            job.cancel()
         }
 
     @Test
     fun deviceEntryBackground_noUdfps_noUpdates() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             fingerprintPropertyRepository.setProperties(
                 sensorId = 0,
                 strength = SensorStrength.STRONG,
                 sensorType = FingerprintSensorType.REAR,
                 sensorLocations = emptyMap(),
             )
-            val values = mutableListOf<Float>()
+            val values by collectValues(underTest.deviceEntryBackgroundViewAlpha)
 
-            val job =
-                underTest.deviceEntryBackgroundViewAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.2f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.1f),
+                    step(0.2f),
+                    step(0.3f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(0) // no updates
-
-            job.cancel()
         }
 
     @Test
     fun lockscreenTranslationY() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
-
+        testScope.runTest {
             val pixels = 100
-            val job =
-                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+            val values by collectValues(underTest.lockscreenTranslationY(pixels))
 
-            repository.sendTransitionStep(step(0f, STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.5f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.3f),
+                    step(0.5f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(5)
             values.forEach { assertThat(it).isIn(Range.closed(-100f, 0f)) }
-
-            job.cancel()
         }
 
     @Test
     fun transitionEnded() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<TransitionStep>()
+        testScope.runTest {
+            val values by collectValues(underTest.transitionEnded)
 
-            val job = underTest.transitionEnded.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(TransitionStep(DOZING, DREAMING, 0.0f, STARTED))
-            repository.sendTransitionStep(TransitionStep(DOZING, DREAMING, 1.0f, FINISHED))
-
-            repository.sendTransitionStep(TransitionStep(DREAMING, LOCKSCREEN, 0.0f, STARTED))
-            repository.sendTransitionStep(TransitionStep(DREAMING, LOCKSCREEN, 0.1f, RUNNING))
-            repository.sendTransitionStep(TransitionStep(DREAMING, LOCKSCREEN, 1.0f, FINISHED))
-
-            repository.sendTransitionStep(TransitionStep(LOCKSCREEN, DREAMING, 0.0f, STARTED))
-            repository.sendTransitionStep(TransitionStep(LOCKSCREEN, DREAMING, 0.5f, RUNNING))
-            repository.sendTransitionStep(TransitionStep(LOCKSCREEN, DREAMING, 1.0f, FINISHED))
-
-            repository.sendTransitionStep(TransitionStep(DREAMING, GONE, 0.0f, STARTED))
-            repository.sendTransitionStep(TransitionStep(DREAMING, GONE, 0.5f, RUNNING))
-            repository.sendTransitionStep(TransitionStep(DREAMING, GONE, 1.0f, CANCELED))
-
-            repository.sendTransitionStep(TransitionStep(DREAMING, AOD, 0.0f, STARTED))
-            repository.sendTransitionStep(TransitionStep(DREAMING, AOD, 1.0f, FINISHED))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    TransitionStep(DOZING, DREAMING, 0.0f, STARTED),
+                    TransitionStep(DOZING, DREAMING, 1.0f, FINISHED),
+                    TransitionStep(DREAMING, LOCKSCREEN, 0.0f, STARTED),
+                    TransitionStep(DREAMING, LOCKSCREEN, 0.1f, RUNNING),
+                    TransitionStep(DREAMING, LOCKSCREEN, 1.0f, FINISHED),
+                    TransitionStep(LOCKSCREEN, DREAMING, 0.0f, STARTED),
+                    TransitionStep(LOCKSCREEN, DREAMING, 0.5f, RUNNING),
+                    TransitionStep(LOCKSCREEN, DREAMING, 1.0f, FINISHED),
+                    TransitionStep(DREAMING, GONE, 0.0f, STARTED),
+                    TransitionStep(DREAMING, GONE, 0.5f, RUNNING),
+                    TransitionStep(DREAMING, GONE, 1.0f, CANCELED),
+                    TransitionStep(DREAMING, AOD, 0.0f, STARTED),
+                    TransitionStep(DREAMING, AOD, 1.0f, FINISHED),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(3)
             values.forEach {
                 assertThat(it.transitionState == FINISHED || it.transitionState == CANCELED)
                     .isTrue()
             }
-
-            job.cancel()
         }
 
     private fun step(value: Float, state: TransitionState = RUNNING): TransitionStep {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
index cf20129..3c07034 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
@@ -19,85 +19,73 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class GoneToDreamingTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: GoneToDreamingTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest = GoneToDreamingTransitionViewModel(interactor)
-    }
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardTransitionRepository
+    private val underTest = kosmos.goneToDreamingTransitionViewModel
 
     @Test
-    fun lockscreenFadeOut() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
+    fun runTest() =
+        testScope.runTest {
+            val values by collectValues(underTest.lockscreenAlpha)
 
-            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
-
-            // Should start running here...
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.2f))
-            repository.sendTransitionStep(step(0.3f))
-            // ...up to here
-            repository.sendTransitionStep(step(1f))
+            repository.sendTransitionSteps(
+                listOf(
+                    // Should start running here...
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.1f),
+                    step(0.2f),
+                    step(0.3f),
+                    // ...up to here
+                    step(1f),
+                ),
+                testScope,
+            )
 
             // Only three values should be present, since the dream overlay runs for a small
             // fraction of the overall animation time
             assertThat(values.size).isEqualTo(5)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
-
-            job.cancel()
         }
 
     @Test
     fun lockscreenTranslationY() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
-
+        testScope.runTest {
             val pixels = 100
-            val job =
-                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+            val values by collectValues(underTest.lockscreenTranslationY(pixels))
 
-            // Should start running here...
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.5f))
-            // And a final reset event on CANCEL
-            repository.sendTransitionStep(step(0.8f, TransitionState.CANCELED))
+            repository.sendTransitionSteps(
+                listOf(
+                    // Should start running here...
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.3f),
+                    step(0.5f),
+                    // And a final reset event on CANCEL
+                    step(0.8f, TransitionState.CANCELED)
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(5)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 100f)) }
-
-            job.cancel()
         }
 
     private fun step(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
index ba72b4c..9226c0d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.flags.featureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionState
@@ -55,11 +54,7 @@
     private val repository = kosmos.fakeKeyguardTransitionRepository
     private val shadeRepository = kosmos.shadeRepository
     private val keyguardRepository = kosmos.fakeKeyguardRepository
-    private val underTest =
-        LockscreenToDreamingTransitionViewModel(
-            interactor = kosmos.keyguardTransitionInteractor,
-            shadeDependentFlows = kosmos.shadeDependentFlows,
-        )
+    private val underTest = kosmos.lockscreenToDreamingTransitionViewModel
 
     @Test
     fun lockscreenFadeOut() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
index fafe74e..bcad72b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -21,19 +21,19 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.featureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.testKosmos
 import com.google.common.collect.Range
@@ -55,11 +55,8 @@
     private val repository = kosmos.fakeKeyguardTransitionRepository
     private val shadeRepository = kosmos.shadeRepository
     private val keyguardRepository = kosmos.fakeKeyguardRepository
-    private val underTest =
-        LockscreenToOccludedTransitionViewModel(
-            interactor = kosmos.keyguardTransitionInteractor,
-            shadeDependentFlows = kosmos.shadeDependentFlows,
-        )
+    private val configurationRepository = kosmos.fakeConfigurationRepository
+    private val underTest = kosmos.lockscreenToOccludedTransitionViewModel
 
     @Test
     fun lockscreenFadeOut() =
@@ -86,8 +83,11 @@
     @Test
     fun lockscreenTranslationY() =
         testScope.runTest {
-            val pixels = 100
-            val values by collectValues(underTest.lockscreenTranslationY(pixels))
+            configurationRepository.setDimensionPixelSize(
+                R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y,
+                100
+            )
+            val values by collectValues(underTest.lockscreenTranslationY)
             repository.sendTransitionSteps(
                 steps =
                     listOf(
@@ -106,8 +106,11 @@
     @Test
     fun lockscreenTranslationYIsCanceled() =
         testScope.runTest {
-            val pixels = 100
-            val values by collectValues(underTest.lockscreenTranslationY(pixels))
+            configurationRepository.setDimensionPixelSize(
+                R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y,
+                100
+            )
+            val values by collectValues(underTest.lockscreenTranslationY)
             repository.sendTransitionSteps(
                 steps =
                     listOf(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
index 02f01bf..d419d4a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
@@ -19,197 +19,161 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.util.mockito.whenever
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
 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.anyInt
-import org.mockito.MockitoAnnotations
 
 @ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: OccludedToLockscreenTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-    private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
-    @Mock private lateinit var configurationInteractor: ConfigurationInteractor
-    private val dimenFlow = MutableStateFlow(0)
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        repository = FakeKeyguardTransitionRepository()
-        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
-        whenever(configurationInteractor.dimensionPixelSize(anyInt())).thenReturn(dimenFlow)
-        underTest =
-            OccludedToLockscreenTransitionViewModel(
-                interactor =
-                    KeyguardTransitionInteractorFactory.create(
-                            scope = TestScope().backgroundScope,
-                            repository = repository,
-                        )
-                        .keyguardTransitionInteractor,
-                deviceEntryUdfpsInteractor =
-                    DeviceEntryUdfpsInteractor(
-                        fingerprintPropertyRepository = fingerprintPropertyRepository,
-                        fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
-                        biometricSettingsRepository = biometricSettingsRepository,
-                    ),
-                configurationInteractor,
-            )
-    }
+    val biometricSettingsRepository = kosmos.biometricSettingsRepository
+    val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    val configurationRepository = kosmos.fakeConfigurationRepository
+    val underTest = kosmos.occludedToLockscreenTransitionViewModel
 
     @Test
     fun lockscreenFadeIn() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
+        testScope.runTest {
+            val values by collectValues(underTest.lockscreenAlpha)
 
-            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.1f))
-            // Should start running here...
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.4f))
-            repository.sendTransitionStep(step(0.5f))
-            repository.sendTransitionStep(step(0.6f))
-            // ...up to here
-            repository.sendTransitionStep(step(0.8f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.1f),
+                    // Should start running here...
+                    step(0.3f),
+                    step(0.4f),
+                    step(0.5f),
+                    step(0.6f),
+                    // ...up to here
+                    step(0.8f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(5)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
-
-            job.cancel()
         }
 
     @Test
     fun lockscreenTranslationY() =
-        runTest(UnconfinedTestDispatcher()) {
-            dimenFlow.value = 100
-            val values = mutableListOf<Float>()
+        testScope.runTest {
+            configurationRepository.setDimensionPixelSize(
+                R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y,
+                100
+            )
+            val values by collectValues(underTest.lockscreenTranslationY)
 
-            val job = underTest.lockscreenTranslationY.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.5f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0f),
+                    step(0.3f),
+                    step(0.5f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(5)
             values.forEach { assertThat(it).isIn(Range.closed(-100f, 0f)) }
-
-            job.cancel()
         }
 
     @Test
     fun lockscreenTranslationYResettedAfterJobCancelled() =
-        runTest(UnconfinedTestDispatcher()) {
-            dimenFlow.value = 100
-            val values = mutableListOf<Float>()
+        testScope.runTest {
+            configurationRepository.setDimensionPixelSize(
+                R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y,
+                100
+            )
+            val values by collectValues(underTest.lockscreenTranslationY)
 
-            val job = underTest.lockscreenTranslationY.onEach { values.add(it) }.launchIn(this)
-            repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED))
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f, TransitionState.CANCELED))
 
             assertThat(values.last()).isEqualTo(0f)
-
-            job.cancel()
         }
 
     @Test
     fun deviceEntryParentViewFadeIn() =
-        runTest(UnconfinedTestDispatcher()) {
-            val values = mutableListOf<Float>()
+        testScope.runTest {
+            val values by collectValues(underTest.deviceEntryParentViewAlpha)
 
-            val job = underTest.deviceEntryParentViewAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.1f))
-            // Should start running here...
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.4f))
-            repository.sendTransitionStep(step(0.5f))
-            repository.sendTransitionStep(step(0.6f))
-            // ...up to here
-            repository.sendTransitionStep(step(0.8f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.1f),
+                    // Should start running here...
+                    step(0.3f),
+                    step(0.4f),
+                    step(0.5f),
+                    step(0.6f),
+                    // ...up to here
+                    step(0.8f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(5)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
-
-            job.cancel()
         }
 
     @Test
     fun deviceEntryBackgroundViewShows() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             fingerprintPropertyRepository.supportsUdfps()
             biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-            val values = mutableListOf<Float>()
+            val values by collectValues(underTest.deviceEntryBackgroundViewAlpha)
 
-            val job =
-                underTest.deviceEntryBackgroundViewAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.4f))
-            repository.sendTransitionStep(step(0.5f))
-            repository.sendTransitionStep(step(0.6f))
-            repository.sendTransitionStep(step(0.8f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            keyguardTransitionRepository.sendTransitionStep(step(0.1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.3f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.4f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.6f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.8f))
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
 
             values.forEach { assertThat(it).isEqualTo(1f) }
-
-            job.cancel()
         }
 
     @Test
     fun deviceEntryBackgroundView_noUdfpsEnrolled_noUpdates() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             fingerprintPropertyRepository.supportsRearFps()
             biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-            val values = mutableListOf<Float>()
+            val values by collectValues(underTest.deviceEntryBackgroundViewAlpha)
 
-            val job =
-                underTest.deviceEntryBackgroundViewAlpha.onEach { values.add(it) }.launchIn(this)
-
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.1f))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.4f))
-            repository.sendTransitionStep(step(0.5f))
-            repository.sendTransitionStep(step(0.6f))
-            repository.sendTransitionStep(step(0.8f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            keyguardTransitionRepository.sendTransitionStep(step(0.1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.3f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.4f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.6f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.8f))
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
 
             assertThat(values).isEmpty() // no updates
-
-            job.cancel()
         }
 
     private fun step(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
index 6cab023..78d87a6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
@@ -19,80 +19,61 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.sysuiStatusBarStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
-import dagger.Lazy
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
 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.MockitoAnnotations
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: PrimaryBouncerToGoneTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var featureFlags: FakeFeatureFlags
-    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
-    @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
-    @Mock private lateinit var bouncerToGoneFlows: BouncerToGoneFlows
-    @Mock
-    private lateinit var keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>
+    val kosmos =
+        testKosmos().apply {
+            featureFlagsClassic.apply {
+                set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false)
+                set(Flags.FULL_SCREEN_USER_SWITCHER, false)
+            }
+        }
+    val testScope = kosmos.testScope
 
-    private val shadeExpansionStateFlow = MutableStateFlow(0.1f)
+    val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    val primaryBouncerInteractor = kosmos.primaryBouncerInteractor
+    val sysuiStatusBarStateController = kosmos.sysuiStatusBarStateController
+    val underTest = kosmos.primaryBouncerToGoneTransitionViewModel
 
     @Before
     fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        repository = FakeKeyguardTransitionRepository()
-        val featureFlags =
-            FakeFeatureFlags().apply { set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false) }
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest =
-            PrimaryBouncerToGoneTransitionViewModel(
-                interactor,
-                statusBarStateController,
-                primaryBouncerInteractor,
-                keyguardDismissActionInteractor,
-                featureFlags,
-                bouncerToGoneFlows,
-            )
-
         whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(false)
-        whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false)
+        sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(false)
     }
 
     @Test
     fun bouncerAlpha() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.bouncerAlpha)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.6f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.3f),
+                    step(0.6f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(3)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
@@ -100,14 +81,19 @@
 
     @Test
     fun bouncerAlpha_runDimissFromKeyguard() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.bouncerAlpha)
 
             whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.6f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.3f),
+                    step(0.6f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(3)
             values.forEach { assertThat(it).isEqualTo(0f) }
@@ -115,11 +101,11 @@
 
     @Test
     fun lockscreenAlpha() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.lockscreenAlpha)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
 
             assertThat(values.size).isEqualTo(2)
             values.forEach { assertThat(it).isEqualTo(0f) }
@@ -127,13 +113,13 @@
 
     @Test
     fun lockscreenAlpha_runDimissFromKeyguard() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.lockscreenAlpha)
 
-            whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true)
+            sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
 
             assertThat(values.size).isEqualTo(2)
             values.forEach { assertThat(it).isEqualTo(1f) }
@@ -141,13 +127,13 @@
 
     @Test
     fun lockscreenAlpha_leaveShadeOpen() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.lockscreenAlpha)
 
-            whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(true)
+            sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
 
             assertThat(values.size).isEqualTo(2)
             values.forEach { assertThat(it).isEqualTo(1f) }
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardTransitionAnimationLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardTransitionAnimationLogger.kt
new file mode 100644
index 0000000..d9830b2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardTransitionAnimationLogger.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 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.keyguard.logging
+
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.KeyguardTransitionAnimationLog
+import javax.inject.Inject
+
+private const val TAG = "KeyguardTransitionAnimationLog"
+
+/**
+ * Generic logger for keyguard that's wrapping [LogBuffer]. This class should be used for adding
+ * temporary logs or logs for smaller classes when creating whole new [LogBuffer] wrapper might be
+ * an overkill.
+ */
+class KeyguardTransitionAnimationLogger
+@Inject
+constructor(
+    @KeyguardTransitionAnimationLog val buffer: LogBuffer,
+) {
+    @JvmOverloads
+    fun logCreate(
+        name: String? = null,
+        start: Float,
+    ) {
+        if (name == null) return
+
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = name
+                str2 = "$start"
+            },
+            { "[$str1] starts at: $str2" }
+        )
+    }
+
+    @JvmOverloads
+    fun logTransitionStep(
+        name: String? = null,
+        step: TransitionStep,
+        value: Float? = null,
+    ) {
+        if (name == null) return
+
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = "[$name][${step.transitionState}]"
+                str2 = "${step.value}"
+                str3 = "$value"
+            },
+            { "$str1 transitionStep=$str2, animationValue=$str3" }
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index 5c76be8..0e487d2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -103,7 +103,7 @@
     private val _transitions =
         MutableSharedFlow<TransitionStep>(
             replay = 2,
-            extraBufferCapacity = 10,
+            extraBufferCapacity = 20,
             onBufferOverflow = BufferOverflow.DROP_OLDEST,
         )
     override val transitions = _transitions.asSharedFlow().distinctUntilChanged()
@@ -227,10 +227,7 @@
 
     private fun emitTransition(nextStep: TransitionStep, isManual: Boolean = false) {
         logAndTrace(nextStep, isManual)
-        val emitted = _transitions.tryEmit(nextStep)
-        if (!emitted) {
-            Log.w(TAG, "Failed to emit next value without suspending")
-        }
+        _transitions.tryEmit(nextStep)
         lastStep = nextStep
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
index d5ad7ab..64ff3b0c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
@@ -17,97 +17,134 @@
 
 import android.view.animation.Interpolator
 import com.android.app.animation.Interpolators.LINEAR
+import com.android.keyguard.logging.KeyguardTransitionAnimationLogger
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
 import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
 import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
 import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import javax.inject.Inject
 import kotlin.math.max
 import kotlin.math.min
 import kotlin.time.Duration
 import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.shareIn
 
 /**
- * For the given transition params, construct a flow using [createFlow] for the specified portion of
- * the overall transition.
+ * Assists in creating sub-flows for a KeyguardTransition. Call [setup] once for a transition, and
+ * then [sharedFlow] for each sub animation that should be trigged when the overall transition runs.
  */
-class KeyguardTransitionAnimationFlow(
-    private val transitionDuration: Duration,
-    private val transitionFlow: Flow<TransitionStep>,
+@SysUISingleton
+class KeyguardTransitionAnimationFlow
+@Inject
+constructor(
+    @Application private val scope: CoroutineScope,
+    private val logger: KeyguardTransitionAnimationLogger,
 ) {
+
     /**
-     * Transitions will occur over a [transitionDuration] with [TransitionStep]s being emitted in
-     * the range of [0, 1]. View animations should begin and end within a subset of this range. This
-     * function maps the [startTime] and [duration] into [0, 1], when this subset is valid.
+     * Invoke once per transition between FROM->TO states to get access to
+     * [SharedFlowBuilder#sharedFlow].
      */
-    fun createFlow(
+    fun setup(
         duration: Duration,
-        onStep: (Float) -> Float,
-        startTime: Duration = 0.milliseconds,
-        onStart: (() -> Unit)? = null,
-        onCancel: (() -> Float)? = null,
-        onFinish: (() -> Float)? = null,
-        interpolator: Interpolator = LINEAR,
-    ): Flow<Float> {
-        if (!duration.isPositive()) {
-            throw IllegalArgumentException("duration must be a positive number: $duration")
-        }
-        if ((startTime + duration).compareTo(transitionDuration) > 0) {
-            throw IllegalArgumentException(
-                "startTime($startTime) + duration($duration) must be" +
-                    " <= transitionDuration($transitionDuration)"
-            )
-        }
+        stepFlow: Flow<TransitionStep>,
+    ) = SharedFlowBuilder(duration, stepFlow)
 
-        val start = (startTime / transitionDuration).toFloat()
-        val chunks = (transitionDuration / duration).toFloat()
-        var isComplete = true
-
-        fun stepToValue(step: TransitionStep): Float? {
-            val value = (step.value - start) * chunks
-            return when (step.transitionState) {
-                // When starting, make sure to always emit. If a transition is started from the
-                // middle, it is possible this animation is being skipped but we need to inform
-                // the ViewModels of the last update
-                STARTED -> {
-                    isComplete = false
-                    onStart?.invoke()
-                    max(0f, min(1f, value))
-                }
-                // Always send a final value of 1. Because of rounding, [value] may never be
-                // exactly 1.
-                RUNNING ->
-                    if (isComplete) {
-                        null
-                    } else if (value >= 1f) {
-                        isComplete = true
-                        1f
-                    } else if (value >= 0f) {
-                        value
-                    } else {
-                        null
-                    }
-                else -> null
-            }?.let { onStep(interpolator.getInterpolation(it)) }
-        }
-
-        return transitionFlow
-            .map { step ->
-                when (step.transitionState) {
-                    STARTED -> stepToValue(step)
-                    RUNNING -> stepToValue(step)
-                    CANCELED -> onCancel?.invoke()
-                    FINISHED -> onFinish?.invoke()
-                }
+    inner class SharedFlowBuilder(
+        private val transitionDuration: Duration,
+        private val stepFlow: Flow<TransitionStep>,
+    ) {
+        /**
+         * Transitions will occur over a [transitionDuration] with [TransitionStep]s being emitted
+         * in the range of [0, 1]. View animations should begin and end within a subset of this
+         * range. This function maps the [startTime] and [duration] into [0, 1], when this subset is
+         * valid.
+         *
+         * Will produce a [SharedFlow], so that identical animations can use the same value.
+         */
+        fun sharedFlow(
+            duration: Duration,
+            onStep: (Float) -> Float,
+            startTime: Duration = 0.milliseconds,
+            onStart: (() -> Unit)? = null,
+            onCancel: (() -> Float)? = null,
+            onFinish: (() -> Float)? = null,
+            interpolator: Interpolator = LINEAR,
+            name: String? = null
+        ): SharedFlow<Float> {
+            if (!duration.isPositive()) {
+                throw IllegalArgumentException("duration must be a positive number: $duration")
             }
-            .filterNotNull()
-    }
+            if ((startTime + duration).compareTo(transitionDuration) > 0) {
+                throw IllegalArgumentException(
+                    "startTime($startTime) + duration($duration) must be" +
+                        " <= transitionDuration($transitionDuration)"
+                )
+            }
 
-    /** Immediately (after 1ms) emits the given value for every step of the KeyguardTransition. */
-    fun immediatelyTransitionTo(value: Float): Flow<Float> {
-        return createFlow(duration = 1.milliseconds, onStep = { value }, onFinish = { value })
+            val start = (startTime / transitionDuration).toFloat()
+            val chunks = (transitionDuration / duration).toFloat()
+            logger.logCreate(name, start)
+            var isComplete = true
+
+            fun stepToValue(step: TransitionStep): Float? {
+                val value = (step.value - start) * chunks
+                return when (step.transitionState) {
+                    // When starting, make sure to always emit. If a transition is started from the
+                    // middle, it is possible this animation is being skipped but we need to inform
+                    // the ViewModels of the last update
+                    STARTED -> {
+                        isComplete = false
+                        onStart?.invoke()
+                        max(0f, min(1f, value))
+                    }
+                    // Always send a final value of 1. Because of rounding, [value] may never be
+                    // exactly 1.
+                    RUNNING ->
+                        if (isComplete) {
+                            null
+                        } else if (value >= 1f) {
+                            isComplete = true
+                            1f
+                        } else if (value >= 0f) {
+                            value
+                        } else {
+                            null
+                        }
+                    else -> null
+                }?.let { onStep(interpolator.getInterpolation(it)) }
+            }
+
+            return stepFlow
+                .map { step ->
+                    val value =
+                        when (step.transitionState) {
+                            STARTED -> stepToValue(step)
+                            RUNNING -> stepToValue(step)
+                            CANCELED -> onCancel?.invoke()
+                            FINISHED -> onFinish?.invoke()
+                        }
+                    logger.logTransitionStep(name, step, value)
+                    value
+                }
+                .filterNotNull()
+                .shareIn(scope, SharingStarted.WhileSubscribed())
+        }
+
+        /**
+         * Immediately (after 1ms) emits the given value for every step of the KeyguardTransition.
+         */
+        fun immediatelyTransitionTo(value: Float): Flow<Float> {
+            return sharedFlow(duration = 1.milliseconds, onStep = { value }, onFinish = { value })
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
index bb7bcd9..8e729f7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
@@ -38,15 +38,17 @@
 constructor(
     private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
     transitionInteractor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
     // When we're fully transitioned to the AlternateBouncer, the alpha of the scrim should be:
     private val alternateBouncerScrimAlpha = .66f
     private val toAlternateBouncerTransition =
-        KeyguardTransitionAnimationFlow(
-                transitionDuration = TRANSITION_DURATION_MS,
-                transitionFlow = transitionInteractor.anyStateToAlternateBouncerTransition,
+        animationFlow
+            .setup(
+                duration = TRANSITION_DURATION_MS,
+                stepFlow = transitionInteractor.anyStateToAlternateBouncerTransition,
             )
-            .createFlow(
+            .sharedFlow(
                 duration = TRANSITION_DURATION_MS,
                 onStep = { it },
                 onFinish = { 1f },
@@ -55,11 +57,12 @@
                 interpolator = Interpolators.FAST_OUT_SLOW_IN,
             )
     private val fromAlternateBouncerTransition =
-        KeyguardTransitionAnimationFlow(
-                transitionDuration = TRANSITION_DURATION_MS,
-                transitionFlow = transitionInteractor.transitionStepsFromState(ALTERNATE_BOUNCER),
+        animationFlow
+            .setup(
+                TRANSITION_DURATION_MS,
+                transitionInteractor.transitionStepsFromState(ALTERNATE_BOUNCER),
             )
-            .createFlow(
+            .sharedFlow(
                 duration = TRANSITION_DURATION_MS,
                 onStep = { 1f - it },
                 // Reset on cancel
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModel.kt
index 4d2af0c..2b14521 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModel.kt
@@ -32,12 +32,13 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromAodTransitionInteractor.TO_GONE_DURATION,
-            transitionFlow = interactor.transition(KeyguardState.AOD, KeyguardState.GONE),
+        animationFlow.setup(
+            duration = FromAodTransitionInteractor.TO_GONE_DURATION,
+            stepFlow = interactor.transition(KeyguardState.AOD, KeyguardState.GONE),
         )
 
     override val deviceEntryParentViewAlpha = transitionAnimation.immediatelyTransitionTo(0f)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
index 1864437..5e552e1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
@@ -39,24 +39,25 @@
 constructor(
     interactor: KeyguardTransitionInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_LOCKSCREEN_DURATION,
-            transitionFlow = interactor.aodToLockscreenTransition,
+        animationFlow.setup(
+            duration = TO_LOCKSCREEN_DURATION,
+            stepFlow = interactor.aodToLockscreenTransition,
         )
 
     /** Ensure alpha is set to be visible */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 500.milliseconds,
             onStart = { 1f },
             onStep = { 1f },
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 167.milliseconds,
             startTime = 67.milliseconds,
             onStep = { it },
@@ -67,7 +68,7 @@
         deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { isUdfps ->
             if (isUdfps) {
                 // fade in
-                transitionAnimation.createFlow(
+                transitionAnimation.sharedFlow(
                     duration = 250.milliseconds,
                     onStep = { it },
                     onFinish = { 1f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt
index 06661d0..d283af3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt
@@ -30,11 +30,12 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromAodTransitionInteractor.TO_OCCLUDED_DURATION,
-            transitionFlow = interactor.transition(KeyguardState.AOD, KeyguardState.OCCLUDED),
+        animationFlow.setup(
+            duration = FromAodTransitionInteractor.TO_OCCLUDED_DURATION,
+            stepFlow = interactor.transition(KeyguardState.AOD, KeyguardState.OCCLUDED),
         )
 
     override val deviceEntryParentViewAlpha = transitionAnimation.immediatelyTransitionTo(0f)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
index da74f2f..41dc157 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
@@ -47,6 +47,7 @@
     private val keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>,
     private val featureFlags: FeatureFlagsClassic,
     private val shadeInteractor: ShadeInteractor,
+    private val animationFlow: KeyguardTransitionAnimationFlow,
 ) {
     /** Common fade for scrim alpha values during *BOUNCER->GONE */
     fun scrimAlpha(duration: Duration, fromState: KeyguardState): Flow<ScrimAlpha> {
@@ -73,14 +74,14 @@
         var leaveShadeOpen: Boolean = false
         var willRunDismissFromKeyguard: Boolean = false
         val transitionAnimation =
-            KeyguardTransitionAnimationFlow(
-                transitionDuration = duration,
-                transitionFlow = interactor.transition(fromState, GONE)
+            animationFlow.setup(
+                duration = duration,
+                stepFlow = interactor.transition(fromState, GONE)
             )
 
         return shadeInteractor.shadeExpansion.flatMapLatest { shadeExpansion ->
             transitionAnimation
-                .createFlow(
+                .sharedFlow(
                     duration = duration,
                     interpolator = EMPHASIZED_ACCELERATE,
                     onStart = {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index 5b5a103..bd6aae8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -57,7 +57,6 @@
     private val sceneContainerFlags: SceneContainerFlags,
     private val keyguardViewController: Lazy<KeyguardViewController>,
     private val deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor,
-    udfpsInteractor: DeviceEntryUdfpsInteractor,
     private val deviceEntryInteractor: DeviceEntryInteractor,
 ) {
     private val intEvaluator = IntEvaluator()
@@ -149,7 +148,7 @@
         }
     val iconType: Flow<DeviceEntryIconView.IconType> =
         combine(
-            udfpsInteractor.isListeningForUdfps,
+            deviceEntryUdfpsInteractor.isListeningForUdfps,
             deviceEntryInteractor.isUnlocked,
         ) { isListeningForUdfps, isUnlocked ->
             if (isUnlocked) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
index a728a28..0b34326 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
@@ -35,15 +35,16 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
-    private val transitionAnimation: KeyguardTransitionAnimationFlow =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromDozingTransitionInteractor.TO_LOCKSCREEN_DURATION,
-            transitionFlow = interactor.dozingToLockscreenTransition,
+    private val transitionAnimation =
+        animationFlow.setup(
+            duration = FromDozingTransitionInteractor.TO_LOCKSCREEN_DURATION,
+            stepFlow = interactor.dozingToLockscreenTransition,
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 150.milliseconds,
             onStep = { it },
             onCancel = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
index 58235ae..8bcf3f8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
@@ -29,16 +29,17 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_LOCKSCREEN_DURATION,
-            transitionFlow = interactor.dreamingLockscreenHostedToLockscreenTransition
+        animationFlow.setup(
+            duration = TO_LOCKSCREEN_DURATION,
+            stepFlow = interactor.dreamingLockscreenHostedToLockscreenTransition,
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { it },
             onCancel = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
index f943bdf..5f620af 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
@@ -45,13 +45,14 @@
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val fromDreamingTransitionInteractor: FromDreamingTransitionInteractor,
     private val deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
     fun startTransition() = fromDreamingTransitionInteractor.startToLockscreenTransition()
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_LOCKSCREEN_DURATION,
-            transitionFlow = keyguardTransitionInteractor.dreamingToLockscreenTransition,
+        animationFlow.setup(
+            duration = TO_LOCKSCREEN_DURATION,
+            stepFlow = keyguardTransitionInteractor.dreamingToLockscreenTransition,
         )
 
     val transitionEnded =
@@ -62,7 +63,7 @@
 
     /** Dream overlay y-translation on exit */
     fun dreamOverlayTranslationY(translatePx: Int): Flow<Float> {
-        return transitionAnimation.createFlow(
+        return transitionAnimation.sharedFlow(
             duration = TO_LOCKSCREEN_DURATION,
             onStep = { it * translatePx },
             interpolator = EMPHASIZED,
@@ -71,14 +72,14 @@
 
     /** Dream overlay views alpha - fade out */
     val dreamOverlayAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1f - it },
         )
 
     /** Lockscreen views y-translation */
     fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
-        return transitionAnimation.createFlow(
+        return transitionAnimation.sharedFlow(
             duration = TO_LOCKSCREEN_DURATION,
             onStep = { value -> -translatePx + value * translatePx },
             // Reset on cancel or finish
@@ -90,14 +91,14 @@
 
     /** Lockscreen views alpha */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             startTime = 233.milliseconds,
             duration = 250.milliseconds,
             onStep = { it },
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             startTime = 233.milliseconds,
             duration = 250.milliseconds,
             onStep = { it },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
index 62b2281..3f27eb0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
@@ -38,17 +38,18 @@
 constructor(
     interactor: KeyguardTransitionInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_AOD_DURATION,
-            transitionFlow = interactor.goneToAodTransition,
+        animationFlow.setup(
+            duration = TO_AOD_DURATION,
+            stepFlow = interactor.goneToAodTransition,
         )
 
     /** y-translation from the top of the screen for AOD */
     fun enterFromTopTranslationY(translatePx: Int): Flow<Float> {
-        return transitionAnimation.createFlow(
+        return transitionAnimation.sharedFlow(
             startTime = 600.milliseconds,
             duration = 500.milliseconds,
             onStart = { translatePx },
@@ -61,7 +62,7 @@
 
     /** alpha animation upon entering AOD */
     val enterFromTopAnimationAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             startTime = 600.milliseconds,
             duration = 500.milliseconds,
             onStart = { 0f },
@@ -74,7 +75,7 @@
             if (udfpsEnrolled) {
                 // fade in at the end of the transition to give time for FP to start running
                 // and avoid a flicker of the unlocked icon
-                transitionAnimation.createFlow(
+                transitionAnimation.sharedFlow(
                     startTime = 1100.milliseconds,
                     duration = 200.milliseconds,
                     onStep = { it },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingLockscreenHostedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingLockscreenHostedTransitionViewModel.kt
index 113f01c..bba790a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingLockscreenHostedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingLockscreenHostedTransitionViewModel.kt
@@ -33,17 +33,18 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_DREAMING_DURATION,
-            transitionFlow = interactor.goneToDreamingLockscreenHostedTransition,
+        animationFlow.setup(
+            duration = TO_DREAMING_DURATION,
+            stepFlow = interactor.goneToDreamingLockscreenHostedTransition,
         )
 
     /** Lockscreen views alpha - hide immediately */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 1.milliseconds,
             onStep = { 0f },
         )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModel.kt
index c135786..6762ba6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModel.kt
@@ -31,17 +31,18 @@
 @Inject
 constructor(
     private val interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_DREAMING_DURATION,
-            transitionFlow = interactor.goneToDreamingTransition,
+        animationFlow.setup(
+            duration = TO_DREAMING_DURATION,
+            stepFlow = interactor.goneToDreamingTransition,
         )
 
     /** Lockscreen views y-translation */
     fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
-        return transitionAnimation.createFlow(
+        return transitionAnimation.sharedFlow(
             duration = 500.milliseconds,
             onStep = { it * translatePx },
             // Reset on cancel or finish
@@ -53,7 +54,7 @@
 
     /** Lockscreen views alpha */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1f - it },
         )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
index 5804a20..adae8ab 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
@@ -29,16 +29,17 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_LOCKSCREEN_DURATION,
-            transitionFlow = interactor.goneToLockscreenTransition
+        animationFlow.setup(
+            duration = TO_LOCKSCREEN_DURATION,
+            stepFlow = interactor.goneToLockscreenTransition
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { it },
             onCancel = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 4c3fc03..889464d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -157,27 +157,27 @@
 
     val translationY: Flow<Float> =
         configurationInteractor
-        .dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y)
-        .flatMapLatest { enterFromTopAmount ->
-            combine(
-                keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
-                burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
-                goneToAodTransitionViewModel
-                    .enterFromTopTranslationY(enterFromTopAmount)
-                    .onStart { emit(0f) },
-                occludedToLockscreenTransitionViewModel.lockscreenTranslationY,
-            ) {
-                keyguardTransitionY,
-                burnInTranslationY,
-                goneToAodTransitionTranslationY,
-                occludedToLockscreenTransitionTranslationY ->
-                // All values need to be combined for a smooth translation
-                keyguardTransitionY +
-                    burnInTranslationY +
-                    goneToAodTransitionTranslationY +
-                    occludedToLockscreenTransitionTranslationY
+            .dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y)
+            .flatMapLatest { enterFromTopAmount ->
+                combine(
+                    keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
+                    burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
+                    goneToAodTransitionViewModel
+                        .enterFromTopTranslationY(enterFromTopAmount)
+                        .onStart { emit(0f) },
+                    occludedToLockscreenTransitionViewModel.lockscreenTranslationY,
+                ) {
+                    keyguardTransitionY,
+                    burnInTranslationY,
+                    goneToAodTransitionTranslationY,
+                    occludedToLockscreenTransitionTranslationY ->
+                    // All values need to be combined for a smooth translation
+                    keyguardTransitionY +
+                        burnInTranslationY +
+                        goneToAodTransitionTranslationY +
+                        occludedToLockscreenTransitionTranslationY
+                }
             }
-        }
 
     val translationX: Flow<Float> = burnIn().map { it.translationX.toFloat() }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
index 8e8fd75c..65614f4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
@@ -39,19 +39,20 @@
     interactor: KeyguardTransitionInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
     shadeDependentFlows: ShadeDependentFlows,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromLockscreenTransitionInteractor.TO_AOD_DURATION,
-            transitionFlow = interactor.lockscreenToAodTransition,
+        animationFlow.setup(
+            duration = FromLockscreenTransitionInteractor.TO_AOD_DURATION,
+            stepFlow = interactor.lockscreenToAodTransition,
         )
 
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f),
             flowWhenShadeIsNotExpanded =
-                transitionAnimation.createFlow(
+                transitionAnimation.sharedFlow(
                     duration = 300.milliseconds,
                     onStep = { 1 - it },
                     onFinish = { 0f },
@@ -59,7 +60,7 @@
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1 - it },
             onFinish = { 0f },
@@ -72,7 +73,7 @@
             if (isUdfpsEnrolledAndEnabled) {
                 shadeDependentFlows.transitionFlow(
                     flowWhenShadeIsExpanded = // fade in
-                    transitionAnimation.createFlow(
+                    transitionAnimation.sharedFlow(
                             duration = 300.milliseconds,
                             onStep = { it },
                             onFinish = { 1f },
@@ -83,7 +84,7 @@
                 shadeDependentFlows.transitionFlow(
                     flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f),
                     flowWhenShadeIsNotExpanded = // fade out
-                    transitionAnimation.createFlow(
+                    transitionAnimation.sharedFlow(
                             duration = 200.milliseconds,
                             onStep = { 1f - it },
                             onFinish = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
index 263ed11..accb20c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
@@ -29,16 +29,17 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_DOZING_DURATION,
-            transitionFlow = interactor.lockscreenToDozingTransition
+        animationFlow.setup(
+            duration = TO_DOZING_DURATION,
+            stepFlow = interactor.lockscreenToDozingTransition
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1 - it },
             onFinish = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
index 1701505..c649b12 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
@@ -29,16 +29,17 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_DREAMING_HOSTED_DURATION,
-            transitionFlow = interactor.lockscreenToDreamingLockscreenHostedTransition
+        animationFlow.setup(
+            duration = TO_DREAMING_HOSTED_DURATION,
+            stepFlow = interactor.lockscreenToDreamingLockscreenHostedTransition
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1 - it },
             onFinish = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
index 401c0ff..7f75b54 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
@@ -36,16 +36,17 @@
 constructor(
     interactor: KeyguardTransitionInteractor,
     shadeDependentFlows: ShadeDependentFlows,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_DREAMING_DURATION,
-            transitionFlow = interactor.lockscreenToDreamingTransition,
+        animationFlow.setup(
+            duration = TO_DREAMING_DURATION,
+            stepFlow = interactor.lockscreenToDreamingTransition,
         )
 
     /** Lockscreen views y-translation */
     fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
-        return transitionAnimation.createFlow(
+        return transitionAnimation.sharedFlow(
             duration = 500.milliseconds,
             onStep = { it * translatePx },
             // Reset on cancel or finish
@@ -57,13 +58,13 @@
 
     /** Lockscreen views alpha */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1f - it },
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1 - it },
             onFinish = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
index cfb4bf5..9e19713 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
@@ -36,16 +36,17 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromLockscreenTransitionInteractor.TO_GONE_DURATION,
-            transitionFlow = interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
+        animationFlow.setup(
+            duration = FromLockscreenTransitionInteractor.TO_GONE_DURATION,
+            stepFlow = interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1 - it },
             onFinish = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
index e1b0102..9db0b77 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
@@ -40,23 +40,25 @@
     interactor: KeyguardTransitionInteractor,
     shadeDependentFlows: ShadeDependentFlows,
     configurationInteractor: ConfigurationInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_OCCLUDED_DURATION,
-            transitionFlow = interactor.lockscreenToOccludedTransition,
+        animationFlow.setup(
+            duration = TO_OCCLUDED_DURATION,
+            stepFlow = interactor.lockscreenToOccludedTransition,
         )
 
     /** Lockscreen views alpha */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1f - it },
+            name = "LOCKSCREEN->OCCLUDED: lockscreenAlpha",
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { 1 - it },
             onFinish = { 0f },
@@ -68,7 +70,7 @@
         configurationInteractor
             .dimensionPixelSize(R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y)
             .flatMapLatest { translatePx ->
-                transitionAnimation.createFlow(
+                transitionAnimation.sharedFlow(
                     duration = TO_OCCLUDED_DURATION,
                     onStep = { value -> value * translatePx },
                     // Reset on cancel or finish
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
index 07dd4ef..52e3257 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
@@ -39,11 +39,12 @@
 constructor(
     interactor: KeyguardTransitionInteractor,
     shadeDependentFlows: ShadeDependentFlows,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromLockscreenTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
-            transitionFlow =
+        animationFlow.setup(
+            duration = FromLockscreenTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
+            stepFlow =
                 interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER),
         )
 
@@ -55,7 +56,7 @@
     override val deviceEntryParentViewAlpha: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsNotExpanded =
-                transitionAnimation.createFlow(
+                transitionAnimation.sharedFlow(
                     duration = 250.milliseconds,
                     onStep = { 1f - it },
                     onFinish = { 0f }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt
index f7cff9b..ed5e83c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt
@@ -37,11 +37,12 @@
 constructor(
     interactor: KeyguardTransitionInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromOccludedTransitionInteractor.TO_AOD_DURATION,
-            transitionFlow = interactor.transition(KeyguardState.OCCLUDED, KeyguardState.AOD),
+        animationFlow.setup(
+            duration = FromOccludedTransitionInteractor.TO_AOD_DURATION,
+            stepFlow = interactor.transition(KeyguardState.OCCLUDED, KeyguardState.AOD),
         )
 
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index 9b2eaef..4c24f83 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -44,12 +44,13 @@
     interactor: KeyguardTransitionInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
     configurationInteractor: ConfigurationInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_LOCKSCREEN_DURATION,
-            transitionFlow = interactor.occludedToLockscreenTransition,
+        animationFlow.setup(
+            duration = TO_LOCKSCREEN_DURATION,
+            stepFlow = interactor.occludedToLockscreenTransition,
         )
 
     /** Lockscreen views y-translation */
@@ -57,7 +58,7 @@
         configurationInteractor
             .dimensionPixelSize(R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y)
             .flatMapLatest { translatePx ->
-                transitionAnimation.createFlow(
+                transitionAnimation.sharedFlow(
                     duration = TO_LOCKSCREEN_DURATION,
                     onStep = { value -> -translatePx + value * translatePx },
                     interpolator = EMPHASIZED_DECELERATE,
@@ -66,7 +67,7 @@
             }
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { it },
             onCancel = { 0f },
@@ -74,10 +75,12 @@
 
     /** Lockscreen views alpha */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             startTime = 233.milliseconds,
             duration = 250.milliseconds,
             onStep = { it },
+            onStart = { 0f },
+            name = "OCCLUDED->LOCKSCREEN: lockscreenAlpha",
         )
 
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
index c3bc799..93482ea 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
@@ -28,16 +28,17 @@
 @Inject
 constructor(
     interactor: KeyguardTransitionInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
 
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = 250.milliseconds,
-            transitionFlow = interactor.offToLockscreenTransition
+        animationFlow.setup(
+            duration = 250.milliseconds,
+            stepFlow = interactor.offToLockscreenTransition
         )
 
     val shortcutsAlpha: Flow<Float> =
-        transitionAnimation.createFlow(
+        transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             onStep = { it },
             onCancel = { 0f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
index 05a6d58..b0e2aa2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
@@ -41,12 +41,12 @@
 constructor(
     interactor: KeyguardTransitionInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromPrimaryBouncerTransitionInteractor.TO_AOD_DURATION,
-            transitionFlow =
-                interactor.transition(KeyguardState.PRIMARY_BOUNCER, KeyguardState.AOD),
+        animationFlow.setup(
+            duration = FromPrimaryBouncerTransitionInteractor.TO_AOD_DURATION,
+            stepFlow = interactor.transition(KeyguardState.PRIMARY_BOUNCER, KeyguardState.AOD),
         )
 
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
@@ -62,7 +62,7 @@
         deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest {
             isUdfpsEnrolledAndEnabled ->
             if (isUdfpsEnrolledAndEnabled) {
-                transitionAnimation.createFlow(
+                transitionAnimation.sharedFlow(
                     duration = 300.milliseconds,
                     onStep = { it },
                     onFinish = { 1f },
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index 0e95be2..9dbe97f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -50,11 +50,12 @@
     keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>,
     featureFlags: FeatureFlagsClassic,
     bouncerToGoneFlows: BouncerToGoneFlows,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) {
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = TO_GONE_DURATION,
-            transitionFlow = interactor.transition(PRIMARY_BOUNCER, GONE)
+        animationFlow.setup(
+            duration = TO_GONE_DURATION,
+            stepFlow = interactor.transition(PRIMARY_BOUNCER, GONE)
         )
 
     private var leaveShadeOpen: Boolean = false
@@ -71,7 +72,7 @@
             createBouncerAlphaFlow(primaryBouncerInteractor::willRunDismissFromKeyguard)
         }
     private fun createBouncerAlphaFlow(willRunAnimationOnKeyguard: () -> Boolean): Flow<Float> {
-        return transitionAnimation.createFlow(
+        return transitionAnimation.sharedFlow(
             duration = 200.milliseconds,
             onStart = { willRunDismissFromKeyguard = willRunAnimationOnKeyguard() },
             onStep = {
@@ -95,7 +96,7 @@
             createLockscreenAlpha(primaryBouncerInteractor::willRunDismissFromKeyguard)
         }
     private fun createLockscreenAlpha(willRunAnimationOnKeyguard: () -> Boolean): Flow<Float> {
-        return transitionAnimation.createFlow(
+        return transitionAnimation.sharedFlow(
             duration = 50.milliseconds,
             onStart = {
                 leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index 7ef8374..b2eed60 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -41,11 +41,12 @@
 constructor(
     interactor: KeyguardTransitionInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
     private val transitionAnimation =
-        KeyguardTransitionAnimationFlow(
-            transitionDuration = FromPrimaryBouncerTransitionInteractor.TO_LOCKSCREEN_DURATION,
-            transitionFlow =
+        animationFlow.setup(
+            duration = FromPrimaryBouncerTransitionInteractor.TO_LOCKSCREEN_DURATION,
+            stepFlow =
                 interactor.transition(KeyguardState.PRIMARY_BOUNCER, KeyguardState.LOCKSCREEN),
         )
 
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardTransitionAnimationLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardTransitionAnimationLog.kt
new file mode 100644
index 0000000..ef06588
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardTransitionAnimationLog.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 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.log.dagger
+
+import javax.inject.Qualifier
+
+/**
+ * A [com.android.systemui.log.LogBuffer] for keyguard transition animations. Should be used mostly
+ * for adding temporary logs or logging from smaller classes when creating new separate log class
+ * might be an overkill.
+ */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class KeyguardTransitionAnimationLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 0b3bbb5..dc55179f 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -525,6 +525,16 @@
     }
 
     /**
+     * Provides a {@link LogBuffer} for keyguard transition animation logs.
+     */
+    @Provides
+    @SysUISingleton
+    @KeyguardTransitionAnimationLog
+    public static LogBuffer provideKeyguardTransitionAnimationLogBuffer(LogBufferFactory factory) {
+        return factory.create("KeyguardTransitionAnimationLog", 250);
+    }
+
+    /**
      * Provides a {@link LogBuffer} for Scrims like LightRevealScrim.
      */
     @Provides
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
index dfb18b9..f5f1622 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
@@ -17,29 +17,23 @@
 package com.android.systemui.biometrics.ui.viewmodel
 
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.flags.featureFlagsClassic
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
-import com.android.systemui.runCurrent
-import com.android.systemui.runTest
-import com.android.systemui.shade.data.repository.FakeShadeRepository
+import com.android.systemui.keyguard.ui.viewmodel.deviceEntryIconViewModelTransitionsMock
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.phone.SystemUIDialogManager
-import com.android.systemui.user.domain.UserDomainLayerModule
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.statusbar.phone.systemUIDialogManager
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -53,35 +47,11 @@
 @SmallTest
 @RunWith(JUnit4::class)
 class DeviceEntryUdfpsTouchOverlayViewModelTest : SysuiTestCase() {
-    @Captor
-    private lateinit var sysuiDialogListenerCaptor: ArgumentCaptor<SystemUIDialogManager.Listener>
-    private var systemUIDialogManager: SystemUIDialogManager = mock()
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-    }
-
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent : SysUITestComponent<DeviceEntryUdfpsTouchOverlayViewModel> {
-        val keyguardRepository: FakeKeyguardRepository
-        val shadeRepository: FakeShadeRepository
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-                featureFlags: FakeFeatureFlagsClassicModule,
-                mocks: TestMocksModule,
-            ): TestComponent
+    val kosmos =
+        testKosmos().apply {
+            featureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, true) }
         }
-    }
+    val testScope = kosmos.testScope
 
     private val testDeviceEntryIconTransitionAlpha = MutableStateFlow(0f)
     private val testDeviceEntryIconTransition: DeviceEntryIconTransition
@@ -90,60 +60,59 @@
                 override val deviceEntryParentViewAlpha: Flow<Float> =
                     testDeviceEntryIconTransitionAlpha.asStateFlow()
             }
-    private val testComponent: TestComponent =
-        DaggerDeviceEntryUdfpsTouchOverlayViewModelTest_TestComponent.factory()
-            .create(
-                test = this,
-                featureFlags =
-                    FakeFeatureFlagsClassicModule { set(Flags.FULL_SCREEN_USER_SWITCHER, true) },
-                mocks =
-                    TestMocksModule(
-                        systemUIDialogManager = systemUIDialogManager,
-                        deviceEntryIconTransitions =
-                            setOf(
-                                testDeviceEntryIconTransition,
-                            )
-                    ),
-            )
+
+    init {
+        kosmos.deviceEntryIconViewModelTransitionsMock.add(testDeviceEntryIconTransition)
+    }
+    val systemUIDialogManager = kosmos.systemUIDialogManager
+    private val underTest = kosmos.deviceEntryUdfpsTouchOverlayViewModel
+
+    @Captor
+    private lateinit var sysuiDialogListenerCaptor: ArgumentCaptor<SystemUIDialogManager.Listener>
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+    }
 
     @Test
     fun dialogShowing_shouldHandleTouchesFalse() =
-        testComponent.runTest {
+        testScope.runTest {
             val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
-            runCurrent()
 
             testDeviceEntryIconTransitionAlpha.value = 1f
+            runCurrent()
+
             verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
             sysuiDialogListenerCaptor.value.shouldHideAffordances(true)
-            runCurrent()
 
             assertThat(shouldHandleTouches).isFalse()
         }
 
     @Test
     fun transitionAlphaIsSmall_shouldHandleTouchesFalse() =
-        testComponent.runTest {
+        testScope.runTest {
             val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
-            runCurrent()
 
             testDeviceEntryIconTransitionAlpha.value = .3f
+            runCurrent()
+
             verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
             sysuiDialogListenerCaptor.value.shouldHideAffordances(false)
-            runCurrent()
 
             assertThat(shouldHandleTouches).isFalse()
         }
 
     @Test
     fun alphaFullyShowing_noDialog_shouldHandleTouchesTrue() =
-        testComponent.runTest {
+        testScope.runTest {
             val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
-            runCurrent()
 
             testDeviceEntryIconTransitionAlpha.value = 1f
+            runCurrent()
+
             verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
             sysuiDialogListenerCaptor.value.shouldHideAffordances(false)
-            runCurrent()
 
             assertThat(shouldHandleTouches).isTrue()
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt
index a04ea2e..edd781d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt
@@ -24,8 +24,10 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -35,125 +37,138 @@
 @SmallTest
 @RunWith(JUnit4::class)
 class KeyguardTransitionAnimationFlowTest : SysuiTestCase() {
-    private lateinit var underTest: KeyguardTransitionAnimationFlow
+    private lateinit var underTest: KeyguardTransitionAnimationFlow.SharedFlowBuilder
     private lateinit var repository: FakeKeyguardTransitionRepository
+    private lateinit var testScope: TestScope
 
     @Before
     fun setUp() {
+        testScope = TestScope()
         repository = FakeKeyguardTransitionRepository()
         underTest =
             KeyguardTransitionAnimationFlow(
-                1000.milliseconds,
-                repository.transitions,
-            )
+                    testScope.backgroundScope,
+                    mock(),
+                )
+                .setup(
+                    duration = 1000.milliseconds,
+                    stepFlow = repository.transitions,
+                )
     }
 
     @Test(expected = IllegalArgumentException::class)
-    fun zeroDurationThrowsException() = runTest {
-        val flow = underTest.createFlow(duration = 0.milliseconds, onStep = { it })
-    }
+    fun zeroDurationThrowsException() =
+        testScope.runTest {
+            val flow = underTest.sharedFlow(duration = 0.milliseconds, onStep = { it })
+        }
 
     @Test(expected = IllegalArgumentException::class)
-    fun startTimePlusDurationGreaterThanTransitionDurationThrowsException() = runTest {
-        val flow =
-            underTest.createFlow(
-                startTime = 300.milliseconds,
-                duration = 800.milliseconds,
-                onStep = { it }
-            )
-    }
+    fun startTimePlusDurationGreaterThanTransitionDurationThrowsException() =
+        testScope.runTest {
+            val flow =
+                underTest.sharedFlow(
+                    startTime = 300.milliseconds,
+                    duration = 800.milliseconds,
+                    onStep = { it }
+                )
+        }
 
     @Test
-    fun onFinishRunsWhenSpecified() = runTest {
-        val flow =
-            underTest.createFlow(
-                duration = 100.milliseconds,
-                onStep = { it },
-                onFinish = { 10f },
-            )
-        var animationValues = collectLastValue(flow)
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED), validateStep = false)
-        assertThat(animationValues()).isEqualTo(10f)
-    }
+    fun onFinishRunsWhenSpecified() =
+        testScope.runTest {
+            val flow =
+                underTest.sharedFlow(
+                    duration = 100.milliseconds,
+                    onStep = { it },
+                    onFinish = { 10f },
+                )
+            var animationValues = collectLastValue(flow)
+            repository.sendTransitionStep(step(1f, TransitionState.FINISHED), validateStep = false)
+            assertThat(animationValues()).isEqualTo(10f)
+        }
 
     @Test
-    fun onCancelRunsWhenSpecified() = runTest {
-        val flow =
-            underTest.createFlow(
-                duration = 100.milliseconds,
-                onStep = { it },
-                onCancel = { 100f },
-            )
-        var animationValues = collectLastValue(flow)
-        repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED))
-        assertThat(animationValues()).isEqualTo(100f)
-    }
+    fun onCancelRunsWhenSpecified() =
+        testScope.runTest {
+            val flow =
+                underTest.sharedFlow(
+                    duration = 100.milliseconds,
+                    onStep = { it },
+                    onCancel = { 100f },
+                )
+            var animationValues = collectLastValue(flow)
+            repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED))
+            assertThat(animationValues()).isEqualTo(100f)
+        }
 
     @Test
-    fun usesStartTime() = runTest {
-        val flow =
-            underTest.createFlow(
-                startTime = 500.milliseconds,
-                duration = 500.milliseconds,
-                onStep = { it },
-            )
-        var animationValues = collectLastValue(flow)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(animationValues()).isEqualTo(0f)
+    fun usesStartTime() =
+        testScope.runTest {
+            val flow =
+                underTest.sharedFlow(
+                    startTime = 500.milliseconds,
+                    duration = 500.milliseconds,
+                    onStep = { it },
+                )
+            var animationValues = collectLastValue(flow)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(animationValues()).isEqualTo(0f)
 
-        // Should not emit a value
-        repository.sendTransitionStep(step(0.1f, TransitionState.RUNNING))
+            // Should not emit a value
+            repository.sendTransitionStep(step(0.1f, TransitionState.RUNNING))
 
-        repository.sendTransitionStep(step(0.5f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 0f)
-        repository.sendTransitionStep(step(0.6f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 0.2f)
-        repository.sendTransitionStep(step(0.8f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 0.6f)
-        repository.sendTransitionStep(step(1f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 1f)
-    }
+            repository.sendTransitionStep(step(0.5f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 0f)
+            repository.sendTransitionStep(step(0.6f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 0.2f)
+            repository.sendTransitionStep(step(0.8f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 0.6f)
+            repository.sendTransitionStep(step(1f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 1f)
+        }
 
     @Test
-    fun usesInterpolator() = runTest {
-        val flow =
-            underTest.createFlow(
-                duration = 1000.milliseconds,
-                interpolator = EMPHASIZED_ACCELERATE,
-                onStep = { it },
-            )
-        var animationValues = collectLastValue(flow)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0f))
-        repository.sendTransitionStep(step(0.5f, TransitionState.RUNNING))
-        assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0.5f))
-        repository.sendTransitionStep(step(0.6f, TransitionState.RUNNING))
-        assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0.6f))
-        repository.sendTransitionStep(step(0.8f, TransitionState.RUNNING))
-        assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0.8f))
-        repository.sendTransitionStep(step(1f, TransitionState.RUNNING))
-        assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(1f))
-    }
+    fun usesInterpolator() =
+        testScope.runTest {
+            val flow =
+                underTest.sharedFlow(
+                    duration = 1000.milliseconds,
+                    interpolator = EMPHASIZED_ACCELERATE,
+                    onStep = { it },
+                )
+            var animationValues = collectLastValue(flow)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0f))
+            repository.sendTransitionStep(step(0.5f, TransitionState.RUNNING))
+            assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0.5f))
+            repository.sendTransitionStep(step(0.6f, TransitionState.RUNNING))
+            assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0.6f))
+            repository.sendTransitionStep(step(0.8f, TransitionState.RUNNING))
+            assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(0.8f))
+            repository.sendTransitionStep(step(1f, TransitionState.RUNNING))
+            assertFloat(animationValues(), EMPHASIZED_ACCELERATE.getInterpolation(1f))
+        }
 
     @Test
-    fun usesOnStepToDoubleValue() = runTest {
-        val flow =
-            underTest.createFlow(
-                duration = 1000.milliseconds,
-                onStep = { it * 2 },
-            )
-        var animationValues = collectLastValue(flow)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertFloat(animationValues(), 0f)
-        repository.sendTransitionStep(step(0.3f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 0.6f)
-        repository.sendTransitionStep(step(0.6f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 1.2f)
-        repository.sendTransitionStep(step(0.8f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 1.6f)
-        repository.sendTransitionStep(step(1f, TransitionState.RUNNING))
-        assertFloat(animationValues(), 2f)
-    }
+    fun usesOnStepToDoubleValue() =
+        testScope.runTest {
+            val flow =
+                underTest.sharedFlow(
+                    duration = 1000.milliseconds,
+                    onStep = { it * 2 },
+                )
+            var animationValues = collectLastValue(flow)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertFloat(animationValues(), 0f)
+            repository.sendTransitionStep(step(0.3f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 0.6f)
+            repository.sendTransitionStep(step(0.6f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 1.2f)
+            repository.sendTransitionStep(step(0.8f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 1.6f)
+            repository.sendTransitionStep(step(1f, TransitionState.RUNNING))
+            assertFloat(animationValues(), 2f)
+        }
 
     private fun assertFloat(actual: Float?, expected: Float) {
         assertThat(actual!!).isWithin(0.01f).of(expected)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
index fc9f54ec..d959872 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
@@ -21,66 +21,45 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
+import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
 
 @ExperimentalCoroutinesApi
 @RunWith(JUnit4::class)
 @SmallTest
 class AlternateBouncerViewModelTest : SysuiTestCase() {
-
-    private lateinit var testScope: TestScope
-
-    @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
-
-    private lateinit var transitionRepository: FakeKeyguardTransitionRepository
-    private lateinit var transitionInteractor: KeyguardTransitionInteractor
-    private lateinit var underTest: AlternateBouncerViewModel
-
-    @Before
-    fun setup() {
-        MockitoAnnotations.initMocks(this)
-        testScope = TestScope()
-
-        val transitionInteractorWithDependencies =
-            KeyguardTransitionInteractorFactory.create(testScope.backgroundScope)
-        transitionInteractor = transitionInteractorWithDependencies.keyguardTransitionInteractor
-        transitionRepository = transitionInteractorWithDependencies.repository
-        underTest =
-            AlternateBouncerViewModel(
-                statusBarKeyguardViewManager,
-                transitionInteractor,
-            )
-    }
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val transitionRepository = kosmos.fakeKeyguardTransitionRepository
+    private val statusBarKeyguardViewManager = kosmos.statusBarKeyguardViewManager
+    private val underTest = kosmos.alternateBouncerViewModel
 
     @Test
     fun transitionToAlternateBouncer_scrimAlphaUpdate() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val scrimAlphas by collectValues(underTest.scrimAlpha)
 
-            transitionRepository.sendTransitionStep(
-                stepToAlternateBouncer(0f, TransitionState.STARTED)
+            transitionRepository.sendTransitionSteps(
+                listOf(
+                    stepToAlternateBouncer(0f, TransitionState.STARTED),
+                    stepToAlternateBouncer(.4f),
+                    stepToAlternateBouncer(.6f),
+                    stepToAlternateBouncer(1f),
+                ),
+                testScope,
             )
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(.4f))
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f))
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f))
 
             assertThat(scrimAlphas.size).isEqualTo(4)
             scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
@@ -88,15 +67,18 @@
 
     @Test
     fun transitionFromAlternateBouncer_scrimAlphaUpdate() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val scrimAlphas by collectValues(underTest.scrimAlpha)
 
-            transitionRepository.sendTransitionStep(
-                stepFromAlternateBouncer(0f, TransitionState.STARTED)
+            transitionRepository.sendTransitionSteps(
+                listOf(
+                    stepToAlternateBouncer(0f, TransitionState.STARTED),
+                    stepToAlternateBouncer(.4f),
+                    stepToAlternateBouncer(.6f),
+                    stepToAlternateBouncer(1f),
+                ),
+                testScope,
             )
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.4f))
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f))
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f))
 
             assertThat(scrimAlphas.size).isEqualTo(4)
             scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
@@ -104,43 +86,57 @@
 
     @Test
     fun forcePluginOpen() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val forcePluginOpen by collectLastValue(underTest.forcePluginOpen)
-            transitionRepository.sendTransitionStep(
-                stepToAlternateBouncer(0f, TransitionState.STARTED)
+
+            transitionRepository.sendTransitionSteps(
+                listOf(
+                    stepToAlternateBouncer(0f, TransitionState.STARTED),
+                    stepToAlternateBouncer(.4f),
+                    stepToAlternateBouncer(.6f),
+                    stepToAlternateBouncer(1f),
+                ),
+                testScope,
             )
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(.3f))
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f))
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f))
             assertThat(forcePluginOpen).isTrue()
 
-            transitionRepository.sendTransitionStep(
-                stepFromAlternateBouncer(0f, TransitionState.STARTED)
+            transitionRepository.sendTransitionSteps(
+                listOf(
+                    stepFromAlternateBouncer(0f, TransitionState.STARTED),
+                    stepFromAlternateBouncer(.3f),
+                    stepFromAlternateBouncer(.6f),
+                    stepFromAlternateBouncer(1f),
+                ),
+                testScope,
             )
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.3f))
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f))
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f))
             assertThat(forcePluginOpen).isFalse()
         }
 
     @Test
     fun registerForDismissGestures() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val registerForDismissGestures by collectLastValue(underTest.registerForDismissGestures)
-            transitionRepository.sendTransitionStep(
-                stepToAlternateBouncer(0f, TransitionState.STARTED)
+
+            transitionRepository.sendTransitionSteps(
+                listOf(
+                    stepToAlternateBouncer(0f, TransitionState.STARTED),
+                    stepToAlternateBouncer(.4f),
+                    stepToAlternateBouncer(.6f),
+                    stepToAlternateBouncer(1f),
+                ),
+                testScope,
             )
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(.3f))
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f))
-            transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f))
             assertThat(registerForDismissGestures).isTrue()
 
-            transitionRepository.sendTransitionStep(
-                stepFromAlternateBouncer(0f, TransitionState.STARTED)
+            transitionRepository.sendTransitionSteps(
+                listOf(
+                    stepFromAlternateBouncer(0f, TransitionState.STARTED),
+                    stepFromAlternateBouncer(.3f),
+                    stepFromAlternateBouncer(.6f),
+                    stepFromAlternateBouncer(1f),
+                ),
+                testScope,
             )
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.3f))
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f))
-            transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f))
             assertThat(registerForDismissGestures).isFalse()
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt
index f282481..4c972e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt
@@ -20,16 +20,15 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -37,34 +36,25 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AodToGoneTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: AodToGoneTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest = AodToGoneTransitionViewModel(interactor)
-    }
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
+    val repository = kosmos.fakeKeyguardTransitionRepository
+    val underTest = kosmos.aodToGoneTransitionViewModel
 
     @Test
-    fun deviceEntryParentViewHides() = runTest {
-        val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        repository.sendTransitionStep(step(0.1f))
-        repository.sendTransitionStep(step(0.3f))
-        repository.sendTransitionStep(step(0.4f))
-        repository.sendTransitionStep(step(0.5f))
-        repository.sendTransitionStep(step(0.6f))
-        repository.sendTransitionStep(step(0.8f))
-        repository.sendTransitionStep(step(1f))
-        deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(0f) }
-    }
+    fun deviceEntryParentViewHides() =
+        testScope.runTest {
+            val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.4f))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(0.6f))
+            repository.sendTransitionStep(step(0.8f))
+            repository.sendTransitionStep(step(1f))
+            deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(0f) }
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
index 517149c..af8d8a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
@@ -19,22 +19,18 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -42,83 +38,67 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AodToLockscreenTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: AodToLockscreenTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
-        underTest =
-            AodToLockscreenTransitionViewModel(
-                interactor =
-                    KeyguardTransitionInteractorFactory.create(
-                            scope = TestScope().backgroundScope,
-                            repository = repository,
-                        )
-                        .keyguardTransitionInteractor,
-                deviceEntryUdfpsInteractor =
-                    DeviceEntryUdfpsInteractor(
-                        fingerprintPropertyRepository = fingerprintPropertyRepository,
-                        fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
-                        biometricSettingsRepository = FakeBiometricSettingsRepository(),
-                    ),
-            )
-    }
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
+    val repository = kosmos.fakeKeyguardTransitionRepository
+    val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    val underTest = kosmos.aodToLockscreenTransitionViewModel
 
     @Test
-    fun deviceEntryParentViewShows() = runTest {
-        val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        repository.sendTransitionStep(step(0.1f))
-        repository.sendTransitionStep(step(0.3f))
-        repository.sendTransitionStep(step(0.5f))
-        repository.sendTransitionStep(step(0.6f))
-        repository.sendTransitionStep(step(1f))
-        deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(1f) }
-    }
+    fun deviceEntryParentViewShows() =
+        testScope.runTest {
+            val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(0.6f))
+            repository.sendTransitionStep(step(1f))
+            deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(1f) }
+        }
 
     @Test
-    fun deviceEntryBackgroundView_udfps_alphaFadeIn() = runTest {
-        fingerprintPropertyRepository.supportsUdfps()
-        val deviceEntryBackgroundViewAlpha by
-            collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
+    fun deviceEntryBackgroundView_udfps_alphaFadeIn() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            val deviceEntryBackgroundViewAlpha by
+                collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
 
-        // fade in
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+            // fade in
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
 
-        repository.sendTransitionStep(step(0.1f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(.2f)
+            repository.sendTransitionStep(step(0.1f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(.2f)
 
-        repository.sendTransitionStep(step(0.3f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(.6f)
+            repository.sendTransitionStep(step(0.3f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(.6f)
 
-        repository.sendTransitionStep(step(0.6f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(1f)
+            repository.sendTransitionStep(step(0.6f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(1f)
-    }
+            repository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(1f)
+        }
 
     @Test
-    fun deviceEntryBackgroundView_rearFp_noUpdates() = runTest {
-        fingerprintPropertyRepository.supportsRearFps()
-        val deviceEntryBackgroundViewAlpha by
-            collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
-        // no updates
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryBackgroundViewAlpha).isNull()
-        repository.sendTransitionStep(step(0.1f))
-        assertThat(deviceEntryBackgroundViewAlpha).isNull()
-        repository.sendTransitionStep(step(0.3f))
-        assertThat(deviceEntryBackgroundViewAlpha).isNull()
-        repository.sendTransitionStep(step(0.6f))
-        assertThat(deviceEntryBackgroundViewAlpha).isNull()
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryBackgroundViewAlpha).isNull()
-    }
+    fun deviceEntryBackgroundView_rearFp_noUpdates() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsRearFps()
+            val deviceEntryBackgroundViewAlpha by
+                collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
+            // no updates
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryBackgroundViewAlpha).isNull()
+            repository.sendTransitionStep(step(0.1f))
+            assertThat(deviceEntryBackgroundViewAlpha).isNull()
+            repository.sendTransitionStep(step(0.3f))
+            assertThat(deviceEntryBackgroundViewAlpha).isNull()
+            repository.sendTransitionStep(step(0.6f))
+            assertThat(deviceEntryBackgroundViewAlpha).isNull()
+            repository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryBackgroundViewAlpha).isNull()
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt
index 96f69462..db8fbf6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt
@@ -20,16 +20,15 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -37,34 +36,25 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AodToOccludedTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: AodToOccludedTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest = AodToOccludedTransitionViewModel(interactor)
-    }
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardTransitionRepository
+    private val underTest = kosmos.aodToOccludedTransitionViewModel
 
     @Test
-    fun deviceEntryParentViewHides() = runTest {
-        val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        repository.sendTransitionStep(step(0.1f))
-        repository.sendTransitionStep(step(0.3f))
-        repository.sendTransitionStep(step(0.4f))
-        repository.sendTransitionStep(step(0.5f))
-        repository.sendTransitionStep(step(0.6f))
-        repository.sendTransitionStep(step(0.8f))
-        repository.sendTransitionStep(step(1f))
-        deviceEntryParentViewAlpha.forEach { Truth.assertThat(it).isEqualTo(0f) }
-    }
+    fun deviceEntryParentViewHides() =
+        testScope.runTest {
+            val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.4f))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(0.6f))
+            repository.sendTransitionStep(step(0.8f))
+            repository.sendTransitionStep(step(1f))
+            deviceEntryParentViewAlpha.forEach { Truth.assertThat(it).isEqualTo(0f) }
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt
index 1ff46db..c9b14a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt
@@ -19,28 +19,26 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.shared.model.ScrimAlpha
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.sysuiStatusBarStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
-import dagger.Lazy
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -51,56 +49,47 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BouncerToGoneFlowsTest : SysuiTestCase() {
-    private lateinit var underTest: BouncerToGoneFlows
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var featureFlags: FakeFeatureFlags
-    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
-    @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
-    @Mock
-    private lateinit var keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>
     @Mock private lateinit var shadeInteractor: ShadeInteractor
 
     private val shadeExpansionStateFlow = MutableStateFlow(0.1f)
 
+    private val kosmos =
+        testKosmos().apply {
+            featureFlagsClassic.apply {
+                set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false)
+                set(Flags.FULL_SCREEN_USER_SWITCHER, false)
+            }
+        }
+    private val testScope = kosmos.testScope
+    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    private val shadeRepository = kosmos.shadeRepository
+    private val sysuiStatusBarStateController = kosmos.sysuiStatusBarStateController
+    private val primaryBouncerInteractor = kosmos.primaryBouncerInteractor
+    private val underTest = kosmos.bouncerToGoneFlows
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        whenever(shadeInteractor.shadeExpansion).thenReturn(shadeExpansionStateFlow)
-
-        repository = FakeKeyguardTransitionRepository()
-        val featureFlags =
-            FakeFeatureFlags().apply { set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false) }
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest =
-            BouncerToGoneFlows(
-                interactor,
-                statusBarStateController,
-                primaryBouncerInteractor,
-                keyguardDismissActionInteractor,
-                featureFlags,
-                shadeInteractor,
-            )
-
         whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(false)
-        whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false)
+        sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(false)
     }
 
     @Test
     fun scrimAlpha_runDimissFromKeyguard_shadeExpanded() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER))
-            shadeExpansionStateFlow.value = 1f
+            shadeRepository.setLockscreenShadeExpansion(1f)
             whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.6f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.3f),
+                    step(0.6f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(4)
             values.forEach { assertThat(it.frontAlpha).isEqualTo(0f) }
@@ -110,16 +99,21 @@
 
     @Test
     fun scrimAlpha_runDimissFromKeyguard_shadeNotExpanded() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER))
-            shadeExpansionStateFlow.value = 0f
+            shadeRepository.setLockscreenShadeExpansion(0f)
 
             whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.6f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.3f),
+                    step(0.6f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(4)
             values.forEach { assertThat(it).isEqualTo(ScrimAlpha()) }
@@ -127,15 +121,20 @@
 
     @Test
     fun scrimBehindAlpha_leaveShadeOpen() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER))
 
-            whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(true)
+            sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true)
 
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.6f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.3f),
+                    step(0.6f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(4)
             values.forEach {
@@ -145,15 +144,17 @@
 
     @Test
     fun scrimBehindAlpha_doNotLeaveShadeOpen() =
-        runTest(UnconfinedTestDispatcher()) {
+        testScope.runTest {
             val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER))
-
-            whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false)
-
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            repository.sendTransitionStep(step(0.3f))
-            repository.sendTransitionStep(step(0.6f))
-            repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionSteps(
+                listOf(
+                    step(0f, TransitionState.STARTED),
+                    step(0.3f),
+                    step(0.6f),
+                    step(1f),
+                ),
+                testScope,
+            )
 
             assertThat(values.size).isEqualTo(4)
             values.forEach { assertThat(it.notificationsAlpha).isEqualTo(0f) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
index 5dccc3b..dd542d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
@@ -25,6 +25,8 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
@@ -43,29 +45,36 @@
 
     @Before
     fun setUp() {
+        testScope = TestScope()
         repository = FakeKeyguardTransitionRepository()
         underTest =
             DozingToLockscreenTransitionViewModel(
                 interactor =
                     KeyguardTransitionInteractorFactory.create(
-                            scope = TestScope().backgroundScope,
+                            scope = testScope.backgroundScope,
                             repository = repository,
                         )
                         .keyguardTransitionInteractor,
+                animationFlow =
+                    KeyguardTransitionAnimationFlow(
+                        scope = testScope.backgroundScope,
+                        logger = mock()
+                    ),
             )
     }
 
     @Test
-    fun deviceEntryParentViewShows() = runTest {
-        val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        repository.sendTransitionStep(step(0.1f))
-        repository.sendTransitionStep(step(0.3f))
-        repository.sendTransitionStep(step(0.5f))
-        repository.sendTransitionStep(step(0.6f))
-        repository.sendTransitionStep(step(1f))
-        deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(1f) }
-    }
+    fun deviceEntryParentViewShows() =
+        testScope.runTest {
+            val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(0.6f))
+            repository.sendTransitionStep(step(1f))
+            deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(1f) }
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
index c1444a5..a105008 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
@@ -19,23 +19,19 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -43,37 +39,12 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class GoneToAodTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: GoneToAodTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-    private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
-    private lateinit var testScope: TestScope
-
-    @Before
-    fun setUp() {
-        val testDispatcher = StandardTestDispatcher()
-        testScope = TestScope(testDispatcher)
-
-        repository = FakeKeyguardTransitionRepository()
-        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
-
-        underTest =
-            GoneToAodTransitionViewModel(
-                interactor =
-                    KeyguardTransitionInteractorFactory.create(
-                            scope = testScope.backgroundScope,
-                            repository = repository,
-                        )
-                        .keyguardTransitionInteractor,
-                deviceEntryUdfpsInteractor =
-                    DeviceEntryUdfpsInteractor(
-                        fingerprintPropertyRepository = fingerprintPropertyRepository,
-                        fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
-                        biometricSettingsRepository = biometricSettingsRepository,
-                    ),
-            )
-    }
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardTransitionRepository
+    private val underTest = kosmos.goneToAodTransitionViewModel
+    private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    private val biometricSettingsRepository = kosmos.biometricSettingsRepository
 
     @Test
     fun enterFromTopTranslationY() =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
index 6735e1a..864acfb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags as AConfigFlags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
@@ -67,6 +68,9 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+
+        mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
+
         whenever(burnInHelperWrapper.burnInOffset(anyInt(), any()))
             .thenReturn(RETURNED_BURN_IN_OFFSET)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index ad3e02d..bc0e416 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -24,49 +24,41 @@
 import com.android.keyguard.KeyguardClockSwitch.LARGE
 import com.android.systemui.Flags as AConfigFlags
 import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
 import com.android.systemui.collectLastValue
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
-import com.android.systemui.flags.FakeFeatureFlagsClassic
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.BurnInModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.ClockController
-import com.android.systemui.runCurrent
-import com.android.systemui.runTest
-import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardViewStateRepository
-import com.android.systemui.statusbar.phone.DozeParameters
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.statusbar.notification.data.repository.fakeNotificationsKeyguardViewStateRepository
+import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
+import com.android.systemui.statusbar.phone.dozeParameters
+import com.android.systemui.statusbar.phone.screenOffAnimationController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.ui.isAnimating
 import com.android.systemui.util.ui.stopAnimating
 import com.android.systemui.util.ui.value
 import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
 import javax.inject.Provider
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -76,54 +68,48 @@
 import org.mockito.Mock
 import org.mockito.Mockito.RETURNS_DEEP_STUBS
 import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.withSettings
 import org.mockito.MockitoAnnotations
 
 @SmallTest
 @RunWith(JUnit4::class)
 class KeyguardRootViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos().apply {
+        featureFlagsClassic.apply { set(Flags.MIGRATE_CLOCKS_TO_BLUEPRINT, false) }
+    }
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardRepository
+    private val configurationRepository = kosmos.fakeConfigurationRepository
+    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    private val screenOffAnimationController = kosmos.screenOffAnimationController
+    private val deviceEntryRepository = kosmos.fakeDeviceEntryRepository
+    private val notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor
+    private val fakeNotificationsKeyguardViewStateRepository =
+        kosmos.fakeNotificationsKeyguardViewStateRepository
+    private val dozeParameters = kosmos.dozeParameters
     private lateinit var underTest: KeyguardRootViewModel
-    private lateinit var testScope: TestScope
-    private lateinit var repository: FakeKeyguardRepository
-    private lateinit var keyguardInteractor: KeyguardInteractor
-    private lateinit var configurationRepository: FakeConfigurationRepository
+
     @Mock private lateinit var burnInInteractor: BurnInInteractor
-    @Mock private lateinit var keyguardClockViewModel: KeyguardClockViewModel
-    @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
+    private val burnInFlow = MutableStateFlow(BurnInModel())
+
     @Mock private lateinit var goneToAodTransitionViewModel: GoneToAodTransitionViewModel
+    private val enterFromTopAnimationAlpha = MutableStateFlow(0f)
+
     @Mock
     private lateinit var aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel
     @Mock
     private lateinit var occludedToLockscreenTransitionViewModel:
         OccludedToLockscreenTransitionViewModel
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var clockController: ClockController
-
-    private val burnInFlow = MutableStateFlow(BurnInModel())
-    private val goneToAodTransitionViewModelVisibility = MutableStateFlow(0)
-    private val enterFromTopAnimationAlpha = MutableStateFlow(0f)
     private val occludedToLockscreenTranslationY = MutableStateFlow(0f)
     private val occludedToLockscreenAlpha = MutableStateFlow(0f)
-    private val goneToAodTransitionStep = MutableSharedFlow<TransitionStep>(replay = 1)
-    private val dozeAmountTransitionStep = MutableSharedFlow<TransitionStep>(replay = 1)
-    private val clockSize = MutableStateFlow(LARGE)
-    private val startedKeyguardState = MutableStateFlow(KeyguardState.GONE)
-    private val featureFlags: FakeFeatureFlagsClassic = FakeFeatureFlagsClassic()
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var clockController: ClockController
 
     @Before
     fun setUp() {
-        val testDispatcher = StandardTestDispatcher()
-        testScope = TestScope(testDispatcher)
         MockitoAnnotations.initMocks(this)
 
         mSetFlagsRule.enableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
-
-        featureFlags.set(Flags.MIGRATE_CLOCKS_TO_BLUEPRINT, false)
-
-        val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags)
-        keyguardInteractor = withDeps.keyguardInteractor
-        repository = withDeps.repository
-        configurationRepository = withDeps.configurationRepository
+        mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION)
 
         whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt()))
             .thenReturn(emptyFlow<Float>())
@@ -132,13 +118,6 @@
 
         whenever(burnInInteractor.keyguardBurnIn).thenReturn(burnInFlow)
 
-        whenever(keyguardTransitionInteractor.goneToAodTransition)
-            .thenReturn(goneToAodTransitionStep)
-        whenever(keyguardTransitionInteractor.dozeAmountTransition)
-            .thenReturn(dozeAmountTransitionStep)
-        whenever(keyguardTransitionInteractor.startedKeyguardState).thenReturn(startedKeyguardState)
-        whenever(keyguardClockViewModel.clockSize).thenReturn(clockSize)
-
         whenever(occludedToLockscreenTransitionViewModel.lockscreenTranslationY)
             .thenReturn(occludedToLockscreenTranslationY)
         whenever(occludedToLockscreenTransitionViewModel.lockscreenAlpha)
@@ -146,26 +125,22 @@
 
         underTest =
             KeyguardRootViewModel(
-                ConfigurationInteractor(configurationRepository),
-                deviceEntryInteractor =
-                    mock { whenever(isBypassEnabled).thenReturn(MutableStateFlow(false)) },
-                dozeParameters = mock(),
-                keyguardInteractor,
-                keyguardTransitionInteractor,
-                notificationsKeyguardInteractor =
-                    mock {
-                        whenever(areNotificationsFullyHidden).thenReturn(emptyFlow())
-                        whenever(isPulseExpanding).thenReturn(emptyFlow())
-                    },
-                burnInInteractor,
-                keyguardClockViewModel,
-                goneToAodTransitionViewModel,
-                aodToLockscreenTransitionViewModel,
-                occludedToLockscreenTransitionViewModel,
-                screenOffAnimationController = mock(),
+                configurationInteractor = kosmos.configurationInteractor,
+                deviceEntryInteractor = kosmos.deviceEntryInteractor,
+                dozeParameters = kosmos.dozeParameters,
+                keyguardInteractor = kosmos.keyguardInteractor,
+                keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
+                notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor,
+                burnInInteractor = burnInInteractor,
+                keyguardClockViewModel = kosmos.keyguardClockViewModel,
+                goneToAodTransitionViewModel = goneToAodTransitionViewModel,
+                aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
+                occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
+                screenOffAnimationController = screenOffAnimationController,
                 // TODO(b/310989341): remove after change to aconfig
-                featureFlags
+                featureFlags = kosmos.featureFlagsClassic
             )
+
         underTest.clockControllerProvider = Provider { clockController }
     }
 
@@ -195,7 +170,15 @@
             val scale by collectLastValue(underTest.scale)
 
             // Set to not dozing (on lockscreen)
-            dozeAmountTransitionStep.emit(TransitionStep(value = 0f))
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.LOCKSCREEN,
+                    value = 1f,
+                    transitionState = TransitionState.FINISHED
+                ),
+                validateStep = false,
+            )
 
             // Trigger a change to the burn-in model
             burnInFlow.value =
@@ -220,7 +203,15 @@
             underTest.statusViewTop = 100
 
             // Set to dozing (on AOD)
-            dozeAmountTransitionStep.emit(TransitionStep(value = 1f))
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                    value = 1f,
+                    transitionState = TransitionState.FINISHED
+                ),
+                validateStep = false,
+            )
             // Trigger a change to the burn-in model
             burnInFlow.value =
                 BurnInModel(
@@ -228,12 +219,21 @@
                     translationY = 30,
                     scale = 0.5f,
                 )
+
             assertThat(translationX).isEqualTo(20)
             assertThat(translationY).isEqualTo(30)
             assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */))
 
             // Set to the beginning of GONE->AOD transition
-            goneToAodTransitionStep.emit(TransitionStep(value = 0f))
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                    value = 0f,
+                    transitionState = TransitionState.STARTED
+                ),
+                validateStep = false,
+            )
             assertThat(translationX).isEqualTo(0)
             assertThat(translationY).isEqualTo(0)
             assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */))
@@ -250,7 +250,16 @@
             underTest.topInset = 80
 
             // Set to dozing (on AOD)
-            dozeAmountTransitionStep.emit(TransitionStep(value = 1f))
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                    value = 1f,
+                    transitionState = TransitionState.FINISHED
+                ),
+                validateStep = false,
+            )
+
             // Trigger a change to the burn-in model
             burnInFlow.value =
                 BurnInModel(
@@ -264,7 +273,15 @@
             assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */))
 
             // Set to the beginning of GONE->AOD transition
-            goneToAodTransitionStep.emit(TransitionStep(value = 0f))
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                    value = 0f,
+                    transitionState = TransitionState.STARTED
+                ),
+                validateStep = false,
+            )
             assertThat(translationX).isEqualTo(0)
             assertThat(translationY).isEqualTo(0)
             assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */))
@@ -280,7 +297,15 @@
             val scale by collectLastValue(underTest.scale)
 
             // Set to dozing (on AOD)
-            dozeAmountTransitionStep.emit(TransitionStep(value = 1f))
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                    value = 1f,
+                    transitionState = TransitionState.FINISHED
+                ),
+                validateStep = false,
+            )
 
             // Trigger a change to the burn-in model
             burnInFlow.value =
@@ -300,10 +325,15 @@
         testScope.runTest {
             val burnInLayerVisibility by collectLastValue(underTest.burnInLayerVisibility)
 
-            startedKeyguardState.value = KeyguardState.OCCLUDED
-            assertThat(burnInLayerVisibility).isNull()
-
-            startedKeyguardState.value = KeyguardState.AOD
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.AOD,
+                    value = 0f,
+                    transitionState = TransitionState.STARTED
+                ),
+                validateStep = false,
+            )
             assertThat(burnInLayerVisibility).isEqualTo(View.VISIBLE)
         }
 
@@ -318,165 +348,124 @@
             enterFromTopAnimationAlpha.value = 1f
             assertThat(burnInLayerAlpha).isEqualTo(1f)
         }
-}
 
-@SmallTest
-class KeyguardRootViewModelTestWithFakes : SysuiTestCase() {
-
-    @Component(modules = [SysUITestModule::class])
-    @SysUISingleton
-    interface TestComponent : SysUITestComponent<KeyguardRootViewModel> {
-        val deviceEntryRepository: FakeDeviceEntryRepository
-        val notifsKeyguardRepository: FakeNotificationsKeyguardViewStateRepository
-        val repository: FakeKeyguardRepository
-        val transitionRepository: FakeKeyguardTransitionRepository
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-                featureFlags: FakeFeatureFlagsClassicModule,
-                mocks: TestMocksModule,
-            ): TestComponent
-        }
-    }
-
-    private val clockController: ClockController =
-        mock(withSettings().defaultAnswer(RETURNS_DEEP_STUBS))
-    private val dozeParams: DozeParameters = mock()
-    private val screenOffAnimController: ScreenOffAnimationController = mock()
-
-    private fun runTest(block: suspend TestComponent.() -> Unit): Unit =
-        DaggerKeyguardRootViewModelTestWithFakes_TestComponent.factory()
-            .create(
-                test = this,
-                featureFlags = FakeFeatureFlagsClassicModule(),
-                mocks =
-                    TestMocksModule(
-                        dozeParameters = dozeParams,
-                        screenOffAnimationController = screenOffAnimController,
-                    ),
+    @Test
+    fun iconContainer_isNotVisible_notOnKeyguard_dontShowAodIconsWhenShade() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            keyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.OFF,
+                to = KeyguardState.GONE,
+                testScope,
             )
-            .runTest {
-                reset(clockController)
-                underTest.clockControllerProvider = Provider { clockController }
-                block()
-            }
+            whenever(screenOffAnimationController.shouldShowAodIconsWhenShade()).thenReturn(false)
+            runCurrent()
 
-    @Before
-    fun before() {
-        mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION)
-    }
+            assertThat(isVisible?.value).isFalse()
+            assertThat(isVisible?.isAnimating).isFalse()
+        }
 
     @Test
-    fun iconContainer_isNotVisible_notOnKeyguard_dontShowAodIconsWhenShade() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        transitionRepository.sendTransitionSteps(
-            from = KeyguardState.OFF,
-            to = KeyguardState.GONE,
-            testScope,
-        )
-        whenever(screenOffAnimController.shouldShowAodIconsWhenShade()).thenReturn(false)
-        runCurrent()
+    fun iconContainer_isVisible_bypassEnabled() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            deviceEntryRepository.setBypassEnabled(true)
+            runCurrent()
 
-        assertThat(isVisible?.value).isFalse()
-        assertThat(isVisible?.isAnimating).isFalse()
-    }
+            assertThat(isVisible?.value).isTrue()
+        }
 
     @Test
-    fun iconContainer_isVisible_bypassEnabled() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        deviceEntryRepository.setBypassEnabled(true)
-        runCurrent()
+    fun iconContainer_isNotVisible_pulseExpanding_notBypassing() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(true)
+            deviceEntryRepository.setBypassEnabled(false)
+            runCurrent()
 
-        assertThat(isVisible?.value).isTrue()
-    }
+            assertThat(isVisible?.value).isEqualTo(false)
+        }
 
     @Test
-    fun iconContainer_isNotVisible_pulseExpanding_notBypassing() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        notifsKeyguardRepository.setPulseExpanding(true)
-        deviceEntryRepository.setBypassEnabled(false)
-        runCurrent()
+    fun iconContainer_isVisible_notifsFullyHidden_bypassEnabled() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+            deviceEntryRepository.setBypassEnabled(true)
+            fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+            runCurrent()
 
-        assertThat(isVisible?.value).isEqualTo(false)
-    }
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isTrue()
+        }
 
     @Test
-    fun iconContainer_isVisible_notifsFullyHidden_bypassEnabled() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        notifsKeyguardRepository.setPulseExpanding(false)
-        deviceEntryRepository.setBypassEnabled(true)
-        notifsKeyguardRepository.setNotificationsFullyHidden(true)
-        runCurrent()
+    fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_aodDisabled() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+            deviceEntryRepository.setBypassEnabled(false)
+            whenever(dozeParameters.alwaysOn).thenReturn(false)
+            fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+            runCurrent()
 
-        assertThat(isVisible?.value).isTrue()
-        assertThat(isVisible?.isAnimating).isTrue()
-    }
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isFalse()
+        }
 
     @Test
-    fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_aodDisabled() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        notifsKeyguardRepository.setPulseExpanding(false)
-        deviceEntryRepository.setBypassEnabled(false)
-        whenever(dozeParams.alwaysOn).thenReturn(false)
-        notifsKeyguardRepository.setNotificationsFullyHidden(true)
-        runCurrent()
+    fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_displayNeedsBlanking() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+            deviceEntryRepository.setBypassEnabled(false)
+            whenever(dozeParameters.alwaysOn).thenReturn(true)
+            whenever(dozeParameters.displayNeedsBlanking).thenReturn(true)
+            fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+            runCurrent()
 
-        assertThat(isVisible?.value).isTrue()
-        assertThat(isVisible?.isAnimating).isFalse()
-    }
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isFalse()
+        }
 
     @Test
-    fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled_displayNeedsBlanking() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        notifsKeyguardRepository.setPulseExpanding(false)
-        deviceEntryRepository.setBypassEnabled(false)
-        whenever(dozeParams.alwaysOn).thenReturn(true)
-        whenever(dozeParams.displayNeedsBlanking).thenReturn(true)
-        notifsKeyguardRepository.setNotificationsFullyHidden(true)
-        runCurrent()
+    fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+            deviceEntryRepository.setBypassEnabled(false)
+            whenever(dozeParameters.alwaysOn).thenReturn(true)
+            whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
+            fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+            runCurrent()
 
-        assertThat(isVisible?.value).isTrue()
-        assertThat(isVisible?.isAnimating).isFalse()
-    }
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isTrue()
+        }
 
     @Test
-    fun iconContainer_isVisible_notifsFullyHidden_bypassDisabled() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        notifsKeyguardRepository.setPulseExpanding(false)
-        deviceEntryRepository.setBypassEnabled(false)
-        whenever(dozeParams.alwaysOn).thenReturn(true)
-        whenever(dozeParams.displayNeedsBlanking).thenReturn(false)
-        notifsKeyguardRepository.setNotificationsFullyHidden(true)
-        runCurrent()
+    fun isIconContainerVisible_stopAnimation() =
+        testScope.runTest {
+            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+            runCurrent()
+            fakeNotificationsKeyguardViewStateRepository.setPulseExpanding(false)
+            deviceEntryRepository.setBypassEnabled(false)
+            whenever(dozeParameters.alwaysOn).thenReturn(true)
+            whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
+            fakeNotificationsKeyguardViewStateRepository.setNotificationsFullyHidden(true)
+            runCurrent()
 
-        assertThat(isVisible?.value).isTrue()
-        assertThat(isVisible?.isAnimating).isTrue()
-    }
+            assertThat(isVisible?.isAnimating).isEqualTo(true)
+            isVisible?.stopAnimating()
+            runCurrent()
 
-    @Test
-    fun isIconContainerVisible_stopAnimation() = runTest {
-        val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
-        runCurrent()
-        notifsKeyguardRepository.setPulseExpanding(false)
-        deviceEntryRepository.setBypassEnabled(false)
-        whenever(dozeParams.alwaysOn).thenReturn(true)
-        whenever(dozeParams.displayNeedsBlanking).thenReturn(false)
-        notifsKeyguardRepository.setNotificationsFullyHidden(true)
-        runCurrent()
-
-        assertThat(isVisible?.isAnimating).isEqualTo(true)
-        isVisible?.stopAnimating()
-        runCurrent()
-
-        assertThat(isVisible?.isAnimating).isEqualTo(false)
-    }
+            assertThat(isVisible?.isAnimating).isEqualTo(false)
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelTest.kt
index 2314c83..c15a2c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelTest.kt
@@ -18,88 +18,47 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
-import com.android.systemui.collectLastValue
-import com.android.systemui.collectValues
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
 import com.android.systemui.flags.Flags.FULL_SCREEN_USER_SWITCHER
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.runCurrent
-import com.android.systemui.runTest
-import com.android.systemui.shade.data.repository.FakeShadeRepository
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
 import kotlin.test.Test
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.runner.RunWith
 
 @ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToAodTransitionViewModelTest : SysuiTestCase() {
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent : SysUITestComponent<LockscreenToAodTransitionViewModel> {
-        val repository: FakeKeyguardTransitionRepository
-        val deviceEntryRepository: FakeDeviceEntryRepository
-        val keyguardRepository: FakeKeyguardRepository
-        val shadeRepository: FakeShadeRepository
-        val fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-        val biometricSettingsRepository: FakeBiometricSettingsRepository
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-                featureFlags: FakeFeatureFlagsClassicModule,
-                mocks: TestMocksModule,
-            ): TestComponent
-        }
-    }
-
-    private fun TestComponent.shadeExpanded(expanded: Boolean) {
-        if (expanded) {
-            shadeRepository.setQsExpansion(1f)
-        } else {
-            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
-            shadeRepository.setQsExpansion(0f)
-            shadeRepository.setLockscreenShadeExpansion(0f)
-        }
-    }
-
-    private val testComponent: TestComponent =
-        DaggerLockscreenToAodTransitionViewModelTest_TestComponent.factory()
-            .create(
-                test = this,
-                featureFlags =
-                    FakeFeatureFlagsClassicModule { set(FULL_SCREEN_USER_SWITCHER, true) },
-                mocks = TestMocksModule(),
-            )
+    private val kosmos =
+        testKosmos().apply { featureFlagsClassic.apply { set(FULL_SCREEN_USER_SWITCHER, false) } }
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardTransitionRepository
+    private val shadeRepository = kosmos.shadeRepository
+    private val keyguardRepository = kosmos.fakeKeyguardRepository
+    private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    private val biometricSettingsRepository = kosmos.biometricSettingsRepository
+    private val underTest = kosmos.lockscreenToAodTransitionViewModel
 
     @Test
     fun backgroundViewAlpha_shadeNotExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val actual by collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
             shadeExpanded(false)
             runCurrent()
@@ -121,7 +80,7 @@
 
     @Test
     fun backgroundViewAlpha_shadeExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val actual by collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
             shadeExpanded(true)
             runCurrent()
@@ -142,7 +101,7 @@
 
     @Test
     fun deviceEntryParentViewAlpha_udfpsEnrolled_shadeNotExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val values by collectValues(underTest.deviceEntryParentViewAlpha)
             fingerprintPropertyRepository.supportsUdfps()
             biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
@@ -165,7 +124,7 @@
 
     @Test
     fun deviceEntryParentViewAlpha_udfpsEnrolled_shadeExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val actual by collectLastValue(underTest.deviceEntryParentViewAlpha)
             fingerprintPropertyRepository.supportsUdfps()
             biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
@@ -189,7 +148,7 @@
 
     @Test
     fun deviceEntryParentViewAlpha_rearFp_shadeNotExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val actual by collectLastValue(underTest.deviceEntryParentViewAlpha)
             fingerprintPropertyRepository.supportsRearFps()
             shadeExpanded(false)
@@ -212,7 +171,7 @@
 
     @Test
     fun deviceEntryParentViewAlpha_rearFp_shadeExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val values by collectValues(underTest.deviceEntryParentViewAlpha)
             fingerprintPropertyRepository.supportsRearFps()
             shadeExpanded(true)
@@ -232,6 +191,16 @@
             values.forEach { assertThat(it).isEqualTo(0f) }
         }
 
+    private fun shadeExpanded(expanded: Boolean) {
+        if (expanded) {
+            shadeRepository.setQsExpansion(1f)
+        } else {
+            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            shadeRepository.setQsExpansion(0f)
+            shadeRepository.setLockscreenShadeExpansion(0f)
+        }
+    }
+
     private fun step(
         value: Float,
         state: TransitionState = TransitionState.RUNNING
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
index 1494c92..8b05a54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
@@ -20,16 +20,15 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -37,37 +36,25 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToGoneTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: LockscreenToGoneTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest =
-            LockscreenToGoneTransitionViewModel(
-                interactor,
-            )
-    }
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardTransitionRepository
+    private val underTest = kosmos.lockscreenToGoneTransitionViewModel
 
     @Test
-    fun deviceEntryParentViewHides() = runTest {
-        val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        repository.sendTransitionStep(step(0.1f))
-        repository.sendTransitionStep(step(0.3f))
-        repository.sendTransitionStep(step(0.4f))
-        repository.sendTransitionStep(step(0.5f))
-        repository.sendTransitionStep(step(0.6f))
-        repository.sendTransitionStep(step(0.8f))
-        repository.sendTransitionStep(step(1f))
-        deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(0f) }
-    }
+    fun deviceEntryParentViewHides() =
+        testScope.runTest {
+            val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.4f))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(0.6f))
+            repository.sendTransitionStep(step(0.8f))
+            repository.sendTransitionStep(step(1f))
+            deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(0f) }
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
index 049e4e2..b31968c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
@@ -18,81 +18,44 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.runCurrent
-import com.android.systemui.runTest
-import com.android.systemui.shade.data.repository.FakeShadeRepository
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth
-import dagger.BindsInstance
-import dagger.Component
 import kotlin.test.Test
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.runner.RunWith
 
 @ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent : SysUITestComponent<LockscreenToPrimaryBouncerTransitionViewModel> {
-        val repository: FakeKeyguardTransitionRepository
-        val keyguardRepository: FakeKeyguardRepository
-        val shadeRepository: FakeShadeRepository
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-                featureFlags: FakeFeatureFlagsClassicModule,
-                mocks: TestMocksModule,
-            ): TestComponent
+    private val kosmos =
+        testKosmos().apply {
+            featureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) }
         }
-    }
-
-    private fun TestComponent.shadeExpanded(expanded: Boolean) {
-        if (expanded) {
-            shadeRepository.setQsExpansion(1f)
-        } else {
-            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
-            shadeRepository.setQsExpansion(0f)
-            shadeRepository.setLockscreenShadeExpansion(0f)
-        }
-    }
-
-    private val testComponent: TestComponent =
-        DaggerLockscreenToPrimaryBouncerTransitionViewModelTest_TestComponent.factory()
-            .create(
-                test = this,
-                featureFlags =
-                    FakeFeatureFlagsClassicModule { set(Flags.FULL_SCREEN_USER_SWITCHER, true) },
-                mocks = TestMocksModule(),
-            )
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardTransitionRepository
+    private val shadeRepository = kosmos.shadeRepository
+    private val keyguardRepository = kosmos.fakeKeyguardRepository
+    private val underTest = kosmos.lockscreenToPrimaryBouncerTransitionViewModel
 
     @Test
     fun deviceEntryParentViewAlpha_shadeExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val actual by collectLastValue(underTest.deviceEntryParentViewAlpha)
             shadeExpanded(true)
             runCurrent()
@@ -117,7 +80,7 @@
 
     @Test
     fun deviceEntryParentViewAlpha_shadeNotExpanded() =
-        testComponent.runTest {
+        testScope.runTest {
             val actual by collectLastValue(underTest.deviceEntryParentViewAlpha)
             shadeExpanded(false)
             runCurrent()
@@ -153,4 +116,14 @@
             ownerName = "LockscreenToPrimaryBouncerTransitionViewModelTest"
         )
     }
+
+    private fun shadeExpanded(expanded: Boolean) {
+        if (expanded) {
+            shadeRepository.setQsExpansion(1f)
+        } else {
+            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            shadeRepository.setQsExpansion(0f)
+            shadeRepository.setLockscreenShadeExpansion(0f)
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt
index 0eb8ff6..5e62317 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt
@@ -19,21 +19,18 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -41,119 +38,105 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OccludedToAodTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: OccludedToAodTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-    private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
 
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
-
-        underTest =
-            OccludedToAodTransitionViewModel(
-                KeyguardTransitionInteractorFactory.create(
-                        scope = TestScope().backgroundScope,
-                        repository = repository,
-                    )
-                    .keyguardTransitionInteractor,
-                DeviceEntryUdfpsInteractor(
-                    fingerprintPropertyRepository = fingerprintPropertyRepository,
-                    fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
-                    biometricSettingsRepository = biometricSettingsRepository,
-                ),
-            )
-    }
+    val biometricSettingsRepository = kosmos.biometricSettingsRepository
+    val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    val underTest = kosmos.occludedToAodTransitionViewModel
 
     @Test
-    fun deviceEntryBackgroundViewAlpha() = runTest {
-        val deviceEntryBackgroundViewAlpha by
-            collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
+    fun deviceEntryBackgroundViewAlpha() =
+        testScope.runTest {
+            val deviceEntryBackgroundViewAlpha by
+                collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
 
-        // immediately 0f
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+            // immediately 0f
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
 
-        repository.sendTransitionStep(step(0.4f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+            keyguardTransitionRepository.sendTransitionStep(step(0.4f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
 
-        repository.sendTransitionStep(step(.85f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+            keyguardTransitionRepository.sendTransitionStep(step(.85f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+        }
 
     @Test
-    fun deviceEntryParentViewAlpha_udfpsEnrolled() = runTest {
-        fingerprintPropertyRepository.supportsUdfps()
-        biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-        val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+    fun deviceEntryParentViewAlpha_udfpsEnrolled() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
 
-        // immediately 1f
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+            // immediately 1f
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(0.5f))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(.95f))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(.95f))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+        }
 
     @Test
-    fun deviceEntryParentViewAlpha_rearFpEnrolled_noUpdates() = runTest {
-        fingerprintPropertyRepository.supportsRearFps()
-        biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-        val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+    fun deviceEntryParentViewAlpha_rearFpEnrolled_noUpdates() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsRearFps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
 
-        // no updates
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            // no updates
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(0.5f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(.95f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(.95f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+        }
 
     @Test
-    fun deviceEntryParentViewAlpha_udfpsNotEnrolled_noUpdates() = runTest {
-        fingerprintPropertyRepository.supportsUdfps()
-        biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
-        val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+    fun deviceEntryParentViewAlpha_udfpsNotEnrolled_noUpdates() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
 
-        // no updates
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            // no updates
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(0.5f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(.95f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(.95f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
index 350b310..9729022 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
@@ -19,21 +19,18 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -41,113 +38,100 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToAodTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: PrimaryBouncerToAodTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-    private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
 
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
-        val interactor =
-            KeyguardTransitionInteractorFactory.create(
-                    scope = TestScope().backgroundScope,
-                    repository = repository,
-                )
-                .keyguardTransitionInteractor
-        underTest =
-            PrimaryBouncerToAodTransitionViewModel(
-                interactor,
-                DeviceEntryUdfpsInteractor(
-                    fingerprintPropertyRepository = fingerprintPropertyRepository,
-                    fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
-                    biometricSettingsRepository = biometricSettingsRepository,
-                ),
-            )
-    }
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
+
+    val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    val biometricSettingsRepository = kosmos.biometricSettingsRepository
+
+    val underTest = kosmos.primaryBouncerToAodTransitionViewModel
 
     @Test
-    fun deviceEntryBackgroundViewAlpha() = runTest {
-        fingerprintPropertyRepository.supportsUdfps()
-        val deviceEntryBackgroundViewAlpha by
-            collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
+    fun deviceEntryBackgroundViewAlpha() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            val deviceEntryBackgroundViewAlpha by
+                collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
 
-        // immediately 0f
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+            // immediately 0f
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
 
-        repository.sendTransitionStep(step(0.4f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+            keyguardTransitionRepository.sendTransitionStep(step(0.4f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
 
-        repository.sendTransitionStep(step(.85f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+            keyguardTransitionRepository.sendTransitionStep(step(.85f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+        }
 
     @Test
-    fun deviceEntryParentViewAlpha_udfpsEnrolled_fadeIn() = runTest {
-        fingerprintPropertyRepository.supportsUdfps()
-        biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-        val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+    fun deviceEntryParentViewAlpha_udfpsEnrolled_fadeIn() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
 
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
 
-        repository.sendTransitionStep(step(0.5f))
-        repository.sendTransitionStep(step(.75f))
-        repository.sendTransitionStep(step(1f))
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            keyguardTransitionRepository.sendTransitionStep(step(.75f))
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+        }
 
     @Test
-    fun deviceEntryParentViewAlpha_rearFpEnrolled_noUpdates() = runTest {
-        fingerprintPropertyRepository.supportsRearFps()
-        biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-        val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+    fun deviceEntryParentViewAlpha_rearFpEnrolled_noUpdates() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsRearFps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
 
-        // animation doesn't start until the end
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            // animation doesn't start until the end
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(0.5f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(.95f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(.95f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+        }
 
     @Test
-    fun deviceEntryParentViewAlpha_udfpsNotEnrolled_noUpdates() = runTest {
-        fingerprintPropertyRepository.supportsUdfps()
-        biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
-        val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+    fun deviceEntryParentViewAlpha_udfpsNotEnrolled_noUpdates() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
 
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(0.5f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(.75f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(.75f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryParentViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(deviceEntryParentViewAlpha).isNull()
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
index 24e4920..2c6436e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
@@ -19,21 +19,18 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -41,91 +38,77 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToLockscreenTransitionViewModelTest : SysuiTestCase() {
-    private lateinit var underTest: PrimaryBouncerToLockscreenTransitionViewModel
-    private lateinit var repository: FakeKeyguardTransitionRepository
-    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
-    private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
 
-    @Before
-    fun setUp() {
-        repository = FakeKeyguardTransitionRepository()
-        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
+    val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    val biometricSettingsRepository = kosmos.biometricSettingsRepository
 
-        underTest =
-            PrimaryBouncerToLockscreenTransitionViewModel(
-                KeyguardTransitionInteractorFactory.create(
-                        scope = TestScope().backgroundScope,
-                        repository = repository,
-                    )
-                    .keyguardTransitionInteractor,
-                DeviceEntryUdfpsInteractor(
-                    fingerprintPropertyRepository = fingerprintPropertyRepository,
-                    fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
-                    biometricSettingsRepository = biometricSettingsRepository,
-                ),
-            )
-    }
+    val underTest = kosmos.primaryBouncerToLockscreenTransitionViewModel
 
     @Test
-    fun deviceEntryParentViewAlpha() = runTest {
-        val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+    fun deviceEntryParentViewAlpha() =
+        testScope.runTest {
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
 
-        // immediately 1f
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+            // immediately 1f
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(0.4f))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(0.4f))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(.85f))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(.85f))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+        }
 
     @Test
-    fun deviceEntryBackgroundViewAlpha_udfpsEnrolled_show() = runTest {
-        fingerprintPropertyRepository.supportsUdfps()
-        val bgViewAlpha by collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
+    fun deviceEntryBackgroundViewAlpha_udfpsEnrolled_show() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            val bgViewAlpha by collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
 
-        // immediately 1f
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(bgViewAlpha).isEqualTo(1f)
+            // immediately 1f
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(bgViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(0.1f))
-        assertThat(bgViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(0.1f))
+            assertThat(bgViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(.3f))
-        assertThat(bgViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(.3f))
+            assertThat(bgViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(.5f))
-        assertThat(bgViewAlpha).isEqualTo(1f)
+            keyguardTransitionRepository.sendTransitionStep(step(.5f))
+            assertThat(bgViewAlpha).isEqualTo(1f)
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(bgViewAlpha).isEqualTo(1f)
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(bgViewAlpha).isEqualTo(1f)
+        }
 
     @Test
-    fun deviceEntryBackgroundViewAlpha_rearFpEnrolled_noUpdates() = runTest {
-        fingerprintPropertyRepository.supportsRearFps()
-        val bgViewAlpha by collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
-        repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-        assertThat(bgViewAlpha).isNull()
+    fun deviceEntryBackgroundViewAlpha_rearFpEnrolled_noUpdates() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsRearFps()
+            val bgViewAlpha by collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
+            keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(bgViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(0.5f))
-        assertThat(bgViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+            assertThat(bgViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(.75f))
-        assertThat(bgViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(.75f))
+            assertThat(bgViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f))
-        assertThat(bgViewAlpha).isNull()
+            keyguardTransitionRepository.sendTransitionStep(step(1f))
+            assertThat(bgViewAlpha).isNull()
 
-        repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-        assertThat(bgViewAlpha).isNull()
-    }
+            keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(bgViewAlpha).isNull()
+        }
 
     private fun step(
         value: Float,
diff --git a/packages/SystemUI/tests/utils/src/com/android/keyguard/logging/BiometricUnlockLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/keyguard/logging/BiometricUnlockLoggerKosmos.kt
new file mode 100644
index 0000000..f55ae2f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/keyguard/logging/BiometricUnlockLoggerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.keyguard.logging
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.biometricUnlockLogger by Kosmos.Fixture { mock<BiometricUnlockLogger>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/keyguard/logging/KeyguardTransitionAnimationLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/keyguard/logging/KeyguardTransitionAnimationLoggerKosmos.kt
new file mode 100644
index 0000000..db2a87e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/keyguard/logging/KeyguardTransitionAnimationLoggerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 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.keyguard.logging
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.keyguardTransitionAnimationLogger by
+    Kosmos.Fixture { mock<KeyguardTransitionAnimationLogger>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt
new file mode 100644
index 0000000..5475659
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 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.biometrics.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.viewmodel.deviceEntryIconViewModel
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.statusbar.phone.systemUIDialogManager
+
+val Kosmos.deviceEntryUdfpsTouchOverlayViewModel by Fixture {
+    DeviceEntryUdfpsTouchOverlayViewModel(
+        deviceEntryIconViewModel = deviceEntryIconViewModel,
+        systemUIDialogManager = systemUIDialogManager,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorKosmos.kt
new file mode 100644
index 0000000..06b6cda6
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.bouncer.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.primaryBouncerInteractor by Kosmos.Fixture { mock<PrimaryBouncerInteractor>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorKosmos.kt
new file mode 100644
index 0000000..7e0e5f3
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 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.common.ui.domain.interactor
+
+import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.configurationInteractor: ConfigurationInteractor by
+    Kosmos.Fixture { ConfigurationInteractor(configurationRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/DeviceEntryHapticsRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/DeviceEntryHapticsRepositoryKosmos.kt
new file mode 100644
index 0000000..8bb07d9
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/DeviceEntryHapticsRepositoryKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 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.deviceentry.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.deviceEntryHapticsRepository: DeviceEntryHapticsRepository by
+    Kosmos.Fixture { fakeDeviceEntryHapticsRepository }
+val Kosmos.fakeDeviceEntryHapticsRepository by Kosmos.Fixture { FakeDeviceEntryHapticsRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
new file mode 100644
index 0000000..de6cacb
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.deviceentry.domain.interactor
+
+import com.android.keyguard.logging.biometricUnlockLogger
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryHapticsRepository
+import com.android.systemui.keyevent.domain.interactor.keyEventInteractor
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.util.time.fakeSystemClock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.deviceEntryHapticsInteractor by
+    Kosmos.Fixture {
+        DeviceEntryHapticsInteractor(
+            repository = fakeDeviceEntryHapticsRepository,
+            fingerprintPropertyRepository = fingerprintPropertyRepository,
+            biometricSettingsRepository = biometricSettingsRepository,
+            keyEventInteractor = keyEventInteractor,
+            powerInteractor = powerInteractor,
+            systemClock = fakeSystemClock,
+            logger = biometricUnlockLogger,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/KeyEventRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/KeyEventRepositoryKosmos.kt
new file mode 100644
index 0000000..1238a7a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/KeyEventRepositoryKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.keyevent.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.keyEventRepository: KeyEventRepository by Kosmos.Fixture { fakeKeyEventRepository }
+val Kosmos.fakeKeyEventRepository by Kosmos.Fixture { FakeKeyEventRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorKosmos.kt
new file mode 100644
index 0000000..53a1b03
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 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.keyevent.domain.interactor
+
+import com.android.systemui.keyevent.data.repository.keyEventRepository
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.keyEventInteractor by
+    Kosmos.Fixture { KeyEventInteractor(repository = keyEventRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
index bb84036..58d99b5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
-import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.keyguard.data.repository.keyguardRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.power.domain.interactor.powerInteractor
@@ -34,7 +34,7 @@
             powerInteractor = powerInteractor,
             sceneContainerFlags = sceneContainerFlags,
             bouncerRepository = keyguardBouncerRepository,
-            configurationRepository = configurationRepository,
+            configurationInteractor = configurationInteractor,
             shadeRepository = shadeRepository,
             sceneInteractorProvider = { sceneInteractor },
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt
new file mode 100644
index 0000000..8d6529a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui
+
+import com.android.keyguard.logging.keyguardTransitionAnimationLogger
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.keyguardTransitionAnimationFlow by Fixture {
+    KeyguardTransitionAnimationFlow(
+        scope = applicationCoroutineScope,
+        logger = keyguardTransitionAnimationLogger,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt
new file mode 100644
index 0000000..9f0466d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.alternateBouncerViewModel by Fixture {
+    AlternateBouncerViewModel(
+        statusBarKeyguardViewManager = statusBarKeyguardViewManager,
+        transitionInteractor = keyguardTransitionInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..44e5426
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.aodToGoneTransitionViewModel by Fixture {
+    AodToGoneTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt
index a31ab3e..b5a5f03 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt
@@ -20,6 +20,7 @@
 
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -28,5 +29,6 @@
     AodToLockscreenTransitionViewModel(
         interactor = keyguardTransitionInteractor,
         deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..27ad0f0
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.aodToOccludedTransitionViewModel by Fixture {
+    AodToOccludedTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt
new file mode 100644
index 0000000..6ffcc9a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.sysuiStatusBarStateController
+import com.android.systemui.util.mockito.mock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.bouncerToGoneFlows by Fixture {
+    BouncerToGoneFlows(
+        interactor = keyguardTransitionInteractor,
+        statusBarStateController = sysuiStatusBarStateController,
+        primaryBouncerInteractor = primaryBouncerInteractor,
+        keyguardDismissActionInteractor = mock(),
+        featureFlags = featureFlagsClassic,
+        shadeInteractor = shadeInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
new file mode 100644
index 0000000..299262b
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 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.keyguard.ui.viewmodel
+
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryHapticsInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.burnInInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.scene.shared.flag.sceneContainerFlags
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
+
+val Kosmos.deviceEntryIconViewModelTransitionsMock by Fixture {
+    mutableSetOf<DeviceEntryIconTransition>()
+}
+
+val Kosmos.deviceEntryIconViewModel by Fixture {
+    DeviceEntryIconViewModel(
+        transitions = deviceEntryIconViewModelTransitionsMock,
+        burnInInteractor = burnInInteractor,
+        shadeInteractor = shadeInteractor,
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        transitionInteractor = keyguardTransitionInteractor,
+        keyguardInteractor = keyguardInteractor,
+        viewModel = aodToLockscreenTransitionViewModel,
+        shadeDependentFlows = shadeDependentFlows,
+        sceneContainerFlags = sceneContainerFlags,
+        keyguardViewController = { statusBarKeyguardViewManager },
+        deviceEntryHapticsInteractor = deviceEntryHapticsInteractor,
+        deviceEntryInteractor = deviceEntryInteractor,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..8b5407c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.util.mockito.mock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.dreamingToLockscreenTransitionViewModel by Fixture {
+    DreamingToLockscreenTransitionViewModel(
+        keyguardTransitionInteractor = keyguardTransitionInteractor,
+        fromDreamingTransitionInteractor = mock(),
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
index 5db95cf..14e2cff 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
@@ -20,6 +20,7 @@
 
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -27,6 +28,7 @@
 val Kosmos.goneToAodTransitionViewModel by Fixture {
     GoneToAodTransitionViewModel(
         interactor = keyguardTransitionInteractor,
-        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..073b34b
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.goneToDreamingTransitionViewModel by Fixture {
+    GoneToDreamingTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
index 4f807e3..13ee747 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
@@ -18,7 +18,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import android.content.applicationContext
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.keyguard.domain.interactor.burnInInteractor
@@ -33,7 +33,7 @@
 
 val Kosmos.keyguardRootViewModel by Fixture {
     KeyguardRootViewModel(
-        context = applicationContext,
+        configurationInteractor = configurationInteractor,
         deviceEntryInteractor = deviceEntryInteractor,
         dozeParameters = dozeParameters,
         keyguardInteractor = keyguardInteractor,
@@ -42,6 +42,7 @@
         burnInInteractor = burnInInteractor,
         goneToAodTransitionViewModel = goneToAodTransitionViewModel,
         aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
+        occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
         screenOffAnimationController = screenOffAnimationController,
         keyguardClockViewModel = keyguardClockViewModel,
         featureFlags = FakeFeatureFlagsClassic(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..7865f71
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.lockscreenToAodTransitionViewModel by Fixture {
+    LockscreenToAodTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        shadeDependentFlows = shadeDependentFlows,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..b9f4b71
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.lockscreenToDreamingTransitionViewModel by Fixture {
+    LockscreenToDreamingTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        shadeDependentFlows = shadeDependentFlows,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..475aa2d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.lockscreenToGoneTransitionViewModel by Fixture {
+    LockscreenToGoneTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..8541a4f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.lockscreenToOccludedTransitionViewModel by Fixture {
+    LockscreenToOccludedTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        shadeDependentFlows = shadeDependentFlows,
+        configurationInteractor = configurationInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..65c47fc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.lockscreenToPrimaryBouncerTransitionViewModel by Fixture {
+    LockscreenToPrimaryBouncerTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        shadeDependentFlows = shadeDependentFlows,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..ddde549
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.occludedToAodTransitionViewModel by Fixture {
+    OccludedToAodTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..5bbde2b
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.occludedToLockscreenTransitionViewModel by Fixture {
+    OccludedToLockscreenTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        configurationInteractor = configurationInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..a7f29d6
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.primaryBouncerToAodTransitionViewModel by Fixture {
+    PrimaryBouncerToAodTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..ace6ae3
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.statusbar.sysuiStatusBarStateController
+import com.android.systemui.util.mockito.mock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.primaryBouncerToGoneTransitionViewModel by Fixture {
+    PrimaryBouncerToGoneTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        statusBarStateController = sysuiStatusBarStateController,
+        primaryBouncerInteractor = primaryBouncerInteractor,
+        keyguardDismissActionInteractor = mock(),
+        featureFlags = featureFlagsClassic,
+        bouncerToGoneFlows = bouncerToGoneFlows,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..3bbabf7
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.primaryBouncerToLockscreenTransitionViewModel by Fixture {
+    PrimaryBouncerToLockscreenTransitionViewModel(
+        interactor = keyguardTransitionInteractor,
+        deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        animationFlow = keyguardTransitionAnimationFlow,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SysuiStatusBarStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SysuiStatusBarStateControllerKosmos.kt
new file mode 100644
index 0000000..fead581
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SysuiStatusBarStateControllerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 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.statusbar
+
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.sysuiStatusBarStateController by Kosmos.Fixture { FakeStatusBarStateController() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index c17083c..e2479fe 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.viewmodel.occludedToLockscreenTransitionViewModel
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.applicationCoroutineScope
@@ -31,5 +32,6 @@
         keyguardInteractor = keyguardInteractor,
         keyguardTransitionInteractor = keyguardTransitionInteractor,
         shadeInteractor = shadeInteractor,
+        occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt
new file mode 100644
index 0000000..4e15ea2
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.statusbar.phone
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.statusBarKeyguardViewManager by Kosmos.Fixture { mock<StatusBarKeyguardViewManager>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogManagerKosmos.kt
new file mode 100644
index 0000000..7dfbf2a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.statusbar.phone
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.systemUIDialogManager by Kosmos.Fixture { mock<SystemUIDialogManager>() }