Merge "Move ContentState.Transition back into TransitionState.Transition (1/2)" into main
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
index bcdb259..eae46e9 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
@@ -111,7 +111,7 @@
                     1f
                 }
 
-            val dir = if (transition.toScene == splitShadeLargeClockScene) -1f else 1f
+            val dir = if (transition.toContent == splitShadeLargeClockScene) -1f else 1f
             val distance = dir * getClockCenteringDistance()
             val largeClock = checkNotNull(currentClock).largeClock
             largeClock.animations.onPositionUpdated(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
index 70c0db1..5dccb68 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
@@ -21,7 +21,7 @@
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.SceneTransitionLayoutState
 import com.android.compose.animation.scene.StaticElementContentPicker
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.systemui.scene.shared.model.Scenes
 
 /** [ElementContentPicker] implementation for the media carousel object. */
@@ -38,7 +38,7 @@
 
     override fun contentDuringTransition(
         element: ElementKey,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         fromContentZIndex: Float,
         toContentZIndex: Float
     ): ContentKey {
@@ -64,7 +64,7 @@
     }
 
     /** Returns true when the media should be laid on top of the rest for the given [transition]. */
-    fun shouldElevateMedia(transition: ContentState.Transition<*>): Boolean {
+    fun shouldElevateMedia(transition: TransitionState.Transition): Boolean {
         return transition.isTransitioningBetween(Scenes.Lockscreen, Scenes.Shade)
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
index 0555346..fc4a8a5 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
@@ -98,7 +98,7 @@
                 else -> QSSceneAdapter.State.CLOSED
             }
         }
-        is TransitionState.Transition ->
+        is TransitionState.Transition.ChangeCurrentScene ->
             with(transitionState) {
                 when {
                     isSplitShade -> UnsquishingQS(squishiness)
@@ -108,16 +108,16 @@
                     fromScene == Scenes.QuickSettings && toScene == Scenes.Shade -> {
                         Collapsing { progress }
                     }
-                    fromScene == Scenes.Shade || toScene == Scenes.Shade -> {
+                    fromContent == Scenes.Shade || toContent == Scenes.Shade -> {
                         UnsquishingQQS(squishiness)
                     }
-                    fromScene == Scenes.QuickSettings || toScene == Scenes.QuickSettings -> {
+                    fromContent == Scenes.QuickSettings || toContent == Scenes.QuickSettings -> {
                         QSSceneAdapter.State.QS
                     }
                     else ->
                         error(
-                            "Bad transition for QuickSettings: fromScene=$fromScene," +
-                                " toScene=$toScene"
+                            "Bad transition for QuickSettings: fromContent=$fromContent," +
+                                " toScene=$toContent"
                         )
                 }
             }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index e064724..d16ba0d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -253,7 +253,7 @@
         val isScrollable =
             when (val state = layoutState.transitionState) {
                 is TransitionState.Idle -> true
-                is TransitionState.Transition -> state.fromScene == Scenes.QuickSettings
+                is TransitionState.Transition -> state.fromContent == Scenes.QuickSettings
             }
 
         LaunchedEffect(isCustomizing, scrollState) {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt
index 5eabd22..2bc8c87 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt
@@ -19,14 +19,14 @@
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.AnimationVector1D
 import androidx.compose.animation.core.SpringSpec
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 
 internal fun CoroutineScope.animateContent(
-    transition: ContentState.Transition<*>,
+    transition: TransitionState.Transition,
     oneOffAnimation: OneOffAnimation,
     targetProgress: Float,
     startTransition: () -> Unit,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
index ae5a84b..ea708a5 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
@@ -396,8 +396,8 @@
             return sharedValue[layoutImpl.state.transitionState.currentScene]
         }
 
-        val fromValue = sharedValue[transition.fromScene]
-        val toValue = sharedValue[transition.toScene]
+        val fromValue = sharedValue[transition.fromContent]
+        val toValue = sharedValue[transition.toContent]
         return if (fromValue != null && toValue != null) {
             if (fromValue == toValue) {
                 // Optimization: avoid reading progress if the values are the same, so we don't
@@ -411,7 +411,7 @@
                             if (canOverflow) transition.progress
                             else transition.progress.fastCoerceIn(0f, 1f)
                         }
-                        overscrollSpec.scene == transition.toScene -> 1f
+                        overscrollSpec.scene == transition.toContent -> 1f
                         else -> 0f
                     }
 
@@ -426,12 +426,12 @@
             if (element != null) {
                 layoutImpl.elements[element]?.stateByContent?.let { sceneStates ->
                     layoutImpl.state.currentTransitions.fastLastOrNull { transition ->
-                        transition.fromScene in sceneStates || transition.toScene in sceneStates
+                        transition.fromContent in sceneStates || transition.toContent in sceneStates
                     }
                 }
             } else {
                 layoutImpl.state.currentTransitions.fastLastOrNull { transition ->
-                    transition.fromScene in targetValues || transition.toScene in targetValues
+                    transition.fromContent in targetValues || transition.toContent in targetValues
                 }
             }
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
index 920c234..f2c2a36 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
@@ -28,7 +28,7 @@
     layoutState: MutableSceneTransitionLayoutStateImpl,
     target: SceneKey,
     transitionKey: TransitionKey?,
-): TransitionState.Transition? {
+): TransitionState.Transition.ChangeCurrentScene? {
     val transitionState = layoutState.transitionState
     if (transitionState.currentScene == target) {
         // This can happen in 3 different situations, for which there isn't anything else to do:
@@ -52,7 +52,7 @@
                 replacedTransition = null,
             )
         }
-        is TransitionState.Transition -> {
+        is TransitionState.Transition.ChangeCurrentScene -> {
             val isInitiatedByUserInput = transitionState.isInitiatedByUserInput
 
             // A transition is currently running: first check whether `transition.toScene` or
@@ -136,7 +136,7 @@
     reversed: Boolean = false,
     fromScene: SceneKey = layoutState.transitionState.currentScene,
     chain: Boolean = true,
-): TransitionState.Transition {
+): TransitionState.Transition.ChangeCurrentScene {
     val oneOffAnimation = OneOffAnimation()
     val targetProgress = if (reversed) 0f else 1f
     val transition =
@@ -181,7 +181,7 @@
     override val isInitiatedByUserInput: Boolean,
     replacedTransition: TransitionState.Transition?,
     private val oneOffAnimation: OneOffAnimation,
-) : TransitionState.Transition(fromScene, toScene, replacedTransition) {
+) : TransitionState.Transition.ChangeCurrentScene(fromScene, toScene, replacedTransition) {
     override val progress: Float
         get() = oneOffAnimation.progress
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index 83db724..7787458 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -31,9 +31,8 @@
 import androidx.compose.ui.unit.round
 import androidx.compose.ui.util.fastCoerceIn
 import com.android.compose.animation.scene.content.Scene
-import com.android.compose.animation.scene.content.state.ContentState
-import com.android.compose.animation.scene.content.state.ContentState.HasOverscrollProperties.Companion.DistanceUnspecified
 import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
 import com.android.compose.nestedscroll.PriorityNestedScrollConnection
 import kotlin.math.absoluteValue
 import kotlinx.coroutines.CoroutineScope
@@ -582,8 +581,8 @@
     replacedTransition: SwipeTransition?,
     var lastDistance: Float = DistanceUnspecified,
 ) :
-    TransitionState.Transition(_fromScene.key, _toScene.key, replacedTransition),
-    ContentState.HasOverscrollProperties {
+    TransitionState.Transition.ChangeCurrentScene(_fromScene.key, _toScene.key, replacedTransition),
+    TransitionState.HasOverscrollProperties {
     var _currentScene by mutableStateOf(_fromScene)
     override val currentScene: SceneKey
         get() = _currentScene.key
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index e619814..7dac2e4 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -49,7 +49,6 @@
 import androidx.compose.ui.util.fastLastOrNull
 import androidx.compose.ui.util.lerp
 import com.android.compose.animation.scene.content.Content
-import com.android.compose.animation.scene.content.state.ContentState
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.transformation.PropertyTransformation
 import com.android.compose.animation.scene.transformation.SharedElementTransformation
@@ -69,7 +68,7 @@
      * The last transition that was used when computing the state (size, position and alpha) of this
      * element in any content, or `null` if it was last laid out when idle.
      */
-    var lastTransition: ContentState.Transition<*>? = null
+    var lastTransition: TransitionState.Transition? = null
 
     /** Whether this element was ever drawn in a content. */
     var wasDrawnInAnyContent = false
@@ -312,7 +311,7 @@
     }
 
     private fun Placeable.PlacementScope.place(
-        transition: ContentState.Transition<*>?,
+        transition: TransitionState.Transition?,
         placeable: Placeable,
     ) {
         with(layoutImpl.lookaheadScope) {
@@ -477,11 +476,11 @@
     layoutImpl: SceneTransitionLayoutImpl,
     element: Element,
     transitions: List<TransitionState.Transition>,
-): ContentState.Transition<*>? {
+): TransitionState.Transition? {
     val transition =
         transitions.fastLastOrNull { transition ->
-            transition.fromScene in element.stateByContent ||
-                transition.toScene in element.stateByContent
+            transition.fromContent in element.stateByContent ||
+                transition.toContent in element.stateByContent
         }
 
     val previousTransition = element.lastTransition
@@ -504,8 +503,8 @@
 private fun prepareInterruption(
     layoutImpl: SceneTransitionLayoutImpl,
     element: Element,
-    transition: ContentState.Transition<*>,
-    previousTransition: ContentState.Transition<*>,
+    transition: TransitionState.Transition,
+    previousTransition: TransitionState.Transition,
 ) {
     if (transition.replacedTransition == previousTransition) {
         return
@@ -552,7 +551,7 @@
  */
 private fun reconcileStates(
     element: Element,
-    transition: ContentState.Transition<*>,
+    transition: TransitionState.Transition,
 ) {
     val fromContentState = element.stateByContent[transition.fromContent] ?: return
     val toContentState = element.stateByContent[transition.toContent] ?: return
@@ -621,7 +620,7 @@
  */
 private inline fun <T> computeInterruptedValue(
     layoutImpl: SceneTransitionLayoutImpl,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
     value: T,
     unspecifiedValue: T,
     zeroValue: T,
@@ -668,7 +667,7 @@
 private inline fun <T> setPlacementInterruptionDelta(
     element: Element,
     stateInContent: Element.State,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
     delta: T,
     setter: (Element.State, T) -> Unit,
 ) {
@@ -694,7 +693,7 @@
     layoutImpl: SceneTransitionLayoutImpl,
     content: ContentKey,
     element: Element,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
 ): Boolean {
     // Always place the element if we are idle.
     if (transition == null) {
@@ -732,7 +731,7 @@
     layoutImpl: SceneTransitionLayoutImpl,
     content: ContentKey,
     element: ElementKey,
-    transition: ContentState.Transition<*>,
+    transition: TransitionState.Transition,
 ): Boolean {
     // If we are overscrolling, only place/compose the element in the overscrolling scene.
     val overscrollScene = transition.currentOverscrollSpec?.scene
@@ -743,7 +742,7 @@
     val scenePicker = element.contentPicker
     val pickedScene =
         when (transition) {
-            is TransitionState.Transition -> {
+            is TransitionState.Transition.ChangeCurrentScene -> {
                 scenePicker.contentDuringTransition(
                     element = element,
                     transition = transition,
@@ -758,14 +757,14 @@
 
 private fun isSharedElementEnabled(
     element: ElementKey,
-    transition: ContentState.Transition<*>,
+    transition: TransitionState.Transition,
 ): Boolean {
     return sharedElementTransformation(element, transition)?.enabled ?: true
 }
 
 internal fun sharedElementTransformation(
     element: ElementKey,
-    transition: ContentState.Transition<*>,
+    transition: TransitionState.Transition,
 ): SharedElementTransformation? {
     val transformationSpec = transition.transformationSpec
     val sharedInFromContent =
@@ -793,7 +792,7 @@
 private fun isElementOpaque(
     content: Content,
     element: Element,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
 ): Boolean {
     if (transition == null) {
         return true
@@ -827,7 +826,7 @@
 private fun elementAlpha(
     layoutImpl: SceneTransitionLayoutImpl,
     element: Element,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
     stateInContent: Element.State,
 ): Float {
     val alpha =
@@ -858,7 +857,7 @@
 private fun interruptedAlpha(
     layoutImpl: SceneTransitionLayoutImpl,
     element: Element,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
     stateInContent: Element.State,
     alpha: Float,
 ): Float {
@@ -888,7 +887,7 @@
 private fun measure(
     layoutImpl: SceneTransitionLayoutImpl,
     element: Element,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
     stateInContent: Element.State,
     measurable: Measurable,
     constraints: Constraints,
@@ -952,7 +951,7 @@
 private fun ContentDrawScope.getDrawScale(
     layoutImpl: SceneTransitionLayoutImpl,
     element: Element,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
     stateInContent: Element.State,
 ): Scale {
     val scale =
@@ -1048,7 +1047,7 @@
     layoutImpl: SceneTransitionLayoutImpl,
     currentContentState: Element.State,
     element: Element,
-    transition: ContentState.Transition<*>?,
+    transition: TransitionState.Transition?,
     contentValue: (Element.State) -> T,
     transformation: (ElementTransformations) -> PropertyTransformation<T>?,
     currentValue: () -> T,
@@ -1076,7 +1075,7 @@
     }
 
     val currentContent = currentContentState.content
-    if (transition is ContentState.HasOverscrollProperties) {
+    if (transition is TransitionState.HasOverscrollProperties) {
         val overscroll = transition.currentOverscrollSpec
         if (overscroll?.scene == currentContent) {
             val elementSpec =
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/InterruptionHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/InterruptionHandler.kt
index bf70ca9..6181cfb 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/InterruptionHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/InterruptionHandler.kt
@@ -37,7 +37,7 @@
      * @see InterruptionResult
      */
     fun onInterruption(
-        interrupted: TransitionState.Transition,
+        interrupted: TransitionState.Transition.ChangeCurrentScene,
         newTargetScene: SceneKey,
     ): InterruptionResult?
 }
@@ -76,7 +76,7 @@
  */
 object DefaultInterruptionHandler : InterruptionHandler {
     override fun onInterruption(
-        interrupted: TransitionState.Transition,
+        interrupted: TransitionState.Transition.ChangeCurrentScene,
         newTargetScene: SceneKey,
     ): InterruptionResult {
         return InterruptionResult(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
index abecdd7..63d51f9 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
@@ -185,7 +185,7 @@
     val contents = element.contentPicker.contents
     val transition =
         transitions.fastLastOrNull { transition ->
-            transition.fromScene in contents || transition.toScene in contents
+            transition.fromContent in contents || transition.toContent in contents
         } ?: return false
 
     // Always compose movable elements in the scene picked by their scene picker.
@@ -215,7 +215,8 @@
 
     // This code is only run during transitions (otherwise the content would be composed and the
     // placeholder would not), so it's ok to cast the state into a Transition directly.
-    val transition = layoutImpl.state.transitionState as TransitionState.Transition
+    val transition =
+        layoutImpl.state.transitionState as TransitionState.Transition.ChangeCurrentScene
 
     // If the content was already composed in the other scene, we use that target size assuming it
     // doesn't change between scenes.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt
index 8f1a4141..5071a7f 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt
@@ -111,7 +111,7 @@
     return snapshotFlow {
             when (val state = transitionState) {
                 is TransitionState.Idle -> ObservableTransitionState.Idle(state.currentScene)
-                is TransitionState.Transition -> {
+                is TransitionState.Transition.ChangeCurrentScene -> {
                     ObservableTransitionState.Transition(
                         fromScene = state.fromScene,
                         toScene = state.toScene,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
index cc53a28..e7e6b2a 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
@@ -70,7 +70,7 @@
     val coroutineScope: CoroutineScope,
     fromScene: SceneKey,
     toScene: SceneKey,
-) : TransitionState.Transition(fromScene, toScene) {
+) : TransitionState.Transition.ChangeCurrentScene(fromScene, toScene) {
     override var currentScene by mutableStateOf(fromScene)
         private set
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index 062d553..392ff7e 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -38,6 +38,7 @@
 import androidx.compose.ui.util.fastForEachReversed
 import com.android.compose.animation.scene.content.Content
 import com.android.compose.animation.scene.content.Scene
+import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.ui.util.lerp
 import kotlinx.coroutines.CoroutineScope
 
@@ -247,8 +248,12 @@
 
                 // Compose the new scene we are going to first.
                 transitions.fastForEachReversed { transition ->
-                    maybeAdd(transition.toScene)
-                    maybeAdd(transition.fromScene)
+                    when (transition) {
+                        is TransitionState.Transition.ChangeCurrentScene -> {
+                            maybeAdd(transition.toScene)
+                            maybeAdd(transition.fromScene)
+                        }
+                    }
                 }
             }
         }
@@ -284,7 +289,8 @@
 
         val width: Int
         val height: Int
-        val transition = layoutImpl.state.currentTransition
+        val transition =
+            layoutImpl.state.currentTransition as? TransitionState.Transition.ChangeCurrentScene
         if (transition == null) {
             width = placeable.width
             height = placeable.height
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index 44f5964f..f37ded0 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -25,7 +25,6 @@
 import androidx.compose.ui.util.fastAll
 import androidx.compose.ui.util.fastFilter
 import androidx.compose.ui.util.fastForEach
-import com.android.compose.animation.scene.content.state.ContentState
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.transition.link.LinkedTransition
 import com.android.compose.animation.scene.transition.link.StateLink
@@ -209,7 +208,7 @@
         targetScene: SceneKey,
         coroutineScope: CoroutineScope,
         transitionKey: TransitionKey?,
-    ): TransitionState.Transition? {
+    ): TransitionState.Transition.ChangeCurrentScene? {
         checkThread()
 
         return coroutineScope.animateToScene(
@@ -228,13 +227,16 @@
      *
      * Important: you *must* call [finishTransition] once the transition is finished.
      */
-    internal fun startTransition(transition: TransitionState.Transition, chain: Boolean = true) {
+    internal fun startTransition(
+        transition: TransitionState.Transition.ChangeCurrentScene,
+        chain: Boolean = true,
+    ) {
         checkThread()
 
         // Compute the [TransformationSpec] when the transition starts.
         val fromScene = transition.fromScene
         val toScene = transition.toScene
-        val orientation = (transition as? ContentState.HasOverscrollProperties)?.orientation
+        val orientation = (transition as? TransitionState.HasOverscrollProperties)?.orientation
 
         // Update the transition specs.
         transition.transformationSpec =
@@ -312,8 +314,8 @@
                 appendLine("  Transitions (size=${transitionStates.size}):")
                 transitionStates.fastForEach { state ->
                     val transition = state as TransitionState.Transition
-                    val from = transition.fromScene
-                    val to = transition.toScene
+                    val from = transition.fromContent
+                    val to = transition.toContent
                     val indicator = if (finishedTransitions.contains(transition)) "x" else " "
                     appendLine("  [$indicator] $from => $to ($transition)")
                 }
@@ -329,27 +331,31 @@
     }
 
     private fun setupTransitionLinks(transition: TransitionState.Transition) {
-        stateLinks.fastForEach { stateLink ->
-            val matchingLinks =
-                stateLink.transitionLinks.fastFilter { it.isMatchingLink(transition) }
-            if (matchingLinks.isEmpty()) return@fastForEach
-            if (matchingLinks.size > 1) error("More than one link matched.")
+        when (transition) {
+            is TransitionState.Transition.ChangeCurrentScene -> {
+                stateLinks.fastForEach { stateLink ->
+                    val matchingLinks =
+                        stateLink.transitionLinks.fastFilter { it.isMatchingLink(transition) }
+                    if (matchingLinks.isEmpty()) return@fastForEach
+                    if (matchingLinks.size > 1) error("More than one link matched.")
 
-            val targetCurrentScene = stateLink.target.transitionState.currentScene
-            val matchingLink = matchingLinks[0]
+                    val targetCurrentScene = stateLink.target.transitionState.currentScene
+                    val matchingLink = matchingLinks[0]
 
-            if (!matchingLink.targetIsInValidState(targetCurrentScene)) return@fastForEach
+                    if (!matchingLink.targetIsInValidState(targetCurrentScene)) return@fastForEach
 
-            val linkedTransition =
-                LinkedTransition(
-                    originalTransition = transition,
-                    fromScene = targetCurrentScene,
-                    toScene = matchingLink.targetTo,
-                    key = matchingLink.targetTransitionKey,
-                )
+                    val linkedTransition =
+                        LinkedTransition(
+                            originalTransition = transition,
+                            fromScene = targetCurrentScene,
+                            toScene = matchingLink.targetTo,
+                            key = matchingLink.targetTransitionKey,
+                        )
 
-            stateLink.target.startTransition(linkedTransition)
-            transition.activeTransitionLinks[stateLink] = linkedTransition
+                    stateLink.target.startTransition(linkedTransition)
+                    transition.activeTransitionLinks[stateLink] = linkedTransition
+                }
+            }
         }
     }
 
@@ -451,8 +457,8 @@
         }
 
         val shouldSnap =
-            (isProgressCloseTo(0f) && transition.currentScene == transition.fromScene) ||
-                (isProgressCloseTo(1f) && transition.currentScene == transition.toScene)
+            (isProgressCloseTo(0f) && transition.currentScene == transition.fromContent) ||
+                (isProgressCloseTo(1f) && transition.currentScene == transition.toContent)
         return if (shouldSnap) {
             finishAllTransitions()
             true
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
index e38c849..5cc194d 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
@@ -25,7 +25,7 @@
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 import kotlin.math.tanh
 
 /** Define the [transitions][SceneTransitions] to be used with a [SceneTransitionLayout]. */
@@ -262,7 +262,7 @@
      */
     fun contentDuringTransition(
         element: ElementKey,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         fromContentZIndex: Float,
         toContentZIndex: Float,
     ): ContentKey
@@ -278,7 +278,7 @@
      */
     fun pickSingleContentIn(
         contents: Set<ContentKey>,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         element: ElementKey,
     ): ContentKey {
         val fromContent = transition.fromContent
@@ -331,7 +331,7 @@
 object HighestZIndexContentPicker : ElementContentPicker {
     override fun contentDuringTransition(
         element: ElementKey,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         fromContentZIndex: Float,
         toContentZIndex: Float
     ): ContentKey {
@@ -352,7 +352,7 @@
 
             override fun contentDuringTransition(
                 element: ElementKey,
-                transition: ContentState.Transition<*>,
+                transition: TransitionState.Transition,
                 fromContentZIndex: Float,
                 toContentZIndex: Float
             ): ContentKey {
@@ -373,7 +373,7 @@
 object LowestZIndexContentPicker : ElementContentPicker {
     override fun contentDuringTransition(
         element: ElementKey,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         fromContentZIndex: Float,
         toContentZIndex: Float
     ): ContentKey {
@@ -394,7 +394,7 @@
 
             override fun contentDuringTransition(
                 element: ElementKey,
-                transition: ContentState.Transition<*>,
+                transition: TransitionState.Transition,
                 fromContentZIndex: Float,
                 toContentZIndex: Float
             ): ContentKey {
@@ -428,7 +428,7 @@
 ) : StaticElementContentPicker {
     override fun contentDuringTransition(
         element: ElementKey,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         fromContentZIndex: Float,
         toContentZIndex: Float,
     ): ContentKey {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/ContentState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/ContentState.kt
deleted file mode 100644
index 0bd676b..0000000
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/ContentState.kt
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2024 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.compose.animation.scene.content.state
-
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.AnimationVector1D
-import androidx.compose.animation.core.spring
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.runtime.Stable
-import com.android.compose.animation.scene.ContentKey
-import com.android.compose.animation.scene.OverscrollScope
-import com.android.compose.animation.scene.OverscrollSpecImpl
-import com.android.compose.animation.scene.ProgressVisibilityThreshold
-import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.TransformationSpec
-import com.android.compose.animation.scene.TransformationSpecImpl
-import com.android.compose.animation.scene.TransitionKey
-import com.android.compose.animation.scene.transition.link.LinkedTransition
-import com.android.compose.animation.scene.transition.link.StateLink
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-
-/** The state associated to one or more contents. */
-@Stable
-sealed interface ContentState<out T : ContentKey> {
-    /** The [content] is idle, it does not animate. */
-    sealed class Idle<T : ContentKey>(val content: T) : ContentState<T>
-
-    /** The content is transitioning with another content. */
-    sealed class Transition<out T : ContentKey>(
-        val fromContent: T,
-        val toContent: T,
-        internal val replacedTransition: Transition<T>?,
-    ) : ContentState<T> {
-        /**
-         * The key of this transition. This should usually be null, but it can be specified to use a
-         * specific set of transformations associated to this transition.
-         */
-        open val key: TransitionKey? = null
-
-        /**
-         * The progress of the transition. This is usually in the `[0; 1]` range, but it can also be
-         * less than `0` or greater than `1` when using transitions with a spring AnimationSpec or
-         * when flinging quickly during a swipe gesture.
-         */
-        abstract val progress: Float
-
-        /** The current velocity of [progress], in progress units. */
-        abstract val progressVelocity: Float
-
-        /** Whether the transition was triggered by user input rather than being programmatic. */
-        abstract val isInitiatedByUserInput: Boolean
-
-        /** Whether user input is currently driving the transition. */
-        abstract val isUserInputOngoing: Boolean
-
-        /**
-         * The progress of the preview transition. This is usually in the `[0; 1]` range, but it can
-         * also be less than `0` or greater than `1` when using transitions with a spring
-         * AnimationSpec or when flinging quickly during a swipe gesture.
-         */
-        internal open val previewProgress: Float = 0f
-
-        /** The current velocity of [previewProgress], in progress units. */
-        internal open val previewProgressVelocity: Float = 0f
-
-        /** Whether the transition is currently in the preview stage */
-        internal open val isInPreviewStage: Boolean = false
-
-        /**
-         * The current [TransformationSpecImpl] and [OverscrollSpecImpl] associated to this
-         * transition.
-         *
-         * Important: These will be set exactly once, when this transition is
-         * [started][MutableSceneTransitionLayoutStateImpl.startTransition].
-         */
-        internal var transformationSpec: TransformationSpecImpl = TransformationSpec.Empty
-        internal var previewTransformationSpec: TransformationSpecImpl? = null
-        private var fromOverscrollSpec: OverscrollSpecImpl? = null
-        private var toOverscrollSpec: OverscrollSpecImpl? = null
-
-        /** The current [OverscrollSpecImpl], if this transition is currently overscrolling. */
-        internal val currentOverscrollSpec: OverscrollSpecImpl?
-            get() {
-                if (this !is HasOverscrollProperties) return null
-                val progress = progress
-                val bouncingContent = bouncingContent
-                return when {
-                    progress < 0f || bouncingContent == fromContent -> fromOverscrollSpec
-                    progress > 1f || bouncingContent == toContent -> toOverscrollSpec
-                    else -> null
-                }
-            }
-
-        /**
-         * An animatable that animates from 1f to 0f. This will be used to nicely animate the sudden
-         * jump of values when this transitions interrupts another one.
-         */
-        private var interruptionDecay: Animatable<Float, AnimationVector1D>? = null
-
-        /** The map of active links that connects this transition to other transitions. */
-        internal val activeTransitionLinks = mutableMapOf<StateLink, LinkedTransition>()
-
-        init {
-            check(fromContent != toContent)
-            check(
-                replacedTransition == null ||
-                    (replacedTransition.fromContent == fromContent &&
-                        replacedTransition.toContent == toContent)
-            )
-        }
-
-        /**
-         * Force this transition to finish and animate to an [Idle] state.
-         *
-         * Important: Once this is called, the effective state of the transition should remain
-         * unchanged. For instance, in the case of a [TransitionState.Transition], its
-         * [currentScene][TransitionState.Transition.currentScene] should never change once [finish]
-         * is called.
-         *
-         * @return the [Job] that animates to the idle state. It can be used to wait until the
-         *   animation is complete or cancel it to snap the animation. Calling [finish] multiple
-         *   times will return the same [Job].
-         */
-        internal abstract fun finish(): Job
-
-        /**
-         * Whether we are transitioning. If [from] or [to] is empty, we will also check that they
-         * match the contents we are animating from and/or to.
-         */
-        fun isTransitioning(from: ContentKey? = null, to: ContentKey? = null): Boolean {
-            return (from == null || fromContent == from) && (to == null || toContent == to)
-        }
-
-        /** Whether we are transitioning from [content] to [other], or from [other] to [content]. */
-        fun isTransitioningBetween(content: ContentKey, other: ContentKey): Boolean {
-            return isTransitioning(from = content, to = other) ||
-                isTransitioning(from = other, to = content)
-        }
-
-        internal fun updateOverscrollSpecs(
-            fromSpec: OverscrollSpecImpl?,
-            toSpec: OverscrollSpecImpl?,
-        ) {
-            fromOverscrollSpec = fromSpec
-            toOverscrollSpec = toSpec
-        }
-
-        /** Returns if the [progress] value of this transition can go beyond range `[0; 1]` */
-        internal fun isWithinProgressRange(progress: Float): Boolean {
-            // If the properties are missing we assume that every [Transition] can overscroll
-            if (this !is HasOverscrollProperties) return true
-            // [OverscrollSpec] for the current scene, even if it hasn't started overscrolling yet.
-            val specForCurrentScene =
-                when {
-                    progress <= 0f -> fromOverscrollSpec
-                    progress >= 1f -> toOverscrollSpec
-                    else -> null
-                } ?: return true
-
-            return specForCurrentScene.transformationSpec.transformations.isNotEmpty()
-        }
-
-        internal open fun interruptionProgress(
-            layoutImpl: SceneTransitionLayoutImpl,
-        ): Float {
-            if (!layoutImpl.state.enableInterruptions) {
-                return 0f
-            }
-
-            if (replacedTransition != null) {
-                return replacedTransition.interruptionProgress(layoutImpl)
-            }
-
-            fun create(): Animatable<Float, AnimationVector1D> {
-                val animatable = Animatable(1f, visibilityThreshold = ProgressVisibilityThreshold)
-                layoutImpl.coroutineScope.launch {
-                    val swipeSpec = layoutImpl.state.transitions.defaultSwipeSpec
-                    val progressSpec =
-                        spring(
-                            stiffness = swipeSpec.stiffness,
-                            dampingRatio = swipeSpec.dampingRatio,
-                            visibilityThreshold = ProgressVisibilityThreshold,
-                        )
-                    animatable.animateTo(0f, progressSpec)
-                }
-
-                return animatable
-            }
-
-            val animatable = interruptionDecay ?: create().also { interruptionDecay = it }
-            return animatable.value
-        }
-    }
-
-    interface HasOverscrollProperties {
-        /**
-         * The position of the [Transition.toContent].
-         *
-         * Used to understand the direction of the overscroll.
-         */
-        val isUpOrLeft: Boolean
-
-        /**
-         * The relative orientation between [Transition.fromContent] and [Transition.toContent].
-         *
-         * Used to understand the orientation of the overscroll.
-         */
-        val orientation: Orientation
-
-        /**
-         * Scope which can be used in the Overscroll DSL to define a transformation based on the
-         * distance between [Transition.fromContent] and [Transition.toContent].
-         */
-        val overscrollScope: OverscrollScope
-
-        /**
-         * The content (scene or overlay) around which the transition is currently bouncing. When
-         * not `null`, this transition is currently oscillating around this content and will soon
-         * settle to that content.
-         */
-        val bouncingContent: ContentKey?
-
-        companion object {
-            const val DistanceUnspecified = 0f
-        }
-    }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
index 77de22c..22df34b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
@@ -16,16 +16,31 @@
 
 package com.android.compose.animation.scene.content.state
 
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.animation.core.spring
+import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.runtime.Stable
+import com.android.compose.animation.scene.ContentKey
+import com.android.compose.animation.scene.OverscrollScope
+import com.android.compose.animation.scene.OverscrollSpecImpl
+import com.android.compose.animation.scene.ProgressVisibilityThreshold
 import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneTransitionLayoutImpl
+import com.android.compose.animation.scene.TransformationSpec
+import com.android.compose.animation.scene.TransformationSpecImpl
+import com.android.compose.animation.scene.TransitionKey
+import com.android.compose.animation.scene.transition.link.LinkedTransition
+import com.android.compose.animation.scene.transition.link.StateLink
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
 
-/** The state associated to one or more scenes. */
-// TODO(b/353679003): Rename to SceneState.
+/** The state associated to a [SceneTransitionLayout] at some specific point in time. */
 @Stable
-sealed interface TransitionState : ContentState<SceneKey> {
+sealed interface TransitionState {
     /**
-     * The current effective scene. If a new transition was triggered, it would start from this
-     * scene.
+     * The current effective scene. If a new scene transition was triggered, it would start from
+     * this scene.
      *
      * For instance, when swiping from scene A to scene B, the [currentScene] is A when the swipe
      * gesture starts, but then if the user flings their finger and commits the transition to scene
@@ -37,17 +52,216 @@
     /** The scene [currentScene] is idle. */
     data class Idle(
         override val currentScene: SceneKey,
-    ) : TransitionState, ContentState.Idle<SceneKey>(currentScene)
+    ) : TransitionState
 
-    /** There is a transition animating between [fromScene] and [toScene]. */
-    abstract class Transition(
-        /** The scene this transition is starting from. Can't be the same as toScene */
-        val fromScene: SceneKey,
+    sealed class Transition(
+        val fromContent: ContentKey,
+        val toContent: ContentKey,
+        val replacedTransition: Transition? = null,
+    ) : TransitionState {
+        /** A transition animating between [fromScene] and [toScene]. */
+        abstract class ChangeCurrentScene(
+            /** The scene this transition is starting from. Can't be the same as toScene */
+            val fromScene: SceneKey,
 
-        /** The scene this transition is going to. Can't be the same as fromScene */
-        val toScene: SceneKey,
+            /** The scene this transition is going to. Can't be the same as fromScene */
+            val toScene: SceneKey,
 
-        /** The transition that `this` transition is replacing, if any. */
-        replacedTransition: Transition? = null,
-    ) : TransitionState, ContentState.Transition<SceneKey>(fromScene, toScene, replacedTransition)
+            /** The transition that `this` transition is replacing, if any. */
+            replacedTransition: Transition? = null,
+        ) : Transition(fromScene, toScene, replacedTransition)
+
+        /**
+         * The key of this transition. This should usually be null, but it can be specified to use a
+         * specific set of transformations associated to this transition.
+         */
+        open val key: TransitionKey? = null
+
+        /**
+         * The progress of the transition. This is usually in the `[0; 1]` range, but it can also be
+         * less than `0` or greater than `1` when using transitions with a spring AnimationSpec or
+         * when flinging quickly during a swipe gesture.
+         */
+        abstract val progress: Float
+
+        /** The current velocity of [progress], in progress units. */
+        abstract val progressVelocity: Float
+
+        /** Whether the transition was triggered by user input rather than being programmatic. */
+        abstract val isInitiatedByUserInput: Boolean
+
+        /** Whether user input is currently driving the transition. */
+        abstract val isUserInputOngoing: Boolean
+
+        /**
+         * The progress of the preview transition. This is usually in the `[0; 1]` range, but it can
+         * also be less than `0` or greater than `1` when using transitions with a spring
+         * AnimationSpec or when flinging quickly during a swipe gesture.
+         */
+        internal open val previewProgress: Float = 0f
+
+        /** The current velocity of [previewProgress], in progress units. */
+        internal open val previewProgressVelocity: Float = 0f
+
+        /** Whether the transition is currently in the preview stage */
+        internal open val isInPreviewStage: Boolean = false
+
+        /**
+         * The current [TransformationSpecImpl] and [OverscrollSpecImpl] associated to this
+         * transition.
+         *
+         * Important: These will be set exactly once, when this transition is
+         * [started][MutableSceneTransitionLayoutStateImpl.startTransition].
+         */
+        internal var transformationSpec: TransformationSpecImpl = TransformationSpec.Empty
+        internal var previewTransformationSpec: TransformationSpecImpl? = null
+        private var fromOverscrollSpec: OverscrollSpecImpl? = null
+        private var toOverscrollSpec: OverscrollSpecImpl? = null
+
+        /** The current [OverscrollSpecImpl], if this transition is currently overscrolling. */
+        internal val currentOverscrollSpec: OverscrollSpecImpl?
+            get() {
+                if (this !is HasOverscrollProperties) return null
+                val progress = progress
+                val bouncingContent = bouncingContent
+                return when {
+                    progress < 0f || bouncingContent == fromContent -> fromOverscrollSpec
+                    progress > 1f || bouncingContent == toContent -> toOverscrollSpec
+                    else -> null
+                }
+            }
+
+        /**
+         * An animatable that animates from 1f to 0f. This will be used to nicely animate the sudden
+         * jump of values when this transitions interrupts another one.
+         */
+        private var interruptionDecay: Animatable<Float, AnimationVector1D>? = null
+
+        /** The map of active links that connects this transition to other transitions. */
+        internal val activeTransitionLinks = mutableMapOf<StateLink, LinkedTransition>()
+
+        init {
+            check(fromContent != toContent)
+            check(
+                replacedTransition == null ||
+                    (replacedTransition.fromContent == fromContent &&
+                        replacedTransition.toContent == toContent)
+            )
+        }
+
+        /**
+         * Whether we are transitioning. If [from] or [to] is empty, we will also check that they
+         * match the contents we are animating from and/or to.
+         */
+        fun isTransitioning(from: ContentKey? = null, to: ContentKey? = null): Boolean {
+            return (from == null || fromContent == from) && (to == null || toContent == to)
+        }
+
+        /** Whether we are transitioning from [content] to [other], or from [other] to [content]. */
+        fun isTransitioningBetween(content: ContentKey, other: ContentKey): Boolean {
+            return isTransitioning(from = content, to = other) ||
+                isTransitioning(from = other, to = content)
+        }
+
+        /**
+         * Force this transition to finish and animate to an [Idle] state.
+         *
+         * Important: Once this is called, the effective state of the transition should remain
+         * unchanged. For instance, in the case of a [TransitionState.Transition], its
+         * [currentScene][TransitionState.Transition.currentScene] should never change once [finish]
+         * is called.
+         *
+         * @return the [Job] that animates to the idle state. It can be used to wait until the
+         *   animation is complete or cancel it to snap the animation. Calling [finish] multiple
+         *   times will return the same [Job].
+         */
+        internal abstract fun finish(): Job
+
+        internal fun updateOverscrollSpecs(
+            fromSpec: OverscrollSpecImpl?,
+            toSpec: OverscrollSpecImpl?,
+        ) {
+            fromOverscrollSpec = fromSpec
+            toOverscrollSpec = toSpec
+        }
+
+        /** Returns if the [progress] value of this transition can go beyond range `[0; 1]` */
+        internal fun isWithinProgressRange(progress: Float): Boolean {
+            // If the properties are missing we assume that every [Transition] can overscroll
+            if (this !is HasOverscrollProperties) return true
+            // [OverscrollSpec] for the current scene, even if it hasn't started overscrolling yet.
+            val specForCurrentScene =
+                when {
+                    progress <= 0f -> fromOverscrollSpec
+                    progress >= 1f -> toOverscrollSpec
+                    else -> null
+                } ?: return true
+
+            return specForCurrentScene.transformationSpec.transformations.isNotEmpty()
+        }
+
+        internal open fun interruptionProgress(
+            layoutImpl: SceneTransitionLayoutImpl,
+        ): Float {
+            if (!layoutImpl.state.enableInterruptions) {
+                return 0f
+            }
+
+            if (replacedTransition != null) {
+                return replacedTransition.interruptionProgress(layoutImpl)
+            }
+
+            fun create(): Animatable<Float, AnimationVector1D> {
+                val animatable = Animatable(1f, visibilityThreshold = ProgressVisibilityThreshold)
+                layoutImpl.coroutineScope.launch {
+                    val swipeSpec = layoutImpl.state.transitions.defaultSwipeSpec
+                    val progressSpec =
+                        spring(
+                            stiffness = swipeSpec.stiffness,
+                            dampingRatio = swipeSpec.dampingRatio,
+                            visibilityThreshold = ProgressVisibilityThreshold,
+                        )
+                    animatable.animateTo(0f, progressSpec)
+                }
+
+                return animatable
+            }
+
+            val animatable = interruptionDecay ?: create().also { interruptionDecay = it }
+            return animatable.value
+        }
+    }
+
+    interface HasOverscrollProperties {
+        /**
+         * The position of the [Transition.toContent].
+         *
+         * Used to understand the direction of the overscroll.
+         */
+        val isUpOrLeft: Boolean
+
+        /**
+         * The relative orientation between [Transition.fromContent] and [Transition.toContent].
+         *
+         * Used to understand the orientation of the overscroll.
+         */
+        val orientation: Orientation
+
+        /**
+         * Scope which can be used in the Overscroll DSL to define a transformation based on the
+         * distance between [Transition.fromContent] and [Transition.toContent].
+         */
+        val overscrollScope: OverscrollScope
+
+        /**
+         * The content (scene or overlay) around which the transition is currently bouncing. When
+         * not `null`, this transition is currently oscillating around this content and will soon
+         * settle to that content.
+         */
+        val bouncingContent: ContentKey?
+
+        companion object {
+            const val DistanceUnspecified = 0f
+        }
+    }
 }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
index 538ce79..c5a3067c 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
@@ -22,7 +22,7 @@
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 
 /** Anchor the size of an element to the size of another element. */
 internal class AnchoredSize(
@@ -36,7 +36,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: IntSize,
     ): IntSize {
         fun anchorSizeIn(content: ContentKey): IntSize {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
index 258f541..05878c2 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
@@ -23,7 +23,7 @@
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 
 /** Anchor the translation of an element to another element. */
 internal class AnchoredTranslate(
@@ -35,7 +35,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: Offset,
     ): Offset {
         fun throwException(content: ContentKey?): Nothing {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt
index be8dac21..7f86479 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt
@@ -22,7 +22,7 @@
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.Scale
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 
 /**
  * Scales the draw size of an element. Note this will only scale the draw inside of an element,
@@ -40,7 +40,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: Scale,
     ): Scale {
         return Scale(scaleX, scaleY, pivot)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
index d72e43a..a32c7dd 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
@@ -22,7 +22,7 @@
 import com.android.compose.animation.scene.Element
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 
 /** Translate an element from an edge of the layout. */
 internal class EdgeTranslate(
@@ -35,7 +35,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: Offset
     ): Offset {
         val sceneSize = layoutImpl.content(content).targetSize
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt
index 92ae30f8..4528eef 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt
@@ -20,7 +20,7 @@
 import com.android.compose.animation.scene.Element
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 
 /** Fade an element in or out. */
 internal class Fade(
@@ -31,7 +31,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: Float
     ): Float {
         // Return the alpha value of [element] either when it starts fading in or when it finished
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt
index e8515dc..5f3fdaf 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt
@@ -21,7 +21,7 @@
 import com.android.compose.animation.scene.Element
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 import kotlin.math.roundToInt
 
 /**
@@ -38,7 +38,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: IntSize,
     ): IntSize {
         return IntSize(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
index eda8ede..505ad04 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
@@ -25,7 +25,7 @@
 import com.android.compose.animation.scene.Element
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 
 /** A transformation applied to one or more elements during a transition. */
 sealed interface Transformation {
@@ -66,7 +66,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: T,
     ): T
 }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
index fab4ced..59bca50 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
@@ -24,7 +24,7 @@
 import com.android.compose.animation.scene.ElementMatcher
 import com.android.compose.animation.scene.OverscrollScope
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.ContentState
+import com.android.compose.animation.scene.content.state.TransitionState
 
 internal class Translate(
     override val matcher: ElementMatcher,
@@ -36,7 +36,7 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: Offset,
     ): Offset {
         return with(layoutImpl.density) {
@@ -58,13 +58,13 @@
         content: ContentKey,
         element: Element,
         stateInContent: Element.State,
-        transition: ContentState.Transition<*>,
+        transition: TransitionState.Transition,
         value: Offset,
     ): Offset {
         // As this object is created by OverscrollBuilderImpl and we retrieve the current
         // OverscrollSpec only when the transition implements HasOverscrollProperties, we can assume
         // that this method was invoked after performing this check.
-        val overscrollProperties = transition as ContentState.HasOverscrollProperties
+        val overscrollProperties = transition as TransitionState.HasOverscrollProperties
 
         return Offset(
             x = value.x + overscrollProperties.overscrollScope.x(),
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt
index 23bcf10..89b0040 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt
@@ -23,11 +23,11 @@
 
 /** A linked transition which is driven by a [originalTransition]. */
 internal class LinkedTransition(
-    private val originalTransition: TransitionState.Transition,
+    private val originalTransition: TransitionState.Transition.ChangeCurrentScene,
     fromScene: SceneKey,
     toScene: SceneKey,
     override val key: TransitionKey? = null,
-) : TransitionState.Transition(fromScene, toScene) {
+) : TransitionState.Transition.ChangeCurrentScene(fromScene, toScene) {
 
     override val currentScene: SceneKey
         get() {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/StateLink.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/StateLink.kt
index c0c40dd..c29bf21 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/StateLink.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/StateLink.kt
@@ -49,7 +49,9 @@
                 error("From and To can't be the same")
         }
 
-        internal fun isMatchingLink(transition: TransitionState.Transition): Boolean {
+        internal fun isMatchingLink(
+            transition: TransitionState.Transition.ChangeCurrentScene,
+        ): Boolean {
             return (sourceFrom == null || sourceFrom == transition.fromScene) &&
                 (sourceTo == null || sourceTo == transition.toScene)
         }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 6360f85..72a16b7 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -182,7 +182,7 @@
             progress: Float? = null,
             isUserInputOngoing: Boolean? = null
         ): Transition {
-            val transition = assertThat(transitionState).isTransition()
+            val transition = assertThat(transitionState).isSceneTransition()
             currentScene?.let { assertThat(transition).hasCurrentScene(it) }
             fromScene?.let { assertThat(transition).hasFromScene(it) }
             toScene?.let { assertThat(transition).hasToScene(it) }
@@ -1075,7 +1075,7 @@
         val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
 
         val dragController = onDragStarted(startedPosition = middle, overSlop = up(0.5f))
-        val transition = assertThat(transitionState).isTransition()
+        val transition = assertThat(transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasProgress(0.5f)
@@ -1101,7 +1101,7 @@
         val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
 
         val dragController = onDragStarted(startedPosition = middle, overSlop = down(0.5f))
-        val transition = assertThat(transitionState).isTransition()
+        val transition = assertThat(transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneC)
         assertThat(transition).hasProgress(0.5f)
@@ -1127,7 +1127,7 @@
         val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
 
         val dragController = onDragStarted(startedPosition = middle, overSlop = up(1.5f))
-        val transition = assertThat(transitionState).isTransition()
+        val transition = assertThat(transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasProgress(1.5f)
@@ -1154,7 +1154,7 @@
         val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
 
         val dragController = onDragStarted(startedPosition = middle, overSlop = down(1.5f))
-        val transition = assertThat(transitionState).isTransition()
+        val transition = assertThat(transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneC)
         assertThat(transition).hasProgress(1.5f)
@@ -1182,7 +1182,7 @@
 
         val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
         val dragController = onDragStarted(startedPosition = middle, overSlop = down(1f))
-        val transition = assertThat(transitionState).isTransition()
+        val transition = assertThat(transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasProgress(-1f)
@@ -1210,7 +1210,7 @@
 
         val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
         val dragController = onDragStarted(startedPosition = middle, overSlop = up(1f))
-        val transition = assertThat(transitionState).isTransition()
+        val transition = assertThat(transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneC)
         assertThat(transition).hasProgress(-1f)
@@ -1267,12 +1267,12 @@
     @Test
     fun interceptingTransitionReplacesCurrentTransition() = runGestureTest {
         val controller = onDragStarted(overSlop = up(fractionOfScreen = 0.5f))
-        val transition = assertThat(layoutState.transitionState).isTransition()
+        val transition = assertThat(layoutState.transitionState).isSceneTransition()
         controller.onDragStopped(velocity = 0f)
 
         // Intercept the transition.
         onDragStartedImmediately()
-        val newTransition = assertThat(layoutState.transitionState).isTransition()
+        val newTransition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(newTransition).isNotSameInstanceAs(transition)
         assertThat(newTransition.replacedTransition).isSameInstanceAs(transition)
     }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index 20b9b49..682fe95 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -735,7 +735,7 @@
 
         val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
         fooElement.assertTopPositionInRootIsEqualTo(0.dp)
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).isNotNull()
         assertThat(transition).hasProgress(0.5f)
         assertThat(animatedFloat).isEqualTo(50f)
@@ -822,7 +822,7 @@
             moveBy(Offset(0f, touchSlop + layoutHeight.toPx() * 0.5f), delayMillis = 1_000)
         }
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasOverscrollSpec()
         assertThat(transition).hasProgress(-0.5f)
         fooElement.assertTopPositionInRootIsEqualTo(overscrollTranslateY * 0.5f)
@@ -905,7 +905,7 @@
             }
         }
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.5f)
         fooElement.assertTopPositionInRootIsEqualTo(translateY * 0.5f)
     }
@@ -939,7 +939,7 @@
             moveBy(Offset(0f, layoutHeight.toPx() * 0.5f), delayMillis = 1_000)
         }
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(animatedFloat).isEqualTo(100f)
 
         // Scroll 150% (100% scroll + 50% overscroll)
@@ -992,7 +992,7 @@
             moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
         }
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(animatedFloat).isEqualTo(100f)
 
         // Scroll 200% (100% scroll + 100% overscroll)
@@ -1039,7 +1039,7 @@
             moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
         }
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(animatedFloat).isEqualTo(100f)
 
         // Scroll 200% (100% scroll + 100% overscroll)
@@ -1083,7 +1083,7 @@
             moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
         }
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(animatedFloat).isEqualTo(100f)
 
         // Scroll 200% (100% scroll + 100% overscroll)
@@ -1143,7 +1143,7 @@
             moveBy(Offset(0f, layoutHeight.toPx() * 0.5f), delayMillis = 1_000)
         }
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
 
         // Scroll 150% (100% scroll + 50% overscroll)
         assertThat(transition).hasProgress(1.5f)
@@ -1160,7 +1160,7 @@
 
         assertThat(transition.progress).isLessThan(1f)
         assertThat(transition).hasOverscrollSpec()
-        assertThat(transition).hasBouncingScene(transition.toScene)
+        assertThat(transition).hasBouncingContent(transition.toContent)
         assertThat(animatedFloat).isEqualTo(100f)
     }
 
@@ -1243,13 +1243,15 @@
 
         val transitions = state.currentTransitions
         assertThat(transitions).hasSize(2)
-        assertThat(transitions[0]).hasFromScene(SceneA)
-        assertThat(transitions[0]).hasToScene(SceneB)
-        assertThat(transitions[0]).hasProgress(0f)
+        val firstTransition = assertThat(transitions[0]).isSceneTransition()
+        assertThat(firstTransition).hasFromScene(SceneA)
+        assertThat(firstTransition).hasToScene(SceneB)
+        assertThat(firstTransition).hasProgress(0f)
 
-        assertThat(transitions[1]).hasFromScene(SceneB)
-        assertThat(transitions[1]).hasToScene(SceneC)
-        assertThat(transitions[1]).hasProgress(0f)
+        val secondTransition = assertThat(transitions[1]).isSceneTransition()
+        assertThat(secondTransition).hasFromScene(SceneB)
+        assertThat(secondTransition).hasToScene(SceneC)
+        assertThat(secondTransition).hasProgress(0f)
 
         // First frame: both are at x = 0dp. For the whole transition, Foo is at y = 0dp and Bar is
         // at y = layoutSize - elementSoze = 100dp.
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
index ca72181..f4e60a2 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
@@ -69,7 +69,7 @@
                     interruptionHandler =
                         object : InterruptionHandler {
                             override fun onInterruption(
-                                interrupted: TransitionState.Transition,
+                                interrupted: TransitionState.Transition.ChangeCurrentScene,
                                 newTargetScene: SceneKey
                             ): InterruptionResult {
                                 return InterruptionResult(
@@ -104,7 +104,7 @@
                     interruptionHandler =
                         object : InterruptionHandler {
                             override fun onInterruption(
-                                interrupted: TransitionState.Transition,
+                                interrupted: TransitionState.Transition.ChangeCurrentScene,
                                 newTargetScene: SceneKey
                             ): InterruptionResult {
                                 return InterruptionResult(
@@ -198,7 +198,7 @@
     companion object {
         val FromToCurrentTriple =
             Correspondence.transforming(
-                { transition: TransitionState.Transition? ->
+                { transition: TransitionState.Transition.ChangeCurrentScene? ->
                     Triple(transition?.fromScene, transition?.toScene, transition?.currentScene)
                 },
                 "(from, to, current) triple"
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt
index 520e759..b7f50fd 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt
@@ -45,7 +45,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.compose.animation.scene.TestScenes.SceneA
 import com.android.compose.animation.scene.TestScenes.SceneB
-import com.android.compose.animation.scene.content.state.ContentState
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.subjects.assertThat
 import com.android.compose.test.assertSizeIsEqualTo
@@ -160,11 +159,11 @@
 
                         override fun contentDuringTransition(
                             element: ElementKey,
-                            transition: ContentState.Transition<*>,
+                            transition: TransitionState.Transition,
                             fromContentZIndex: Float,
                             toContentZIndex: Float
                         ): ContentKey {
-                            transition as TransitionState.Transition
+                            transition as TransitionState.Transition.ChangeCurrentScene
                             assertThat(transition).hasFromScene(SceneA)
                             assertThat(transition).hasToScene(SceneB)
                             assertThat(fromContentZIndex).isEqualTo(0)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt
index ccefe3d..d58a0a3 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt
@@ -125,7 +125,7 @@
 
         scrollUp(percent = 0.5f)
         // STL will start a transition with the remaining scroll
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.5f)
 
         scrollUp(percent = 1f)
@@ -156,7 +156,7 @@
         // Start a new gesture
         pointerDownAndScrollTouchSlop()
         scrollUp(percent = 0.5f)
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.5f)
 
         pointerUp()
@@ -181,7 +181,7 @@
         // Reach the end of the scrollable element
         canScroll = false
         scrollUp(percent = 0.5f)
-        val transition1 = assertThat(state.transitionState).isTransition()
+        val transition1 = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition1).hasProgress(0.5f)
 
         pointerUp()
@@ -192,7 +192,7 @@
         // Start a new gesture
         pointerDownAndScrollTouchSlop()
         scrollUp(percent = 0.5f)
-        val transition2 = assertThat(state.transitionState).isTransition()
+        val transition2 = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition2).hasProgress(0.5f)
 
         pointerUp()
@@ -215,7 +215,7 @@
         // Reach the end of the scrollable element
         canScroll = false
         scrollUp(percent = 0.5f)
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.5f)
 
         pointerUp()
@@ -244,7 +244,7 @@
 
         scrollUp(percent = 0.5f)
         // EdgeAlways always consume the remaining scroll, EdgeNoPreview does not.
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.5f)
     }
 
@@ -278,7 +278,7 @@
         scrollUp(percent = 0.2f)
 
         // STL can only start the transition if it has reset the amount of scroll consumed.
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.2f)
     }
 }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
index 0eaecb0..00c7588 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
@@ -76,7 +76,7 @@
             dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
         }
 
-        val transition = assertThat(layoutState.transitionState).isTransition()
+        val transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasProgress(0.4f)
@@ -124,7 +124,7 @@
             dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
         }
 
-        val transition = assertThat(layoutState.transitionState).isTransition()
+        val transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasPreviewProgress(0.4f)
@@ -178,13 +178,13 @@
         val dispatcher = rule.activity.onBackPressedDispatcher
         rule.runOnUiThread { dispatcher.dispatchOnBackStarted(backEvent()) }
 
-        val predictiveTransition = assertThat(layoutState.transitionState).isTransition()
+        val predictiveTransition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(predictiveTransition).hasFromScene(SceneA)
         assertThat(predictiveTransition).hasToScene(SceneB)
 
         // Start a new transition to C.
         rule.runOnUiThread { layoutState.setTargetScene(SceneC, coroutineScope) }
-        val newTransition = assertThat(layoutState.transitionState).isTransition()
+        val newTransition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(newTransition).hasFromScene(SceneA)
         assertThat(newTransition).hasToScene(SceneC)
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
index c8ac580..3422a8e 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
@@ -478,7 +478,7 @@
                         overscroll(SceneB, Orientation.Vertical) { fade(TestElements.Foo) }
                     }
             )
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasNoOverscrollSpec()
 
         // overscroll for SceneA is NOT defined
@@ -510,7 +510,7 @@
                     }
             )
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasNoOverscrollSpec()
 
         // overscroll for SceneA is defined
@@ -539,7 +539,7 @@
                 sceneTransitions = transitions {}
             )
 
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasNoOverscrollSpec()
 
         // overscroll for SceneA is NOT defined
@@ -642,7 +642,7 @@
 
         // Transition to B.
         state.setTargetScene(SceneB, coroutineScope = this)
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasCurrentScene(SceneB)
 
         // Snap to C.
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index 84bcc28f..e97c27e 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -179,7 +179,7 @@
 
         // Change the current scene.
         currentScene = SceneB
-        val transition = assertThat(layoutState.transitionState).isTransition()
+        val transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasProgress(0f)
@@ -241,7 +241,7 @@
         // 100.dp. We pause at the middle of the transition, so it should now be 75.dp given that we
         // use a linear interpolator. Foo was at (x = layoutSize - 50dp, y = 0) in SceneA and is
         // going to (x = 0, y = 0), so the offset should now be half what it was.
-        var transition = assertThat(layoutState.transitionState).isTransition()
+        var transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.5f)
         sharedFoo.assertWidthIsEqualTo(75.dp)
         sharedFoo.assertHeightIsEqualTo(75.dp)
@@ -269,7 +269,7 @@
         val expectedSize = 100.dp + (150.dp - 100.dp) * interpolatedProgress
 
         sharedFoo = rule.onNode(isElement(TestElements.Foo, SceneC))
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(interpolatedProgress)
         sharedFoo.assertWidthIsEqualTo(expectedSize)
         sharedFoo.assertHeightIsEqualTo(expectedSize)
@@ -399,7 +399,7 @@
         rule.mainClock.advanceTimeBy(duration / 2)
         rule.waitForIdle()
 
-        var transition = assertThat(state.transitionState).isTransition()
+        var transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0.5f)
 
         // A and B are composed.
@@ -412,7 +412,7 @@
         rule.mainClock.advanceTimeByFrame()
         rule.waitForIdle()
 
-        transition = assertThat(state.transitionState).isTransition()
+        transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasProgress(0f)
 
         // A, B and C are composed.
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index 04a9380..06799bc 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -155,7 +155,7 @@
 
         // We should be at a progress = 55dp / LayoutWidth given that we use the layout size in
         // the gesture axis as swipe distance.
-        var transition = assertThat(layoutState.transitionState).isTransition()
+        var transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasCurrentScene(SceneA)
@@ -165,7 +165,7 @@
         // Release the finger. We should now be animating back to A (currentScene = SceneA) given
         // that 55dp < positional threshold.
         rule.onRoot().performTouchInput { up() }
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasCurrentScene(SceneA)
@@ -185,7 +185,7 @@
         }
 
         // Drag is in progress, so currentScene = SceneA and progress = 56dp / LayoutHeight
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(TestScenes.SceneC)
         assertThat(transition).hasCurrentScene(SceneA)
@@ -195,7 +195,7 @@
         // Release the finger. We should now be animating to C (currentScene = SceneC) given
         // that 56dp >= positional threshold.
         rule.onRoot().performTouchInput { up() }
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(TestScenes.SceneC)
         assertThat(transition).hasCurrentScene(TestScenes.SceneC)
@@ -236,7 +236,7 @@
 
         // We should be animating back to A (currentScene = SceneA) given that 124 dp/s < velocity
         // threshold.
-        var transition = assertThat(layoutState.transitionState).isTransition()
+        var transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasCurrentScene(SceneA)
@@ -260,7 +260,7 @@
         }
 
         // We should be animating to C (currentScene = SceneC).
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(TestScenes.SceneC)
         assertThat(transition).hasCurrentScene(TestScenes.SceneC)
@@ -297,7 +297,7 @@
         }
 
         // We are transitioning to B because we used 2 fingers.
-        val transition = assertThat(layoutState.transitionState).isTransition()
+        val transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(TestScenes.SceneC)
         assertThat(transition).hasToScene(SceneB)
 
@@ -332,7 +332,7 @@
         }
 
         // We are transitioning to B (and not A) because we started from the top edge.
-        var transition = assertThat(layoutState.transitionState).isTransition()
+        var transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(TestScenes.SceneC)
         assertThat(transition).hasToScene(SceneB)
 
@@ -350,7 +350,7 @@
         }
 
         // We are transitioning to B (and not A) because we started from the left edge.
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(TestScenes.SceneC)
         assertThat(transition).hasToScene(SceneB)
 
@@ -406,7 +406,7 @@
         }
 
         // We should be at 50%
-        val transition = assertThat(layoutState.transitionState).isTransition()
+        val transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).isNotNull()
         assertThat(transition).hasProgress(0.5f)
     }
@@ -427,7 +427,7 @@
         }
 
         // We should still correctly compute that we are swiping down to scene C.
-        var transition = assertThat(layoutState.transitionState).isTransition()
+        var transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasToScene(TestScenes.SceneC)
 
         // Release the finger, animating back to scene A.
@@ -443,7 +443,7 @@
         }
 
         // We should still correctly compute that we are swiping up to scene B.
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasToScene(SceneB)
 
         // Release the finger, animating back to scene A.
@@ -459,7 +459,7 @@
         }
 
         // We should still correctly compute that we are swiping down to scene B.
-        transition = assertThat(layoutState.transitionState).isTransition()
+        transition = assertThat(layoutState.transitionState).isSceneTransition()
         assertThat(transition).hasToScene(SceneB)
     }
 
@@ -597,7 +597,7 @@
         }
 
         rule.waitForIdle()
-        val transition = assertThat(state.transitionState).isTransition()
+        val transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         assertThat(transition).hasProgress(0.5f, tolerance = 0.01f)
@@ -686,7 +686,7 @@
         }
 
         // Scene B should come from the right (end) edge.
-        var transition = assertThat(state.transitionState).isTransition()
+        var transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         rule
@@ -707,7 +707,7 @@
         }
 
         // Scene C should come from the left (start) edge.
-        transition = assertThat(state.transitionState).isTransition()
+        transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneC)
         rule
@@ -761,7 +761,7 @@
         }
 
         // Scene C should come from the right (start) edge.
-        var transition = assertThat(state.transitionState).isTransition()
+        var transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneC)
         rule
@@ -782,7 +782,7 @@
         }
 
         // Scene C should come from the left (end) edge.
-        transition = assertThat(state.transitionState).isTransition()
+        transition = assertThat(state.transitionState).isSceneTransition()
         assertThat(transition).hasFromScene(SceneA)
         assertThat(transition).hasToScene(SceneB)
         rule
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt
index e4e4108..1f7fe37 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt
@@ -17,7 +17,6 @@
 package com.android.compose.animation.scene
 
 import androidx.compose.foundation.gestures.Orientation
-import com.android.compose.animation.scene.content.state.ContentState
 import com.android.compose.animation.scene.content.state.TransitionState
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
@@ -43,10 +42,10 @@
     orientation: Orientation = Orientation.Horizontal,
     onFinish: ((TransitionState.Transition) -> Job)? = null,
     replacedTransition: TransitionState.Transition? = null,
-): TransitionState.Transition {
+): TransitionState.Transition.ChangeCurrentScene {
     return object :
-        TransitionState.Transition(from, to, replacedTransition),
-        ContentState.HasOverscrollProperties {
+        TransitionState.Transition.ChangeCurrentScene(from, to, replacedTransition),
+        TransitionState.HasOverscrollProperties {
         override val currentScene: SceneKey
             get() = current()
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
index a12ab78..a98bd76 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
@@ -16,9 +16,9 @@
 
 package com.android.compose.animation.scene.subjects
 
+import com.android.compose.animation.scene.ContentKey
 import com.android.compose.animation.scene.OverscrollSpec
 import com.android.compose.animation.scene.SceneKey
-import com.android.compose.animation.scene.content.state.ContentState
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.google.common.truth.Fact.simpleFact
 import com.google.common.truth.FailureMetadata
@@ -31,9 +31,9 @@
     return Truth.assertAbout(TransitionStateSubject.transitionStates()).that(state)
 }
 
-/** Assert on a [TransitionState.Transition]. */
-fun assertThat(transitions: TransitionState.Transition): TransitionSubject {
-    return Truth.assertAbout(TransitionSubject.transitions()).that(transitions)
+/** Assert on a [TransitionState.Transition.ChangeCurrentScene]. */
+fun assertThat(transition: TransitionState.Transition.ChangeCurrentScene): SceneTransitionSubject {
+    return Truth.assertAbout(SceneTransitionSubject.transitions()).that(transition)
 }
 
 class TransitionStateSubject
@@ -53,12 +53,14 @@
         return actual as TransitionState.Idle
     }
 
-    fun isTransition(): TransitionState.Transition {
-        if (actual !is TransitionState.Transition) {
-            failWithActual(simpleFact("expected to be TransitionState.Transition"))
+    fun isSceneTransition(): TransitionState.Transition.ChangeCurrentScene {
+        if (actual !is TransitionState.Transition.ChangeCurrentScene) {
+            failWithActual(
+                simpleFact("expected to be TransitionState.Transition.ChangeCurrentScene")
+            )
         }
 
-        return actual as TransitionState.Transition
+        return actual as TransitionState.Transition.ChangeCurrentScene
     }
 
     companion object {
@@ -68,10 +70,10 @@
     }
 }
 
-class TransitionSubject
+class SceneTransitionSubject
 private constructor(
     metadata: FailureMetadata,
-    private val actual: TransitionState.Transition,
+    private val actual: TransitionState.Transition.ChangeCurrentScene,
 ) : Subject(metadata, actual) {
     fun hasCurrentScene(sceneKey: SceneKey) {
         check("currentScene").that(actual.currentScene).isEqualTo(sceneKey)
@@ -132,19 +134,21 @@
         check("currentOverscrollSpec").that(actual.currentOverscrollSpec).isNull()
     }
 
-    fun hasBouncingScene(scene: SceneKey) {
-        if (actual !is ContentState.HasOverscrollProperties) {
+    fun hasBouncingContent(content: ContentKey) {
+        val actual = actual
+        if (actual !is TransitionState.HasOverscrollProperties) {
             failWithActual(simpleFact("expected to be ContentState.HasOverscrollProperties"))
         }
 
         check("bouncingContent")
-            .that((actual as ContentState.HasOverscrollProperties).bouncingContent)
-            .isEqualTo(scene)
+            .that((actual as TransitionState.HasOverscrollProperties).bouncingContent)
+            .isEqualTo(content)
     }
 
     companion object {
-        fun transitions() = Factory { metadata, actual: TransitionState.Transition ->
-            TransitionSubject(metadata, actual)
-        }
+        fun transitions() =
+            Factory { metadata, actual: TransitionState.Transition.ChangeCurrentScene ->
+                SceneTransitionSubject(metadata, actual)
+            }
     }
 }