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

Commit 8b08ad09 authored by omarmt's avatar omarmt
Browse files

SwipeAnimation.animateOffset() returns the consumed velocity

It allows us to consume, even partially, the velocity during scrolling.
Allowing other components to consume the remaining velocity.

Before and after: b/336710600#comment24

Test: atest DraggableHandlerTest
Bug: 336710600
Flag: com.android.systemui.scene_container
Change-Id: If6b055f567ba308078227db92f36b17216b7f293
parent 2b865f36
Loading
Loading
Loading
Loading
+4 −12
Original line number Diff line number Diff line
@@ -397,14 +397,8 @@ private class DragControllerImpl(
            return 0f
        }

        fun animateTo(targetContent: T) {
            swipeAnimation.animateOffset(
                initialVelocity = velocity,
                targetContent = targetContent,
            )
        }

        val fromContent = swipeAnimation.fromContent
        val consumedVelocity: Float
        if (canChangeContent) {
            // If we are halfway between two contents, we check what the target will be based on the
            // velocity and offset of the transition, then we launch the animation.
@@ -429,18 +423,16 @@ private class DragControllerImpl(
                } else {
                    fromContent
                }

            animateTo(targetContent = targetContent)
            consumedVelocity = swipeAnimation.animateOffset(velocity, targetContent = targetContent)
        } else {
            // We are doing an overscroll preview animation between scenes.
            check(fromContent == swipeAnimation.currentContent) {
                "canChangeContent is false but currentContent != fromContent"
            }
            animateTo(targetContent = fromContent)
            consumedVelocity = swipeAnimation.animateOffset(velocity, targetContent = fromContent)
        }

        // The onStop animation consumes any remaining velocity.
        return velocity
        return consumedVelocity
    }

    /**
+10 −2
Original line number Diff line number Diff line
@@ -312,11 +312,16 @@ internal class SwipeAnimation<T : ContentKey>(

    fun isAnimatingOffset(): Boolean = offsetAnimation != null

    /**
     * Animate the offset to a [targetContent], using the [initialVelocity] and an optional [spec]
     *
     * @return the velocity consumed
     */
    fun animateOffset(
        initialVelocity: Float,
        targetContent: T,
        spec: AnimationSpec<Float>? = null,
    ) {
    ): Float {
        check(!isAnimatingOffset()) { "SwipeAnimation.animateOffset() can only be called once" }

        val initialProgress = progress
@@ -374,7 +379,7 @@ internal class SwipeAnimation<T : ContentKey>(
        if (skipAnimation) {
            // Unblock the job.
            offsetAnimationRunnable.complete(null)
            return
            return 0f
        }

        val isTargetGreater = targetOffset > animatable.value
@@ -424,6 +429,9 @@ internal class SwipeAnimation<T : ContentKey>(
                /* Ignore. */
            }
        }

        // This animation always consumes the whole available velocity
        return initialVelocity
    }

    /** An exception thrown during the animation to stop it immediately. */
+1 −1
Original line number Diff line number Diff line
@@ -1111,7 +1111,7 @@ class DraggableHandlerTest {
        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1f)

        // Release the finger.
        dragController.onDragStopped(velocity = -velocityThreshold)
        dragController.onDragStopped(velocity = -velocityThreshold, expectedConsumed = false)

        // Exhaust all coroutines *without advancing the clock*. Given that we are at progress >=
        // 100% and that the overscroll on scene B is doing nothing, we are already idle.