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

Commit 6ad54c34 authored by Jorge Gil's avatar Jorge Gil
Browse files

[30/N] Desks: Track desk deactivation on moves to fullscreen

A few remaining callers of #addMoveToFullscreenChanges, where desk
deactivation happens, were not handling the returned RunOnTransitStart
that needs to be invoked with the transition token that allows
DesksTransitionObserver to monitor desk deactivations.

Now, deactivating through core-started call sites (#handleRequest)
always results in the desk being deactivated in the repository.

Flag: com.android.window.flags.enable_multiple_desktops_backend
Bug: 394268248
Test: atest WMShellUnitTests
Change-Id: I4c6066ae94b425cc3a93df9e6fe86c67db1e8ccf
parent 2bde8a52
Loading
Loading
Loading
Loading
+41 −28
Original line number Diff line number Diff line
@@ -2056,12 +2056,13 @@ class DesktopTasksController(
            triggerTask?.let { task ->
                when {
                    // Check if freeform task launch during recents should be handled
                    shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task)
                    shouldHandleMidRecentsFreeformLaunch ->
                        handleMidRecentsFreeformTaskLaunch(task, transition)
                    // Check if the closing task needs to be handled
                    TransitionUtil.isClosingType(request.type) ->
                        handleTaskClosing(task, transition, request.type)
                    // Check if the top task shouldn't be allowed to enter desktop mode
                    isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task)
                    isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task, transition)
                    // Check if fullscreen task should be updated
                    task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
                    // Check if freeform task should be updated
@@ -2300,10 +2301,12 @@ class DesktopTasksController(
     * This is a special case where we want to launch the task in fullscreen instead of freeform.
     */
    private fun handleMidRecentsFreeformTaskLaunch(
        task: RunningTaskInfo
        task: RunningTaskInfo,
        transition: IBinder,
    ): WindowContainerTransaction? {
        logV("DesktopTasksController: handleMidRecentsFreeformTaskLaunch")
        val wct = WindowContainerTransaction()
        val runOnTransitStart =
            addMoveToFullscreenChanges(
                wct = wct,
                taskInfo = task,
@@ -2314,6 +2317,7 @@ class DesktopTasksController(
                        forceExitDesktop = true,
                    ),
            )
        runOnTransitStart?.invoke(transition)
        wct.reorder(task.token, true)
        return wct
    }
@@ -2337,6 +2341,7 @@ class DesktopTasksController(
                // launched. We should make this task go to fullscreen instead of freeform. Note
                // that this means any re-launch of a freeform window outside of desktop will be in
                // fullscreen as long as default-desktop flag is disabled.
                val runOnTransitStart =
                    addMoveToFullscreenChanges(
                        wct = wct,
                        taskInfo = task,
@@ -2347,6 +2352,7 @@ class DesktopTasksController(
                                forceExitDesktop = true,
                            ),
                    )
                runOnTransitStart?.invoke(transition)
                return wct
            }
            bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
@@ -2442,7 +2448,8 @@ class DesktopTasksController(
            // If a freeform task receives a request for a fullscreen launch, apply the same
            // changes we do for similar transitions. The task not having WINDOWING_MODE_UNDEFINED
            // set when needed can interfere with future split / multi-instance transitions.
            return WindowContainerTransaction().also { wct ->
            val wct = WindowContainerTransaction()
            val runOnTransitStart =
                addMoveToFullscreenChanges(
                    wct = wct,
                    taskInfo = task,
@@ -2453,7 +2460,8 @@ class DesktopTasksController(
                            forceExitDesktop = true,
                        ),
                )
            }
            runOnTransitStart?.invoke(transition)
            return wct
        }
        return null
    }
@@ -2468,7 +2476,10 @@ class DesktopTasksController(
     * If a task is not compatible with desktop mode freeform, it should always be launched in
     * fullscreen.
     */
    private fun handleIncompatibleTaskLaunch(task: RunningTaskInfo): WindowContainerTransaction? {
    private fun handleIncompatibleTaskLaunch(
        task: RunningTaskInfo,
        transition: IBinder,
    ): WindowContainerTransaction? {
        logV("handleIncompatibleTaskLaunch")
        if (!isDesktopModeShowing(task.displayId) && !forceEnterDesktop(task.displayId)) return null
        // Only update task repository for transparent task.
@@ -2480,7 +2491,8 @@ class DesktopTasksController(
        }
        // Already fullscreen, no-op.
        if (task.isFullscreen) return null
        return WindowContainerTransaction().also { wct ->
        val wct = WindowContainerTransaction()
        val runOnTransitStart =
            addMoveToFullscreenChanges(
                wct = wct,
                taskInfo = task,
@@ -2491,7 +2503,8 @@ class DesktopTasksController(
                        forceExitDesktop = true,
                    ),
            )
        }
        runOnTransitStart?.invoke(transition)
        return wct
    }

    /**
+76 −0
Original line number Diff line number Diff line
@@ -3512,6 +3512,25 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
        verify(desksOrganizer).moveTaskToDesk(wct = wct, deskId = 5, task = fullscreenTask)
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    fun handleRequest_fullscreenTaskThatWasInactiveInDesk_tracksDeskDeactivation() {
        // Set up and existing desktop task in an active desk.
        val inactiveInDeskTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0)
        taskRepository.setDeskInactive(deskId = 0)

        // Now the task is launching as fullscreen.
        inactiveInDeskTask.configuration.windowConfiguration.windowingMode =
            WINDOWING_MODE_FULLSCREEN
        val transition = Binder()
        val wct = controller.handleRequest(transition, createTransition(inactiveInDeskTask))

        // Desk is deactivated.
        assertNotNull(wct, "should handle request")
        verify(desksTransitionsObserver)
            .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId = 0))
    }

    @Test
    fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() {
        val homeTask = setUpHomeTask()
@@ -3687,6 +3706,20 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
        wct!!.assertReorderAt(0, freeformTasks[0], toTop = false) // Reorder to the bottom
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    fun handleRequest_freeformTaskFromInactiveDesk_tracksDeskDeactivation() {
        val deskId = 0
        val freeformTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
        taskRepository.setDeskInactive(deskId = deskId)

        val transition = Binder()
        controller.handleRequest(transition, createTransition(freeformTask))

        verify(desksTransitionsObserver)
            .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId))
    }

    @Test
    fun handleRequest_freeformTask_relaunchActiveTask_taskBecomesUndefined() {
        val freeformTask = setUpFreeformTask()
@@ -3934,6 +3967,24 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            .isEqualTo(WINDOWING_MODE_UNDEFINED)
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    fun handleRequest_recentsAnimationRunning_relaunchActiveTask_tracksDeskDeactivation() {
        // Set up a visible freeform task
        val freeformTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0)
        markTaskVisible(freeformTask)

        // Mark recents animation running
        recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_ANIMATING)

        val transition = Binder()
        controller.handleRequest(transition, createTransition(freeformTask))

        desksTransitionsObserver.addPendingTransition(
            DeskTransition.DeactivateDesk(transition, deskId = 0)
        )
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
    fun handleRequest_topActivityTransparentWithoutDisplay_returnSwitchToFreeformWCT() {
@@ -4051,6 +4102,31 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
    }

    @Test
    @EnableFlags(
        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY,
    )
    fun handleRequest_systemUIActivityWithDisplayInFreeformTask_inDesktop_tracksDeskDeactivation() {
        val deskId = 5
        taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
        taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
        val systemUIPackageName =
            context.resources.getString(com.android.internal.R.string.config_systemUi)
        val baseComponent = ComponentName(systemUIPackageName, /* cls= */ "")
        val task =
            setUpFreeformTask(displayId = DEFAULT_DISPLAY).apply {
                baseActivity = baseComponent
                isTopActivityNoDisplay = false
            }

        val transition = Binder()
        controller.handleRequest(transition, createTransition(task))

        verify(desksTransitionsObserver)
            .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId))
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
    fun handleRequest_systemUIActivityWithoutDisplay_returnSwitchToFreeformWCT() {