Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +42 −11 Original line number Diff line number Diff line Loading @@ -797,13 +797,34 @@ class DesktopTasksController( return runOnTransitStart } private fun getDisplayIdForTaskOrDefault(task: TaskInfo): Int { return when { task.displayId != INVALID_DISPLAY -> task.displayId focusTransitionObserver.globallyFocusedDisplayId != INVALID_DISPLAY -> focusTransitionObserver.globallyFocusedDisplayId else -> DEFAULT_DISPLAY private fun getDisplayIdForTaskOrDefault(task: TaskInfo?): Int { // First, try to get the display already associated with the task. if ( task != null && task.displayId != INVALID_DISPLAY && desktopState.isDesktopModeSupportedOnDisplay(displayId = task.displayId) ) { return task.displayId } // Second, try to use the globally focused display. val globallyFocusedDisplayId = focusTransitionObserver.globallyFocusedDisplayId if ( globallyFocusedDisplayId != INVALID_DISPLAY && desktopState.isDesktopModeSupportedOnDisplay(displayId = globallyFocusedDisplayId) ) { return globallyFocusedDisplayId } // Fallback to any display that supports desktop. val supportedDisplayId = rootTaskDisplayAreaOrganizer.displayIds.firstOrNull { displayId -> desktopState.isDesktopModeSupportedOnDisplay(displayId) } if (supportedDisplayId != null) { return supportedDisplayId } // Use the default display as the last option even if it does not support desktop. Callers // should handle this case. return DEFAULT_DISPLAY } /** Moves task to desktop mode if task is running, else launches it in desktop mode. */ Loading Loading @@ -1466,13 +1487,23 @@ class DesktopTasksController( remoteTransition: RemoteTransition?, unminimizeReason: UnminimizeReason, ) { logV("moveBackgroundTaskToFront taskId=%s", taskId) logV("moveBackgroundTaskToFront taskId=%s unminimizeReason=%s", taskId, unminimizeReason) val wct = WindowContainerTransaction() val deskIdForTask = taskRepository.getDeskIdForTask(taskId) val deskId = taskRepository.getDeskIdForTask(taskId) ?: getOrCreateDefaultDeskId(DEFAULT_DISPLAY) ?: return if (deskIdForTask != null) { deskIdForTask } else { val task = recentTasksController?.findTaskInBackground(taskId) val displayId = getDisplayIdForTaskOrDefault(task) logV( "background taskId=%s did not have desk associated, " + "using default desk of displayId=%d", taskId, displayId, ) getOrCreateDefaultDeskId(displayId) ?: return } val displayId = if (ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY.isTrue) taskRepository.getDisplayForDesk(deskId) Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +110 −0 Original line number Diff line number Diff line Loading @@ -417,6 +417,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(userProfileContexts[anyInt()]).thenReturn(context) whenever(userProfileContexts.getOrCreate(anyInt())).thenReturn(context) whenever(freeformTaskTransitionStarter.startPipTransition(any())).thenReturn(Binder()) whenever(rootTaskDisplayAreaOrganizer.displayIds).thenReturn(intArrayOf(DEFAULT_DISPLAY)) controller = createController() controller.setSplitScreenController(splitScreenController) Loading Loading @@ -3195,6 +3196,115 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() wct.assertLaunchTaskOnDisplay(SECOND_DISPLAY) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY, ) fun moveTaskToFront_backgroundTask_notInDesk_launchesInAssociatedDisplay() { val deskId = 2 val taskId = 1 val task = createRecentTaskInfo(taskId, displayId = SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = deskId) whenever(shellTaskOrganizer.getRunningTaskInfo(taskId)).thenReturn(null) whenever(recentTasksController.findTaskInBackground(taskId)).thenReturn(task) whenever( desktopMixedTransitionHandler.startLaunchTransition( eq(TRANSIT_OPEN), any(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), ) ) .thenReturn(Binder()) desktopState.overrideDesktopModeSupportPerDisplay[SECOND_DISPLAY] = true controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) wct.assertLaunchTaskOnDisplay(SECOND_DISPLAY) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY, ) fun moveTaskToFront_backgroundTask_notInDesk_unsupportedAssociatedDisplay_launchesInFocused() { val focusedDisplayId = 10 val deskId = 2 val taskId = 1 val task = createRecentTaskInfo(taskId, displayId = SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = deskId) taskRepository.addDesk(displayId = focusedDisplayId, deskId = focusedDisplayId) whenever(shellTaskOrganizer.getRunningTaskInfo(taskId)).thenReturn(null) whenever(recentTasksController.findTaskInBackground(taskId)).thenReturn(task) whenever(focusTransitionObserver.globallyFocusedDisplayId).thenReturn(focusedDisplayId) whenever( desktopMixedTransitionHandler.startLaunchTransition( eq(TRANSIT_OPEN), any(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), ) ) .thenReturn(Binder()) desktopState.overrideDesktopModeSupportPerDisplay[SECOND_DISPLAY] = false desktopState.overrideDesktopModeSupportPerDisplay[focusedDisplayId] = true controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) wct.assertLaunchTaskOnDisplay(focusedDisplayId) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY, ) fun moveTaskToFront_backgroundTask_notInDesk_unsupportedAssociatedAndFocusedDisplay_launchesInSupported() { val supportedDisplayId = 11 val focusedDisplayId = 10 val deskId = 2 val taskId = 1 val task = createRecentTaskInfo(taskId, displayId = SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = deskId) taskRepository.addDesk(displayId = focusedDisplayId, deskId = focusedDisplayId) taskRepository.addDesk(displayId = supportedDisplayId, deskId = supportedDisplayId) whenever(shellTaskOrganizer.getRunningTaskInfo(taskId)).thenReturn(null) whenever(recentTasksController.findTaskInBackground(taskId)).thenReturn(task) whenever(focusTransitionObserver.globallyFocusedDisplayId).thenReturn(focusedDisplayId) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(SECOND_DISPLAY, focusedDisplayId, supportedDisplayId)) whenever( desktopMixedTransitionHandler.startLaunchTransition( eq(TRANSIT_OPEN), any(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), ) ) .thenReturn(Binder()) desktopState.overrideDesktopModeSupportPerDisplay[SECOND_DISPLAY] = false desktopState.overrideDesktopModeSupportPerDisplay[focusedDisplayId] = false desktopState.overrideDesktopModeSupportPerDisplay[supportedDisplayId] = true controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) wct.assertLaunchTaskOnDisplay(supportedDisplayId) } @Test @DisableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +42 −11 Original line number Diff line number Diff line Loading @@ -797,13 +797,34 @@ class DesktopTasksController( return runOnTransitStart } private fun getDisplayIdForTaskOrDefault(task: TaskInfo): Int { return when { task.displayId != INVALID_DISPLAY -> task.displayId focusTransitionObserver.globallyFocusedDisplayId != INVALID_DISPLAY -> focusTransitionObserver.globallyFocusedDisplayId else -> DEFAULT_DISPLAY private fun getDisplayIdForTaskOrDefault(task: TaskInfo?): Int { // First, try to get the display already associated with the task. if ( task != null && task.displayId != INVALID_DISPLAY && desktopState.isDesktopModeSupportedOnDisplay(displayId = task.displayId) ) { return task.displayId } // Second, try to use the globally focused display. val globallyFocusedDisplayId = focusTransitionObserver.globallyFocusedDisplayId if ( globallyFocusedDisplayId != INVALID_DISPLAY && desktopState.isDesktopModeSupportedOnDisplay(displayId = globallyFocusedDisplayId) ) { return globallyFocusedDisplayId } // Fallback to any display that supports desktop. val supportedDisplayId = rootTaskDisplayAreaOrganizer.displayIds.firstOrNull { displayId -> desktopState.isDesktopModeSupportedOnDisplay(displayId) } if (supportedDisplayId != null) { return supportedDisplayId } // Use the default display as the last option even if it does not support desktop. Callers // should handle this case. return DEFAULT_DISPLAY } /** Moves task to desktop mode if task is running, else launches it in desktop mode. */ Loading Loading @@ -1466,13 +1487,23 @@ class DesktopTasksController( remoteTransition: RemoteTransition?, unminimizeReason: UnminimizeReason, ) { logV("moveBackgroundTaskToFront taskId=%s", taskId) logV("moveBackgroundTaskToFront taskId=%s unminimizeReason=%s", taskId, unminimizeReason) val wct = WindowContainerTransaction() val deskIdForTask = taskRepository.getDeskIdForTask(taskId) val deskId = taskRepository.getDeskIdForTask(taskId) ?: getOrCreateDefaultDeskId(DEFAULT_DISPLAY) ?: return if (deskIdForTask != null) { deskIdForTask } else { val task = recentTasksController?.findTaskInBackground(taskId) val displayId = getDisplayIdForTaskOrDefault(task) logV( "background taskId=%s did not have desk associated, " + "using default desk of displayId=%d", taskId, displayId, ) getOrCreateDefaultDeskId(displayId) ?: return } val displayId = if (ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY.isTrue) taskRepository.getDisplayForDesk(deskId) Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +110 −0 Original line number Diff line number Diff line Loading @@ -417,6 +417,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(userProfileContexts[anyInt()]).thenReturn(context) whenever(userProfileContexts.getOrCreate(anyInt())).thenReturn(context) whenever(freeformTaskTransitionStarter.startPipTransition(any())).thenReturn(Binder()) whenever(rootTaskDisplayAreaOrganizer.displayIds).thenReturn(intArrayOf(DEFAULT_DISPLAY)) controller = createController() controller.setSplitScreenController(splitScreenController) Loading Loading @@ -3195,6 +3196,115 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() wct.assertLaunchTaskOnDisplay(SECOND_DISPLAY) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY, ) fun moveTaskToFront_backgroundTask_notInDesk_launchesInAssociatedDisplay() { val deskId = 2 val taskId = 1 val task = createRecentTaskInfo(taskId, displayId = SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = deskId) whenever(shellTaskOrganizer.getRunningTaskInfo(taskId)).thenReturn(null) whenever(recentTasksController.findTaskInBackground(taskId)).thenReturn(task) whenever( desktopMixedTransitionHandler.startLaunchTransition( eq(TRANSIT_OPEN), any(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), ) ) .thenReturn(Binder()) desktopState.overrideDesktopModeSupportPerDisplay[SECOND_DISPLAY] = true controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) wct.assertLaunchTaskOnDisplay(SECOND_DISPLAY) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY, ) fun moveTaskToFront_backgroundTask_notInDesk_unsupportedAssociatedDisplay_launchesInFocused() { val focusedDisplayId = 10 val deskId = 2 val taskId = 1 val task = createRecentTaskInfo(taskId, displayId = SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = deskId) taskRepository.addDesk(displayId = focusedDisplayId, deskId = focusedDisplayId) whenever(shellTaskOrganizer.getRunningTaskInfo(taskId)).thenReturn(null) whenever(recentTasksController.findTaskInBackground(taskId)).thenReturn(task) whenever(focusTransitionObserver.globallyFocusedDisplayId).thenReturn(focusedDisplayId) whenever( desktopMixedTransitionHandler.startLaunchTransition( eq(TRANSIT_OPEN), any(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), ) ) .thenReturn(Binder()) desktopState.overrideDesktopModeSupportPerDisplay[SECOND_DISPLAY] = false desktopState.overrideDesktopModeSupportPerDisplay[focusedDisplayId] = true controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) wct.assertLaunchTaskOnDisplay(focusedDisplayId) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_BUG_FIXES_FOR_SECONDARY_DISPLAY, ) fun moveTaskToFront_backgroundTask_notInDesk_unsupportedAssociatedAndFocusedDisplay_launchesInSupported() { val supportedDisplayId = 11 val focusedDisplayId = 10 val deskId = 2 val taskId = 1 val task = createRecentTaskInfo(taskId, displayId = SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = deskId) taskRepository.addDesk(displayId = focusedDisplayId, deskId = focusedDisplayId) taskRepository.addDesk(displayId = supportedDisplayId, deskId = supportedDisplayId) whenever(shellTaskOrganizer.getRunningTaskInfo(taskId)).thenReturn(null) whenever(recentTasksController.findTaskInBackground(taskId)).thenReturn(task) whenever(focusTransitionObserver.globallyFocusedDisplayId).thenReturn(focusedDisplayId) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(SECOND_DISPLAY, focusedDisplayId, supportedDisplayId)) whenever( desktopMixedTransitionHandler.startLaunchTransition( eq(TRANSIT_OPEN), any(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), ) ) .thenReturn(Binder()) desktopState.overrideDesktopModeSupportPerDisplay[SECOND_DISPLAY] = false desktopState.overrideDesktopModeSupportPerDisplay[focusedDisplayId] = false desktopState.overrideDesktopModeSupportPerDisplay[supportedDisplayId] = true controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN) val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) wct.assertLaunchTaskOnDisplay(supportedDisplayId) } @Test @DisableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Loading