Revert^2 "[flexiglass] Add bouncer predictive back motion test"

This reverts commit cdf10953f4e35ac1e8f8882df1e833395c7d5911.

Reason for revert: reland revert

Change-Id: I40ca0f0c099213836527b0a23ff26ac70e762e2b
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index d26a906..a9e81c7 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -756,6 +756,7 @@
         "notification_flags_lib",
         "PlatformComposeCore",
         "PlatformComposeSceneTransitionLayout",
+        "PlatformComposeSceneTransitionLayoutTestsUtils",
         "androidx.compose.runtime_runtime",
         "androidx.compose.material3_material3",
         "androidx.compose.material_material-icons-extended",
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index 7fb88e8..ae92d259 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -99,8 +99,8 @@
         BouncerContent(
             viewModel,
             dialogFactory,
-            Modifier.sysuiResTag(Bouncer.TestTags.Root)
-                .element(Bouncer.Elements.Content)
+            Modifier.element(Bouncer.Elements.Content)
+                .sysuiResTag(Bouncer.TestTags.Root)
                 .fillMaxSize()
         )
     }
diff --git a/packages/SystemUI/tests/goldens/bouncerPredictiveBackMotion.json b/packages/SystemUI/tests/goldens/bouncerPredictiveBackMotion.json
new file mode 100644
index 0000000..f37580d
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/bouncerPredictiveBackMotion.json
@@ -0,0 +1,831 @@
+{
+  "frame_ids": [
+    "before",
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816,
+    832,
+    848,
+    864,
+    880,
+    896,
+    912,
+    928,
+    944,
+    960,
+    976,
+    992,
+    1008,
+    1024,
+    "after"
+  ],
+  "features": [
+    {
+      "name": "content_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.9954499,
+        0.9805035,
+        0.9527822,
+        0.9092045,
+        0.84588075,
+        0.7583043,
+        0.6424476,
+        0.49766344,
+        0.33080608,
+        0.15650165,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        {
+          "type": "not_found"
+        }
+      ]
+    },
+    {
+      "name": "content_scale",
+      "type": "scale",
+      "data_points": [
+        "default",
+        {
+          "x": 0.9995097,
+          "y": 0.9995097,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.997352,
+          "y": 0.997352,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.990635,
+          "y": 0.990635,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.97249764,
+          "y": 0.97249764,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.94287145,
+          "y": 0.94287145,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.9128026,
+          "y": 0.9128026,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8859569,
+          "y": 0.8859569,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8629254,
+          "y": 0.8629254,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8442908,
+          "y": 0.8442908,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8303209,
+          "y": 0.8303209,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8205137,
+          "y": 0.8205137,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.81387186,
+          "y": 0.81387186,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80941653,
+          "y": 0.80941653,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80641484,
+          "y": 0.80641484,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80437464,
+          "y": 0.80437464,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80297637,
+          "y": 0.80297637,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80201286,
+          "y": 0.80201286,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8013477,
+          "y": 0.8013477,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8008894,
+          "y": 0.8008894,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8005756,
+          "y": 0.8005756,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80036324,
+          "y": 0.80036324,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8002219,
+          "y": 0.8002219,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80012995,
+          "y": 0.80012995,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8000721,
+          "y": 0.8000721,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.80003715,
+          "y": 0.80003715,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8000173,
+          "y": 0.8000173,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.800007,
+          "y": 0.800007,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8000022,
+          "y": 0.8000022,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8000004,
+          "y": 0.8000004,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.79999995,
+          "y": 0.79999995,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "x": 0.8,
+          "y": 0.8,
+          "pivot": "unspecified"
+        },
+        {
+          "type": "not_found"
+        }
+      ]
+    },
+    {
+      "name": "content_offset",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "x": 0,
+          "y": 0.5714286
+        },
+        {
+          "x": 0,
+          "y": 2.857143
+        },
+        {
+          "x": 0,
+          "y": 7.142857
+        },
+        {
+          "x": 0,
+          "y": 13.714286
+        },
+        {
+          "x": 0,
+          "y": 23.142857
+        },
+        {
+          "x": 0,
+          "y": 36.285713
+        },
+        {
+          "x": 0,
+          "y": 53.714287
+        },
+        {
+          "x": 0,
+          "y": 75.42857
+        },
+        {
+          "x": 0,
+          "y": 100.28571
+        },
+        {
+          "x": 0,
+          "y": 126.57143
+        },
+        {
+          "x": 0,
+          "y": 151.42857
+        },
+        {
+          "x": 0,
+          "y": 174
+        },
+        {
+          "x": 0,
+          "y": 193.42857
+        },
+        {
+          "x": 0,
+          "y": 210.28572
+        },
+        {
+          "x": 0,
+          "y": 224.85715
+        },
+        {
+          "x": 0,
+          "y": 237.14285
+        },
+        {
+          "x": 0,
+          "y": 247.71428
+        },
+        {
+          "x": 0,
+          "y": 256.85715
+        },
+        {
+          "x": 0,
+          "y": 264.57144
+        },
+        {
+          "x": 0,
+          "y": 271.42856
+        },
+        {
+          "x": 0,
+          "y": 277.14285
+        },
+        {
+          "x": 0,
+          "y": 282
+        },
+        {
+          "x": 0,
+          "y": 286.2857
+        },
+        {
+          "x": 0,
+          "y": 289.7143
+        },
+        {
+          "x": 0,
+          "y": 292.57144
+        },
+        {
+          "x": 0,
+          "y": 294.85715
+        },
+        {
+          "x": 0,
+          "y": 296.85715
+        },
+        {
+          "x": 0,
+          "y": 298.2857
+        },
+        {
+          "x": 0,
+          "y": 299.14285
+        },
+        {
+          "x": 0,
+          "y": 299.7143
+        },
+        {
+          "x": 0,
+          "y": 300
+        },
+        {
+          "x": 0,
+          "y": 0
+        },
+        {
+          "type": "not_found"
+        }
+      ]
+    },
+    {
+      "name": "background_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.9900334,
+        0.8403853,
+        0.71002257,
+        0.5979084,
+        0.50182605,
+        0.41945767,
+        0.34874845,
+        0.28797746,
+        0.23573697,
+        0.19087732,
+        0.1524564,
+        0.11970067,
+        0.091962695,
+        0.068702936,
+        0.049464583,
+        0.033859253,
+        0.021552086,
+        0.012255073,
+        0.005717635,
+        0.0017191172,
+        6.711483e-05,
+        0,
+        {
+          "type": "not_found"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
new file mode 100644
index 0000000..22946c8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
@@ -0,0 +1,348 @@
+/*
+ * 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.systemui.bouncer.ui.composable
+
+import android.app.AlertDialog
+import android.platform.test.annotations.MotionTest
+import android.testing.TestableLooper.RunWithLooper
+import androidx.activity.BackEventCompat
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.layout.Box
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.isFinite
+import androidx.compose.ui.geometry.isUnspecified
+import androidx.compose.ui.semantics.SemanticsNode
+import androidx.compose.ui.test.junit4.AndroidComposeTestRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.Scale
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneScope
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
+import com.android.compose.animation.scene.isElement
+import com.android.compose.animation.scene.testing.lastAlphaForTesting
+import com.android.compose.animation.scene.testing.lastScaleForTesting
+import com.android.compose.theme.PlatformTheme
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
+import com.android.systemui.bouncer.ui.BouncerDialogFactory
+import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerUserActionsViewModel
+import com.android.systemui.bouncer.ui.viewmodel.bouncerSceneContentViewModel
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.motion.createSysUiComposeMotionTestRule
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.domain.startable.sceneContainerStartable
+import com.android.systemui.scene.shared.logger.sceneLogger
+import com.android.systemui.scene.shared.model.SceneContainerConfig
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.sceneDataSourceDelegator
+import com.android.systemui.scene.ui.composable.Scene
+import com.android.systemui.scene.ui.composable.SceneContainer
+import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
+import com.android.systemui.scene.ui.viewmodel.splitEdgeDetector
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
+import org.json.JSONObject
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoAnnotations
+import platform.test.motion.compose.ComposeFeatureCaptures.positionInRoot
+import platform.test.motion.compose.ComposeRecordingSpec
+import platform.test.motion.compose.MotionControl
+import platform.test.motion.compose.feature
+import platform.test.motion.compose.recordMotion
+import platform.test.motion.compose.runTest
+import platform.test.motion.golden.DataPoint
+import platform.test.motion.golden.DataPointType
+import platform.test.motion.golden.DataPointTypes
+import platform.test.motion.golden.FeatureCapture
+import platform.test.motion.golden.UnknownTypeException
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.Displays.Phone
+
+/** MotionTest for the Bouncer Predictive Back animation */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper
+@EnableSceneContainer
+@MotionTest
+class BouncerPredictiveBackTest : SysuiTestCase() {
+
+    private val deviceSpec = DeviceEmulationSpec(Phone)
+    private val kosmos = testKosmos()
+
+    @get:Rule val motionTestRule = createSysUiComposeMotionTestRule(kosmos, deviceSpec)
+    private val androidComposeTestRule =
+        motionTestRule.toolkit.composeContentTestRule as AndroidComposeTestRule<*, *>
+
+    private val sceneInteractor by lazy { kosmos.sceneInteractor }
+    private val Kosmos.sceneKeys by Fixture { listOf(Scenes.Lockscreen, Scenes.Bouncer) }
+    private val Kosmos.initialSceneKey by Fixture { Scenes.Bouncer }
+    private val Kosmos.sceneContainerConfig by Fixture {
+        val navigationDistances =
+            mapOf(
+                Scenes.Lockscreen to 1,
+                Scenes.Bouncer to 0,
+            )
+        SceneContainerConfig(sceneKeys, initialSceneKey, emptyList(), navigationDistances)
+    }
+
+    private val transitionState by lazy {
+        MutableStateFlow<ObservableTransitionState>(
+            ObservableTransitionState.Idle(kosmos.sceneContainerConfig.initialSceneKey)
+        )
+    }
+    private val sceneContainerViewModel by lazy {
+        SceneContainerViewModel(
+                sceneInteractor = kosmos.sceneInteractor,
+                falsingInteractor = kosmos.falsingInteractor,
+                powerInteractor = kosmos.powerInteractor,
+                shadeInteractor = kosmos.shadeInteractor,
+                splitEdgeDetector = kosmos.splitEdgeDetector,
+                logger = kosmos.sceneLogger,
+                motionEventHandlerReceiver = {},
+            )
+            .apply { setTransitionState(transitionState) }
+    }
+
+    private val bouncerDialogFactory =
+        object : BouncerDialogFactory {
+            override fun invoke(): AlertDialog {
+                throw AssertionError()
+            }
+        }
+    private val bouncerSceneActionsViewModelFactory =
+        object : BouncerUserActionsViewModel.Factory {
+            override fun create() = BouncerUserActionsViewModel(kosmos.bouncerInteractor)
+        }
+    private lateinit var bouncerSceneContentViewModel: BouncerSceneContentViewModel
+    private val bouncerSceneContentViewModelFactory =
+        object : BouncerSceneContentViewModel.Factory {
+            override fun create() = bouncerSceneContentViewModel
+        }
+    private val bouncerScene =
+        BouncerScene(
+            bouncerSceneActionsViewModelFactory,
+            bouncerSceneContentViewModelFactory,
+            bouncerDialogFactory
+        )
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        bouncerSceneContentViewModel = kosmos.bouncerSceneContentViewModel
+
+        val startable = kosmos.sceneContainerStartable
+        startable.start()
+    }
+
+    @Test
+    fun bouncerPredictiveBackMotion() =
+        motionTestRule.runTest {
+            val motion =
+                recordMotion(
+                    content = { play ->
+                        PlatformTheme {
+                            BackGestureAnimation(play)
+                            SceneContainer(
+                                viewModel =
+                                    rememberViewModel("BouncerPredictiveBackTest") {
+                                        sceneContainerViewModel
+                                    },
+                                sceneByKey =
+                                    mapOf(
+                                        Scenes.Lockscreen to FakeLockscreen(),
+                                        Scenes.Bouncer to bouncerScene
+                                    ),
+                                initialSceneKey = Scenes.Bouncer,
+                                overlayByKey = emptyMap(),
+                                dataSourceDelegator = kosmos.sceneDataSourceDelegator
+                            )
+                        }
+                    },
+                    ComposeRecordingSpec(
+                        MotionControl(
+                            delayRecording = {
+                                awaitCondition {
+                                    sceneInteractor.transitionState.value.isTransitioning()
+                                }
+                            }
+                        ) {
+                            awaitCondition {
+                                sceneInteractor.transitionState.value.isIdle(Scenes.Lockscreen)
+                            }
+                        }
+                    ) {
+                        feature(isElement(Bouncer.Elements.Content), elementAlpha, "content_alpha")
+                        feature(isElement(Bouncer.Elements.Content), elementScale, "content_scale")
+                        feature(
+                            isElement(Bouncer.Elements.Content),
+                            positionInRoot,
+                            "content_offset"
+                        )
+                        feature(
+                            isElement(Bouncer.Elements.Background),
+                            elementAlpha,
+                            "background_alpha"
+                        )
+                    }
+                )
+
+            assertThat(motion).timeSeriesMatchesGolden()
+        }
+
+    @Composable
+    private fun BackGestureAnimation(play: Boolean) {
+        val backProgress = remember { Animatable(0f) }
+
+        LaunchedEffect(play) {
+            if (play) {
+                val dispatcher = androidComposeTestRule.activity.onBackPressedDispatcher
+                androidComposeTestRule.runOnUiThread {
+                    dispatcher.dispatchOnBackStarted(backEvent())
+                }
+                backProgress.animateTo(
+                    targetValue = 1f,
+                    animationSpec = tween(durationMillis = 500)
+                ) {
+                    androidComposeTestRule.runOnUiThread {
+                        dispatcher.dispatchOnBackProgressed(
+                            backEvent(progress = backProgress.value)
+                        )
+                        if (backProgress.value == 1f) {
+                            dispatcher.onBackPressed()
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private fun backEvent(progress: Float = 0f): BackEventCompat {
+        return BackEventCompat(
+            touchX = 0f,
+            touchY = 0f,
+            progress = progress,
+            swipeEdge = BackEventCompat.EDGE_LEFT,
+        )
+    }
+
+    private class FakeLockscreen : ExclusiveActivatable(), Scene {
+        override val key: SceneKey = Scenes.Lockscreen
+        override val userActions: Flow<Map<UserAction, UserActionResult>> = flowOf()
+
+        @Composable
+        override fun SceneScope.Content(modifier: Modifier) {
+            Box(modifier = modifier, contentAlignment = Alignment.Center) {
+                Text(text = "Fake Lockscreen")
+            }
+        }
+
+        override suspend fun onActivated() = awaitCancellation()
+    }
+
+    companion object {
+        private val elementAlpha =
+            FeatureCapture<SemanticsNode, Float>("alpha") {
+                DataPoint.of(it.lastAlphaForTesting, DataPointTypes.float)
+            }
+
+        private val elementScale =
+            FeatureCapture<SemanticsNode, Scale>("scale") {
+                DataPoint.of(it.lastScaleForTesting, scale)
+            }
+
+        private val scale: DataPointType<Scale> =
+            DataPointType(
+                "scale",
+                jsonToValue = {
+                    when (it) {
+                        "unspecified" -> Scale.Unspecified
+                        "default" -> Scale.Default
+                        "zero" -> Scale.Zero
+                        is JSONObject -> {
+                            val pivot = it.get("pivot")
+                            Scale(
+                                scaleX = it.getDouble("x").toFloat(),
+                                scaleY = it.getDouble("y").toFloat(),
+                                pivot =
+                                    when (pivot) {
+                                        "unspecified" -> Offset.Unspecified
+                                        "infinite" -> Offset.Infinite
+                                        is JSONObject ->
+                                            Offset(
+                                                pivot.getDouble("x").toFloat(),
+                                                pivot.getDouble("y").toFloat()
+                                            )
+                                        else -> throw UnknownTypeException()
+                                    }
+                            )
+                        }
+                        else -> throw UnknownTypeException()
+                    }
+                },
+                valueToJson = {
+                    when (it) {
+                        Scale.Unspecified -> "unspecified"
+                        Scale.Default -> "default"
+                        Scale.Zero -> "zero"
+                        else -> {
+                            JSONObject().apply {
+                                put("x", it.scaleX)
+                                put("y", it.scaleY)
+                                put(
+                                    "pivot",
+                                    when {
+                                        it.pivot.isUnspecified -> "unspecified"
+                                        !it.pivot.isFinite -> "infinite"
+                                        else ->
+                                            JSONObject().apply {
+                                                put("x", it.pivot.x)
+                                                put("y", it.pivot.y)
+                                            }
+                                    }
+                                )
+                            }
+                        }
+                    }
+                }
+            )
+    }
+}