Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +35 −28 Original line number Original line Diff line number Diff line Loading @@ -2043,6 +2043,11 @@ class DesktopTasksController( return false return false } } private fun taskDisplaySupportDesktopMode(triggerTask: RunningTaskInfo) = displayController.getDisplay(triggerTask.displayId)?.let { display -> DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display) } ?: false override fun handleRequest( override fun handleRequest( transition: IBinder, transition: IBinder, request: TransitionRequestInfo, request: TransitionRequestInfo, Loading @@ -2051,13 +2056,22 @@ class DesktopTasksController( // Check if we should skip handling this transition // Check if we should skip handling this transition var reason = "" var reason = "" val triggerTask = request.triggerTask val triggerTask = request.triggerTask // Skipping early if the trigger task is null if (triggerTask == null) { logV("skipping handleRequest reason=triggerTask is null", reason) return null } val recentsAnimationRunning = val recentsAnimationRunning = RecentsTransitionStateListener.isAnimating(recentsTransitionState) RecentsTransitionStateListener.isAnimating(recentsTransitionState) var shouldHandleMidRecentsFreeformLaunch = val shouldHandleMidRecentsFreeformLaunch = recentsAnimationRunning && isFreeformRelaunch(triggerTask, request) recentsAnimationRunning && isFreeformRelaunch(triggerTask, request) val isDragAndDropFullscreenTransition = taskContainsDragAndDropCookie(triggerTask) val isDragAndDropFullscreenTransition = taskContainsDragAndDropCookie(triggerTask) val shouldHandleRequest = val shouldHandleRequest = when { when { !taskDisplaySupportDesktopMode(triggerTask) -> { reason = "triggerTask's display doesn't support desktop mode" false } // Handle freeform relaunch during recents animation // Handle freeform relaunch during recents animation shouldHandleMidRecentsFreeformLaunch -> true shouldHandleMidRecentsFreeformLaunch -> true recentsAnimationRunning -> { recentsAnimationRunning -> { Loading @@ -2078,11 +2092,6 @@ class DesktopTasksController( reason = "transition type not handled (${request.type})" reason = "transition type not handled (${request.type})" false false } } // Only handle when it is a task transition triggerTask == null -> { reason = "triggerTask is null" false } // Only handle standard type tasks // Only handle standard type tasks triggerTask.activityType != ACTIVITY_TYPE_STANDARD -> { triggerTask.activityType != ACTIVITY_TYPE_STANDARD -> { reason = "activityType not handled (${triggerTask.activityType})" reason = "activityType not handled (${triggerTask.activityType})" Loading @@ -2103,25 +2112,24 @@ class DesktopTasksController( } } val result = val result = triggerTask?.let { task -> when { when { // Check if freeform task launch during recents should be handled // Check if freeform task launch during recents should be handled shouldHandleMidRecentsFreeformLaunch -> shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task, transition) handleMidRecentsFreeformTaskLaunch(triggerTask, transition) // Check if the closing task needs to be handled // Check if the closing task needs to be handled TransitionUtil.isClosingType(request.type) -> TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task, transition, request.type) handleTaskClosing(triggerTask, transition, request.type) // Check if the top task shouldn't be allowed to enter desktop mode // Check if the top task shouldn't be allowed to enter desktop mode isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task, transition) isIncompatibleTask(triggerTask) -> handleIncompatibleTaskLaunch(triggerTask, transition) // Check if fullscreen task should be updated // Check if fullscreen task should be updated task.isFullscreen -> handleFullscreenTaskLaunch(task, transition) triggerTask.isFullscreen -> handleFullscreenTaskLaunch(triggerTask, transition) // Check if freeform task should be updated // Check if freeform task should be updated task.isFreeform -> handleFreeformTaskLaunch(task, transition) triggerTask.isFreeform -> handleFreeformTaskLaunch(triggerTask, transition) else -> { else -> { null null } } } } } logV("handleRequest result=%s", result) logV("handleRequest result=%s", result) return result return result } } Loading Loading @@ -2184,8 +2192,8 @@ class DesktopTasksController( ) ) } } private fun taskContainsDragAndDropCookie(taskInfo: RunningTaskInfo?) = private fun taskContainsDragAndDropCookie(taskInfo: RunningTaskInfo) = taskInfo?.launchCookies?.any { it == dragAndDropFullscreenCookie } ?: false taskInfo.launchCookies?.any { it == dragAndDropFullscreenCookie } ?: false /** /** * Applies the proper surface states (rounded corners) to tasks when desktop mode is active. * Applies the proper surface states (rounded corners) to tasks when desktop mode is active. Loading @@ -2209,9 +2217,8 @@ class DesktopTasksController( } } /** Returns whether an existing desktop task is being relaunched in freeform or not. */ /** Returns whether an existing desktop task is being relaunched in freeform or not. */ private fun isFreeformRelaunch(triggerTask: RunningTaskInfo?, request: TransitionRequestInfo) = private fun isFreeformRelaunch(triggerTask: RunningTaskInfo, request: TransitionRequestInfo) = (triggerTask != null && (triggerTask.windowingMode == WINDOWING_MODE_FREEFORM && triggerTask.windowingMode == WINDOWING_MODE_FREEFORM && TransitionUtil.isOpeningType(request.type) && TransitionUtil.isOpeningType(request.type) && taskRepository.isActiveTask(triggerTask.taskId)) taskRepository.isActiveTask(triggerTask.taskId)) Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +12 −0 Original line number Original line Diff line number Diff line Loading @@ -317,6 +317,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() .spyStatic(Toast::class.java) .spyStatic(Toast::class.java) .startMocking() .startMocking() doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(any()) } doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(any()) } doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupportedOnDisplay(any(), any()) } testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob()) testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob()) spyContext = spy(mContext) spyContext = spy(mContext) Loading Loading @@ -5293,6 +5294,17 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertNull(result, "Should not handle request") assertNull(result, "Should not handle request") } } @Test fun handleRequest_freeformTask_displayDoesntHandleDesktop_returnNull() { doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupportedOnDisplay(any(), any()) } val task1 = createFreeformTask(displayId = SECOND_DISPLAY) val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_OPEN)) assertNull(result, "Should not handle request") } @Test @Test @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop_multiDesksDisabled() { fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop_multiDesksDisabled() { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +35 −28 Original line number Original line Diff line number Diff line Loading @@ -2043,6 +2043,11 @@ class DesktopTasksController( return false return false } } private fun taskDisplaySupportDesktopMode(triggerTask: RunningTaskInfo) = displayController.getDisplay(triggerTask.displayId)?.let { display -> DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display) } ?: false override fun handleRequest( override fun handleRequest( transition: IBinder, transition: IBinder, request: TransitionRequestInfo, request: TransitionRequestInfo, Loading @@ -2051,13 +2056,22 @@ class DesktopTasksController( // Check if we should skip handling this transition // Check if we should skip handling this transition var reason = "" var reason = "" val triggerTask = request.triggerTask val triggerTask = request.triggerTask // Skipping early if the trigger task is null if (triggerTask == null) { logV("skipping handleRequest reason=triggerTask is null", reason) return null } val recentsAnimationRunning = val recentsAnimationRunning = RecentsTransitionStateListener.isAnimating(recentsTransitionState) RecentsTransitionStateListener.isAnimating(recentsTransitionState) var shouldHandleMidRecentsFreeformLaunch = val shouldHandleMidRecentsFreeformLaunch = recentsAnimationRunning && isFreeformRelaunch(triggerTask, request) recentsAnimationRunning && isFreeformRelaunch(triggerTask, request) val isDragAndDropFullscreenTransition = taskContainsDragAndDropCookie(triggerTask) val isDragAndDropFullscreenTransition = taskContainsDragAndDropCookie(triggerTask) val shouldHandleRequest = val shouldHandleRequest = when { when { !taskDisplaySupportDesktopMode(triggerTask) -> { reason = "triggerTask's display doesn't support desktop mode" false } // Handle freeform relaunch during recents animation // Handle freeform relaunch during recents animation shouldHandleMidRecentsFreeformLaunch -> true shouldHandleMidRecentsFreeformLaunch -> true recentsAnimationRunning -> { recentsAnimationRunning -> { Loading @@ -2078,11 +2092,6 @@ class DesktopTasksController( reason = "transition type not handled (${request.type})" reason = "transition type not handled (${request.type})" false false } } // Only handle when it is a task transition triggerTask == null -> { reason = "triggerTask is null" false } // Only handle standard type tasks // Only handle standard type tasks triggerTask.activityType != ACTIVITY_TYPE_STANDARD -> { triggerTask.activityType != ACTIVITY_TYPE_STANDARD -> { reason = "activityType not handled (${triggerTask.activityType})" reason = "activityType not handled (${triggerTask.activityType})" Loading @@ -2103,25 +2112,24 @@ class DesktopTasksController( } } val result = val result = triggerTask?.let { task -> when { when { // Check if freeform task launch during recents should be handled // Check if freeform task launch during recents should be handled shouldHandleMidRecentsFreeformLaunch -> shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task, transition) handleMidRecentsFreeformTaskLaunch(triggerTask, transition) // Check if the closing task needs to be handled // Check if the closing task needs to be handled TransitionUtil.isClosingType(request.type) -> TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task, transition, request.type) handleTaskClosing(triggerTask, transition, request.type) // Check if the top task shouldn't be allowed to enter desktop mode // Check if the top task shouldn't be allowed to enter desktop mode isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task, transition) isIncompatibleTask(triggerTask) -> handleIncompatibleTaskLaunch(triggerTask, transition) // Check if fullscreen task should be updated // Check if fullscreen task should be updated task.isFullscreen -> handleFullscreenTaskLaunch(task, transition) triggerTask.isFullscreen -> handleFullscreenTaskLaunch(triggerTask, transition) // Check if freeform task should be updated // Check if freeform task should be updated task.isFreeform -> handleFreeformTaskLaunch(task, transition) triggerTask.isFreeform -> handleFreeformTaskLaunch(triggerTask, transition) else -> { else -> { null null } } } } } logV("handleRequest result=%s", result) logV("handleRequest result=%s", result) return result return result } } Loading Loading @@ -2184,8 +2192,8 @@ class DesktopTasksController( ) ) } } private fun taskContainsDragAndDropCookie(taskInfo: RunningTaskInfo?) = private fun taskContainsDragAndDropCookie(taskInfo: RunningTaskInfo) = taskInfo?.launchCookies?.any { it == dragAndDropFullscreenCookie } ?: false taskInfo.launchCookies?.any { it == dragAndDropFullscreenCookie } ?: false /** /** * Applies the proper surface states (rounded corners) to tasks when desktop mode is active. * Applies the proper surface states (rounded corners) to tasks when desktop mode is active. Loading @@ -2209,9 +2217,8 @@ class DesktopTasksController( } } /** Returns whether an existing desktop task is being relaunched in freeform or not. */ /** Returns whether an existing desktop task is being relaunched in freeform or not. */ private fun isFreeformRelaunch(triggerTask: RunningTaskInfo?, request: TransitionRequestInfo) = private fun isFreeformRelaunch(triggerTask: RunningTaskInfo, request: TransitionRequestInfo) = (triggerTask != null && (triggerTask.windowingMode == WINDOWING_MODE_FREEFORM && triggerTask.windowingMode == WINDOWING_MODE_FREEFORM && TransitionUtil.isOpeningType(request.type) && TransitionUtil.isOpeningType(request.type) && taskRepository.isActiveTask(triggerTask.taskId)) taskRepository.isActiveTask(triggerTask.taskId)) Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +12 −0 Original line number Original line Diff line number Diff line Loading @@ -317,6 +317,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() .spyStatic(Toast::class.java) .spyStatic(Toast::class.java) .startMocking() .startMocking() doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(any()) } doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(any()) } doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupportedOnDisplay(any(), any()) } testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob()) testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob()) spyContext = spy(mContext) spyContext = spy(mContext) Loading Loading @@ -5293,6 +5294,17 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertNull(result, "Should not handle request") assertNull(result, "Should not handle request") } } @Test fun handleRequest_freeformTask_displayDoesntHandleDesktop_returnNull() { doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupportedOnDisplay(any(), any()) } val task1 = createFreeformTask(displayId = SECOND_DISPLAY) val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_OPEN)) assertNull(result, "Should not handle request") } @Test @Test @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop_multiDesksDisabled() { fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop_multiDesksDisabled() { Loading