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

Commit 709e3b33 authored by Nick Chameyev's avatar Nick Chameyev Committed by Automerger Merge Worker
Browse files

Merge "[Taskbar icons unfold animation issue] Do not take into account initial...

Merge "[Taskbar icons unfold animation issue] Do not take into account initial translation" into sc-v2-dev am: 73ad0800

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15786489

Change-Id: I0c507c6c5cd3eeab25aef33f78286ef453cc3891
parents 0e266ded 73ad0800
Loading
Loading
Loading
Loading
+30 −27
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package com.android.systemui.shared.animation

import android.graphics.Point
import android.util.MathUtils.lerp
import android.view.Surface
import android.view.View
import android.view.WindowManager
@@ -27,7 +26,7 @@ import java.lang.ref.WeakReference
 * Creates an animation where all registered views are moved into their final location
 * by moving from the center of the screen to the sides
 */
class UnfoldMoveFromCenterAnimator(
class UnfoldMoveFromCenterAnimator @JvmOverloads constructor(
    private val windowManager: WindowManager,
    /**
     * Allows to set custom translation applier
@@ -36,14 +35,13 @@ class UnfoldMoveFromCenterAnimator(
     * using custom methods instead of [View.setTranslationX] or
     * [View.setTranslationY]
     */
    var translationApplier: TranslationApplier = object : TranslationApplier {}
    private val translationApplier: TranslationApplier = object : TranslationApplier {},
) : UnfoldTransitionProgressProvider.TransitionProgressListener {

    private val screenSize = Point()
    private var isVerticalFold = false

    private val animatedViews: MutableList<AnimatedView> = arrayListOf()
    private val tmpArray = IntArray(2)

    /**
     * Updates display properties in order to calculate the initial position for the views
@@ -82,45 +80,52 @@ class UnfoldMoveFromCenterAnimator(
            it.view.get()?.let { view ->
                translationApplier.apply(
                    view = view,
                    x = lerp(it.startTranslationX, it.finishTranslationX, progress),
                    y = lerp(it.startTranslationY, it.finishTranslationY, progress)
                    x = it.startTranslationX * (1 - progress),
                    y = it.startTranslationY * (1 - progress)
                )
            }
        }
    }

    private fun createAnimatedView(view: View): AnimatedView {
        val viewLocation = tmpArray
        view.getLocationOnScreen(viewLocation)

        val viewX = viewLocation[0].toFloat()
        val viewY = viewLocation[1].toFloat()

        val viewCenterX = viewX + view.width / 2
        val viewCenterY = viewY + view.height / 2
        val viewCenter = getViewCenter(view)
        val viewCenterX = viewCenter.x
        val viewCenterY = viewCenter.y

        val translationXDiff: Float
        val translationYDiff: Float
        val translationX: Float
        val translationY: Float

        if (isVerticalFold) {
            val distanceFromScreenCenterToViewCenter = screenSize.x / 2 - viewCenterX
            translationXDiff = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
            translationYDiff = 0f
            translationX = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
            translationY = 0f
        } else {
            val distanceFromScreenCenterToViewCenter = screenSize.y / 2 - viewCenterY
            translationXDiff = 0f
            translationYDiff = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
            translationX = 0f
            translationY = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
        }

        return AnimatedView(
            view = WeakReference(view),
            startTranslationX = view.translationX + translationXDiff,
            startTranslationY = view.translationY + translationYDiff,
            finishTranslationX = view.translationX,
            finishTranslationY = view.translationY
            startTranslationX = translationX,
            startTranslationY = translationY
        )
    }

    private fun getViewCenter(view: View): Point {
        val viewLocation = IntArray(2)
        view.getLocationOnScreen(viewLocation)

        val viewX = viewLocation[0]
        val viewY = viewLocation[1]

        val outPoint = Point()
        outPoint.x = viewX + view.width / 2
        outPoint.y = viewY + view.height / 2

        return outPoint
    }

    /**
     * Interface that allows to use custom logic to apply translation to view
     */
@@ -137,9 +142,7 @@ class UnfoldMoveFromCenterAnimator(
    private class AnimatedView(
        val view: WeakReference<View>,
        val startTranslationX: Float,
        val startTranslationY: Float,
        val finishTranslationX: Float,
        val finishTranslationY: Float
        val startTranslationY: Float
    )
}

+40 −12
Original line number Diff line number Diff line
@@ -56,45 +56,71 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
    @Test
    fun testRegisterViewOnTheLeftOfVerticalFold_halfProgress_viewTranslatedToTheRight() {
        givenScreen(width = 100, height = 100, rotation = ROTATION_0)
        val view = createView(x = 20)
        val view = createView(x = 20, width = 10, height = 10)
        animator.registerViewForAnimation(view)
        animator.onTransitionStarted()

        animator.onTransitionProgress(0.5f)

        // Positive translationX -> translated to the right
        assertThat(view.translationX).isWithin(0.1f).of(3.75f)
        // 10x10 view center is 25px from the center,
        // When progress is 0.5 it should be translated at:
        // 25 * 0.3 * (1 - 0.5) = 3.75px
        assertThat(view.translationX).isWithin(0.01f).of(3.75f)
    }

    @Test
    fun testRegisterViewOnTheLeftOfVerticalFold_zeroProgress_viewTranslatedToTheRight() {
        givenScreen(width = 100, height = 100, rotation = ROTATION_0)
        val view = createView(x = 20)
        val view = createView(x = 20, width = 10, height = 10)
        animator.registerViewForAnimation(view)
        animator.onTransitionStarted()

        animator.onTransitionProgress(0f)

        // Positive translationX -> translated to the right
        assertThat(view.translationX).isWithin(0.1f).of(7.5f)
        // 10x10 view center is 25px from the center,
        // When progress is 0 it should be translated at:
        // 25 * 0.3 * (1 - 0) = 7.5px
        assertThat(view.translationX).isWithin(0.01f).of(7.5f)
    }

    @Test
    fun testRegisterViewOnTheLeftOfVerticalFold_fullProgress_viewTranslatedToTheOriginalPosition() {
        givenScreen(width = 100, height = 100, rotation = ROTATION_0)
        val view = createView(x = 20)
        val view = createView(x = 20, width = 10, height = 10)
        animator.registerViewForAnimation(view)
        animator.onTransitionStarted()

        animator.onTransitionProgress(1f)

        // Positive translationX -> translated to the right
        // 10x10 view center is 25px from the center,
        // When progress is 1 it should be translated at:
        // 25 * 0.3 * 0 = 0px
        assertThat(view.translationX).isEqualTo(0f)
    }

    @Test
    fun testViewOnTheLeftOfVerticalFoldWithTranslation_halfProgress_viewTranslatedToTheRight() {
        givenScreen(width = 100, height = 100, rotation = ROTATION_0)
        val view = createView(x = 20, width = 10, height = 10, translationX = 100f)
        animator.registerViewForAnimation(view)
        animator.onTransitionStarted()

        animator.onTransitionProgress(0.5f)

        // Positive translationX -> translated to the right, original translation is ignored
        // 10x10 view center is 25px from the center,
        // When progress is 0.5 it should be translated at:
        // 25 * 0.3 * (1 - 0.5) = 3.75px
        assertThat(view.translationX).isWithin(0.01f).of(3.75f)
    }

    @Test
    fun testRegisterViewAndUnregister_halfProgress_viewIsNotUpdated() {
        givenScreen(width = 100, height = 100, rotation = ROTATION_0)
        val view = createView(x = 20)
        val view = createView(x = 20, width = 10, height = 10)
        animator.registerViewForAnimation(view)
        animator.onTransitionStarted()
        animator.clearRegisteredViews()
@@ -107,7 +133,7 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
    @Test
    fun testRegisterViewUpdateProgressAndUnregister_halfProgress_viewIsNotUpdated() {
        givenScreen(width = 100, height = 100, rotation = ROTATION_0)
        val view = createView(x = 20)
        val view = createView(x = 20, width = 10, height = 10)
        animator.registerViewForAnimation(view)
        animator.onTransitionStarted()
        animator.onTransitionProgress(0.2f)
@@ -121,14 +147,14 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
    @Test
    fun testRegisterViewOnTheTopOfHorizontalFold_halfProgress_viewTranslatedToTheBottom() {
        givenScreen(width = 100, height = 100, rotation = ROTATION_90)
        val view = createView(y = 20)
        val view = createView(y = 20, width = 10, height = 10)
        animator.registerViewForAnimation(view)
        animator.onTransitionStarted()

        animator.onTransitionProgress(0.5f)

        // Positive translationY -> translated to the bottom
        assertThat(view.translationY).isWithin(0.1f).of(3.75f)
        assertThat(view.translationY).isWithin(0.01f).of(3.75f)
    }

    private fun createView(
@@ -156,9 +182,11 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
        }
    }

    private fun givenScreen(width: Int = 100,
    private fun givenScreen(
        width: Int = 100,
        height: Int = 100,
                            rotation: Int = ROTATION_0) {
        rotation: Int = ROTATION_0
    ) {
        val display = mock(Display::class.java)
        whenever(display.getSize(any())).thenAnswer {
            val size = (it.arguments[0] as Point)