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

Commit f27d4f75 authored by Jorge Gil's avatar Jorge Gil Committed by Android (Google) Code Review
Browse files

Merge "Skip return-to-start drag animation if already at end" into main

parents 49743bb4 cfed47a6
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -5669,10 +5669,14 @@ class DesktopTasksController(
                    validDragArea,
                )

                if (destinationBounds == dragStartBounds) {
                if (
                    destinationBounds == dragStartBounds && destinationBounds != currentDragBounds
                ) {
                    // There's no actual difference between the start and end bounds, so while a
                    // WCT change isn't needed, the dragged surface still needs to be snapped back
                    // to its original location.
                    // to its original location. This is as long as it moved some in the first
                    // place, if it didn't and |currentDragBounds| is already at destination then
                    // there's no need to animate.
                    releaseVisualIndicator()
                    returnToDragStartAnimator.start(
                        taskInfo.taskId,
+51 −23
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.view.SurfaceControl
import androidx.core.animation.addListener
import com.android.internal.jank.Cuj
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.protolog.ShellProtoLogGroup
import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener
import java.util.function.Supplier

@@ -52,6 +54,15 @@ class ReturnToDragStartAnimator(
        endBounds: Rect,
        doOnEnd: (() -> Unit)? = null,
    ) {
        if (startBounds == endBounds) {
            ProtoLog.w(
                ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                "%s: reposition animation request with equal start/end bounds=%s, ignoring",
                TAG,
                startBounds,
            )
            return
        }
        val tx = transactionSupplier.get()

        boundsAnimator?.cancel()
@@ -61,27 +72,31 @@ class ReturnToDragStartAnimator(
                .apply {
                    addListener(
                        onStart = {
                            taskSurface.checkValidOrCancel()?.let { surface ->
                                val startTransaction = transactionSupplier.get()
                                startTransaction
                                    .setPosition(
                                    taskSurface,
                                        surface,
                                        startBounds.left.toFloat(),
                                        startBounds.top.toFloat(),
                                    )
                                .show(taskSurface)
                                    .show(surface)
                                    .apply()
                                taskRepositionAnimationListener.onAnimationStart(taskId)
                            }
                        },
                        onEnd = {
                            taskSurface.checkValid()?.let { surface ->
                                val finishTransaction = transactionSupplier.get()
                                finishTransaction
                                    .setPosition(
                                    taskSurface,
                                        surface,
                                        endBounds.left.toFloat(),
                                        endBounds.top.toFloat(),
                                    )
                                .show(taskSurface)
                                    .show(surface)
                                    .apply()
                            }
                            taskRepositionAnimationListener.onAnimationEnd(taskId)
                            boundsAnimator = null
                            doOnEnd?.invoke()
@@ -89,16 +104,29 @@ class ReturnToDragStartAnimator(
                        },
                    )
                    addUpdateListener { anim ->
                        taskSurface.checkValidOrCancel()?.let { surface ->
                            val rect = anim.animatedValue as Rect
                        tx.setPosition(taskSurface, rect.left.toFloat(), rect.top.toFloat())
                            .show(taskSurface)
                            tx.setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
                                .show(surface)
                                .apply()
                        }
                    }
                }
                .also(ValueAnimator::start)
    }

    private fun SurfaceControl.checkValid(): SurfaceControl? = if (isValid) this else null

    private fun SurfaceControl.checkValidOrCancel(): SurfaceControl? {
        if (isValid) {
            return this
        }
        boundsAnimator?.cancel()
        return null
    }

    companion object {
        private const val TAG = "ReturnToDragStartAnimator"
        const val RETURN_TO_DRAG_START_ANIMATION_MS = 300L
    }
}
+44 −0
Original line number Diff line number Diff line
@@ -9265,6 +9265,50 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            .logTaskResizingEnded(any(), any(), any(), any(), any(), any(), any())
    }
    @Test
    fun onDesktopDragEnd_noIndicator_noBoundsMovement_noReturnToStartAnimation() {
        val task = setUpFreeformTask(bounds = STABLE_BOUNDS)
        val spyController = spy(controller)
        val mockSurface = mock(SurfaceControl::class.java)
        val mockDisplayLayout = mock(DisplayLayout::class.java)
        whenever(displayController.getDisplayLayout(task.displayId)).thenReturn(mockDisplayLayout)
        whenever(mockDisplayLayout.stableInsets()).thenReturn(Rect(0, 100, 2000, 2000))
        whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i ->
            (i.arguments.first() as Rect).set(STABLE_BOUNDS)
        }
        whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
        whenever(desktopModeVisualIndicator.updateIndicatorType(any(), anyOrNull()))
            .thenReturn(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
        whenever(motionEvent.displayId).thenReturn(DEFAULT_DISPLAY)
        // "Drag move" the task, but the bounds aren't actually changing. Which can be the case
        // on mouse clicks that generate ACTION_MOVE events without position changes.
        val currentDragBounds = Rect(200, 200, 700, 700)
        spyController.onDragPositioningMove(
            taskInfo = task,
            taskSurface = mockSurface,
            displayId = DEFAULT_DISPLAY,
            inputX = 500f,
            inputY = 210f,
            taskBounds = currentDragBounds,
        )
        spyController.onDragPositioningEnd(
            taskInfo = task,
            taskSurface = mockSurface,
            displayId = DEFAULT_DISPLAY,
            inputCoordinate = PointF(510f, 210f),
            currentDragBounds = currentDragBounds,
            validDragArea = Rect(0, 50, 2000, 2000),
            dragStartBounds = currentDragBounds,
            motionEvent = motionEvent,
        )
        // Even though end bounds are the same as start bounds, there's no need to animate the
        // return because the current bounds are also the same as start/end.
        verify(mReturnToDragStartAnimator, never())
            .start(eq(task.taskId), eq(mockSurface), any(), any(), anyOrNull())
    }
    @Test
    fun enterSplit_freeformTaskIsMovedToSplit() {
        val task1 = setUpFreeformTask()