Revert^2 "A few fixes for animation takeovers."

Reason for revert: this test on Cuttlefish seems to be very unstable in general. I tried to re-test on ABTD with these reverts patched in, but the test isn't being included in the suite, and I couldn't find information anywhere on whether it's supposed to be still running. Since these changes are fully flagged, I don't see how they could be the real culprit. Trying to submit again and monitoring the impact on the post submits.

Change-Id: I909b4e2c00296ca7ea66f73ad25f843ae64aad40
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index eee0caf..8cf9d15 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -867,6 +867,9 @@
                     ) {
                         // Raise closing task to "above" layer so it isn't covered.
                         t.setLayer(target.leash, aboveLayers - i)
+                    } else if (TransitionUtil.isOpeningType(change.mode)) {
+                        // Put into the "below" layer space.
+                        t.setLayer(target.leash, belowLayers - i)
                     }
                 } else if (TransitionInfo.isIndependent(change, info)) {
                     // Root tasks
@@ -1133,7 +1136,7 @@
                 // If a [controller.windowAnimatorState] exists, treat this like a takeover.
                 takeOverAnimationInternal(
                     window,
-                    startWindowStates = null,
+                    startWindowState = null,
                     startTransaction = null,
                     callback,
                 )
@@ -1148,22 +1151,23 @@
             callback: IRemoteAnimationFinishedCallback?,
         ) {
             val window = setUpAnimation(apps, callback) ?: return
-            takeOverAnimationInternal(window, startWindowStates, startTransaction, callback)
+            val startWindowState = startWindowStates[apps!!.indexOf(window)]
+            takeOverAnimationInternal(window, startWindowState, startTransaction, callback)
         }
 
         private fun takeOverAnimationInternal(
             window: RemoteAnimationTarget,
-            startWindowStates: Array<WindowAnimationState>?,
+            startWindowState: WindowAnimationState?,
             startTransaction: SurfaceControl.Transaction?,
             callback: IRemoteAnimationFinishedCallback?,
         ) {
             val useSpring =
-                !controller.isLaunching && startWindowStates != null && startTransaction != null
+                !controller.isLaunching && startWindowState != null && startTransaction != null
             startAnimation(
                 window,
                 navigationBar = null,
                 useSpring,
-                startWindowStates,
+                startWindowState,
                 startTransaction,
                 callback,
             )
@@ -1273,7 +1277,7 @@
             window: RemoteAnimationTarget,
             navigationBar: RemoteAnimationTarget? = null,
             useSpring: Boolean = false,
-            startingWindowStates: Array<WindowAnimationState>? = null,
+            startingWindowState: WindowAnimationState? = null,
             startTransaction: SurfaceControl.Transaction? = null,
             iCallback: IRemoteAnimationFinishedCallback? = null,
         ) {
@@ -1319,6 +1323,7 @@
 
             val isExpandingFullyAbove =
                 transitionAnimator.isExpandingFullyAbove(controller.transitionContainer, endState)
+            val windowState = startingWindowState ?: controller.windowAnimatorState
 
             // We animate the opening window and delegate the view expansion to [this.controller].
             val delegate = this.controller
@@ -1341,18 +1346,6 @@
                                 }
                         }
 
-                        // The states are sorted matching the changes inside the transition info.
-                        // Using this info, the RemoteAnimationTargets are created, with their
-                        // prefixOrderIndex fields in reverse order to that of changes. To extract
-                        // the right state, we need to invert again.
-                        val windowState =
-                            if (startingWindowStates != null) {
-                                startingWindowStates[
-                                    startingWindowStates.size - window.prefixOrderIndex]
-                            } else {
-                                controller.windowAnimatorState
-                            }
-
                         // TODO(b/323863002): use the timestamp and velocity to update the initial
                         //   position.
                         val bounds = windowState?.bounds
@@ -1441,12 +1434,6 @@
                         delegate.onTransitionAnimationProgress(state, progress, linearProgress)
                     }
                 }
-            val windowState =
-                if (startingWindowStates != null) {
-                    startingWindowStates[startingWindowStates.size - window.prefixOrderIndex]
-                } else {
-                    controller.windowAnimatorState
-                }
             val velocityPxPerS =
                 if (longLivedReturnAnimationsEnabled() && windowState?.velocityPxPerMs != null) {
                     val xVelocityPxPerS = windowState.velocityPxPerMs.x * 1000
@@ -1465,6 +1452,7 @@
                     fadeWindowBackgroundLayer = !controller.isBelowAnimatingWindow,
                     drawHole = !controller.isBelowAnimatingWindow,
                     startVelocity = velocityPxPerS,
+                    startFrameTime = windowState?.timestamp ?: -1,
                 )
         }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
index e2bc409..4e889e9 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
@@ -27,6 +27,8 @@
 import android.util.FloatProperty
 import android.util.Log
 import android.util.MathUtils
+import android.util.TimeUtils
+import android.view.Choreographer
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewGroupOverlay
@@ -366,6 +368,7 @@
         @get:VisibleForTesting val springY: SpringAnimation,
         @get:VisibleForTesting val springScale: SpringAnimation,
         private val springState: SpringState,
+        private val startFrameTime: Long,
         private val onAnimationStart: Runnable,
     ) : Animation {
         @get:VisibleForTesting
@@ -374,6 +377,42 @@
 
         override fun start() {
             onAnimationStart.run()
+
+            // If no start frame time is provided, we start the springs normally.
+            if (startFrameTime < 0) {
+                startSprings()
+                return
+            }
+
+            // This function is not guaranteed to be called inside a frame. We try to access the
+            // frame time immediately, but if we're not inside a frame this will throw an exception.
+            // We must then post a callback to be run at the beginning of the next frame.
+            try {
+                initAndStartSprings(Choreographer.getInstance().frameTime)
+            } catch (_: IllegalStateException) {
+                Choreographer.getInstance().postFrameCallback { frameTimeNanos ->
+                    initAndStartSprings(frameTimeNanos / TimeUtils.NANOS_PER_MS)
+                }
+            }
+        }
+
+        private fun initAndStartSprings(frameTime: Long) {
+            // Initialize the spring as if it had started at the time that its start state
+            // was created.
+            springX.doAnimationFrame(startFrameTime)
+            springY.doAnimationFrame(startFrameTime)
+            springScale.doAnimationFrame(startFrameTime)
+            // Move the spring time forward to the current frame, so it updates its internal state
+            // following the initial momentum over the elapsed time.
+            springX.doAnimationFrame(frameTime)
+            springY.doAnimationFrame(frameTime)
+            springScale.doAnimationFrame(frameTime)
+            // Actually start the spring. We do this after the previous calls because the framework
+            // doesn't like it when you call doAnimationFrame() after start() with an earlier time.
+            startSprings()
+        }
+
+        private fun startSprings() {
             springX.start()
             springY.start()
             springScale.start()
@@ -471,7 +510,9 @@
      * is true.
      *
      * If [startVelocity] (expressed in pixels per second) is not null, a multi-spring animation
-     * using it for the initial momentum will be used instead of the default interpolators.
+     * using it for the initial momentum will be used instead of the default interpolators. In this
+     * case, [startFrameTime] (if non-negative) represents the frame time at which the springs
+     * should be started.
      */
     fun startAnimation(
         controller: Controller,
@@ -480,6 +521,7 @@
         fadeWindowBackgroundLayer: Boolean = true,
         drawHole: Boolean = false,
         startVelocity: PointF? = null,
+        startFrameTime: Long = -1,
     ): Animation {
         if (!controller.isLaunching) assertReturnAnimations()
         if (startVelocity != null) assertLongLivedReturnAnimations()
@@ -502,6 +544,7 @@
                 fadeWindowBackgroundLayer,
                 drawHole,
                 startVelocity,
+                startFrameTime,
             )
             .apply { start() }
     }
@@ -515,6 +558,7 @@
         fadeWindowBackgroundLayer: Boolean = true,
         drawHole: Boolean = false,
         startVelocity: PointF? = null,
+        startFrameTime: Long = -1,
     ): Animation {
         val transitionContainer = controller.transitionContainer
         val transitionContainerOverlay = transitionContainer.overlay
@@ -537,6 +581,7 @@
                 startState,
                 endState,
                 startVelocity,
+                startFrameTime,
                 windowBackgroundLayer,
                 transitionContainer,
                 transitionContainerOverlay,
@@ -722,6 +767,7 @@
         startState: State,
         endState: State,
         startVelocity: PointF,
+        startFrameTime: Long,
         windowBackgroundLayer: GradientDrawable,
         transitionContainer: View,
         transitionContainerOverlay: ViewGroupOverlay,
@@ -912,7 +958,7 @@
                     }
                 }
 
-        return MultiSpringAnimation(springX, springY, springScale, springState) {
+        return MultiSpringAnimation(springX, springY, springScale, springState, startFrameTime) {
             onAnimationStart(
                 controller,
                 isExpandingFullyAbove,