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

Commit bf5549ea authored by Matt Sziklay's avatar Matt Sziklay
Browse files

Fixes for restoring minimized tasks on reconnect.

Instead of running the onCreateCallback when the desk root appears, run it when the subsequent minimization root appears to allow for immediately adding minimized tasks to new desks.

Additionally, update the repository when tasks are restored.

Bug: 433967620
Test: Manual; restore desks with minimized tasks
Flag: com.android.window.flags.enable_display_reconnect_interaction
Change-Id: Ie32fdf442254520c0e8289ab8544ba422fce3b3a
parent f656c995
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -977,7 +977,7 @@ class DesktopTasksController(
        val boundsByTaskId = repository.getPreservedTaskBounds(uniqueDisplayId)
        val activeDeskId = repository.getPreservedActiveDesk(uniqueDisplayId)
        val wct = WindowContainerTransaction()
        var runOnTransitStart: RunOnTransitStart? = null
        var runOnTransitStartList = mutableListOf<RunOnTransitStart>()
        val destDisplayLayout = displayController.getDisplayLayout(displayId) ?: return
        val tilingReconnectHandler =
            TilingDisplayReconnectEventHandler(repository, snapEventHandler, transitions, displayId)
@@ -997,13 +997,14 @@ class DesktopTasksController(
                )
                val isActiveDesk = preservedDeskId == activeDeskId
                if (isActiveDesk) {
                    runOnTransitStart =
                    runOnTransitStartList.add(
                        addDeskActivationChanges(
                            deskId = newDeskId,
                            wct = wct,
                            userId = userId,
                            enterReason = EnterReason.DISPLAY_CONNECT,
                        )
                    )
                }

                preservedTaskIds.asReversed().forEach { taskId ->
@@ -1014,9 +1015,11 @@ class DesktopTasksController(
                                deskId = newDeskId,
                                taskId = taskId,
                                userId = userId,
                                displayId = displayId,
                                uniqueDisplayId = uniqueDisplayId,
                                taskBounds = boundsByTaskId[taskId],
                            )
                            ?.let { runOnTransitStartList.add(it) }
                    }
                }

@@ -1035,7 +1038,7 @@ class DesktopTasksController(
            }
            val transition = transitions.startTransition(TRANSIT_CHANGE, wct, null)
            tilingReconnectHandler.activationBinder = transition
            runOnTransitStart?.invoke(transition)
            runOnTransitStartList.forEach { it.invoke(transition) }
            repository.removePreservedDisplay(uniqueDisplayId)
        }
    }
@@ -1046,9 +1049,10 @@ class DesktopTasksController(
        deskId: Int,
        taskId: Int,
        userId: Int,
        displayId: Int,
        uniqueDisplayId: String,
        taskBounds: Rect?,
    ) {
    ): RunOnTransitStart? {
        logD(
            "addRestoreTaskToDeskChanges: taskId=$taskId; deskId=$deskId; userId=$userId; " +
                "taskBounds=$taskBounds; uniqueDisplayId=$uniqueDisplayId"
@@ -1058,7 +1062,7 @@ class DesktopTasksController(
        val task = shellTaskOrganizer.getRunningTaskInfo(taskId)
        if (task == null) {
            logE("restoreDisplay: Could not find running task info for taskId=$taskId.")
            return
            return null
        }
        desksOrganizer.moveTaskToDesk(wct, deskId, task, minimized = minimized)
        wct.setDensityDpi(task.token, destinationDisplayLayout.densityDpi())
@@ -1068,6 +1072,19 @@ class DesktopTasksController(
            // Bring display to front if task is not minimized to ensure display focus.
            wct.reorder(task.token, /* onTop= */ true, /* includingParents= */ true)
        }
        return { transition ->
            desksTransitionObserver.addPendingTransition(
                DeskTransition.AddTaskToDesk(
                    token = transition,
                    userId = userId,
                    displayId = displayId,
                    deskId = deskId,
                    taskId = taskId,
                    taskBounds = taskBounds,
                    minimized = minimized,
                )
            )
        }
    }

    private fun handleUserChangeTransitionRequest(
+14 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.wm.shell.desktopmode.multidesks

import android.graphics.Rect
import android.os.IBinder
import com.android.wm.shell.desktopmode.DesktopModeEventLogger

@@ -152,4 +153,17 @@ sealed interface DeskTransition {
    ) : DeskTransition {
        override fun copyWithToken(token: IBinder): DeskTransition = copy(token)
    }

    /** A transition to add a task to a desk, including bounds and minimize state */
    data class AddTaskToDesk(
        override val token: IBinder,
        override val userId: Int,
        val displayId: Int,
        val deskId: Int,
        val taskId: Int,
        val taskBounds: Rect?,
        val minimized: Boolean,
    ) : DeskTransition {
        override fun copyWithToken(token: IBinder): DeskTransition = copy(token)
    }
}
+20 −0
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ class DesksTransitionObserver(
            is DeskTransition.DeactivateDesk -> handleDeactivateDeskTransition(info, deskTransition)
            is DeskTransition.ChangeDeskDisplay -> handleChangeDeskDisplay(info, deskTransition)
            is DeskTransition.RemoveDisplay -> handleRemoveDisplay(deskTransition)
            is DeskTransition.AddTaskToDesk -> handleAddTaskToDesk(deskTransition)
        }
    }

@@ -258,6 +259,25 @@ class DesksTransitionObserver(
        }
    }

    private fun handleAddTaskToDesk(deskTransition: DeskTransition.AddTaskToDesk) {
        logD("handleAddTaskToDesk: %s", deskTransition)
        val taskRepository = desktopUserRepositories.getProfile(deskTransition.userId)
        taskRepository.addTaskToDesk(
            deskTransition.displayId,
            deskTransition.deskId,
            deskTransition.taskId,
            !deskTransition.minimized,
            deskTransition.taskBounds,
        )
        if (deskTransition.minimized) {
            taskRepository.minimizeTaskInDesk(
                deskTransition.displayId,
                deskTransition.deskId,
                deskTransition.taskId,
            )
        }
    }

    private fun handleIndependentDeskTransitionIfNeeded(info: TransitionInfo) {
        val deskChanges = info.deskChanges()
        val desktopWallpaperChanges = info.desktopWallpaperChanges()
+21 −5
Original line number Diff line number Diff line
@@ -520,8 +520,11 @@ class RootTaskDesksOrganizer(
                        },
                )
            createDeskRootRequests.remove(deskRequest)
            deskRequest.onCreateCallback.onCreated(deskId)
            createDeskMinimizationRoot(displayId = appearingInDisplayId, deskId = deskId)
            createDeskMinimizationRoot(
                displayId = appearingInDisplayId,
                deskId = deskId,
                callback = deskRequest.onCreateCallback,
            )
            return
        }
        // Check if there's any pending minimization container creation requests under this display.
@@ -532,6 +535,7 @@ class RootTaskDesksOrganizer(
        val deskMinimizationRoot = DeskMinimizationRoot(deskId, taskInfo, leash)
        deskMinimizationRootsByDeskId[deskId] = deskMinimizationRoot
        createDeskMinimizationRootRequests.remove(deskMinimizationRootRequest)
        deskMinimizationRootRequest.callback.onCreated(deskId)
        hideMinimizationRoot(deskMinimizationRoot)
    }

@@ -630,9 +634,17 @@ class RootTaskDesksOrganizer(
        }
    }

    private fun createDeskMinimizationRoot(displayId: Int, deskId: Int) {
    private fun createDeskMinimizationRoot(
        displayId: Int,
        deskId: Int,
        callback: OnCreateCallback,
    ) {
        createDeskMinimizationRootRequests +=
            CreateDeskMinimizationRootRequest(displayId = displayId, deskId = deskId)
            CreateDeskMinimizationRootRequest(
                displayId = displayId,
                deskId = deskId,
                callback = callback,
            )
        shellTaskOrganizer.createRootTask(
            TaskOrganizer.CreateRootTaskRequest()
                .setName("MinimizedDesk_$deskId")
@@ -723,7 +735,11 @@ class RootTaskDesksOrganizer(
        val onCreateCallback: OnCreateCallback,
    )

    private data class CreateDeskMinimizationRootRequest(val displayId: Int, val deskId: Int)
    private data class CreateDeskMinimizationRootRequest(
        val displayId: Int,
        val deskId: Int,
        val callback: OnCreateCallback,
    )

    private fun logD(msg: String, vararg arguments: Any?) {
        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+90 −0
Original line number Diff line number Diff line
@@ -11033,6 +11033,9 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
                        deskId = 5
                    )
                }
            val transition = Binder()
            whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull()))
                .thenReturn(transition)

            controller.restoreDisplay(
                displayId = SECOND_DISPLAY_ON_RECONNECT,
@@ -11049,6 +11052,93 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            wct.assertReorder(task = secondTask, toTop = true, includingParents = true)
            verify(desksOrganizer).moveTaskToDesk(any(), anyInt(), eq(firstTask), eq(false))
            verify(desksOrganizer).moveTaskToDesk(any(), anyInt(), eq(secondTask), eq(false))
            val deskIds = taskRepository.getDeskIds(SECOND_DISPLAY_ON_RECONNECT)
            assertThat(deskIds.size).isEqualTo(1)
            verify(desksTransitionsObserver)
                .addPendingTransition(
                    DeskTransition.AddTaskToDesk(
                        token = transition,
                        displayId = SECOND_DISPLAY_ON_RECONNECT,
                        deskId = 5,
                        taskId = firstTask.taskId,
                        userId = taskRepository.userId,
                        taskBounds = firstTaskBounds,
                        minimized = false,
                    )
                )
            verify(desksTransitionsObserver)
                .addPendingTransition(
                    DeskTransition.AddTaskToDesk(
                        token = transition,
                        displayId = SECOND_DISPLAY_ON_RECONNECT,
                        deskId = 5,
                        taskId = secondTask.taskId,
                        userId = taskRepository.userId,
                        taskBounds = secondTaskBounds,
                        minimized = false,
                    )
                )
        }

    @Test
    @EnableFlags(
        Flags.FLAG_ENABLE_DISPLAY_DISCONNECT_INTERACTION,
        Flags.FLAG_ENABLE_DISPLAY_RECONNECT_INTERACTION,
        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
    )
    fun restoreDisplay_restoresMinimizedTask() =
        testScope.runTest {
            taskRepository.addDesk(SECOND_DISPLAY, DISCONNECTED_DESK_ID)
            taskRepository.setActiveDesk(displayId = SECOND_DISPLAY, deskId = DISCONNECTED_DESK_ID)
            val firstTaskBounds = Rect(100, 300, 1000, 1200)
            val firstTask =
                setUpFreeformTask(
                    displayId = SECOND_DISPLAY,
                    deskId = DISCONNECTED_DESK_ID,
                    bounds = firstTaskBounds,
                )
            taskRepository.minimizeTaskInDesk(
                SECOND_DISPLAY,
                DISCONNECTED_DESK_ID,
                firstTask.taskId,
            )
            val wctCaptor = argumentCaptor<WindowContainerTransaction>()
            taskRepository.preserveDisplay(SECOND_DISPLAY, SECOND_DISPLAY_UNIQUE_ID)
            taskRepository.onDeskDisplayChanged(
                DISCONNECTED_DESK_ID,
                DEFAULT_DISPLAY,
                DEFAULT_DISPLAY_UNIQUE_ID,
            )
            whenever(desksOrganizer.createDesk(eq(SECOND_DISPLAY_ON_RECONNECT), any(), any()))
                .thenAnswer { invocation ->
                    (invocation.arguments[2] as DesksOrganizer.OnCreateCallback).onCreated(
                        deskId = 5
                    )
                }
            val transition = Binder()
            whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull()))
                .thenReturn(transition)

            controller.restoreDisplay(
                SECOND_DISPLAY_ON_RECONNECT,
                SECOND_DISPLAY_UNIQUE_ID,
                taskRepository.userId,
            )
            runCurrent()

            verify(transitions).startTransition(anyInt(), wctCaptor.capture(), anyOrNull())
            verify(desksTransitionsObserver)
                .addPendingTransition(
                    DeskTransition.AddTaskToDesk(
                        token = transition,
                        displayId = SECOND_DISPLAY_ON_RECONNECT,
                        deskId = 5,
                        taskId = firstTask.taskId,
                        userId = taskRepository.userId,
                        taskBounds = firstTaskBounds,
                        minimized = true,
                    )
                )
        }

    @Test
Loading