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

Commit 414134a0 authored by Omar Elmekkawy's avatar Omar Elmekkawy
Browse files

[1/n] Adding tiling session persistence to the repositories

This CL adds the persistence data to persistent_desktop_repositories.proto
and introduces the means to read and write this field through
DesktopRepositories and DesktopPersistenceRepository.

This CL does NOT initialize tiling upon device reboot and just persists the
tiling data.
The actual initialization will come at a later CL.

Flag: com.android.window.flags.enable_tile_resizing

Test: unit tests

Bug: 400973989

Change-Id: Ibd4cc1115cbe6f4ac055f033a2a9987d92470e23
parent 0e672114
Loading
Loading
Loading
Loading
+110 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ class DesktopRepository(
     * @property topTransparentFullscreenTaskId the task id of any current top transparent
     *   fullscreen task launched on top of the desk. Cleared when the transparent task is closed or
     *   sent to back. (top is at index 0).
     * @property leftTiledTaskId task id of the task tiled on the left.
     * @property rightTiledTaskId task id of the task tiled on the right.
     */
    private data class Desk(
        val deskId: Int,
@@ -80,6 +82,8 @@ class DesktopRepository(
        val freeformTasksInZOrder: ArrayList<Int> = ArrayList(),
        var fullImmersiveTaskId: Int? = null,
        var topTransparentFullscreenTaskId: Int? = null,
        var leftTiledTaskId: Int? = null,
        var rightTiledTaskId: Int? = null,
    ) {
        fun deepCopy(): Desk =
            Desk(
@@ -92,6 +96,8 @@ class DesktopRepository(
                freeformTasksInZOrder = ArrayList(freeformTasksInZOrder),
                fullImmersiveTaskId = fullImmersiveTaskId,
                topTransparentFullscreenTaskId = topTransparentFullscreenTaskId,
                leftTiledTaskId = leftTiledTaskId,
                rightTiledTaskId = rightTiledTaskId,
            )

        // TODO: b/362720497 - remove when multi-desktops is enabled where instances aren't
@@ -104,6 +110,8 @@ class DesktopRepository(
            freeformTasksInZOrder.clear()
            fullImmersiveTaskId = null
            topTransparentFullscreenTaskId = null
            leftTiledTaskId = null
            rightTiledTaskId = null
        }
    }

@@ -268,6 +276,106 @@ class DesktopRepository(
        }
    }

    /** Register a left tiled task to desktop state. */
    fun addLeftTiledTask(displayId: Int, taskId: Int) {
        logD("addLeftTiledTask for displayId=%d, taskId=%d", displayId, taskId)
        val activeDesk =
            checkNotNull(desktopData.getDefaultDesk(displayId)) {
                "Expected desk in display: $displayId"
            }
        addLeftTiledTaskToDesk(displayId, taskId, activeDesk.deskId)
    }

    private fun addLeftTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) {
        logD("addLeftTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId)
        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
        desk.leftTiledTaskId = taskId
        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
            updatePersistentRepository(displayId)
        }
    }

    /** Register a right tiled task to desktop state. */
    fun addRightTiledTask(displayId: Int, taskId: Int) {
        logD("addRightTiledTask for displayId=%d, taskId=%d", displayId, taskId)
        val activeDesk =
            checkNotNull(desktopData.getDefaultDesk(displayId)) {
                "Expected desk in display: $displayId"
            }
        addRightTiledTaskToDesk(displayId, taskId, activeDesk.deskId)
    }

    private fun addRightTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) {
        logD("addRightTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId)
        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
        desk.rightTiledTaskId = taskId
        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
            updatePersistentRepository(displayId)
        }
    }

    /** Gets a registered left tiled task to desktop state or returns null. */
    fun getLeftTiledTask(displayId: Int): Int? {
        logD("getLeftTiledTask for displayId=%d", displayId)
        val activeDesk =
            checkNotNull(desktopData.getDefaultDesk(displayId)) {
                "Expected desk in display: $displayId"
            }
        val deskId = activeDesk.deskId
        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
        return desk.leftTiledTaskId
    }

    /** gets a registered right tiled task to desktop state or returns null. */
    fun getRightTiledTask(displayId: Int): Int? {
        logD("getRightTiledTask for displayId=%d", displayId)
        val activeDesk =
            checkNotNull(desktopData.getDefaultDesk(displayId)) {
                "Expected desk in display: $displayId"
            }
        val deskId = activeDesk.deskId
        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
        return desk.rightTiledTaskId
    }

    /* Unregisters a left tiled task from desktop state. */
    fun removeLeftTiledTask(displayId: Int) {
        logD("removeLeftTiledTask for displayId=%d", displayId)
        val activeDesk =
            checkNotNull(desktopData.getDefaultDesk(displayId)) {
                "Expected desk in display: $displayId"
            }
        removeLeftTiledTaskFromDesk(displayId, activeDesk.deskId)
    }

    private fun removeLeftTiledTaskFromDesk(displayId: Int, deskId: Int) {
        logD("removeLeftTiledTaskToDesk for displayId=%d", displayId)
        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
        desk.leftTiledTaskId = null
        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
            updatePersistentRepository(displayId)
        }
    }

    /* Unregisters a right tiled task from desktop state. */
    fun removeRightTiledTask(displayId: Int) {
        logD("removeRightTiledTask for displayId=%d", displayId)
        val activeDesk =
            checkNotNull(desktopData.getDefaultDesk(displayId)) {
                "Expected desk in display: $displayId"
            }
        removeRightTiledTaskFromDesk(displayId, activeDesk.deskId)
    }

    private fun removeRightTiledTaskFromDesk(displayId: Int, deskId: Int) {
        logD("removeRightTiledTaskFromDesk for displayId=%d", displayId)
        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
        desk.rightTiledTaskId = null
        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
            updatePersistentRepository(displayId)
        }
    }

    /** Returns the id of the active desk in the given display, if any. */
    fun getActiveDeskId(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.deskId

@@ -972,6 +1080,8 @@ class DesktopRepository(
                visibleTasks = desk.visibleTasks,
                minimizedTasks = desk.minimizedTasks,
                freeformTasksInZOrder = desk.freeformTasksInZOrder,
                leftTiledTask = desk.leftTiledTaskId,
                rightTiledTask = desk.rightTiledTaskId,
            )
        } catch (exception: Exception) {
            logE(
+33 −3
Original line number Diff line number Diff line
@@ -113,6 +113,8 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis
        visibleTasks: ArraySet<Int> = ArraySet(),
        minimizedTasks: ArraySet<Int> = ArraySet(),
        freeformTasksInZOrder: ArrayList<Int> = ArrayList(),
        leftTiledTask: Int? = null,
        rightTiledTask: Int? = null,
    ) {
        // TODO: b/367609270 - Improve the API to support multi-user
        try {
@@ -125,7 +127,13 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis
                val desktop =
                    getDesktop(currentRepository, desktopId)
                        .toBuilder()
                        .updateTaskStates(visibleTasks, minimizedTasks, freeformTasksInZOrder)
                        .updateTaskStates(
                            visibleTasks,
                            minimizedTasks,
                            freeformTasksInZOrder,
                            leftTiledTask,
                            rightTiledTask,
                        )
                        .updateZOrder(freeformTasksInZOrder)

                persistentRepositories
@@ -222,6 +230,8 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis
            visibleTasks: ArraySet<Int>,
            minimizedTasks: ArraySet<Int>,
            freeformTasksInZOrder: ArrayList<Int>,
            leftTiledTask: Int?,
            rightTiledTask: Int?,
        ): Desktop.Builder {
            clearTasksByTaskId()

@@ -238,7 +248,11 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis
            }
            putAllTasksByTaskId(
                visibleTasks.associateWith {
                    createDesktopTask(it, state = DesktopTaskState.VISIBLE)
                    createDesktopTask(
                        it,
                        state = DesktopTaskState.VISIBLE,
                        getTilingStateForTask(it, leftTiledTask, rightTiledTask),
                    )
                }
            )
            putAllTasksByTaskId(
@@ -249,6 +263,17 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis
            return this
        }

        private fun getTilingStateForTask(
            taskId: Int,
            leftTiledTask: Int?,
            rightTiledTask: Int?,
        ): DesktopTaskTilingState =
            when (taskId) {
                leftTiledTask -> DesktopTaskTilingState.LEFT
                rightTiledTask -> DesktopTaskTilingState.RIGHT
                else -> DesktopTaskTilingState.NONE
            }

        private fun Desktop.Builder.updateZOrder(
            freeformTasksInZOrder: ArrayList<Int>
        ): Desktop.Builder {
@@ -260,7 +285,12 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis
        private fun createDesktopTask(
            taskId: Int,
            state: DesktopTaskState = DesktopTaskState.VISIBLE,
            tiling_state: DesktopTaskTilingState = DesktopTaskTilingState.NONE,
        ): DesktopTask =
            DesktopTask.newBuilder().setTaskId(taskId).setDesktopTaskState(state).build()
            DesktopTask.newBuilder()
                .setTaskId(taskId)
                .setDesktopTaskState(state)
                .setDesktopTaskTilingState(tiling_state)
                .build()
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -126,6 +126,20 @@ class DesktopRepositoryInitializerImpl(
                                        taskId = task.taskId,
                                    )
                                }

                                if (task.desktopTaskTilingState == DesktopTaskTilingState.LEFT) {
                                    repository.addLeftTiledTask(
                                        persistentDesktop.displayId,
                                        task.taskId,
                                    )
                                } else if (
                                    task.desktopTaskTilingState == DesktopTaskTilingState.RIGHT
                                ) {
                                    repository.addRightTiledTask(
                                        persistentDesktop.displayId,
                                        task.taskId,
                                    )
                                }
                            }
                    }
                }
+7 −0
Original line number Diff line number Diff line
@@ -9,9 +9,16 @@ enum DesktopTaskState {
  MINIMIZED = 1;
}

enum DesktopTaskTilingState {
  NONE = 1;
  LEFT = 2;
  RIGHT = 3;
}

message DesktopTask {
  optional int32 task_id = 1;
  optional DesktopTaskState desktop_task_state= 2;
  optional DesktopTaskTilingState desktop_task_tiling_state = 3;
}

message Desktop {
+11 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ class DesktopTilingWindowDecoration(
        // Observe drag resizing to break tiling if a task is drag resized.
        desktopModeWindowDecoration.addDragResizeListener(this)
        val callback = { initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp) }
        updateDesktopRepository(taskInfo.taskId, snapPosition = position)
        if (isTiled) {
            val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
            toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds, callback)
@@ -159,6 +160,14 @@ class DesktopTilingWindowDecoration(
        return isTiled
    }

    private fun updateDesktopRepository(taskId: Int, snapPosition: SnapPosition) {
        when (snapPosition) {
            SnapPosition.LEFT -> desktopUserRepositories.current.addLeftTiledTask(displayId, taskId)
            SnapPosition.RIGHT ->
                desktopUserRepositories.current.addRightTiledTask(displayId, taskId)
        }
    }

    // If a task is already tiled on the same position, release this task, otherwise if the same
    // task is tiled on the opposite side, remove it from the opposite side so it's tiled correctly.
    private fun initTilingApps(
@@ -580,6 +589,7 @@ class DesktopTilingWindowDecoration(
    ) {
        val taskRepository = desktopUserRepositories.current
        if (taskId == leftTaskResizingHelper?.taskInfo?.taskId) {
            desktopUserRepositories.current.removeLeftTiledTask(displayId)
            removeTask(leftTaskResizingHelper, taskVanished, shouldDelayUpdate)
            leftTaskResizingHelper = null
            val taskId = rightTaskResizingHelper?.taskInfo?.taskId
@@ -593,6 +603,7 @@ class DesktopTilingWindowDecoration(
        }

        if (taskId == rightTaskResizingHelper?.taskInfo?.taskId) {
            desktopUserRepositories.current.removeRightTiledTask(displayId)
            removeTask(rightTaskResizingHelper, taskVanished, shouldDelayUpdate)
            rightTaskResizingHelper = null
            val taskId = leftTaskResizingHelper?.taskInfo?.taskId
Loading