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

Commit 6aa4d477 authored by Vania Desmonda's avatar Vania Desmonda
Browse files

Disallow stashing on cross-displays drag PiP window.

On cross-display drag, disallow stashing if display ID on down and on up
are different. Previously, this caused the PiP to be stashed on the edge
of the other display because the target display layout state bounds is
not updated until PiP is released.

Product decision to disallow stashing while dragging across displays.

Fixes: 423023871
Test: atest PipTouchHandlerTest
Flag: com.android.window.flags.enable_dragging_pip_across_displays
Change-Id: I8dc4abcd5dedbe3b840a7caaedb10cf69130856b
parent e5d353a3
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -977,7 +977,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha

                // Reset the touch state on up before the fling settles
                mTouchState.reset();
                if (mEnableStash && shouldStash(vel, getPossiblyMotionBounds())) {
                if (mEnableStash && shouldStash(vel, getPossiblyMotionBounds(), displayIdOnUp)) {
                    mMotionHelper.stashToEdge(vel.x, vel.y, null /* endAction */);
                } else {
                    if (mPipBoundsState.isStashed()) {
@@ -1059,7 +1059,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
            }
        }

        private boolean shouldStash(PointF vel, Rect motionBounds) {
        private boolean shouldStash(PointF vel, Rect motionBounds, int displayIdOnUp) {
            final boolean flingToLeft = vel.x < -mStashVelocityThreshold;
            final boolean flingToRight = vel.x > mStashVelocityThreshold;
            final int offset = motionBounds.width() / 2;
@@ -1094,10 +1094,11 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
            final boolean stashFromDroppingOnEdge = droppingOnLeft || droppingOnRight;

            // If dragging PiP across displays is allowed, then ensure that stashing only occurs
            // when no drag mirrors of the window are shown, meaning that it wasn't partially shown
            // on another display
            // when no drag mirrors of the window are shown, and the display ID on down and up are
            // the same, meaning that we don't allow stashing while moving PiP across displays
            return (stashFromFlingToEdge || stashFromDroppingOnEdge)
                    && !mPipDisplayTransferHandler.isMirrorShown();
                    && !mPipDisplayTransferHandler.isMirrorShown()
                    && mDisplayIdOnDown == displayIdOnUp;
        }
    }

+55 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
@@ -130,6 +131,8 @@ class PipTouchHandlerTest : ShellTestCase() {
        whenever(pipTouchState.latestMotionEvent).thenReturn(mockMotionEvent)
        whenever(pipTransitionState.pinnedTaskLeash).thenReturn(mockLeash)
        whenever(mockPipBoundsState.movementBounds).thenReturn(PIP_BOUNDS)
        whenever(mockPipBoundsState.displayLayout).thenReturn(mockDisplayLayout)
        whenever(mockPipBoundsState.displayBounds).thenReturn(DISPLAY_BOUNDS)
        whenever(mockPipBoundsState.motionBoundsState).thenReturn(mockMotionBoundsState)
        whenever(pipTouchHandler.possiblyMotionBounds).thenReturn(PIP_BOUNDS)
        whenever(mockDisplayController.getDisplayLayout(anyInt()))
@@ -294,10 +297,62 @@ class PipTouchHandlerTest : ShellTestCase() {
        verify(mockPipDisplayTransferHandler, never()).removeMirrors()
    }


    @Test
    fun pipTouchGesture_onUpMotionBoundsDroppingOnLeft_pipStashedToEdge() {
        pipTouchGesture.onDown(pipTouchState)

        pipTouchHandler.mEnableStash = true
        whenever(pipTouchState.isDragging).thenReturn(true)
        PIP_BOUNDS.offset(-500, 0)
        whenever(mockPipBoundsState.bounds).thenReturn(PIP_BOUNDS)
        pipTouchGesture.onUp(pipTouchState)

        verify(mockPipMotionHelper).stashToEdge(
            any(), any(), anyOrNull()
        )
    }

    @Test
    fun pipTouchGesture_onUpDisplayIdChanged_disallowsStashing() {
        whenever(mockPipDesktopState.isDraggingPipAcrossDisplaysEnabled()).thenReturn(true)
        pipTouchGesture.onDown(pipTouchState)

        pipTouchHandler.mEnableStash = true
        whenever(pipTouchState.isDragging).thenReturn(true)
        PIP_BOUNDS.offset(-500, 0)
        whenever(mockPipBoundsState.bounds).thenReturn(PIP_BOUNDS)
        whenever(pipTouchState.lastTouchDisplayId).thenReturn(TARGET_DISPLAY_ID)
        pipTouchGesture.onUp(pipTouchState)

        verify(mockPipMotionHelper, never()).stashToEdge(
            any(), any(), anyOrNull()
        )
    }

    @Test
    fun pipTouchGesture_onUpMirrorIsShown_disallowsStashing() {
        whenever(mockPipDesktopState.isDraggingPipAcrossDisplaysEnabled()).thenReturn(true)
        pipTouchGesture.onDown(pipTouchState)

        pipTouchHandler.mEnableStash = true
        whenever(pipTouchState.isDragging).thenReturn(true)
        PIP_BOUNDS.offset(-500, 0)
        whenever(mockPipBoundsState.bounds).thenReturn(PIP_BOUNDS)
        whenever(mockPipDisplayTransferHandler.isMirrorShown).thenReturn(true)
        pipTouchGesture.onUp(pipTouchState)

        verify(mockPipMotionHelper, never()).stashToEdge(
            any(), any(), anyOrNull()
        )
    }


    private companion object {
        const val ORIGIN_DISPLAY_ID = 0
        const val TARGET_DISPLAY_ID = 1
        val PIP_BOUNDS = Rect(0, 0, 700, 700)
        val DISPLAY_BOUNDS = Rect(0, 0, 1000, 1000)
        val GLOBAL_BOUNDS = RectF(0f, 0f, 400f, 400f)
    }
}
 No newline at end of file