diff options
| author | 2024-10-21 01:52:32 +0000 | |
|---|---|---|
| committer | 2024-10-22 03:43:54 +0000 | |
| commit | 4cd3fa430febd8c5fd4c4066bd8bb437db17eb03 (patch) | |
| tree | e065501831290741a7c4689c88fd2c6b72acf24d | |
| parent | 883b408292ffd42863c5abc05b23f4af68e3d753 (diff) | |
Exclude opening/move-to-front task from exiting immersive
It's possible for a non-top task to be moved to front and enter
immersive at the same time, so exclude it in move-to-front or opening
WCT from exiting immersive mode, since it doesn't make sense to exit
immersive in those cases.
Flag: com.android.window.flags.enable_fully_immersive_in_desktop
Fix: 374772576
Test: open Candy Crush in desktop, enter immersive, open settings from
notification shade, close settings, put candy crash back in immersive
and verify the app header can't be dragged or double clicked.
Change-Id: I9f614065814dcfbb2bae347ba00c10a53cdae71a
4 files changed, 70 insertions, 19 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt index 9d4926b47def..19ffd969cfac 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt @@ -137,14 +137,19 @@ class DesktopFullImmersiveTransitionHandler( * * @param wct that will apply these changes * @param displayId of the display that should exit immersive mode + * @param excludeTaskId of the task to ignore (not exit) if it is the immersive one * @return a function to apply once the transition that will apply these changes is started */ fun exitImmersiveIfApplicable( wct: WindowContainerTransaction, - displayId: Int + displayId: Int, + excludeTaskId: Int? = null, ): ((IBinder) -> Unit)? { if (!Flags.enableFullyImmersiveInDesktop()) return null val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId) ?: return null + if (immersiveTask == excludeTaskId) { + return null + } val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask) ?: return null logV("Appending immersive exit for task: $immersiveTask in display: $displayId") wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo)) 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 1d17cd62c0d2..28e63f3cfb0d 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 @@ -357,8 +357,11 @@ class DesktopTasksController( // TODO(342378842): Instead of using default display, support multiple displays val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( DEFAULT_DISPLAY, wct, taskId) - val runOnTransit = immersiveTransitionHandler - .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY) + val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( + wct = wct, + displayId = DEFAULT_DISPLAY, + excludeTaskId = taskId, + ) wct.startTask( taskId, ActivityOptions.makeBasic().apply { @@ -385,7 +388,11 @@ class DesktopTasksController( } logV("moveRunningTaskToDesktop taskId=%d", task.taskId) exitSplitIfApplicable(wct, task) - val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable(wct, task.displayId) + val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( + wct = wct, + displayId = task.displayId, + excludeTaskId = task.taskId, + ) // Bring other apps to front first val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId) @@ -594,8 +601,11 @@ class DesktopTasksController( logV("moveBackgroundTaskToFront taskId=%s", taskId) val wct = WindowContainerTransaction() // TODO: b/342378842 - Instead of using default display, support multiple displays - val runOnTransit = immersiveTransitionHandler - .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY) + val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( + wct = wct, + displayId = DEFAULT_DISPLAY, + excludeTaskId = taskId, + ) wct.startTask( taskId, ActivityOptions.makeBasic().apply { @@ -618,7 +628,10 @@ class DesktopTasksController( val wct = WindowContainerTransaction() wct.reorder(taskInfo.token, true /* onTop */, true /* includingParents */) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( - wct, taskInfo.displayId) + wct = wct, + displayId = taskInfo.displayId, + excludeTaskId = taskInfo.taskId, + ) val transition = startLaunchTransition(TRANSIT_TO_FRONT, wct, taskInfo.taskId, remoteTransition) runOnTransit?.invoke(transition) @@ -1218,8 +1231,11 @@ class DesktopTasksController( wct.startTask(requestedTaskId, options.toBundle()) val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( callingTask.displayId, wct, requestedTaskId) - val runOnTransit = immersiveTransitionHandler - .exitImmersiveIfApplicable(wct, callingTask.displayId) + val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( + wct = wct, + displayId = callingTask.displayId, + excludeTaskId = requestedTaskId, + ) val transition = transitions.startTransition(TRANSIT_OPEN, wct, null) addPendingMinimizeTransition(transition, taskToMinimize) runOnTransit?.invoke(transition) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt index ef99b000d759..5842dfaef0fe 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt @@ -340,6 +340,31 @@ class DesktopFullImmersiveTransitionHandlerTest : ShellTestCase() { @Test @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) + fun exitImmersiveIfApplicable_byDisplay_withExcludeTask_doesNotExit() { + val task = createFreeformTask() + whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) + val wct = WindowContainerTransaction() + val transition = Binder() + desktopRepository.setTaskInFullImmersiveState( + displayId = DEFAULT_DISPLAY, + taskId = task.taskId, + immersive = true + ) + + immersiveHandler.exitImmersiveIfApplicable( + wct = wct, + displayId = DEFAULT_DISPLAY, + excludeTaskId = task.taskId + )?.invoke(transition) + + assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit -> + exit.transition == transition && exit.displayId == DEFAULT_DISPLAY + && exit.taskId == task.taskId + }).isFalse() + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) fun exitImmersiveIfApplicable_byTask_inImmersive_changesTaskBounds() { val task = createFreeformTask() whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) 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 af51e32b2086..c50d304a4678 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 @@ -3060,12 +3060,13 @@ class DesktopTasksControllerTest : ShellTestCase() { whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull())) .thenReturn(transition) whenever(mockDesktopFullImmersiveTransitionHandler - .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId))).thenReturn(runOnStartTransit) + .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId))) + .thenReturn(runOnStartTransit) runOpenInstance(immersiveTask, freeformTask.taskId) verify(mockDesktopFullImmersiveTransitionHandler) - .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId)) + .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } @@ -3370,12 +3371,13 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler - .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit) + .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit) whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition) controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN) - verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId) + verify(mockDesktopFullImmersiveTransitionHandler) + .exitImmersiveIfApplicable(wct, task.displayId, task.taskId) runOnStartTransit.assertOnlyInvocation(transition) } @@ -3386,12 +3388,13 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler - .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit) + .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit) whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition) controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN) - verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId) + verify(mockDesktopFullImmersiveTransitionHandler) + .exitImmersiveIfApplicable(wct, task.displayId, task.taskId) runOnStartTransit.assertOnlyInvocation(transition) } @@ -3401,13 +3404,14 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler - .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit) + .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))) + .thenReturn(runOnStartTransit) whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) controller.moveTaskToFront(task.taskId, remoteTransition = null) verify(mockDesktopFullImmersiveTransitionHandler) - .exitImmersiveIfApplicable(any(), eq(task.displayId)) + .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } @@ -3417,13 +3421,14 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler - .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit) + .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))) + .thenReturn(runOnStartTransit) whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) controller.moveTaskToFront(task.taskId, remoteTransition = null) verify(mockDesktopFullImmersiveTransitionHandler) - .exitImmersiveIfApplicable(any(), eq(task.displayId)) + .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } |