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

Commit a440a7d4 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Idcb266a6,I3de82638,Ic6d9c4b2,Id4773618 into main

* changes:
  [37/N] Desks: Unminimize when moving task to front
  [36/N] Desks: Activate desk of launching task if inactive
  [35/N] Desks: Add DesksOrganizer#unminimizeTask
  [34/N] Desks: Implement task-limit policy
parents 6a161e3f 0e1e0e73
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -451,7 +451,8 @@ public abstract class WMShellModule {
            Optional<DesktopImmersiveController> desktopImmersiveController,
            WindowDecorViewModel windowDecorViewModel,
            Optional<TaskChangeListener> taskChangeListener,
            FocusTransitionObserver focusTransitionObserver) {
            FocusTransitionObserver focusTransitionObserver,
            Optional<DesksTransitionObserver> desksTransitionObserver) {
        return new FreeformTaskTransitionObserver(
                context,
                shellInit,
@@ -459,7 +460,8 @@ public abstract class WMShellModule {
                desktopImmersiveController,
                windowDecorViewModel,
                taskChangeListener,
                focusTransitionObserver);
                focusTransitionObserver,
                desksTransitionObserver);
    }

    @WMSingleton
@@ -772,7 +774,7 @@ public abstract class WMShellModule {
            Optional<BubbleController> bubbleController,
            OverviewToDesktopTransitionObserver overviewToDesktopTransitionObserver,
            DesksOrganizer desksOrganizer,
            DesksTransitionObserver desksTransitionObserver,
            Optional<DesksTransitionObserver> desksTransitionObserver,
            UserProfileContexts userProfileContexts,
            DesktopModeCompatPolicy desktopModeCompatPolicy,
            DragToDisplayTransitionHandler dragToDisplayTransitionHandler,
@@ -813,7 +815,7 @@ public abstract class WMShellModule {
                bubbleController,
                overviewToDesktopTransitionObserver,
                desksOrganizer,
                desksTransitionObserver,
                desksTransitionObserver.get(),
                userProfileContexts,
                desktopModeCompatPolicy,
                dragToDisplayTransitionHandler,
@@ -874,6 +876,7 @@ public abstract class WMShellModule {
            Transitions transitions,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            ShellTaskOrganizer shellTaskOrganizer,
            DesksOrganizer desksOrganizer,
            InteractionJankMonitor interactionJankMonitor,
            @ShellMainThread Handler handler) {
        int maxTaskLimit = DesktopModeStatus.getMaxTaskLimit(context);
@@ -886,6 +889,7 @@ public abstract class WMShellModule {
                        transitions,
                        desktopUserRepositories,
                        shellTaskOrganizer,
                        desksOrganizer,
                        maxTaskLimit <= 0 ? null : maxTaskLimit,
                        interactionJankMonitor,
                        context,
@@ -1215,7 +1219,6 @@ public abstract class WMShellModule {
            Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler,
            Optional<BackAnimationController> backAnimationController,
            DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
            @NonNull DesksTransitionObserver desksTransitionObserver,
            ShellInit shellInit) {
        return desktopUserRepositories.flatMap(
                repository ->
@@ -1228,17 +1231,21 @@ public abstract class WMShellModule {
                                        desktopMixedTransitionHandler.get(),
                                        backAnimationController.get(),
                                        desktopWallpaperActivityTokenProvider,
                                        desksTransitionObserver,
                                        shellInit)));
    }

    @WMSingleton
    @Provides
    static DesksTransitionObserver provideDesksTransitionObserver(
            @NonNull @DynamicOverride DesktopUserRepositories desktopUserRepositories,
    static Optional<DesksTransitionObserver> provideDesksTransitionObserver(
            Context context,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            @NonNull DesksOrganizer desksOrganizer
    ) {
        return new DesksTransitionObserver(desktopUserRepositories, desksOrganizer);
        if (DesktopModeStatus.canEnterDesktopMode(context)) {
            return Optional.of(
                    new DesksTransitionObserver(desktopUserRepositories, desksOrganizer));
        }
        return Optional.empty();
    }

    @WMSingleton
+5 −1
Original line number Diff line number Diff line
@@ -235,6 +235,10 @@ class DesktopRepository(
    /** Returns the default desk in the given display. */
    private fun getDefaultDesk(displayId: Int): Desk? = desktopData.getDefaultDesk(displayId)

    /** Returns whether the given desk is active in its display. */
    fun isDeskActive(deskId: Int): Boolean =
        desktopData.getAllActiveDesks().any { desk -> desk.deskId == deskId }

    /** Sets the given desk as the active one in the given display. */
    fun setActiveDesk(displayId: Int, deskId: Int) {
        logD("setActiveDesk for displayId=%d and deskId=%d", displayId, deskId)
@@ -485,7 +489,7 @@ class DesktopRepository(
    fun getExpandedTasksOrdered(displayId: Int): List<Int> =
        getFreeformTasksInZOrder(displayId).filter { !isMinimizedTask(it) }

    @VisibleForTesting
    /** Returns all active non-minimized tasks for [deskId] ordered from top to bottom. */
    fun getExpandedTasksIdsInDeskOrdered(deskId: Int): List<Int> =
        getFreeformTasksIdsInDeskInZOrder(deskId).filter { !isMinimizedTask(it) }

+74 −24
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.view.DragEvent
import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import android.view.WindowManager
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_NONE
@@ -961,10 +962,13 @@ class DesktopTasksController(
                .apply { launchWindowingMode = WINDOWING_MODE_FREEFORM }
                .toBundle(),
        )
        val deskId = taskRepository.getDeskIdForTask(taskId) ?: getDefaultDeskId(DEFAULT_DISPLAY)
        startLaunchTransition(
            TRANSIT_OPEN,
            wct,
            taskId,
            deskId = deskId,
            displayId = DEFAULT_DISPLAY,
            remoteTransition = remoteTransition,
            unminimizeReason = unminimizeReason,
        )
@@ -982,19 +986,26 @@ class DesktopTasksController(
        remoteTransition: RemoteTransition? = null,
        unminimizeReason: UnminimizeReason = UnminimizeReason.UNKNOWN,
    ) {
        logV("moveTaskToFront taskId=%s", taskInfo.taskId)
        val deskId =
            taskRepository.getDeskIdForTask(taskInfo.taskId) ?: getDefaultDeskId(taskInfo.displayId)
        logV("moveTaskToFront taskId=%s deskId=%s", taskInfo.taskId, deskId)
        // If a task is tiled, another task should be brought to foreground with it so let
        // tiling controller handle the request.
        if (snapEventHandler.moveTaskToFrontIfTiled(taskInfo)) {
            return
        }
        val wct = WindowContainerTransaction()
        if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
            desksOrganizer.reorderTaskToFront(wct, deskId, taskInfo)
        } else {
            wct.reorder(taskInfo.token, /* onTop= */ true, /* includingParents= */ true)
        }
        startLaunchTransition(
            transitionType = TRANSIT_TO_FRONT,
            wct = wct,
            launchingTaskId = taskInfo.taskId,
            remoteTransition = remoteTransition,
            deskId = deskId,
            displayId = taskInfo.displayId,
            unminimizeReason = unminimizeReason,
        )
@@ -1006,14 +1017,22 @@ class DesktopTasksController(
        wct: WindowContainerTransaction,
        launchingTaskId: Int?,
        remoteTransition: RemoteTransition? = null,
        displayId: Int = DEFAULT_DISPLAY,
        deskId: Int,
        displayId: Int,
        unminimizeReason: UnminimizeReason = UnminimizeReason.UNKNOWN,
    ): IBinder {
        logV(
            "startLaunchTransition type=%s launchingTaskId=%d deskId=%d displayId=%d",
            WindowManager.transitTypeToString(transitionType),
            launchingTaskId,
            deskId,
            displayId,
        )
        // TODO: b/397619806 - Consolidate sharable logic with [handleFreeformTaskLaunch].
        var launchTransaction = wct
        val taskIdToMinimize =
            addAndGetMinimizeChanges(
                displayId,
                deskId,
                launchTransaction,
                newTaskId = launchingTaskId,
                launchingNewIntent = launchingTaskId == null,
@@ -1027,21 +1046,20 @@ class DesktopTasksController(
            )
        var activationRunOnTransitStart: RunOnTransitStart? = null
        val shouldActivateDesk =
            (DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue ||
                DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) &&
            when {
                DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ->
                    !taskRepository.isDeskActive(deskId)
                DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue -> {
                    !isDesktopModeShowing(displayId)
                }
                else -> false
            }
        if (shouldActivateDesk) {
            val deskIdToActivate =
                checkNotNull(
                    launchingTaskId?.let { taskRepository.getDeskIdForTask(it) }
                        ?: getDefaultDeskId(displayId)
                )
            val activateDeskWct = WindowContainerTransaction()
            // TODO: b/391485148 - pass in the launching task here to apply task-limit policy,
            //  but make sure to not do it twice since it is also done at the start of this
            //  function.
            activationRunOnTransitStart =
                addDeskActivationChanges(deskIdToActivate, activateDeskWct)
            activationRunOnTransitStart = addDeskActivationChanges(deskId, activateDeskWct)
            // Desk activation must be handled before app launch-related transactions.
            activateDeskWct.merge(launchTransaction, /* transfer= */ true)
            launchTransaction = activateDeskWct
@@ -1152,7 +1170,14 @@ class DesktopTasksController(
            }

        wct.sendPendingIntent(pendingIntent, intent, ops.toBundle())
        startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null)
        val deskId = getDefaultDeskId(displayId)
        startLaunchTransition(
            TRANSIT_OPEN,
            wct,
            launchingTaskId = null,
            deskId = deskId,
            displayId = displayId,
        )
    }

    /**
@@ -2141,10 +2166,14 @@ class DesktopTasksController(
            WINDOWING_MODE_FREEFORM -> {
                val wct = WindowContainerTransaction()
                wct.sendPendingIntent(launchIntent, fillIn, options.toBundle())
                val deskId =
                    taskRepository.getDeskIdForTask(callingTaskInfo.taskId)
                        ?: getDefaultDeskId(callingTaskInfo.displayId)
                startLaunchTransition(
                    transitionType = TRANSIT_OPEN,
                    wct = wct,
                    launchingTaskId = null,
                    deskId = deskId,
                    displayId = callingTaskInfo.displayId,
                )
            }
@@ -2224,6 +2253,7 @@ class DesktopTasksController(
            logV("skip keyguard is locked")
            return null
        }
        val deskId = getDefaultDeskId(task.displayId)
        val wct = WindowContainerTransaction()
        if (shouldFreeformTaskLaunchSwitchToFullscreen(task)) {
            logD("Bring desktop tasks to front on transition=taskId=%d", task.taskId)
@@ -2246,7 +2276,6 @@ class DesktopTasksController(
                runOnTransitStart?.invoke(transition)
                return wct
            }
            val deskId = getDefaultDeskId(task.displayId)
            val runOnTransitStart = addDeskActivationChanges(deskId, wct, task)
            runOnTransitStart?.invoke(transition)
            wct.reorder(task.token, true)
@@ -2288,7 +2317,7 @@ class DesktopTasksController(
            reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
        )
        // 2) minimize a Task if needed.
        val taskIdToMinimize = addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
        val taskIdToMinimize = addAndGetMinimizeChanges(deskId, wct, task.taskId)
        addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
        if (taskIdToMinimize != null) {
            addPendingMinimizeTransition(transition, taskIdToMinimize, MinimizeReason.TASK_LIMIT)
@@ -2334,7 +2363,7 @@ class DesktopTasksController(
                            // The desk was already showing and we're launching a new Task - we
                            // might need to minimize another Task.
                            val taskIdToMinimize =
                                addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
                                addAndGetMinimizeChanges(deskId, wct, task.taskId)
                            taskIdToMinimize?.let { minimizingTaskId ->
                                addPendingMinimizeTransition(
                                    transition,
@@ -2670,7 +2699,7 @@ class DesktopTasksController(

    /** Returns the ID of the Task that will be minimized, or null if no task will be minimized. */
    private fun addAndGetMinimizeChanges(
        displayId: Int,
        deskId: Int,
        wct: WindowContainerTransaction,
        newTaskId: Int?,
        launchingNewIntent: Boolean = false,
@@ -2679,7 +2708,7 @@ class DesktopTasksController(
        require(newTaskId == null || !launchingNewIntent)
        return desktopTasksLimiter
            .get()
            .addAndGetMinimizeTaskChanges(displayId, wct, newTaskId, launchingNewIntent)
            .addAndGetMinimizeTaskChanges(deskId, wct, newTaskId, launchingNewIntent)
    }

    private fun addPendingMinimizeTransition(
@@ -2782,9 +2811,20 @@ class DesktopTasksController(
        taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
            doesAnyTaskRequireTaskbarRounding(displayId)
        )
        // TODO: b/362720497 - activating a desk with the intention to move a new task to
        //  it means we may need to minimize something in the activating desk. Do so here
        //  similar to how it's done in #bringDesktopAppsToFront.
        val expandedTasksOrderedFrontToBack =
            taskRepository.getExpandedTasksIdsInDeskOrdered(deskId = deskId)
        // If we're adding a new Task we might need to minimize an old one
        val taskIdToMinimize =
            desktopTasksLimiter
                .getOrNull()
                ?.getTaskIdToMinimize(expandedTasksOrderedFrontToBack, newTaskIdInFront)
        if (taskIdToMinimize != null) {
            val taskToMinimize = shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize)
            // TODO(b/365725441): Handle non running task minimization
            if (taskToMinimize != null) {
                desksOrganizer.minimizeTask(wct, deskId, taskToMinimize)
            }
        }
        return { transition ->
            val activateDeskTransition =
                if (newTaskIdInFront != null) {
@@ -2802,6 +2842,9 @@ class DesktopTasksController(
                    )
                }
            desksTransitionObserver.addPendingTransition(activateDeskTransition)
            taskIdToMinimize?.let { minimizingTask ->
                addPendingMinimizeTransition(transition, minimizingTask, MinimizeReason.TASK_LIMIT)
            }
        }
    }

@@ -3381,7 +3424,14 @@ class DesktopTasksController(
        if (windowingMode == WINDOWING_MODE_FREEFORM) {
            if (DesktopModeFlags.ENABLE_DESKTOP_TAB_TEARING_MINIMIZE_ANIMATION_BUGFIX.isTrue()) {
                // TODO b/376389593: Use a custom tab tearing transition/animation
                startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null)
                val deskId = getDefaultDeskId(DEFAULT_DISPLAY)
                startLaunchTransition(
                    TRANSIT_OPEN,
                    wct,
                    launchingTaskId = null,
                    deskId = deskId,
                    displayId = DEFAULT_DISPLAY,
                )
            } else {
                desktopModeDragAndDropTransitionHandler.handleDropEvent(wct)
            }
+12 −5
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.os.Handler
import android.os.IBinder
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_TO_BACK
import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags
import android.window.TransitionInfo
import android.window.WindowContainerTransaction
@@ -31,6 +32,7 @@ import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.sysui.UserChangeListener
@@ -48,6 +50,7 @@ class DesktopTasksLimiter(
    transitions: Transitions,
    private val desktopUserRepositories: DesktopUserRepositories,
    private val shellTaskOrganizer: ShellTaskOrganizer,
    private val desksOrganizer: DesksOrganizer,
    private val maxTasksLimit: Int?,
    private val interactionJankMonitor: InteractionJankMonitor,
    private val context: Context,
@@ -258,7 +261,7 @@ class DesktopTasksLimiter(
     * returning the task to minimize.
     */
    fun addAndGetMinimizeTaskChanges(
        displayId: Int,
        deskId: Int,
        wct: WindowContainerTransaction,
        newFrontTaskId: Int?,
        launchingNewIntent: Boolean = false,
@@ -267,15 +270,19 @@ class DesktopTasksLimiter(
        val taskRepository = desktopUserRepositories.current
        val taskIdToMinimize =
            getTaskIdToMinimize(
                taskRepository.getExpandedTasksOrdered(displayId),
                taskRepository.getExpandedTasksIdsInDeskOrdered(deskId),
                newFrontTaskId,
                launchingNewIntent,
            )
        // If it's a running task, reorder it to back.
        taskIdToMinimize
            ?.let { shellTaskOrganizer.getRunningTaskInfo(it) }
            // TODO: b/391485148 - this won't really work with multi-desks enabled.
            ?.let { wct.reorder(it.token, /* onTop= */ false) }
            ?.let { task ->
                if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
                    wct.reorder(task.token, /* onTop= */ false)
                } else {
                    desksOrganizer.minimizeTask(wct, deskId, task)
                }
            }
        return taskIdToMinimize
    }

+0 −3
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ 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,7 +57,6 @@ class DesktopTasksTransitionObserver(
    private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler,
    private val backAnimationController: BackAnimationController,
    private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
    private val desksTransitionObserver: DesksTransitionObserver,
    shellInit: ShellInit,
) : Transitions.TransitionObserver {

@@ -88,7 +86,6 @@ 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