Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +11 −19 Original line number Diff line number Diff line Loading @@ -1510,28 +1510,20 @@ class DesktopTasksController( /** Open an existing instance of an app. */ fun openInstance(callingTask: RunningTaskInfo, requestedTaskId: Int) { val wct = WindowContainerTransaction() val options = createNewWindowOptions(callingTask) if (options.launchWindowingMode == WINDOWING_MODE_FREEFORM) { wct.startTask(requestedTaskId, options.toBundle()) val taskIdToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( callingTask.displayId, wct, if (callingTask.isFreeform) { val requestedTaskInfo = shellTaskOrganizer.getRunningTaskInfo(requestedTaskId) if (requestedTaskInfo?.isFreeform == true) { // If requested task is an already open freeform task, just move it to front. moveTaskToFront(requestedTaskId) } else { moveBackgroundTaskToDesktop( requestedTaskId, WindowContainerTransaction(), DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON, ) val exitResult = desktopImmersiveController.exitImmersiveIfApplicable( wct = wct, displayId = callingTask.displayId, excludeTaskId = requestedTaskId, reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH, ) val transition = transitions.startTransition(TRANSIT_OPEN, wct, null) taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) } addPendingAppLaunchTransition(transition, requestedTaskId, taskIdToMinimize) exitResult.asExit()?.runOnTransitionStart?.invoke(transition) } } else { val options = createNewWindowOptions(callingTask) val splitPosition = splitScreenController.determineNewInstancePosition(callingTask) splitScreenController.startTask( requestedTaskId, Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +20 −21 Original line number Diff line number Diff line Loading @@ -3305,44 +3305,41 @@ class DesktopTasksControllerTest : ShellTestCase() { setUpLandscapeDisplay() val task = setUpFreeformTask() val taskToRequest = setUpFreeformTask() val wctCaptor = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) runOpenInstance(task, taskToRequest.taskId) verify(transitions).startTransition(anyInt(), wctCaptor.capture(), anyOrNull()) assertThat(ActivityOptions.fromBundle(wctCaptor.value.hierarchyOps[0].launchOptions) .launchWindowingMode).isEqualTo(WINDOWING_MODE_FREEFORM) verify(desktopMixedTransitionHandler).startLaunchTransition(anyInt(), any(), anyInt(), anyOrNull(), anyOrNull()) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_TO_FRONT) assertThat(wct.hierarchyOps).hasSize(1) wct.assertReorderAt(index = 0, taskToRequest) } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES) fun openInstance_fromFreeform_minimizesIfNeeded() { setUpLandscapeDisplay() val homeTask = setUpHomeTask() val freeformTasks = (1..MAX_TASK_LIMIT + 1).map { _ -> setUpFreeformTask() } val oldestTask = freeformTasks.first() val newestTask = freeformTasks.last() val transition = Binder() val wctCaptor = argumentCaptor<WindowContainerTransaction>() whenever(desktopMixedTransitionHandler.startLaunchTransition(anyInt(), wctCaptor.capture(), anyInt(), anyOrNull(), anyOrNull() )) .thenReturn(transition) runOpenInstance(newestTask, freeformTasks[1].taskId) val wct = getLatestWct(type = TRANSIT_OPEN) // Home is moved to front of everything. assertThat( wct.hierarchyOps.any { hop -> hop.container == homeTask.token.asBinder() && hop.toTop } ).isTrue() // And the oldest task isn't moved in front of home, effectively minimizing it. assertThat( wct.hierarchyOps.none { hop -> hop.container == oldestTask.token.asBinder() && hop.toTop } ).isTrue() val wct = wctCaptor.firstValue assertThat(wct.hierarchyOps.size).isEqualTo(2) // move-to-front + minimize wct.assertReorderAt(0, freeformTasks[1], toTop = true) wct.assertReorderAt(1, oldestTask, toTop = false) } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES) fun openInstance_fromFreeform_exitsImmersiveIfNeeded() { setUpLandscapeDisplay() val homeTask = setUpHomeTask() val freeformTask = setUpFreeformTask() val immersiveTask = setUpFreeformTask() taskRepository.setTaskInFullImmersiveState( Loading @@ -3352,11 +3349,13 @@ class DesktopTasksControllerTest : ShellTestCase() { ) val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull())) whenever(desktopMixedTransitionHandler.startLaunchTransition(anyInt(), any(), anyInt(), anyOrNull(), anyOrNull() )) .thenReturn(transition) whenever(mMockDesktopImmersiveController .exitImmersiveIfApplicable( any(), eq(immersiveTask.displayId), eq(freeformTask.taskId), any())) any(), eq(DEFAULT_DISPLAY), eq(freeformTask.taskId), any())) .thenReturn( ExitResult.Exit( exitingTask = immersiveTask.taskId, Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +11 −19 Original line number Diff line number Diff line Loading @@ -1510,28 +1510,20 @@ class DesktopTasksController( /** Open an existing instance of an app. */ fun openInstance(callingTask: RunningTaskInfo, requestedTaskId: Int) { val wct = WindowContainerTransaction() val options = createNewWindowOptions(callingTask) if (options.launchWindowingMode == WINDOWING_MODE_FREEFORM) { wct.startTask(requestedTaskId, options.toBundle()) val taskIdToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( callingTask.displayId, wct, if (callingTask.isFreeform) { val requestedTaskInfo = shellTaskOrganizer.getRunningTaskInfo(requestedTaskId) if (requestedTaskInfo?.isFreeform == true) { // If requested task is an already open freeform task, just move it to front. moveTaskToFront(requestedTaskId) } else { moveBackgroundTaskToDesktop( requestedTaskId, WindowContainerTransaction(), DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON, ) val exitResult = desktopImmersiveController.exitImmersiveIfApplicable( wct = wct, displayId = callingTask.displayId, excludeTaskId = requestedTaskId, reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH, ) val transition = transitions.startTransition(TRANSIT_OPEN, wct, null) taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) } addPendingAppLaunchTransition(transition, requestedTaskId, taskIdToMinimize) exitResult.asExit()?.runOnTransitionStart?.invoke(transition) } } else { val options = createNewWindowOptions(callingTask) val splitPosition = splitScreenController.determineNewInstancePosition(callingTask) splitScreenController.startTask( requestedTaskId, Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +20 −21 Original line number Diff line number Diff line Loading @@ -3305,44 +3305,41 @@ class DesktopTasksControllerTest : ShellTestCase() { setUpLandscapeDisplay() val task = setUpFreeformTask() val taskToRequest = setUpFreeformTask() val wctCaptor = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) runOpenInstance(task, taskToRequest.taskId) verify(transitions).startTransition(anyInt(), wctCaptor.capture(), anyOrNull()) assertThat(ActivityOptions.fromBundle(wctCaptor.value.hierarchyOps[0].launchOptions) .launchWindowingMode).isEqualTo(WINDOWING_MODE_FREEFORM) verify(desktopMixedTransitionHandler).startLaunchTransition(anyInt(), any(), anyInt(), anyOrNull(), anyOrNull()) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_TO_FRONT) assertThat(wct.hierarchyOps).hasSize(1) wct.assertReorderAt(index = 0, taskToRequest) } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES) fun openInstance_fromFreeform_minimizesIfNeeded() { setUpLandscapeDisplay() val homeTask = setUpHomeTask() val freeformTasks = (1..MAX_TASK_LIMIT + 1).map { _ -> setUpFreeformTask() } val oldestTask = freeformTasks.first() val newestTask = freeformTasks.last() val transition = Binder() val wctCaptor = argumentCaptor<WindowContainerTransaction>() whenever(desktopMixedTransitionHandler.startLaunchTransition(anyInt(), wctCaptor.capture(), anyInt(), anyOrNull(), anyOrNull() )) .thenReturn(transition) runOpenInstance(newestTask, freeformTasks[1].taskId) val wct = getLatestWct(type = TRANSIT_OPEN) // Home is moved to front of everything. assertThat( wct.hierarchyOps.any { hop -> hop.container == homeTask.token.asBinder() && hop.toTop } ).isTrue() // And the oldest task isn't moved in front of home, effectively minimizing it. assertThat( wct.hierarchyOps.none { hop -> hop.container == oldestTask.token.asBinder() && hop.toTop } ).isTrue() val wct = wctCaptor.firstValue assertThat(wct.hierarchyOps.size).isEqualTo(2) // move-to-front + minimize wct.assertReorderAt(0, freeformTasks[1], toTop = true) wct.assertReorderAt(1, oldestTask, toTop = false) } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES) fun openInstance_fromFreeform_exitsImmersiveIfNeeded() { setUpLandscapeDisplay() val homeTask = setUpHomeTask() val freeformTask = setUpFreeformTask() val immersiveTask = setUpFreeformTask() taskRepository.setTaskInFullImmersiveState( Loading @@ -3352,11 +3349,13 @@ class DesktopTasksControllerTest : ShellTestCase() { ) val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull())) whenever(desktopMixedTransitionHandler.startLaunchTransition(anyInt(), any(), anyInt(), anyOrNull(), anyOrNull() )) .thenReturn(transition) whenever(mMockDesktopImmersiveController .exitImmersiveIfApplicable( any(), eq(immersiveTask.displayId), eq(freeformTask.taskId), any())) any(), eq(DEFAULT_DISPLAY), eq(freeformTask.taskId), any())) .thenReturn( ExitResult.Exit( exitingTask = immersiveTask.taskId, Loading