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

Commit 8d989e6d authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update cross-display drag reparenting for multi-desks" into main

parents 97ea5f66 e6aadd7f
Loading
Loading
Loading
Loading
+31 −18
Original line number Diff line number Diff line
@@ -150,6 +150,7 @@ import com.android.wm.shell.transition.FocusTransitionObserver
import com.android.wm.shell.transition.OneShotRemoteHandler
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TransitionFinishCallback
import com.android.wm.shell.transition.Transitions.TransitionHandler
import com.android.wm.shell.windowdecor.DragPositioningCallbackUtility
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener
@@ -1283,13 +1284,20 @@ class DesktopTasksController(
    }

    /**
     * Move [task] to display with [displayId].
     * Move [task] to display with [displayId]. When [bounds] is not null, it will be used as the
     * bounds on the new display. When [transitionHandler] is not null, it will be used instead of
     * the default [DesktopModeMoveToDisplayTransitionHandler].
     *
     * No-op if task is already on that display per [RunningTaskInfo.displayId].
     *
     * TODO: b/399411604 - split this up into smaller functions.
     */
    private fun moveToDisplay(task: RunningTaskInfo, displayId: Int) {
    private fun moveToDisplay(
        task: RunningTaskInfo,
        displayId: Int,
        bounds: Rect? = null,
        transitionHandler: TransitionHandler? = null,
    ) {
        logV("moveToDisplay: taskId=%d displayId=%d", task.taskId, displayId)
        if (task.displayId == displayId) {
            logD("moveToDisplay: task already on display %d", displayId)
@@ -1321,7 +1329,9 @@ class DesktopTasksController(
            if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
                desksOrganizer.moveTaskToDesk(wct, destinationDeskId, task)
            }
            if (Flags.enableMoveToNextDisplayShortcut()) {
            if (bounds != null) {
                wct.setBounds(task.token, bounds)
            } else if (Flags.enableMoveToNextDisplayShortcut()) {
                applyFreeformDisplayChange(wct, task, displayId)
            }
        }
@@ -1362,7 +1372,11 @@ class DesktopTasksController(
                null
            }
        val transition =
            transitions.startTransition(TRANSIT_CHANGE, wct, moveToDisplayTransitionHandler)
            transitions.startTransition(
                TRANSIT_CHANGE,
                wct,
                transitionHandler ?: moveToDisplayTransitionHandler,
            )
        deactivationRunnable?.invoke(transition)
        activationRunnable?.invoke(transition)
    }
@@ -3326,29 +3340,28 @@ class DesktopTasksController(
                    return
                }

                // Update task bounds so that the task position will match the position of its leash
                val wct = WindowContainerTransaction()
                wct.setBounds(taskInfo.token, destinationBounds)

                val newDisplayId = motionEvent.getDisplayId()
                val displayAreaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(newDisplayId)
                val isCrossDisplayDrag =
                    Flags.enableConnectedDisplaysWindowDrag() &&
                        newDisplayId != taskInfo.getDisplayId() &&
                        displayAreaInfo != null
                val handler =

                if (isCrossDisplayDrag) {
                        dragToDisplayTransitionHandler
                    moveToDisplay(
                        taskInfo,
                        newDisplayId,
                        destinationBounds,
                        dragToDisplayTransitionHandler,
                    )
                } else {
                        null
                    }
                if (isCrossDisplayDrag) {
                    // TODO: b/362720497 - reparent to a specific desk within the target display.
                    wct.reparent(taskInfo.token, displayAreaInfo.token, /* onTop= */ true)
                    // Update task bounds so that the task position will match the position of its
                    // leash
                    val wct = WindowContainerTransaction()
                    wct.setBounds(taskInfo.token, destinationBounds)
                    transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null)
                }

                transitions.startTransition(TRANSIT_CHANGE, wct, handler)

                releaseVisualIndicator()
            }
            IndicatorType.TO_DESKTOP_INDICATOR -> {
+36 −0
Original line number Diff line number Diff line
@@ -6057,6 +6057,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG)
    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    fun onDesktopDragEnd_noIndicatorAndMoveToNewDisplay_reparent() {
        val task = setUpFreeformTask()
        val spyController = spy(controller)
@@ -6092,6 +6093,41 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            )
    }

    @Test
    @EnableFlags(
        Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG,
        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
    )
    fun onDesktopDragEnd_noIndicatorAndMoveToNewDisplay_reparentToDesk() {
        val deskId = 5
        val task = setUpFreeformTask()
        val spyController = spy(controller)
        val mockSurface = mock(SurfaceControl::class.java)
        val mockDisplayLayout = mock(DisplayLayout::class.java)
        taskRepository.addDesk(displayId = SECONDARY_DISPLAY_ID, deskId = deskId)
        whenever(displayController.getDisplayLayout(task.displayId)).thenReturn(mockDisplayLayout)
        whenever(mockDisplayLayout.stableInsets()).thenReturn(Rect(0, 100, 2000, 2000))
        spyController.onDragPositioningMove(task, mockSurface, 200f, Rect(100, 200, 500, 1000))

        val currentDragBounds = Rect(100, 200, 500, 1000)
        whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
        whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
            .thenReturn(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
        whenever(motionEvent.displayId).thenReturn(SECONDARY_DISPLAY_ID)

        spyController.onDragPositioningEnd(
            task,
            mockSurface,
            inputCoordinate = PointF(200f, 300f),
            currentDragBounds,
            validDragArea = Rect(0, 50, 2000, 2000),
            dragStartBounds = Rect(),
            motionEvent,
        )

        verify(desksOrganizer).moveTaskToDesk(any(), eq(deskId), eq(task))
    }

    @Test
    fun onDesktopDragEnd_fullscreenIndicator_dragToExitDesktop() {
        val task = setUpFreeformTask(bounds = Rect(0, 0, 100, 100))