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

Commit d1c26d03 authored by Yuichiro Hanada's avatar Yuichiro Hanada
Browse files

Correct opacitiy for drag move indicator

Switching to use mirrored surface for the move indicator broke the
opacity changes of the move indicator.
This CL fixes the issue.

Bug: 418920013
Test: WMShellUnitTest
Test: go/cd-smoke
Flag: com.android.window.flags.enable_connected_displays_window_drag
Change-Id: Ibe86db0aaa6ab20ac76a27f8db9dbf09c524ffd3
parent 952d0a71
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -61,12 +61,8 @@ class MultiDisplayDragMoveIndicatorController(
                displayController.getDisplayLayout(startDisplayId)?.densityDpi() ?: return@execute
            val transaction = transactionSupplier()
            for (displayId in displayIds) {
                if (
                    displayId == startDisplayId ||
                        !desktopState.isDesktopModeSupportedOnDisplay(displayId)
                ) {
                    // No need to render indicators on the original display where the drag started,
                    // or on displays that do not support desktop mode.
                if (!desktopState.isDesktopModeSupportedOnDisplay(displayId)) {
                    // No need to render indicators on displays that do not support desktop mode.
                    continue
                }
                val displayLayout = displayController.getDisplayLayout(displayId) ?: continue
+6 −10
Original line number Diff line number Diff line
@@ -211,19 +211,15 @@ class MultiDisplayVeiledResizeTaskPositioner(
                    transactionSupplier,
                )

                // Put the task window outside of the display to make it invisible from user.
                // This is needed because mirroring surfaces cannot have a bigger alpha value than
                // the original surface.
                // Only DragMoveIndicator is visible for users while multi-display aware drag move.
                t.setPosition(
                    desktopWindowDecoration.leash,
                    repositionTaskBounds.left.toFloat(),
                    repositionTaskBounds.top.toFloat(),
                    startDisplayLayout.width().toFloat(),
                    startDisplayLayout.height().toFloat(),
                )
                // Make the window translucent in the case when the cursor moves to another display.
                val alpha =
                    if (startDisplayId == displayId) {
                        ALPHA_FOR_WINDOW_ON_DISPLAY_WITH_CURSOR
                    } else {
                        ALPHA_FOR_WINDOW_ON_NON_CURSOR_DISPLAY
                    }
                t.setAlpha(desktopWindowDecoration.leash, alpha)
            }
            t.setFrameTimeline(Choreographer.getInstance().vsyncId)
            t.apply()
+44 −21
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ import org.mockito.Mockito.`when` as whenever
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor

/**
 * Tests for [MultiDisplayVeiledResizeTaskPositioner].
@@ -212,6 +213,9 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {

    @Test
    fun testDragResize_movesTask_doesNotShowResizeVeil() = runOnUiThread {
        whenever(spyDisplayLayout0.width()).thenReturn(DISPLAY_BOUNDS.width())
        whenever(spyDisplayLayout0.height()).thenReturn(DISPLAY_BOUNDS.height())

        taskPositioner.onDragPositioningStart(
            CTRL_TYPE_UNDEFINED,
            DISPLAY_ID_0,
@@ -224,10 +228,16 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {
            STARTING_BOUNDS.left.toFloat() + 60,
            STARTING_BOUNDS.top.toFloat() + 100,
        )
        val rectAfterMove = Rect(STARTING_BOUNDS)
        rectAfterMove.offset(60, 100)
        val leftAfterMoveCaptor = argumentCaptor<Float>()
        val topAfterMoveCaptor = argumentCaptor<Float>()
        verify(mockTransaction)
            .setPosition(any(), eq(rectAfterMove.left.toFloat()), eq(rectAfterMove.top.toFloat()))
            .setPosition(any(), leftAfterMoveCaptor.capture(), topAfterMoveCaptor.capture())
        val rectAfterMove = Rect(STARTING_BOUNDS)
        rectAfterMove.offsetTo(
            leftAfterMoveCaptor.firstValue.toInt(),
            topAfterMoveCaptor.firstValue.toInt(),
        )
        Assert.assertFalse(DISPLAY_BOUNDS.intersect(rectAfterMove))

        val endBounds =
            taskPositioner.onDragPositioningEnd(
@@ -266,6 +276,9 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {

    @Test
    fun testDragResize_movesTaskToNewDisplay() = runOnUiThread {
        whenever(spyDisplayLayout0.width()).thenReturn(DISPLAY_BOUNDS.width())
        whenever(spyDisplayLayout0.height()).thenReturn(DISPLAY_BOUNDS.height())

        taskPositioner.onDragPositioningStart(
            CTRL_TYPE_UNDEFINED,
            DISPLAY_ID_0,
@@ -275,11 +288,16 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {

        taskPositioner.onDragPositioningMove(DISPLAY_ID_1, 200f, 1900f)

        val rectAfterMove = Rect(200, -50, 300, 50)
        verify(mockTransaction)
            .setPosition(any(), eq(rectAfterMove.left.toFloat()), eq(rectAfterMove.top.toFloat()))
        val leftAfterMoveCaptor = argumentCaptor<Float>()
        val topAfterMoveCaptor = argumentCaptor<Float>()
        verify(mockTransaction)
            .setAlpha(eq(mockDesktopWindowDecoration.leash), eq(ALPHA_FOR_TRANSLUCENT_WINDOW))
            .setPosition(any(), leftAfterMoveCaptor.capture(), topAfterMoveCaptor.capture())
        val boundsAfterMove = Rect(STARTING_BOUNDS)
        boundsAfterMove.offsetTo(
            leftAfterMoveCaptor.firstValue.toInt(),
            topAfterMoveCaptor.firstValue.toInt(),
        )
        Assert.assertFalse(DISPLAY_BOUNDS.intersect(boundsAfterMove))

        val endBounds = taskPositioner.onDragPositioningEnd(DISPLAY_ID_1, 300f, 450f)
        val rectAfterEnd = Rect(300, 450, 500, 650)
@@ -292,6 +310,9 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {

    @Test
    fun testDragResize_movesTaskToNewDisplayThenBackToOriginalDisplay() = runOnUiThread {
        whenever(spyDisplayLayout0.width()).thenReturn(DISPLAY_BOUNDS.width())
        whenever(spyDisplayLayout0.height()).thenReturn(DISPLAY_BOUNDS.height())

        taskPositioner.onDragPositioningStart(
            CTRL_TYPE_UNDEFINED,
            DISPLAY_ID_0,
@@ -303,32 +324,36 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {

        // Move to the display 1
        taskPositioner.onDragPositioningMove(DISPLAY_ID_1, 200f, 800f)
        val rectAfterMove = Rect(200, -600, 300, -400)
        inOrder
            .verify(mockTransaction)
            .setPosition(any(), eq(rectAfterMove.left.toFloat()), eq(rectAfterMove.top.toFloat()))
        val leftAfterMoveCaptor = argumentCaptor<Float>()
        val topAfterMoveCaptor = argumentCaptor<Float>()
        inOrder
            .verify(mockTransaction)
            .setAlpha(eq(mockDesktopWindowDecoration.leash), eq(ALPHA_FOR_TRANSLUCENT_WINDOW))
            .setPosition(any(), leftAfterMoveCaptor.capture(), topAfterMoveCaptor.capture())
        val boundsAfterMove = Rect(STARTING_BOUNDS)
        boundsAfterMove.offsetTo(
            leftAfterMoveCaptor.firstValue.toInt(),
            topAfterMoveCaptor.firstValue.toInt(),
        )
        Assert.assertFalse(DISPLAY_BOUNDS.intersect(boundsAfterMove))

        // Moving back to the original display
        taskPositioner.onDragPositioningMove(DISPLAY_ID_0, 100f, 1500f)
        rectAfterMove.set(100, 1500, 200, 1700)
        inOrder
            .verify(mockTransaction)
            .setPosition(any(), eq(rectAfterMove.left.toFloat()), eq(rectAfterMove.top.toFloat()))
        inOrder
            .verify(mockTransaction)
            .setAlpha(eq(mockDesktopWindowDecoration.leash), eq(ALPHA_FOR_VISIBLE_WINDOW))
            .setPosition(
                any(),
                eq(boundsAfterMove.left.toFloat()),
                eq(boundsAfterMove.top.toFloat()),
            )

        // Finish the drag move on the original display
        val endBounds = taskPositioner.onDragPositioningEnd(DISPLAY_ID_0, 50f, 50f)
        rectAfterMove.set(50, 50, 150, 150)
        val rectAfterFinishingMove = Rect(50, 50, 150, 150)

        verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
        verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
        verify(mockMultiDisplayDragMoveIndicatorController).onDragEnd(eq(TASK_ID), any())
        Assert.assertEquals(rectAfterMove, endBounds)
        Assert.assertEquals(rectAfterFinishingMove, endBounds)
    }

    @Test
@@ -719,8 +744,6 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {
        private const val NAVBAR_HEIGHT = 50
        private const val CAPTION_HEIGHT = 50
        private const val DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT = 10
        private const val ALPHA_FOR_TRANSLUCENT_WINDOW = 0.7f
        private const val ALPHA_FOR_VISIBLE_WINDOW = 1.0f
        private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
        private val STARTING_BOUNDS = Rect(100, 100, 200, 200)
        private val STABLE_BOUNDS_LANDSCAPE =