Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +32 −4 Original line number Diff line number Diff line Loading @@ -2646,7 +2646,8 @@ class DesktopTasksController( isIncompatibleTask(triggerTask) -> handleIncompatibleTaskLaunch(triggerTask, transition) // Check if fullscreen task should be updated triggerTask.isFullscreen -> handleFullscreenTaskLaunch(triggerTask, transition) triggerTask.isFullscreen -> handleFullscreenTaskLaunch(triggerTask, transition, request.type) // Check if freeform task should be updated triggerTask.isFreeform -> handleFreeformTaskLaunch(triggerTask, transition) else -> { Loading Loading @@ -2685,7 +2686,7 @@ class DesktopTasksController( triggerTask.isFullscreen -> { // Trigger fullscreen task will enter desktop, so any existing immersive task // should exit. shouldFullscreenTaskLaunchSwitchToDesktop(triggerTask) shouldFullscreenTaskLaunchSwitchToDesktop(triggerTask, info.type) } triggerTask.isFreeform -> { // Trigger freeform task will enter desktop, so any existing immersive task should Loading Loading @@ -2745,6 +2746,22 @@ class DesktopTasksController( TransitionUtil.isOpeningType(request.type) && taskRepository.isActiveTask(triggerTask.taskId)) /** Returns whether a visible fullscreen task is being relaunched on the same display or not. */ private fun isFullscreenRelaunch( triggerTask: RunningTaskInfo, @WindowManager.TransitionType requestType: Int, ): Boolean { // Do not treat fullscreen-in-desktop as fullscreen. if (taskRepository.isActiveTask(triggerTask.taskId)) return false val existingTask = shellTaskOrganizer.getRunningTaskInfo(triggerTask.taskId) ?: return false return triggerTask.isFullscreen && TransitionUtil.isOpeningType(requestType) && existingTask.isFullscreen && existingTask.isVisible && existingTask.displayId == triggerTask.displayId } private fun isIncompatibleTask(task: RunningTaskInfo) = desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(task) Loading Loading @@ -3086,9 +3103,10 @@ class DesktopTasksController( private fun handleFullscreenTaskLaunch( task: RunningTaskInfo, transition: IBinder, @WindowManager.TransitionType requestType: Int, ): WindowContainerTransaction? { logV("handleFullscreenTaskLaunch") if (shouldFullscreenTaskLaunchSwitchToDesktop(task)) { if (shouldFullscreenTaskLaunchSwitchToDesktop(task, requestType)) { logD("Switch fullscreen task to freeform on transition: taskId=%d", task.taskId) return WindowContainerTransaction().also { wct -> val deskId = getOrCreateDefaultDeskId(task.displayId) ?: return@also Loading Loading @@ -3173,7 +3191,17 @@ class DesktopTasksController( private fun shouldFreeformTaskLaunchSwitchToFullscreen(task: RunningTaskInfo): Boolean = !isAnyDeskActive(task.displayId) private fun shouldFullscreenTaskLaunchSwitchToDesktop(task: RunningTaskInfo): Boolean { private fun shouldFullscreenTaskLaunchSwitchToDesktop( task: RunningTaskInfo, @WindowManager.TransitionType requestType: Int, ): Boolean { if ( DesktopExperienceFlags.ENABLE_DESKTOP_FIRST_FULLSCREEN_REFOCUS_BUGFIX.isTrue && isFullscreenRelaunch(task, requestType) ) { logV("shouldFullscreenTaskLaunchSwitchToDesktop: no switch as fullscreen relaunch") return false } val isAnyDeskActive = isAnyDeskActive(task.displayId) val forceEnterDesktop = forceEnterDesktop(task.displayId) logV( Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +21 −8 Original line number Diff line number Diff line Loading @@ -1344,7 +1344,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Create new active desk and launch new task. taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 2) taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 2) val newDeskTask = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) val newDeskTask = createFullscreenTask(displayId = DEFAULT_DISPLAY) val wct = controller.handleRequest(Binder(), createTransition(newDeskTask)) // New task should be cascaded independently of tasks in other desks. Loading Loading @@ -5689,7 +5689,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() markTaskVisible(freeformTask) val task = setUpFullscreenTask().apply { createFullscreenTask().apply { isActivityStackTransparent = true isTopActivityNoDisplay = true numActivities = 1 Loading @@ -5711,7 +5711,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() markTaskVisible(freeformTask) val task = setUpFullscreenTask().apply { createFullscreenTask().apply { isActivityStackTransparent = true isTopActivityNoDisplay = true numActivities = 1 Loading Loading @@ -5835,7 +5835,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val topTransparentTask = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) taskRepository.setTopTransparentFullscreenTaskData(DEFAULT_DISPLAY, topTransparentTask) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) val task = createFullscreenTask(displayId = DEFAULT_DISPLAY) val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) Loading Loading @@ -5931,7 +5931,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() context.resources.getString(com.android.internal.R.string.config_systemUi) val baseComponent = ComponentName(systemUIPackageName, /* cls= */ "") val task = setUpFullscreenTask().apply { createFullscreenTask().apply { baseActivity = baseComponent isTopActivityNoDisplay = true } Loading @@ -5956,7 +5956,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() context.resources.getString(com.android.internal.R.string.config_systemUi) val baseComponent = ComponentName(systemUIPackageName, /* cls= */ "") val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY).apply { createFullscreenTask(displayId = DEFAULT_DISPLAY).apply { baseActivity = baseComponent isTopActivityNoDisplay = true } Loading Loading @@ -6719,6 +6719,16 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertNull(result, "Should not handle request") } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_FIRST_FULLSCREEN_REFOCUS_BUGFIX) fun handleRequest_fullscreenTaskRelaunch_returnNull() { val task = setUpFullscreenTask() val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_OPEN)) assertNull(result, "Should not handle request") } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY) fun moveFocusedTaskToDesktop_noDisplayActivity_doesNothing() { Loading Loading @@ -9546,7 +9556,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test fun handleRequest_fullscreenLaunchToDesktop_attemptsImmersiveExit() { setUpFreeformTask() val task = setUpFullscreenTask() val task = createFullscreenTask() val binder = Binder() controller.handleRequest(binder, createTransition(task)) Loading Loading @@ -9674,7 +9684,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() fun shouldPlayDesktopAnimation_fullscreenEntersDesktop_plays() { // At least one freeform task to be in a desktop. val existingTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY) val triggerTask = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) val triggerTask = createFullscreenTask(displayId = DEFAULT_DISPLAY) assertThat(controller.isAnyDeskActive(triggerTask.displayId)).isTrue() taskRepository.setTaskInFullImmersiveState( displayId = existingTask.displayId, Loading Loading @@ -10509,6 +10519,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() enableUserFullscreenOverride: Boolean = false, enableSystemFullscreenOverride: Boolean = false, aspectRatioOverrideApplied: Boolean = false, visible: Boolean = true, ): RunningTaskInfo { val task = createFullscreenTask(displayId) val activityInfo = ActivityInfo() Loading Loading @@ -10557,6 +10568,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() appCompatTaskInfo.topActivityAppBounds.set(0, 0, 1600, 1200) } } isVisible = visible } whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) runningTasks.add(task) Loading Loading @@ -10710,6 +10722,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() FlagsParameterization.allCombinationsOf( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_DESKTOP_FIRST_BASED_DEFAULT_TO_DESKTOP_BUGFIX, Flags.FLAG_ENABLE_DESKTOP_FIRST_FULLSCREEN_REFOCUS_BUGFIX, ) } } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +32 −4 Original line number Diff line number Diff line Loading @@ -2646,7 +2646,8 @@ class DesktopTasksController( isIncompatibleTask(triggerTask) -> handleIncompatibleTaskLaunch(triggerTask, transition) // Check if fullscreen task should be updated triggerTask.isFullscreen -> handleFullscreenTaskLaunch(triggerTask, transition) triggerTask.isFullscreen -> handleFullscreenTaskLaunch(triggerTask, transition, request.type) // Check if freeform task should be updated triggerTask.isFreeform -> handleFreeformTaskLaunch(triggerTask, transition) else -> { Loading Loading @@ -2685,7 +2686,7 @@ class DesktopTasksController( triggerTask.isFullscreen -> { // Trigger fullscreen task will enter desktop, so any existing immersive task // should exit. shouldFullscreenTaskLaunchSwitchToDesktop(triggerTask) shouldFullscreenTaskLaunchSwitchToDesktop(triggerTask, info.type) } triggerTask.isFreeform -> { // Trigger freeform task will enter desktop, so any existing immersive task should Loading Loading @@ -2745,6 +2746,22 @@ class DesktopTasksController( TransitionUtil.isOpeningType(request.type) && taskRepository.isActiveTask(triggerTask.taskId)) /** Returns whether a visible fullscreen task is being relaunched on the same display or not. */ private fun isFullscreenRelaunch( triggerTask: RunningTaskInfo, @WindowManager.TransitionType requestType: Int, ): Boolean { // Do not treat fullscreen-in-desktop as fullscreen. if (taskRepository.isActiveTask(triggerTask.taskId)) return false val existingTask = shellTaskOrganizer.getRunningTaskInfo(triggerTask.taskId) ?: return false return triggerTask.isFullscreen && TransitionUtil.isOpeningType(requestType) && existingTask.isFullscreen && existingTask.isVisible && existingTask.displayId == triggerTask.displayId } private fun isIncompatibleTask(task: RunningTaskInfo) = desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(task) Loading Loading @@ -3086,9 +3103,10 @@ class DesktopTasksController( private fun handleFullscreenTaskLaunch( task: RunningTaskInfo, transition: IBinder, @WindowManager.TransitionType requestType: Int, ): WindowContainerTransaction? { logV("handleFullscreenTaskLaunch") if (shouldFullscreenTaskLaunchSwitchToDesktop(task)) { if (shouldFullscreenTaskLaunchSwitchToDesktop(task, requestType)) { logD("Switch fullscreen task to freeform on transition: taskId=%d", task.taskId) return WindowContainerTransaction().also { wct -> val deskId = getOrCreateDefaultDeskId(task.displayId) ?: return@also Loading Loading @@ -3173,7 +3191,17 @@ class DesktopTasksController( private fun shouldFreeformTaskLaunchSwitchToFullscreen(task: RunningTaskInfo): Boolean = !isAnyDeskActive(task.displayId) private fun shouldFullscreenTaskLaunchSwitchToDesktop(task: RunningTaskInfo): Boolean { private fun shouldFullscreenTaskLaunchSwitchToDesktop( task: RunningTaskInfo, @WindowManager.TransitionType requestType: Int, ): Boolean { if ( DesktopExperienceFlags.ENABLE_DESKTOP_FIRST_FULLSCREEN_REFOCUS_BUGFIX.isTrue && isFullscreenRelaunch(task, requestType) ) { logV("shouldFullscreenTaskLaunchSwitchToDesktop: no switch as fullscreen relaunch") return false } val isAnyDeskActive = isAnyDeskActive(task.displayId) val forceEnterDesktop = forceEnterDesktop(task.displayId) logV( Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +21 −8 Original line number Diff line number Diff line Loading @@ -1344,7 +1344,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Create new active desk and launch new task. taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 2) taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 2) val newDeskTask = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) val newDeskTask = createFullscreenTask(displayId = DEFAULT_DISPLAY) val wct = controller.handleRequest(Binder(), createTransition(newDeskTask)) // New task should be cascaded independently of tasks in other desks. Loading Loading @@ -5689,7 +5689,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() markTaskVisible(freeformTask) val task = setUpFullscreenTask().apply { createFullscreenTask().apply { isActivityStackTransparent = true isTopActivityNoDisplay = true numActivities = 1 Loading @@ -5711,7 +5711,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() markTaskVisible(freeformTask) val task = setUpFullscreenTask().apply { createFullscreenTask().apply { isActivityStackTransparent = true isTopActivityNoDisplay = true numActivities = 1 Loading Loading @@ -5835,7 +5835,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val topTransparentTask = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) taskRepository.setTopTransparentFullscreenTaskData(DEFAULT_DISPLAY, topTransparentTask) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) val task = createFullscreenTask(displayId = DEFAULT_DISPLAY) val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) Loading Loading @@ -5931,7 +5931,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() context.resources.getString(com.android.internal.R.string.config_systemUi) val baseComponent = ComponentName(systemUIPackageName, /* cls= */ "") val task = setUpFullscreenTask().apply { createFullscreenTask().apply { baseActivity = baseComponent isTopActivityNoDisplay = true } Loading @@ -5956,7 +5956,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() context.resources.getString(com.android.internal.R.string.config_systemUi) val baseComponent = ComponentName(systemUIPackageName, /* cls= */ "") val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY).apply { createFullscreenTask(displayId = DEFAULT_DISPLAY).apply { baseActivity = baseComponent isTopActivityNoDisplay = true } Loading Loading @@ -6719,6 +6719,16 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertNull(result, "Should not handle request") } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_FIRST_FULLSCREEN_REFOCUS_BUGFIX) fun handleRequest_fullscreenTaskRelaunch_returnNull() { val task = setUpFullscreenTask() val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_OPEN)) assertNull(result, "Should not handle request") } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY) fun moveFocusedTaskToDesktop_noDisplayActivity_doesNothing() { Loading Loading @@ -9546,7 +9556,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test fun handleRequest_fullscreenLaunchToDesktop_attemptsImmersiveExit() { setUpFreeformTask() val task = setUpFullscreenTask() val task = createFullscreenTask() val binder = Binder() controller.handleRequest(binder, createTransition(task)) Loading Loading @@ -9674,7 +9684,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() fun shouldPlayDesktopAnimation_fullscreenEntersDesktop_plays() { // At least one freeform task to be in a desktop. val existingTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY) val triggerTask = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) val triggerTask = createFullscreenTask(displayId = DEFAULT_DISPLAY) assertThat(controller.isAnyDeskActive(triggerTask.displayId)).isTrue() taskRepository.setTaskInFullImmersiveState( displayId = existingTask.displayId, Loading Loading @@ -10509,6 +10519,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() enableUserFullscreenOverride: Boolean = false, enableSystemFullscreenOverride: Boolean = false, aspectRatioOverrideApplied: Boolean = false, visible: Boolean = true, ): RunningTaskInfo { val task = createFullscreenTask(displayId) val activityInfo = ActivityInfo() Loading Loading @@ -10557,6 +10568,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() appCompatTaskInfo.topActivityAppBounds.set(0, 0, 1600, 1200) } } isVisible = visible } whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) runningTasks.add(task) Loading Loading @@ -10710,6 +10722,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() FlagsParameterization.allCombinationsOf( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_ENABLE_DESKTOP_FIRST_BASED_DEFAULT_TO_DESKTOP_BUGFIX, Flags.FLAG_ENABLE_DESKTOP_FIRST_FULLSCREEN_REFOCUS_BUGFIX, ) } } Loading