Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +27 −0 Original line number Diff line number Diff line Loading @@ -819,8 +819,12 @@ class DesktopTasksController( // Check if we should skip handling this transition var reason = "" val triggerTask = request.triggerTask var shouldHandleMidRecentsFreeformLaunch = recentsAnimationRunning && isFreeformRelaunch(triggerTask, request) val shouldHandleRequest = when { // Handle freeform relaunch during recents animation shouldHandleMidRecentsFreeformLaunch -> true recentsAnimationRunning -> { reason = "recents animation is running" false Loading Loading @@ -860,6 +864,8 @@ class DesktopTasksController( val result = triggerTask?.let { task -> when { // Check if freeform task launch during recents should be handled shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task) // Check if the closing task needs to be handled TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task) // Check if the top task shouldn't be allowed to enter desktop mode Loading Loading @@ -893,6 +899,12 @@ class DesktopTasksController( .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) } } /** Returns whether an existing desktop task is being relaunched in freeform or not. */ private fun isFreeformRelaunch(triggerTask: RunningTaskInfo?, request: TransitionRequestInfo) = (triggerTask != null && triggerTask.windowingMode == WINDOWING_MODE_FREEFORM && TransitionUtil.isOpeningType(request.type) && taskRepository.isActiveTask(triggerTask.taskId)) private fun isIncompatibleTask(task: TaskInfo) = DesktopModeFlags.MODALS_POLICY.isEnabled(context) && isTopActivityExemptFromDesktopWindowing(context, task) Loading Loading @@ -957,6 +969,21 @@ class DesktopTasksController( } } /** * Handles the case where a freeform task is launched from recents. * * This is a special case where we want to launch the task in fullscreen instead of freeform. */ private fun handleMidRecentsFreeformTaskLaunch( task: RunningTaskInfo ): WindowContainerTransaction? { logV("DesktopTasksController: handleMidRecentsFreeformTaskLaunch") val wct = WindowContainerTransaction() addMoveToFullscreenChanges(wct, task) wct.reorder(task.token, true) return wct } private fun handleFreeformTaskLaunch( task: RunningTaskInfo, transition: IBinder Loading libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +16 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,14 @@ package com.android.wm.shell.recents; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; import static android.view.WindowManager.TRANSIT_PIP; import static android.view.WindowManager.TRANSIT_SLEEP; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION; Loading Loading @@ -775,6 +777,20 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { // Don't consider order-only & non-leaf changes as changing apps. if (!TransitionUtil.isOrderOnly(change) && isLeafTask) { hasChangingApp = true; // Check if the changing app is moving to top and fullscreen. This handles // the case where we moved from desktop to recents and launching a desktop // task in fullscreen. if ((change.getFlags() & FLAG_MOVED_TO_TOP) != 0 && taskInfo != null && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) { if (openingTasks == null) { openingTasks = new ArrayList<>(); openingTaskIsLeafs = new IntArray(); } openingTasks.add(change); openingTaskIsLeafs.add(1); } } else if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME && !isRecentsTask ) { // Unless it is a 3p launcher. This means that the 3p launcher was already Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +15 −0 Original line number Diff line number Diff line Loading @@ -1565,6 +1565,21 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull() } @Test fun handleRequest_recentsAnimationRunning_relaunchActiveTask_taskBecomesUndefined() { // Set up a visible freeform task val freeformTask = setUpFreeformTask() markTaskVisible(freeformTask) // Mark recents animation running recentsTransitionStateListener.onAnimationStateChanged(true) // Should become undefined as the TDA is set to fullscreen. It will inherit from the TDA. val result = controller.handleRequest(Binder(), createTransition(freeformTask)) assertThat(result?.changes?.get(freeformTask.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_UNDEFINED) } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY) fun handleRequest_topActivityTransparentWithStyleFloating_returnSwitchToFreeformWCT() { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +27 −0 Original line number Diff line number Diff line Loading @@ -819,8 +819,12 @@ class DesktopTasksController( // Check if we should skip handling this transition var reason = "" val triggerTask = request.triggerTask var shouldHandleMidRecentsFreeformLaunch = recentsAnimationRunning && isFreeformRelaunch(triggerTask, request) val shouldHandleRequest = when { // Handle freeform relaunch during recents animation shouldHandleMidRecentsFreeformLaunch -> true recentsAnimationRunning -> { reason = "recents animation is running" false Loading Loading @@ -860,6 +864,8 @@ class DesktopTasksController( val result = triggerTask?.let { task -> when { // Check if freeform task launch during recents should be handled shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task) // Check if the closing task needs to be handled TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task) // Check if the top task shouldn't be allowed to enter desktop mode Loading Loading @@ -893,6 +899,12 @@ class DesktopTasksController( .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) } } /** Returns whether an existing desktop task is being relaunched in freeform or not. */ private fun isFreeformRelaunch(triggerTask: RunningTaskInfo?, request: TransitionRequestInfo) = (triggerTask != null && triggerTask.windowingMode == WINDOWING_MODE_FREEFORM && TransitionUtil.isOpeningType(request.type) && taskRepository.isActiveTask(triggerTask.taskId)) private fun isIncompatibleTask(task: TaskInfo) = DesktopModeFlags.MODALS_POLICY.isEnabled(context) && isTopActivityExemptFromDesktopWindowing(context, task) Loading Loading @@ -957,6 +969,21 @@ class DesktopTasksController( } } /** * Handles the case where a freeform task is launched from recents. * * This is a special case where we want to launch the task in fullscreen instead of freeform. */ private fun handleMidRecentsFreeformTaskLaunch( task: RunningTaskInfo ): WindowContainerTransaction? { logV("DesktopTasksController: handleMidRecentsFreeformTaskLaunch") val wct = WindowContainerTransaction() addMoveToFullscreenChanges(wct, task) wct.reorder(task.token, true) return wct } private fun handleFreeformTaskLaunch( task: RunningTaskInfo, transition: IBinder Loading
libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +16 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,14 @@ package com.android.wm.shell.recents; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; import static android.view.WindowManager.TRANSIT_PIP; import static android.view.WindowManager.TRANSIT_SLEEP; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION; Loading Loading @@ -775,6 +777,20 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { // Don't consider order-only & non-leaf changes as changing apps. if (!TransitionUtil.isOrderOnly(change) && isLeafTask) { hasChangingApp = true; // Check if the changing app is moving to top and fullscreen. This handles // the case where we moved from desktop to recents and launching a desktop // task in fullscreen. if ((change.getFlags() & FLAG_MOVED_TO_TOP) != 0 && taskInfo != null && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) { if (openingTasks == null) { openingTasks = new ArrayList<>(); openingTaskIsLeafs = new IntArray(); } openingTasks.add(change); openingTaskIsLeafs.add(1); } } else if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME && !isRecentsTask ) { // Unless it is a 3p launcher. This means that the 3p launcher was already Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +15 −0 Original line number Diff line number Diff line Loading @@ -1565,6 +1565,21 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull() } @Test fun handleRequest_recentsAnimationRunning_relaunchActiveTask_taskBecomesUndefined() { // Set up a visible freeform task val freeformTask = setUpFreeformTask() markTaskVisible(freeformTask) // Mark recents animation running recentsTransitionStateListener.onAnimationStateChanged(true) // Should become undefined as the TDA is set to fullscreen. It will inherit from the TDA. val result = controller.handleRequest(Binder(), createTransition(freeformTask)) assertThat(result?.changes?.get(freeformTask.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_UNDEFINED) } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY) fun handleRequest_topActivityTransparentWithStyleFloating_returnSwitchToFreeformWCT() { Loading