diff options
| author | 2025-02-19 21:38:41 +0900 | |
|---|---|---|
| committer | 2025-02-20 20:23:39 +0900 | |
| commit | fe05a0b30a377ad23f17256a6947402d014f018d (patch) | |
| tree | 3d4a03933d472da664e7ccbc5eda32701dd61cec | |
| parent | 6b3d33e24ae86cb283670f590e4290d3ed71ebc6 (diff) | |
Setup desktop when entering desktop by app-initiated transition
This CL setup the desktop env (e.g., bring up DesktopWallpaper) when an
app is launched (or moved to top) into the desktop by app-initiated
transition when the desktop session is not activated.
We probably want to consolidate the logic with handleFreeformTaskLaunch
but this CL is the hot fix.
Flag: com.android.window.flags.enable_display_windowing_mode_switching
Bug: 397249847
Test: DesktopTasksControllerTest
Change-Id: Ia778bff76eaccadb1adb9558c4b529a145d48ea3
2 files changed, 132 insertions, 17 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 93058db0c171..0da611e02def 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 @@ -1055,7 +1055,8 @@ class DesktopTasksController( ) } - private fun startLaunchTransition( + @VisibleForTesting + fun startLaunchTransition( transitionType: Int, wct: WindowContainerTransaction, launchingTaskId: Int?, @@ -1063,34 +1064,52 @@ class DesktopTasksController( displayId: Int = DEFAULT_DISPLAY, unminimizeReason: UnminimizeReason = UnminimizeReason.UNKNOWN, ): IBinder { + // TODO: b/397619806 - Consolidate sharable logic with [handleFreeformTaskLaunch]. + var launchTransaction = wct val taskIdToMinimize = addAndGetMinimizeChanges( displayId, - wct, + launchTransaction, newTaskId = launchingTaskId, launchingNewIntent = launchingTaskId == null, ) val exitImmersiveResult = desktopImmersiveController.exitImmersiveIfApplicable( - wct = wct, + wct = launchTransaction, displayId = displayId, excludeTaskId = launchingTaskId, reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH, ) + var deskIdToActivate: Int? = null + if ( + DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue && + !isDesktopModeShowing(displayId) + ) { + deskIdToActivate = + checkNotNull( + launchingTaskId?.let { taskRepository.getDeskIdForTask(it) } + ?: getDefaultDeskId(displayId) + ) + val activateDeskWct = WindowContainerTransaction() + addDeskActivationChanges(deskIdToActivate, activateDeskWct) + // Desk activation must be handled before app launch-related transactions. + activateDeskWct.merge(launchTransaction, /* transfer= */ true) + launchTransaction = activateDeskWct + } val t = if (remoteTransition == null) { desktopMixedTransitionHandler.startLaunchTransition( transitionType = transitionType, - wct = wct, + wct = launchTransaction, taskId = launchingTaskId, minimizingTaskId = taskIdToMinimize, exitingImmersiveTask = exitImmersiveResult.asExit()?.exitingTask, ) } else if (taskIdToMinimize == null) { val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition) - transitions.startTransition(transitionType, wct, remoteTransitionHandler).also { - remoteTransitionHandler.setTransition(it) - } + transitions + .startTransition(transitionType, launchTransaction, remoteTransitionHandler) + .also { remoteTransitionHandler.setTransition(it) } } else { val remoteTransitionHandler = DesktopWindowLimitRemoteHandler( @@ -1099,9 +1118,9 @@ class DesktopTasksController( remoteTransition, taskIdToMinimize, ) - transitions.startTransition(transitionType, wct, remoteTransitionHandler).also { - remoteTransitionHandler.setTransition(it) - } + transitions + .startTransition(transitionType, launchTransaction, remoteTransitionHandler) + .also { remoteTransitionHandler.setTransition(it) } } if (taskIdToMinimize != null) { addPendingMinimizeTransition(t, taskIdToMinimize, MinimizeReason.TASK_LIMIT) @@ -1109,6 +1128,24 @@ class DesktopTasksController( if (launchingTaskId != null && taskRepository.isMinimizedTask(launchingTaskId)) { addPendingUnminimizeTransition(t, displayId, launchingTaskId, unminimizeReason) } + if ( + DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue && + deskIdToActivate != null + ) { + if (DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue) { + desksTransitionObserver.addPendingTransition( + DeskTransition.ActivateDesk( + token = t, + displayId = displayId, + deskId = deskIdToActivate, + ) + ) + } + + desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted( + FREEFORM_ANIMATION_DURATION + ) + } exitImmersiveResult.asExit()?.runOnTransitionStart?.invoke(t) return t } @@ -2665,10 +2702,9 @@ class DesktopTasksController( activateDesk(deskId, remoteTransition) } - /** Activates the given desk. */ - fun activateDesk(deskId: Int, remoteTransition: RemoteTransition? = null) { + /** Activates the given desk but without starting a transition. */ + fun addDeskActivationChanges(deskId: Int, wct: WindowContainerTransaction) { val displayId = taskRepository.getDisplayForDesk(deskId) - val wct = WindowContainerTransaction() if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { prepareForDeskActivation(displayId, wct) desksOrganizer.activateDesk(wct, deskId) @@ -2681,6 +2717,13 @@ class DesktopTasksController( } else { bringDesktopAppsToFront(displayId, wct) } + } + + /** Activates the given desk. */ + fun activateDesk(deskId: Int, remoteTransition: RemoteTransition? = null) { + val displayId = taskRepository.getDisplayForDesk(deskId) + val wct = WindowContainerTransaction() + addDeskActivationChanges(deskId, wct) val transitionType = transitionType(remoteTransition) val handler = 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 fcd92ac2678a..950d38a63395 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 @@ -2477,8 +2477,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) - assertThat(wct.hierarchyOps).hasSize(1) - wct.assertLaunchTaskAt(0, task.taskId, WINDOWING_MODE_FREEFORM) + wct.assertLaunchTask(task.taskId, WINDOWING_MODE_FREEFORM) } @Test @@ -6240,6 +6239,61 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertThat(taskRepository.getNumberOfDesks(DEFAULT_DISPLAY)).isEqualTo(currentDeskCount + 1) } + @Test + @EnableFlags( + Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY, + Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER, + ) + fun startLaunchTransition_desktopNotShowing_movesWallpaperToFront() { + val launchingTask = createFreeformTask() + val wct = WindowContainerTransaction() + wct.reorder(launchingTask.token, /* onTop= */ true) + whenever( + desktopMixedTransitionHandler.startLaunchTransition( + eq(TRANSIT_OPEN), + any(), + anyOrNull(), + anyOrNull(), + anyOrNull(), + ) + ) + .thenReturn(Binder()) + + controller.startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null) + + val latestWct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) + val launchingTaskReorderIndex = latestWct.indexOfReorder(launchingTask, toTop = true) + val wallpaperReorderIndex = latestWct.indexOfReorder(wallpaperToken, toTop = true) + assertThat(launchingTaskReorderIndex).isNotEqualTo(-1) + assertThat(wallpaperReorderIndex).isNotEqualTo(-1) + assertThat(launchingTaskReorderIndex).isGreaterThan(wallpaperReorderIndex) + } + + @Test + @EnableFlags( + Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY, + Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER, + ) + fun startLaunchTransition_desktopShowing_doesNotReorderWallpaper() { + val wct = WindowContainerTransaction() + whenever( + desktopMixedTransitionHandler.startLaunchTransition( + eq(TRANSIT_OPEN), + any(), + anyOrNull(), + anyOrNull(), + anyOrNull(), + ) + ) + .thenReturn(Binder()) + + setUpFreeformTask() + controller.startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null) + + val latestWct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) + assertNull(latestWct.hierarchyOps.find { op -> op.container == wallpaperToken.asBinder() }) + } + private class RunOnStartTransitionCallback : ((IBinder) -> Unit) { var invocations = 0 private set @@ -6626,13 +6680,20 @@ private fun WindowContainerTransaction.assertWithoutHop( } private fun WindowContainerTransaction.indexOfReorder( - task: RunningTaskInfo, + token: WindowContainerToken, toTop: Boolean? = null, ): Int { - val hop = hierarchyOps.singleOrNull(ReorderPredicate(task.token, toTop)) ?: return -1 + val hop = hierarchyOps.singleOrNull(ReorderPredicate(token, toTop)) ?: return -1 return hierarchyOps.indexOf(hop) } +private fun WindowContainerTransaction.indexOfReorder( + task: RunningTaskInfo, + toTop: Boolean? = null, +): Int { + return indexOfReorder(task.token, toTop) +} + private class ReorderPredicate(val token: WindowContainerToken, val toTop: Boolean? = null) : ((WindowContainerTransaction.HierarchyOp) -> Boolean) { override fun invoke(hop: WindowContainerTransaction.HierarchyOp): Boolean = @@ -6750,6 +6811,17 @@ private fun WindowContainerTransaction.assertPendingIntentAt(index: Int, intent: assertThat(op.pendingIntent?.intent?.categories).isEqualTo(intent.categories) } +private fun WindowContainerTransaction.assertLaunchTask(taskId: Int, windowingMode: Int) { + val keyLaunchWindowingMode = "android.activity.windowingMode" + + assertHop { hop -> + hop.type == HIERARCHY_OP_TYPE_LAUNCH_TASK && + hop.launchOptions?.getInt(LAUNCH_KEY_TASK_ID) == taskId && + hop.launchOptions?.getInt(keyLaunchWindowingMode, WINDOWING_MODE_UNDEFINED) == + windowingMode + } +} + private fun WindowContainerTransaction.assertLaunchTaskAt( index: Int, taskId: Int, |