Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e71a5f7 authored by Luca Zuccarini's avatar Luca Zuccarini
Browse files

Use initial velocity with spring animations in TransitionAnimator.

I've also reworked the test a bunch to reduce repetition and use
parameters better. Shouldn't need to touch it much after this.

Bug: 323863002
Flag: com.android.systemui.shared.return_animation_framework_library
Test: atest TransitionAnimatorTest
Change-Id: I961198763a73a58b3b3db0fa8b3f79f53cbf1c98
parent 4a10fd11
Loading
Loading
Loading
Loading
+39 −24
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.PointF
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.drawable.GradientDrawable
@@ -33,13 +34,13 @@ import android.view.ViewOverlay
import android.view.animation.Interpolator
import android.window.WindowAnimationState
import com.android.app.animation.Interpolators.LINEAR
import com.android.app.animation.MathUtils.max
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.dynamicanimation.animation.SpringAnimation
import com.android.internal.dynamicanimation.animation.SpringForce
import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary
import java.util.concurrent.Executor
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt

@@ -91,6 +92,14 @@ class TransitionAnimator(
            )
        }

        /**
         * Similar to [getProgress] above, bug the delay and duration are expressed as percentages
         * of the animation duration (between 0f and 1f).
         */
        internal fun getProgress(linearProgress: Float, delay: Float, duration: Float): Float {
            return getProgressInternal(totalDuration = 1f, linearProgress, delay, duration)
        }

        private fun getProgressInternal(
            totalDuration: Float,
            linearProgress: Float,
@@ -262,10 +271,10 @@ class TransitionAnimator(
        var centerY: Float,
        var scale: Float = 0f,

        // Cached values.
        var previousCenterX: Float = -1f,
        var previousCenterY: Float = -1f,
        var previousScale: Float = -1f,
        // Update flags (used to decide whether it's time to update the transition state).
        var isCenterXUpdated: Boolean = false,
        var isCenterYUpdated: Boolean = false,
        var isScaleUpdated: Boolean = false,

        // Completion flags.
        var isCenterXDone: Boolean = false,
@@ -286,6 +295,7 @@ class TransitionAnimator(

            override fun setValue(state: SpringState, value: Float) {
                state.centerX = value
                state.isCenterXUpdated = true
            }
        },
        CENTER_Y {
@@ -295,6 +305,7 @@ class TransitionAnimator(

            override fun setValue(state: SpringState, value: Float) {
                state.centerY = value
                state.isCenterYUpdated = true
            }
        },
        SCALE {
@@ -304,6 +315,7 @@ class TransitionAnimator(

            override fun setValue(state: SpringState, value: Float) {
                state.scale = value
                state.isScaleUpdated = true
            }
        };

@@ -444,8 +456,8 @@ class TransitionAnimator(
     * punching a hole in the [transition container][Controller.transitionContainer]) iff [drawHole]
     * is true.
     *
     * If [useSpring] is true, a multi-spring animation will be used instead of the default
     * interpolators.
     * 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.
     */
    fun startAnimation(
        controller: Controller,
@@ -453,9 +465,9 @@ class TransitionAnimator(
        windowBackgroundColor: Int,
        fadeWindowBackgroundLayer: Boolean = true,
        drawHole: Boolean = false,
        useSpring: Boolean = false,
        startVelocity: PointF? = null,
    ): Animation {
        if (!controller.isLaunching || useSpring) checkReturnAnimationFrameworkFlag()
        if (!controller.isLaunching || startVelocity != null) checkReturnAnimationFrameworkFlag()

        // We add an extra layer with the same color as the dialog/app splash screen background
        // color, which is usually the same color of the app background. We first fade in this layer
@@ -474,7 +486,7 @@ class TransitionAnimator(
                windowBackgroundLayer,
                fadeWindowBackgroundLayer,
                drawHole,
                useSpring,
                startVelocity,
            )
            .apply { start() }
    }
@@ -487,7 +499,7 @@ class TransitionAnimator(
        windowBackgroundLayer: GradientDrawable,
        fadeWindowBackgroundLayer: Boolean = true,
        drawHole: Boolean = false,
        useSpring: Boolean = false,
        startVelocity: PointF? = null,
    ): Animation {
        val transitionContainer = controller.transitionContainer
        val transitionContainerOverlay = transitionContainer.overlay
@@ -504,11 +516,12 @@ class TransitionAnimator(
            openingWindowSyncView != null &&
                openingWindowSyncView.viewRootImpl != controller.transitionContainer.viewRootImpl

        return if (useSpring && springTimings != null && springInterpolators != null) {
        return if (startVelocity != null && springTimings != null && springInterpolators != null) {
            createSpringAnimation(
                controller,
                startState,
                endState,
                startVelocity,
                windowBackgroundLayer,
                transitionContainer,
                transitionContainerOverlay,
@@ -693,6 +706,7 @@ class TransitionAnimator(
        controller: Controller,
        startState: State,
        endState: State,
        startVelocity: PointF,
        windowBackgroundLayer: GradientDrawable,
        transitionContainer: View,
        transitionContainerOverlay: ViewGroupOverlay,
@@ -721,19 +735,20 @@ class TransitionAnimator(

        fun updateProgress(state: SpringState) {
            if (
                (!state.isCenterXDone && state.centerX == state.previousCenterX) ||
                    (!state.isCenterYDone && state.centerY == state.previousCenterY) ||
                    (!state.isScaleDone && state.scale == state.previousScale)
                !(state.isCenterXUpdated || state.isCenterXDone) ||
                    !(state.isCenterYUpdated || state.isCenterYDone) ||
                    !(state.isScaleUpdated || state.isScaleDone)
            ) {
                // Because all three springs use the same update method, we only actually update
                // when all values have changed, avoiding two redundant calls per frame.
                // when all properties have received their new value (which could be unchanged from
                // the previous one), avoiding two redundant calls per frame.
                return
            }

            // Update the latest values for the check above.
            state.previousCenterX = state.centerX
            state.previousCenterY = state.centerY
            state.previousScale = state.scale
            // Reset the update flags.
            state.isCenterXUpdated = false
            state.isCenterYUpdated = false
            state.isScaleUpdated = false

            // Current scale-based values, that will be used to find the new animation bounds.
            val width =
@@ -829,6 +844,7 @@ class TransitionAnimator(
                        }

                    setStartValue(startState.centerX)
                    setStartVelocity(startVelocity.x)
                    setMinValue(min(startState.centerX, endState.centerX))
                    setMaxValue(max(startState.centerX, endState.centerX))

@@ -850,6 +866,7 @@ class TransitionAnimator(
                        }

                    setStartValue(startState.centerY)
                    setStartVelocity(startVelocity.y)
                    setMinValue(min(startState.centerY, endState.centerY))
                    setMaxValue(max(startState.centerY, endState.centerY))

@@ -1057,15 +1074,13 @@ class TransitionAnimator(
            interpolators = springInterpolators!!
            val timings = springTimings!!
            fadeInProgress =
                getProgressInternal(
                    totalDuration = 1f,
                getProgress(
                    linearProgress,
                    timings.contentBeforeFadeOutDelay,
                    timings.contentBeforeFadeOutDuration,
                )
            fadeOutProgress =
                getProgressInternal(
                    totalDuration = 1f,
                getProgress(
                    linearProgress,
                    timings.contentAfterFadeInDelay,
                    timings.contentAfterFadeInDuration,
+0 −0

File moved.

+68 −59
Original line number Diff line number Diff line
@@ -33,118 +33,118 @@
          "bottom": 0
        },
        {
          "left": 94,
          "top": 284,
          "right": 206,
          "left": 104,
          "top": 285,
          "right": 215,
          "bottom": 414
        },
        {
          "left": 83,
          "top": 251,
          "right": 219,
          "left": 92,
          "top": 252,
          "right": 227,
          "bottom": 447
        },
        {
          "left": 70,
          "top": 212,
          "right": 234,
          "bottom": 485
          "left": 77,
          "top": 213,
          "right": 242,
          "bottom": 486
        },
        {
          "left": 57,
          "top": 173,
          "right": 250,
          "bottom": 522
          "left": 63,
          "top": 175,
          "right": 256,
          "bottom": 524
        },
        {
          "left": 46,
          "top": 139,
          "right": 264,
          "bottom": 555
          "left": 50,
          "top": 141,
          "right": 269,
          "bottom": 558
        },
        {
          "left": 36,
          "top": 109,
          "right": 276,
          "bottom": 584
          "left": 40,
          "top": 112,
          "right": 279,
          "bottom": 587
        },
        {
          "left": 28,
          "top": 84,
          "right": 285,
          "bottom": 608
          "left": 31,
          "top": 88,
          "right": 288,
          "bottom": 611
        },
        {
          "left": 21,
          "top": 65,
          "right": 293,
          "bottom": 627
          "left": 23,
          "top": 68,
          "right": 296,
          "bottom": 631
        },
        {
          "left": 16,
          "top": 49,
          "right": 300,
          "bottom": 642
          "left": 18,
          "top": 53,
          "right": 301,
          "bottom": 646
        },
        {
          "left": 12,
          "top": 36,
          "right": 305,
          "bottom": 653
          "left": 13,
          "top": 41,
          "right": 306,
          "bottom": 658
        },
        {
          "left": 9,
          "top": 27,
          "right": 308,
          "bottom": 662
          "left": 10,
          "top": 31,
          "right": 309,
          "bottom": 667
        },
        {
          "left": 7,
          "top": 20,
          "top": 24,
          "right": 312,
          "bottom": 669
          "bottom": 673
        },
        {
          "left": 5,
          "top": 14,
          "top": 18,
          "right": 314,
          "bottom": 675
          "bottom": 678
        },
        {
          "left": 4,
          "top": 11,
          "top": 13,
          "right": 315,
          "bottom": 678
          "bottom": 681
        },
        {
          "left": 3,
          "top": 8,
          "top": 10,
          "right": 316,
          "bottom": 681
          "bottom": 684
        },
        {
          "left": 2,
          "top": 5,
          "top": 7,
          "right": 317,
          "bottom": 684
          "bottom": 685
        },
        {
          "left": 1,
          "top": 4,
          "top": 5,
          "right": 318,
          "bottom": 685
          "bottom": 687
        },
        {
          "left": 1,
          "top": 3,
          "top": 4,
          "right": 318,
          "bottom": 686
          "bottom": 688
        },
        {
          "left": 0,
          "top": 2,
          "top": 3,
          "right": 319,
          "bottom": 687
          "bottom": 688
        }
      ]
    },
@@ -371,5 +371,14 @@
        0
      ]
    }
  ]
  ],
  "\/\/metadata": {
    "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimation_whenLaunching_withSpring.json",
    "goldenIdentifier": "backgroundAnimation_whenLaunching_withSpring",
    "testClassName": "TransitionAnimatorTest",
    "testMethodName": "backgroundAnimation_whenLaunching[true]",
    "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
    "result": "FAILED",
    "videoLocation": "TransitionAnimatorTest\/backgroundAnimation_whenLaunching_withSpring.actual.mp4"
  }
}
 No newline at end of file
+0 −0

File moved.

+68 −59
Original line number Diff line number Diff line
@@ -33,118 +33,118 @@
          "bottom": 0
        },
        {
          "left": 94,
          "top": 284,
          "right": 206,
          "left": 104,
          "top": 285,
          "right": 215,
          "bottom": 414
        },
        {
          "left": 83,
          "top": 251,
          "right": 219,
          "left": 92,
          "top": 252,
          "right": 227,
          "bottom": 447
        },
        {
          "left": 70,
          "top": 212,
          "right": 234,
          "bottom": 485
          "left": 77,
          "top": 213,
          "right": 242,
          "bottom": 486
        },
        {
          "left": 57,
          "top": 173,
          "right": 250,
          "bottom": 522
          "left": 63,
          "top": 175,
          "right": 256,
          "bottom": 524
        },
        {
          "left": 46,
          "top": 139,
          "right": 264,
          "bottom": 555
          "left": 50,
          "top": 141,
          "right": 269,
          "bottom": 558
        },
        {
          "left": 36,
          "top": 109,
          "right": 276,
          "bottom": 584
          "left": 40,
          "top": 112,
          "right": 279,
          "bottom": 587
        },
        {
          "left": 28,
          "top": 84,
          "right": 285,
          "bottom": 608
          "left": 31,
          "top": 88,
          "right": 288,
          "bottom": 611
        },
        {
          "left": 21,
          "top": 65,
          "right": 293,
          "bottom": 627
          "left": 23,
          "top": 68,
          "right": 296,
          "bottom": 631
        },
        {
          "left": 16,
          "top": 49,
          "right": 300,
          "bottom": 642
          "left": 18,
          "top": 53,
          "right": 301,
          "bottom": 646
        },
        {
          "left": 12,
          "top": 36,
          "right": 305,
          "bottom": 653
          "left": 13,
          "top": 41,
          "right": 306,
          "bottom": 658
        },
        {
          "left": 9,
          "top": 27,
          "right": 308,
          "bottom": 662
          "left": 10,
          "top": 31,
          "right": 309,
          "bottom": 667
        },
        {
          "left": 7,
          "top": 20,
          "top": 24,
          "right": 312,
          "bottom": 669
          "bottom": 673
        },
        {
          "left": 5,
          "top": 14,
          "top": 18,
          "right": 314,
          "bottom": 675
          "bottom": 678
        },
        {
          "left": 4,
          "top": 11,
          "top": 13,
          "right": 315,
          "bottom": 678
          "bottom": 681
        },
        {
          "left": 3,
          "top": 8,
          "top": 10,
          "right": 316,
          "bottom": 681
          "bottom": 684
        },
        {
          "left": 2,
          "top": 5,
          "top": 7,
          "right": 317,
          "bottom": 684
          "bottom": 685
        },
        {
          "left": 1,
          "top": 4,
          "top": 5,
          "right": 318,
          "bottom": 685
          "bottom": 687
        },
        {
          "left": 1,
          "top": 3,
          "top": 4,
          "right": 318,
          "bottom": 686
          "bottom": 688
        },
        {
          "left": 0,
          "top": 2,
          "top": 3,
          "right": 319,
          "bottom": 687
          "bottom": 688
        }
      ]
    },
@@ -371,5 +371,14 @@
        0
      ]
    }
  ]
  ],
  "\/\/metadata": {
    "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimation_whenReturning_withSpring.json",
    "goldenIdentifier": "backgroundAnimation_whenReturning_withSpring",
    "testClassName": "TransitionAnimatorTest",
    "testMethodName": "backgroundAnimation_whenReturning[true]",
    "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
    "result": "FAILED",
    "videoLocation": "TransitionAnimatorTest\/backgroundAnimation_whenReturning_withSpring.actual.mp4"
  }
}
 No newline at end of file
Loading