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

Commit 77c0e14a authored by Jorge Gil's avatar Jorge Gil
Browse files

[6/N] Desks: Implement desk removal

Wires DesktopTasksController#removeDesk to remove the desk root task
using a shell transition, and updates the repository state when the
transition completes.

Also wires the desktop command handler to remove a desk through adb.

Flag: com.android.window.flags.enable_multiple_desktops_backend
Bug: 390460212
Test: adb shell dumpsys activity service SystemUIService WMShell | grep
 \ -A20 DesksOrganizer -> does not show desk after removal
Change-Id: I3618950c6483efc20bec9e0e0cbd0dcf1ac04307
parent 70e09e95
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ import com.android.wm.shell.desktopmode.education.AppToWebEducationFilter;
import com.android.wm.shell.desktopmode.education.data.AppHandleEducationDatastoreRepository;
import com.android.wm.shell.desktopmode.education.data.AppToWebEducationDatastoreRepository;
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer;
import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver;
import com.android.wm.shell.desktopmode.multidesks.RootTaskDesksOrganizer;
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository;
import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer;
@@ -760,6 +761,7 @@ public abstract class WMShellModule {
            Optional<BubbleController> bubbleController,
            OverviewToDesktopTransitionObserver overviewToDesktopTransitionObserver,
            DesksOrganizer desksOrganizer,
            DesksTransitionObserver desksTransitionObserver,
            UserProfileContexts userProfileContexts,
            DesktopModeCompatPolicy desktopModeCompatPolicy) {
        return new DesktopTasksController(
@@ -797,6 +799,7 @@ public abstract class WMShellModule {
                bubbleController,
                overviewToDesktopTransitionObserver,
                desksOrganizer,
                desksTransitionObserver,
                userProfileContexts,
                desktopModeCompatPolicy);
    }
@@ -1136,6 +1139,7 @@ public abstract class WMShellModule {
            Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler,
            Optional<BackAnimationController> backAnimationController,
            DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
            @NonNull DesksTransitionObserver desksTransitionObserver,
            ShellInit shellInit) {
        return desktopUserRepositories.flatMap(
                repository ->
@@ -1148,9 +1152,18 @@ public abstract class WMShellModule {
                                        desktopMixedTransitionHandler.get(),
                                        backAnimationController.get(),
                                        desktopWallpaperActivityTokenProvider,
                                        desksTransitionObserver,
                                        shellInit)));
    }

    @WMSingleton
    @Provides
    static DesksTransitionObserver provideDesksTransitionObserver(
            @NonNull @DynamicOverride DesktopUserRepositories desktopUserRepositories
    ) {
        return new DesksTransitionObserver(desktopUserRepositories);
    }

    @WMSingleton
    @Provides
    static Optional<DesktopMixedTransitionHandler> provideDesktopMixedTransitionHandler(
+2 −2
Original line number Diff line number Diff line
@@ -152,8 +152,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.removeDesk(deskId)
        return true
    }

    private fun runRemoveAllDesks(args: Array<String>, pw: PrintWriter): Boolean {
+19 −12
Original line number Diff line number Diff line
@@ -174,6 +174,9 @@ class DesktopRepository(
    /** Returns the number of desks in the given display. */
    fun getNumberOfDesks(displayId: Int) = desktopData.getNumberOfDesks(displayId)

    /** Returns the display the given desk is in. */
    fun getDisplayForDesk(deskId: Int) = desktopData.getDisplayForDesk(deskId)

    /** Adds [regionListener] to inform about changes to exclusion regions for all Desktop tasks. */
    fun setExclusionRegionListener(regionListener: Consumer<Region>, executor: Executor) {
        desktopGestureExclusionListener = regionListener
@@ -207,6 +210,14 @@ class DesktopRepository(
        desktopData.createDesk(displayId, deskId)
    }

    /** Returns the ids of the existing desks in the given display. */
    @VisibleForTesting
    fun getDeskIds(displayId: Int): Set<Int> =
        desktopData.desksSequence(displayId).map { desk -> desk.deskId }.toSet()

    /** Returns the id of the default desk in the given display. */
    fun getDefaultDeskId(displayId: Int): Int? = getDefaultDesk(displayId)?.deskId

    /** Returns the default desk in the given display. */
    private fun getDefaultDesk(displayId: Int): Desk? = desktopData.getDefaultDesk(displayId)

@@ -716,16 +727,12 @@ class DesktopRepository(
        }
    }

    /**
     * Removes the active desk for the given [displayId] and returns the active tasks on that desk.
     *
     * TODO: b/389960283 - add explicit [deskId] argument.
     */
    fun removeDesk(displayId: Int): ArraySet<Int> {
        val desk = desktopData.getActiveDesk(displayId)
        if (desk == null) {
            logW("Could not find desk to remove: displayId=%d", displayId)
            return ArraySet()
    /** Removes the given desk and returns the active tasks in that desk. */
    fun removeDesk(deskId: Int): Set<Int> {
        val desk =
            desktopData.getDesk(deskId)
                ?: return emptySet<Int>().also {
                    logW("Could not find desk to remove: deskId=%d", deskId)
                }
        val activeTasks = ArraySet(desk.activeTasks)
        desktopData.remove(desk.deskId)
@@ -1066,7 +1073,7 @@ class DesktopRepository(
        }

        override fun getDisplayForDesk(deskId: Int): Int =
            getAllActiveDesks().find { it.deskId == deskId }?.displayId
            desksSequence().find { it.deskId == deskId }?.displayId
                ?: error("Display for desk=$deskId not found")
    }

+55 −10
Original line number Diff line number Diff line
@@ -103,7 +103,9 @@ import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler.FULLSCR
import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction
import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
import com.android.wm.shell.desktopmode.minimize.DesktopWindowLimitRemoteHandler
import com.android.wm.shell.desktopmode.multidesks.DeskTransition
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver
import com.android.wm.shell.desktopmode.multidesks.OnDeskRemovedListener
import com.android.wm.shell.draganddrop.DragAndDropController
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
@@ -185,6 +187,7 @@ class DesktopTasksController(
    private val bubbleController: Optional<BubbleController>,
    private val overviewToDesktopTransitionObserver: OverviewToDesktopTransitionObserver,
    private val desksOrganizer: DesksOrganizer,
    private val desksTransitionObserver: DesksTransitionObserver,
    private val userProfileContexts: UserProfileContexts,
    private val desktopModeCompatPolicy: DesktopModeCompatPolicy,
) :
@@ -2363,11 +2366,37 @@ class DesktopTasksController(
        )
    }

    fun removeDesktop(displayId: Int) {
    /** Removes the default desk in the given display. */
    @Deprecated("Deprecated with multi-desks.", ReplaceWith("removeDesk()"))
    fun removeDefaultDeskInDisplay(displayId: Int) {
        val deskId =
            checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
                "Expected a default desk to exist"
            }
        removeDesk(displayId = displayId, deskId = deskId)
    }

    /** Removes the given desk. */
    fun removeDesk(deskId: Int) {
        val displayId = taskRepository.getDisplayForDesk(deskId)
        removeDesk(displayId = displayId, deskId = deskId)
    }

    private fun removeDesk(displayId: Int, deskId: Int) {
        if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue()) return
        logV("removeDesk deskId=%d from displayId=%d", deskId, displayId)

        val tasksToRemove =
            if (Flags.enableMultipleDesktopsBackend()) {
                taskRepository.getActiveTaskIdsInDesk(deskId)
            } else {
                // TODO: 362720497 - make sure minimized windows are also removed in WM
                //  and the repository.
                taskRepository.removeDesk(deskId)
            }

        val tasksToRemove = taskRepository.removeDesk(displayId)
        val wct = WindowContainerTransaction()
        if (!Flags.enableMultipleDesktopsBackend()) {
            tasksToRemove.forEach {
                val task = shellTaskOrganizer.getRunningTaskInfo(it)
                if (task != null) {
@@ -2376,7 +2405,23 @@ class DesktopTasksController(
                    recentTasksController?.removeBackgroundTask(it)
                }
            }
        if (!wct.isEmpty) transitions.startTransition(TRANSIT_CLOSE, wct, null)
        } else {
            // TODO: 362720497 - double check background tasks are also removed.
            desksOrganizer.removeDesk(wct, deskId)
        }
        if (!Flags.enableMultipleDesktopsBackend() && wct.isEmpty) return
        val transition = transitions.startTransition(TRANSIT_CLOSE, wct, /* handler= */ null)
        if (Flags.enableMultipleDesktopsBackend()) {
            desksTransitionObserver.addPendingTransition(
                DeskTransition.RemoveDesk(
                    token = transition,
                    displayId = displayId,
                    deskId = deskId,
                    tasks = tasksToRemove,
                    onDeskRemovedListener = onDeskRemovedListener,
                )
            )
        }
    }

    /** Enter split by using the focused desktop task in given `displayId`. */
@@ -3082,7 +3127,7 @@ class DesktopTasksController(

        override fun removeDesktop(displayId: Int) {
            executeRemoteCallWithTaskPermission(controller, "removeDesktop") { c ->
                c.removeDesktop(displayId)
                c.removeDefaultDeskInDisplay(displayId)
            }
        }

+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.back.BackAnimationController
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.isExitDesktopModeTransition
import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
@@ -58,6 +59,7 @@ class DesktopTasksTransitionObserver(
    private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler,
    private val backAnimationController: BackAnimationController,
    private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
    private val desksTransitionObserver: DesksTransitionObserver,
    shellInit: ShellInit,
) : Transitions.TransitionObserver {

@@ -87,6 +89,7 @@ class DesktopTasksTransitionObserver(
        finishTransaction: SurfaceControl.Transaction,
    ) {
        // TODO: b/332682201 Update repository state
        desksTransitionObserver.onTransitionReady(transition, info)
        if (
            DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC
                .isTrue() && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue()
Loading