diff options
2 files changed, 77 insertions, 31 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 5d3cb86bf584..6c6606fe7202 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -22,6 +22,7 @@ import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityOptions import android.app.KeyguardManager import android.app.PendingIntent +import android.app.TaskInfo import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM @@ -520,7 +521,8 @@ class DesktopTasksController( return false } logV("moveBackgroundTaskToDesktop with taskId=%d", taskId) - val taskIdToMinimize = bringDesktopAppsToFront(task.displayId, wct, taskId) + val deskId = getDefaultDeskId(task.displayId) + val runOnTransitStart = addDeskActivationChanges(deskId, wct, task) val exitResult = desktopImmersiveController.exitImmersiveIfApplicable( wct = wct, @@ -549,9 +551,7 @@ class DesktopTasksController( desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted( FREEFORM_ANIMATION_DURATION ) - taskIdToMinimize?.let { - addPendingMinimizeTransition(transition, it, MinimizeReason.TASK_LIMIT) - } + runOnTransitStart?.invoke(transition) exitResult.asExit()?.runOnTransitionStart?.invoke(transition) return true } @@ -1626,7 +1626,10 @@ class DesktopTasksController( } } - @Deprecated("Use activeDesk() instead.", ReplaceWith("activateDesk()")) + @Deprecated( + "Use addDeskActivationChanges() instead.", + ReplaceWith("addDeskActivationChanges()"), + ) private fun bringDesktopAppsToFront( displayId: Int, wct: WindowContainerTransaction, @@ -2240,7 +2243,9 @@ class DesktopTasksController( runOnTransitStart?.invoke(transition) return wct } - bringDesktopAppsToFront(task.displayId, wct, task.taskId) + val deskId = getDefaultDeskId(task.displayId) + val runOnTransitStart = addDeskActivationChanges(deskId, wct, task) + runOnTransitStart?.invoke(transition) wct.reorder(task.token, true) return wct } @@ -2303,25 +2308,42 @@ class DesktopTasksController( return WindowContainerTransaction().also { wct -> val deskId = getDefaultDeskId(task.displayId) addMoveToDeskTaskChanges(wct = wct, task = task, deskId = deskId) - // In some launches home task is moved behind new task being launched. Make sure - // that's not the case for launches in desktop. Also, if this launch is the first - // one to trigger the desktop mode (e.g., when [forceEnterDesktop()]), activate the - // desktop mode here. - if ( - task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0 || - !isDesktopModeShowing(task.displayId) - ) { - bringDesktopAppsToFront(task.displayId, wct, task.taskId) - wct.reorder(task.token, true) - } - - // Desktop Mode is already showing and we're launching a new Task - we might need to - // minimize another Task. - val taskIdToMinimize = addAndGetMinimizeChanges(task.displayId, wct, task.taskId) - taskIdToMinimize?.let { - addPendingMinimizeTransition(transition, it, MinimizeReason.TASK_LIMIT) - } - addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize) + val runOnTransitStart: RunOnTransitStart? = + if ( + task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0 || + !isDesktopModeShowing(task.displayId) + ) { + // In some launches home task is moved behind new task being launched. Make + // sure that's not the case for launches in desktop. Also, if this launch is + // the first one to trigger the desktop mode (e.g., when + // [forceEnterDesktop()]), activate the desk here. + val activationRunnable = + addDeskActivationChanges( + deskId = deskId, + wct = wct, + newTask = task, + addPendingLaunchTransition = true, + ) + wct.reorder(task.token, true) + activationRunnable + } else { + { transition: IBinder -> + // 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) + taskIdToMinimize?.let { minimizingTaskId -> + addPendingMinimizeTransition( + transition, + minimizingTaskId, + MinimizeReason.TASK_LIMIT, + ) + } + // Also track the pending launching task. + addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize) + } + } + runOnTransitStart?.invoke(transition) desktopImmersiveController.exitImmersiveIfApplicable( transition, wct, @@ -2716,11 +2738,20 @@ class DesktopTasksController( activateDesk(deskId, remoteTransition) } - /** Activates the given desk but without starting a transition. */ + /** + * Applies the necessary [wct] changes to activate the given desk. + * + * When a task is being brought into a desk together with the activation, then [newTask] is not + * null and may be used to run other desktop policies, such as minimizing another task if the + * task limit has been exceeded. + */ fun addDeskActivationChanges( deskId: Int, wct: WindowContainerTransaction, - newTask: RunningTaskInfo? = null, + newTask: TaskInfo? = null, + // TODO: b/362720497 - should this be true in other places? Can it be calculated locally + // without having to specify the value? + addPendingLaunchTransition: Boolean = false, ): RunOnTransitStart? { logV("addDeskActivationChanges newTaskId=%d deskId=%d", newTask?.taskId, deskId) val newTaskIdInFront = newTask?.taskId @@ -2735,6 +2766,9 @@ class DesktopTasksController( minimizeReason = MinimizeReason.TASK_LIMIT, ) } + if (newTask != null && addPendingLaunchTransition) { + addPendingAppLaunchTransition(transition, newTask.taskId, taskIdToMinimize) + } } } prepareForDeskActivation(displayId, wct) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index 8fdad0625556..8599bf4c81b4 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -3524,9 +3524,15 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask)) // Make sure we reorder the new task to top, and the back task to the bottom - assertThat(wct!!.hierarchyOps.size).isEqualTo(9) + assertThat(wct!!.hierarchyOps.size).isEqualTo(8) wct.assertReorderAt(0, fullscreenTask, toTop = true) - wct.assertReorderAt(8, freeformTasks[0], toTop = false) + // Oldest task that needs to minimized is never reordered to top over Home. + val taskToMinimize = freeformTasks[0] + wct.assertWithoutHop { hop -> + hop.container == taskToMinimize.token && + hop.type == HIERARCHY_OP_TYPE_REORDER && + hop.toTop == true + } } @Test @@ -3541,12 +3547,18 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask)) - assertThat(wct!!.hierarchyOps.size).isEqualTo(10) + assertThat(wct!!.hierarchyOps.size).isEqualTo(9) wct.assertReorderAt(0, fullscreenTask, toTop = true) // Make sure we reorder the home task to the top, desktop tasks to top of them and minimized // task is under the home task. wct.assertReorderAt(1, homeTask, toTop = true) - wct.assertReorderAt(9, freeformTasks[0], toTop = false) + // Oldest task that needs to minimized is never reordered to top over Home. + val taskToMinimize = freeformTasks[0] + wct.assertWithoutHop { hop -> + hop.container == taskToMinimize.token && + hop.type == HIERARCHY_OP_TYPE_REORDER && + hop.toTop == true + } } @Test |