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

Commit 91a04ab9 authored by Graciela Wissen Putri's avatar Graciela Wissen Putri Committed by Graciela Putri
Browse files

Add move to external display

Allow app to move to external display with cascading and initial bounds
applied. Expose moveToExternalDisplay to launcher.

Flag: com.android.window.flags.move_to_external_display_shortcut
Test: atest DesktopTasksControllerTest
Bug: 372872848
Change-Id: I42a4fe8d1850d6f4cf8ff67b88e6d08806dd5c3f
parent c1fb29f1
Loading
Loading
Loading
Loading
+24 −10
Original line number Diff line number Diff line
@@ -659,6 +659,7 @@ class DesktopTasksController(
        }

        val wct = WindowContainerTransaction()
        if (!task.isFreeform) addMoveToDesktopChanges(wct, task, displayId)
        wct.reparent(task.token, displayAreaInfo.token, true /* onTop */)

        transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
@@ -1245,7 +1246,7 @@ class DesktopTasksController(
        val bounds = when (newTaskWindowingMode) {
            WINDOWING_MODE_FREEFORM -> {
                displayController.getDisplayLayout(callingTask.displayId)
                    ?.let { getInitialBounds(it, callingTask) }
                    ?.let { getInitialBounds(it, callingTask, callingTask.displayId) }
            }
            WINDOWING_MODE_MULTI_WINDOW -> {
                Rect()
@@ -1311,7 +1312,7 @@ class DesktopTasksController(
            val displayLayout = displayController.getDisplayLayout(task.displayId)
            if (displayLayout != null) {
                val initialBounds = Rect(task.configuration.windowConfiguration.bounds)
                cascadeWindow(task, initialBounds, displayLayout)
                cascadeWindow(initialBounds, displayLayout, task.displayId)
                wct.setBounds(task.token, initialBounds)
            }
        }
@@ -1399,13 +1400,19 @@ class DesktopTasksController(
        return if (wct.isEmpty) null else wct
    }

    /**
     * Apply all changes required when task is first added to desktop. Uses the task's current
     * display by default to apply initial bounds and placement relative to the display.
     * Use a different [displayId] if the task should be moved to a different display.
     */
    @VisibleForTesting
    fun addMoveToDesktopChanges(
        wct: WindowContainerTransaction,
        taskInfo: RunningTaskInfo
        taskInfo: RunningTaskInfo,
        displayId: Int = taskInfo.displayId,
    ) {
        val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
        val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!!
        val displayLayout = displayController.getDisplayLayout(displayId) ?: return
        val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)!!
        val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
        val targetWindowingMode =
            if (tdaWindowingMode == WINDOWING_MODE_FREEFORM) {
@@ -1414,7 +1421,7 @@ class DesktopTasksController(
            } else {
                WINDOWING_MODE_FREEFORM
            }
        val initialBounds = getInitialBounds(displayLayout, taskInfo)
        val initialBounds = getInitialBounds(displayLayout, taskInfo, displayId)

        if (canChangeTaskPosition(taskInfo)) {
            wct.setBounds(taskInfo.token, initialBounds)
@@ -1428,7 +1435,8 @@ class DesktopTasksController(

    private fun getInitialBounds(
        displayLayout: DisplayLayout,
        taskInfo: RunningTaskInfo
        taskInfo: RunningTaskInfo,
        displayId: Int,
    ): Rect {
        val bounds = if (ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isTrue) {
            calculateInitialBounds(displayLayout, taskInfo)
@@ -1437,7 +1445,7 @@ class DesktopTasksController(
        }

        if (DesktopModeFlags.ENABLE_CASCADING_WINDOWS.isTrue) {
            cascadeWindow(taskInfo, bounds, displayLayout)
            cascadeWindow(bounds, displayLayout, displayId)
        }
        return bounds
    }
@@ -1466,11 +1474,11 @@ class DesktopTasksController(
        }
    }

    private fun cascadeWindow(task: TaskInfo, bounds: Rect, displayLayout: DisplayLayout) {
    private fun cascadeWindow(bounds: Rect, displayLayout: DisplayLayout, displayId: Int) {
        val stableBounds = Rect()
        displayLayout.getStableBoundsForDesktopMode(stableBounds)

        val activeTasks = taskRepository.getActiveNonMinimizedOrderedTasks(task.displayId)
        val activeTasks = taskRepository.getActiveNonMinimizedOrderedTasks(displayId)
        activeTasks.firstOrNull()?.let { activeTask ->
            shellTaskOrganizer.getRunningTaskInfo(activeTask)?.let {
                cascadeWindow(context.resources, stableBounds,
@@ -2069,6 +2077,12 @@ class DesktopTasksController(
                c.removeDesktop(displayId)
            }
        }

        override fun moveToExternalDisplay(taskId: Int) {
            executeRemoteCallWithTaskPermission(controller, "moveTaskToExternalDisplay") { c ->
                c.moveToNextDisplay(taskId)
            }
        }
    }

    private fun logV(msg: String, vararg arguments: Any?) {
+3 −0
Original line number Diff line number Diff line
@@ -52,4 +52,7 @@ interface IDesktopMode {

    /** Remove desktop on the given display */
    oneway void removeDesktop(int displayId);

    /** Move a task with given `taskId` to external display */
    void moveToExternalDisplay(int taskId);
}
 No newline at end of file