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

Commit d6fa50d7 authored by Michael Mikhail's avatar Michael Mikhail
Browse files

Fix animation of UMO on long press

Flag: None
Bug: 286142657
Test: Checked the animation of UMO using animation scale x5.
Change-Id: Ia81b0d9a31cd94574dd51b083dd99146f9ff9b1e
parent 0fab2856
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ constructor(
    }

    companion object {
        @JvmField val GUTS_ANIMATION_DURATION = 500L
        @JvmField val GUTS_ANIMATION_DURATION = 234L
    }

    /** A listener when the current dimensions of the player change */
@@ -234,7 +234,8 @@ constructor(
            currentStartLocation,
            currentEndLocation,
            currentTransitionProgress,
            applyImmediately = false
            applyImmediately = false,
            isGutsAnimation = true,
        )
    }

@@ -254,7 +255,8 @@ constructor(
            currentStartLocation,
            currentEndLocation,
            currentTransitionProgress,
            applyImmediately = immediate
            applyImmediately = immediate,
            isGutsAnimation = true,
        )
    }

@@ -414,7 +416,10 @@ constructor(
     * it's not available, it will recreate one by measuring, which may be expensive.
     */
    @VisibleForTesting
    fun obtainViewState(state: MediaHostState?): TransitionViewState? {
    fun obtainViewState(
        state: MediaHostState?,
        isGutsAnimation: Boolean = false
    ): TransitionViewState? {
        if (state == null || state.measurementInput == null) {
            return null
        }
@@ -423,7 +428,7 @@ constructor(
        val viewState = viewStates[cacheKey]
        if (viewState != null) {
            // we already have cached this measurement, let's continue
            if (state.squishFraction <= 1f) {
            if (state.squishFraction <= 1f && !isGutsAnimation) {
                return squishViewState(viewState, state.squishFraction)
            }
            return viewState
@@ -455,13 +460,14 @@ constructor(

            // Given that we have a measurement and a view, let's get (guaranteed) viewstates
            // from the start and end state and interpolate them
            val startViewState = obtainViewState(startState) as TransitionViewState
            val startViewState = obtainViewState(startState, isGutsAnimation) as TransitionViewState
            val endState = state.copy().also { it.expansion = 1.0f }
            val endViewState = obtainViewState(endState) as TransitionViewState
            val endViewState = obtainViewState(endState, isGutsAnimation) as TransitionViewState
            result =
                layoutController.getInterpolatedState(startViewState, endViewState, state.expansion)
        }
        if (state.squishFraction <= 1f) {
        // Skip the adjustments of squish view state if UMO changes due to guts animation.
        if (state.squishFraction <= 1f && !isGutsAnimation) {
            return squishViewState(result, state.squishFraction)
        }
        return result
@@ -521,7 +527,8 @@ constructor(
        @MediaLocation startLocation: Int,
        @MediaLocation endLocation: Int,
        transitionProgress: Float,
        applyImmediately: Boolean
        applyImmediately: Boolean,
        isGutsAnimation: Boolean = false,
    ) =
        traceSection("MediaViewController#setCurrentState") {
            currentEndLocation = endLocation
@@ -537,7 +544,7 @@ constructor(
            // Obtain the view state that we'd want to be at the end
            // The view might not be bound yet or has never been measured and in that case will be
            // reset once the state is fully available
            var endViewState = obtainViewState(endHostState) ?: return
            var endViewState = obtainViewState(endHostState, isGutsAnimation) ?: return
            endViewState = updateViewStateSize(endViewState, endLocation, tmpState2)!!
            layoutController.setMeasureState(endViewState)

@@ -548,7 +555,7 @@ constructor(
            }

            val result: TransitionViewState
            var startViewState = obtainViewState(startHostState)
            var startViewState = obtainViewState(startHostState, isGutsAnimation)
            startViewState = updateViewStateSize(startViewState, startLocation, tmpState3)

            if (!endHostState.visible) {
@@ -602,7 +609,8 @@ constructor(
                applyImmediately,
                shouldAnimate,
                animationDuration,
                animationDelay
                animationDelay,
                isGutsAnimation,
            )
        }

+109 −36
Original line number Diff line number Diff line
@@ -25,6 +25,16 @@ import com.android.app.animation.Interpolators
 * The fraction after which we start fading in when going from a gone widget to a visible one
 */
private const val GONE_FADE_FRACTION = 0.8f
/**
 * The fraction after which we start fading in going from a gone widget to a visible one in guts
 * animation.
 */
private const val GONE_FADE_GUTS_FRACTION = 0.286f
/**
 * The fraction before which we fade out when going from a visible widget to a gone one in guts
 * animation.
 */
private const val VISIBLE_FADE_GUTS_FRACTION = 0.355f

/**
 * The amont we're scaling appearing views
@@ -45,6 +55,7 @@ open class TransitionLayoutController {
    private var animationStartState: TransitionViewState? = null
    private var state = TransitionViewState()
    private var animator: ValueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f)
    private var isGutsAnimation = false
    private var currentHeight: Int = 0
    private var currentWidth: Int = 0
    var sizeChangedListener: ((Int, Int) -> Unit)? = null
@@ -152,15 +163,6 @@ open class TransitionLayoutController {
                // this looks quite ugly
                val nowGone: Boolean
                if (widgetStart.gone) {

                    // Only fade it in at the very end
                    alphaProgress = MathUtils.map(GONE_FADE_FRACTION, 1.0f, 0.0f, 1.0f, progress)
                    nowGone = progress < GONE_FADE_FRACTION

                    // Scale it just a little, not all the way
                    val endScale = widgetEnd.scale
                    newScale = MathUtils.lerp(GONE_SCALE_AMOUNT * endScale, endScale, progress)

                    // don't clip
                    widthProgress = 1.0f

@@ -168,25 +170,52 @@ open class TransitionLayoutController {
                    resultMeasureWidth = widgetEnd.measureWidth
                    resultMeasureHeight = widgetEnd.measureHeight

                    // Let's make sure we're centering the view in the gone view instead of having
                    // the left at 0
                    resultX = MathUtils.lerp(widgetStart.x - resultMeasureWidth / 2.0f,
                            widgetEnd.x,
                            progress)
                    resultY = MathUtils.lerp(widgetStart.y - resultMeasureHeight / 2.0f,
                            widgetEnd.y,
                            progress)
                    if (isGutsAnimation) {
                        // if animation is open/close guts, fade in starts early.
                        alphaProgress = MathUtils.map(
                            GONE_FADE_GUTS_FRACTION,
                            1.0f,
                            0.0f,
                            1.0f,
                            progress
                        )
                        nowGone = progress < GONE_FADE_GUTS_FRACTION

                        // Do not change scale of widget.
                        newScale = 1.0f

                        // We do not want any horizontal or vertical movement.
                        resultX = widgetStart.x
                        resultY = widgetStart.y
                    } else {

                    // Fadeout in the very beginning
                    alphaProgress = MathUtils.map(0.0f, 1.0f - GONE_FADE_FRACTION, 0.0f, 1.0f,
                            progress)
                    nowGone = progress > 1.0f - GONE_FADE_FRACTION
                        // Only fade it in at the very end
                        alphaProgress = MathUtils.map(
                            GONE_FADE_FRACTION,
                            1.0f,
                            0.0f,
                            1.0f,
                            progress
                        )
                        nowGone = progress < GONE_FADE_FRACTION

                        // Scale it just a little, not all the way
                    val startScale = widgetStart.scale
                    newScale = MathUtils.lerp(startScale, startScale * GONE_SCALE_AMOUNT, progress)
                        val endScale = widgetEnd.scale
                        newScale = MathUtils.lerp(GONE_SCALE_AMOUNT * endScale, endScale, progress)

                        // Let's make sure we're centering the view in the gone view instead of
                        // having the left at 0
                        resultX = MathUtils.lerp(
                                widgetStart.x - resultMeasureWidth / 2.0f,
                                widgetEnd.x,
                                progress
                        )
                        resultY = MathUtils.lerp(
                                widgetStart.y - resultMeasureHeight / 2.0f,
                                widgetEnd.y,
                                progress
                        )
                    }
                } else {
                    // Don't clip
                    widthProgress = 0.0f

@@ -194,14 +223,54 @@ open class TransitionLayoutController {
                    resultMeasureWidth = widgetStart.measureWidth
                    resultMeasureHeight = widgetStart.measureHeight

                    // Let's make sure we're centering the view in the gone view instead of having
                    // the left at 0
                    resultX = MathUtils.lerp(widgetStart.x,
                    // Fadeout in the very beginning
                    if (isGutsAnimation) {
                        alphaProgress = MathUtils.map(
                            0.0f,
                            VISIBLE_FADE_GUTS_FRACTION,
                            0.0f,
                            1.0f,
                            progress
                        )
                        nowGone = progress > VISIBLE_FADE_GUTS_FRACTION

                        // Do not change scale of widget during open/close guts animation.
                        newScale = 1.0f

                        // We do not want any horizontal or vertical movement.
                        resultX = widgetEnd.x
                        resultY = widgetEnd.y
                    } else {
                        alphaProgress = MathUtils.map(
                            0.0f,
                            1.0f - GONE_FADE_FRACTION,
                            0.0f,
                            1.0f,
                            progress
                        )
                        nowGone = progress > 1.0f - GONE_FADE_FRACTION

                        // Scale it just a little, not all the way
                        val startScale = widgetStart.scale
                        newScale = MathUtils.lerp(
                                startScale,
                                startScale * GONE_SCALE_AMOUNT,
                                progress
                        )

                        // Let's make sure we're centering the view in the gone view instead of
                        // having the left at 0
                        resultX = MathUtils.lerp(
                                widgetStart.x,
                                widgetEnd.x - resultMeasureWidth / 2.0f,
                            progress)
                    resultY = MathUtils.lerp(widgetStart.y,
                                progress
                        )
                        resultY = MathUtils.lerp(
                                widgetStart.y,
                                widgetEnd.y - resultMeasureHeight / 2.0f,
                            progress)
                                progress
                        )
                    }
                }
                resultWidgetState.gone = nowGone
            } else {
@@ -279,8 +348,10 @@ open class TransitionLayoutController {
        applyImmediately: Boolean,
        animate: Boolean,
        duration: Long = 0,
        delay: Long = 0
        delay: Long = 0,
        isGuts: Boolean,
    ) {
        isGutsAnimation = isGuts
        val animated = animate && currentState.width != 0
        this.state = state.copy()
        if (applyImmediately || transitionLayout == null) {
@@ -291,6 +362,8 @@ open class TransitionLayoutController {
            animationStartState = currentState.copy()
            animator.duration = duration
            animator.startDelay = delay
            animator.interpolator =
                if (isGutsAnimation) Interpolators.LINEAR else Interpolators.FAST_OUT_SLOW_IN
            animator.start()
        } else if (!animator.isRunning) {
            applyStateToLayout(this.state)