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

Commit b6d9507d authored by Jorge Gil's avatar Jorge Gil
Browse files

[7/N] Desks: Implement desk activation

Adds a new DesktopTasksController#activateDesk to focus the given desk
and its tasks.

The existing #showDesktopApps used by Launcher maps to #activateDesk
with the default desk in the given display, and the #activateDesk shell
adb command is also wired to activate the given desk.

A small refactor of #bringDesktopAppsToFront is needed now that manually
bringing every one of the desk's tasks to the front isn't needed, and
instead the desk root container is the one being sent to front.

Flag: com.android.window.flags.enable_multiple_desktops_backend
Bug: 390692038
Test: adb shell dumpsys activity service SystemUIService WMShell
 \ desktopmode activateDesk <deskId>
Test: selecting desk overview tile activates the desk

Change-Id: I92a9a4675e9d605fa6ffd4d5df375f8cc6e0740e
parent d44604d2
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1157,9 +1157,10 @@ public abstract class WMShellModule {
    @WMSingleton
    @Provides
    static DesksTransitionObserver provideDesksTransitionObserver(
            @NonNull @DynamicOverride DesktopUserRepositories desktopUserRepositories
            @NonNull @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            @NonNull DesksOrganizer desksOrganizer
    ) {
        return new DesksTransitionObserver(desktopUserRepositories);
        return new DesksTransitionObserver(desktopUserRepositories, desksOrganizer);
    }

    @WMSingleton
+2 −2
Original line number Diff line number Diff line
@@ -131,8 +131,8 @@ class DesktopModeShellCommandHandler(private val controller: DesktopTasksControl
                pw.println("Error: desk id should be an integer")
                return false
            }
        pw.println("Not implemented.")
        return false
        controller.activateDesk(deskId)
        return true
    }

    private fun runRemoveDesk(args: Array<String>, pw: PrintWriter): Boolean {
+5 −1
Original line number Diff line number Diff line
@@ -226,6 +226,10 @@ class DesktopRepository(
        desktopData.setActiveDesk(displayId = displayId, deskId = deskId)
    }

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

    /**
     * Adds task with [taskId] to the list of freeform tasks on [displayId]'s active desk.
     *
@@ -435,7 +439,7 @@ class DesktopRepository(
                ?: error("Expected non-null desk in display $displayId")
            unminimizeTask(displayId, taskId)
        } else {
            desktopData.getActiveDesk(displayId)?.visibleTasks?.remove(taskId)
            desktopData.getDefaultDesk(displayId)?.visibleTasks?.remove(taskId)
        }
        val newCount = getVisibleTaskCount(displayId)
        if (prevCount != newCount) {
+76 −40
Original line number Diff line number Diff line
@@ -315,24 +315,10 @@ class DesktopTasksController(
    }

    /** Show all tasks, that are part of the desktop, on top of launcher */
    @Deprecated("Use activateDesk() instead.", ReplaceWith("activateDesk()"))
    fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition? = null) {
        logV("showDesktopApps")
        val wct = WindowContainerTransaction()
        bringDesktopAppsToFront(displayId, wct)

        val transitionType = transitionType(remoteTransition)
        val handler =
            remoteTransition?.let {
                OneShotRemoteHandler(transitions.mainExecutor, remoteTransition)
            }
        transitions.startTransition(transitionType, wct, handler).also { t ->
            handler?.setTransition(t)
        }

        // launch from recent DesktopTaskView
        desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
            FREEFORM_ANIMATION_DURATION
        )
        activateDefaultDeskInDisplay(displayId, remoteTransition)
    }

    /** Gets number of visible freeform tasks in [displayId]. */
@@ -606,9 +592,9 @@ class DesktopTasksController(
        val wct = WindowContainerTransaction()
        exitSplitIfApplicable(wct, taskInfo)
        if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
            moveHomeTask(wct, toTop = true, taskInfo.displayId)
            moveHomeTask(taskInfo.displayId, wct)
        } else {
            moveHomeTask(wct, toTop = true)
            moveHomeTask(context.displayId, wct)
        }
        val taskIdToMinimize =
            bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
@@ -780,7 +766,7 @@ class DesktopTasksController(

        // We are moving a freeform task to fullscreen, put the home task under the fullscreen task.
        if (!forceEnterDesktop(task.displayId)) {
            moveHomeTask(wct, toTop = true, task.displayId)
            moveHomeTask(task.displayId, wct)
            wct.reorder(task.token, /* onTop= */ true)
        }

@@ -1416,33 +1402,36 @@ class DesktopTasksController(
            ?: WINDOWING_MODE_UNDEFINED
    }

    private fun prepareForDeskActivation(displayId: Int, wct: WindowContainerTransaction) {
        // Move home to front, ensures that we go back home when all desktop windows are closed
        val useParamDisplayId =
            Flags.enableMultipleDesktopsBackend() ||
                Flags.enablePerDisplayDesktopWallpaperActivity()
        moveHomeTask(displayId = if (useParamDisplayId) displayId else context.displayId, wct = wct)
        // Currently, we only handle the desktop on the default display really.
        if (
            (displayId == DEFAULT_DISPLAY || Flags.enablePerDisplayDesktopWallpaperActivity()) &&
                ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY.isTrue()
        ) {
            // Add translucent wallpaper activity to show the wallpaper underneath.
            addWallpaperActivity(displayId, wct)
        }
    }

    private fun bringDesktopAppsToFrontBeforeShowingNewTask(
        displayId: Int,
        wct: WindowContainerTransaction,
        newTaskIdInFront: Int,
    ): Int? = bringDesktopAppsToFront(displayId, wct, newTaskIdInFront)

    @Deprecated("Use activeDesk() instead.", ReplaceWith("activateDesk()"))
    private fun bringDesktopAppsToFront(
        displayId: Int,
        wct: WindowContainerTransaction,
        newTaskIdInFront: Int? = null,
    ): Int? {
        logV("bringDesktopAppsToFront, newTaskId=%d", newTaskIdInFront)
        // Move home to front, ensures that we go back home when all desktop windows are closed
        if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
            moveHomeTask(wct, toTop = true, displayId)
        } else {
            moveHomeTask(wct, toTop = true)
        }

        // Currently, we only handle the desktop on the default display really.
        if (
            (displayId == DEFAULT_DISPLAY || Flags.enablePerDisplayDesktopWallpaperActivity()) &&
                ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY.isTrue()
        ) {
            // Add translucent wallpaper activity to show the wallpaper underneath
            addWallpaperActivity(displayId, wct)
        }
        prepareForDeskActivation(displayId, wct)

        val expandedTasksOrderedFrontToBack = taskRepository.getExpandedTasksOrdered(displayId)
        // If we're adding a new Task we might need to minimize an old one
@@ -1486,15 +1475,11 @@ class DesktopTasksController(
        return taskIdToMinimize
    }

    private fun moveHomeTask(
        wct: WindowContainerTransaction,
        toTop: Boolean,
        displayId: Int = DEFAULT_DISPLAY,
    ) {
    private fun moveHomeTask(displayId: Int, wct: WindowContainerTransaction) {
        shellTaskOrganizer
            .getRunningTasks(displayId)
            .firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
            ?.let { homeTask -> wct.reorder(homeTask.getToken(), /* onTop= */ toTop) }
            ?.let { homeTask -> wct.reorder(homeTask.getToken(), /* onTop= */ true) }
    }

    private fun addLaunchHomePendingIntent(wct: WindowContainerTransaction, displayId: Int) {
@@ -2372,6 +2357,57 @@ class DesktopTasksController(
        )
    }

    private fun activateDefaultDeskInDisplay(
        displayId: Int,
        remoteTransition: RemoteTransition? = null,
    ) {
        val deskId =
            checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
                "Expected a default desk to exist"
            }
        activateDesk(deskId, remoteTransition)
    }

    /** Activates the given desk. */
    fun activateDesk(deskId: Int, remoteTransition: RemoteTransition? = null) {
        val displayId = taskRepository.getDisplayForDesk(deskId)
        val wct = WindowContainerTransaction()
        if (Flags.enableMultipleDesktopsBackend()) {
            prepareForDeskActivation(displayId, wct)
            desksOrganizer.activateDesk(wct, deskId)
            if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
                // TODO: 362720497 - do non-running tasks need to be restarted with |wct#startTask|?
            }
            taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
                doesAnyTaskRequireTaskbarRounding(displayId)
            )
        } else {
            bringDesktopAppsToFront(displayId, wct)
        }

        val transitionType = transitionType(remoteTransition)
        val handler =
            remoteTransition?.let {
                OneShotRemoteHandler(transitions.mainExecutor, remoteTransition)
            }

        val transition = transitions.startTransition(transitionType, wct, handler)
        handler?.setTransition(transition)
        if (Flags.enableMultipleDesktopsBackend()) {
            desksTransitionObserver.addPendingTransition(
                DeskTransition.ActivateDesk(
                    token = transition,
                    displayId = displayId,
                    deskId = deskId,
                )
            )
        }

        desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
            FREEFORM_ANIMATION_DURATION
        )
    }

    /** Removes the default desk in the given display. */
    @Deprecated("Deprecated with multi-desks.", ReplaceWith("removeDesk()"))
    fun removeDefaultDeskInDisplay(displayId: Int) {
+4 −0
Original line number Diff line number Diff line
@@ -30,4 +30,8 @@ sealed class DeskTransition {
        val tasks: Set<Int>,
        val onDeskRemovedListener: OnDeskRemovedListener?,
    ) : DeskTransition()

    /** A transition to activate a desk in its display. */
    data class ActivateDesk(override val token: IBinder, val displayId: Int, val deskId: Int) :
        DeskTransition()
}
Loading