Loading core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -7096,6 +7096,10 @@ <!-- Maximum number of active tasks on a given Desktop Windowing session. Set to 0 for unlimited. --> <integer name="config_maxDesktopWindowingActiveTasks">0</integer> <!-- Whether a display enters desktop mode by default when the windowing mode of the display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM. --> <bool name="config_enterDesktopByDefaultOnFreeformDisplay">false</bool> <!-- Frame rate compatibility value for Wallpaper FRAME_RATE_COMPATIBILITY_MIN (102) is used by default for lower power consumption --> <integer name="config_wallpaperFrameRateCompatibility">102</integer> Loading core/res/res/values/symbols.xml +4 −0 Original line number Diff line number Diff line Loading @@ -5542,6 +5542,10 @@ <!-- Maximum number of active tasks on a given Desktop Windowing session. Set to 0 for unlimited. --> <java-symbol type="integer" name="config_maxDesktopWindowingActiveTasks"/> <!-- Whether a display enters desktop mode by default when the windowing mode of the display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM. --> <java-symbol type="bool" name="config_enterDesktopByDefaultOnFreeformDisplay" /> <!-- Frame rate compatibility value for Wallpaper --> <java-symbol type="integer" name="config_wallpaperFrameRateCompatibility" /> Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java +23 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,16 @@ public class DesktopModeStatus { /** The number of [WindowDecorViewHost] instances to warm up on system start. */ private static final int WINDOW_DECOR_PRE_WARM_SIZE = 2; /** * Sysprop declaring whether to enters desktop mode by default when the windowing mode of the * display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM. * * <p>If it is not defined, then {@code R.integer.config_enterDesktopByDefaultOnFreeformDisplay} * is used. */ public static final String ENTER_DESKTOP_BY_DEFAULT_ON_FREEFORM_DISPLAY_SYS_PROP = "persist.wm.debug.enter_desktop_by_default_on_freeform_display"; /** * Sysprop declaring the maximum number of Tasks to show in Desktop Mode at any one time. * Loading Loading @@ -223,6 +233,19 @@ public class DesktopModeStatus { return !enforceDeviceRestrictions() || isDesktopModeSupported(context); } /** * Return {@code true} if a display should enter desktop mode by default when the windowing mode * of the display's root [TaskDisplayArea] is set to WINDOWING_MODE_FREEFORM. */ public static boolean enterDesktopByDefaultOnFreeformDisplay(@NonNull Context context) { if (!Flags.enterDesktopByDefaultOnFreeformDisplays()) { return false; } return SystemProperties.getBoolean(ENTER_DESKTOP_BY_DEFAULT_ON_FREEFORM_DISPLAY_SYS_PROP, context.getResources().getBoolean( R.bool.config_enterDesktopByDefaultOnFreeformDisplay)); } /** Dumps DesktopModeStatus flags and configs. */ public static void dump(PrintWriter pw, String prefix, Context context) { String innerPrefix = prefix + " "; Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +12 −1 Original line number Diff line number Diff line Loading @@ -303,6 +303,15 @@ class DesktopTasksController( private fun getSplitFocusedTask(task1: RunningTaskInfo, task2: RunningTaskInfo) = if (task1.taskId == task2.parentTaskId) task2 else task1 private fun isFreeformDisplay(displayId: Int): Boolean { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId) requireNotNull(tdaInfo) { "This method can only be called with the ID of a display having non-null DisplayArea." } val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode return tdaWindowingMode == WINDOWING_MODE_FREEFORM } /** Moves task to desktop mode if task is running, else launches it in desktop mode. */ fun moveTaskToDesktop( taskId: Int, Loading Loading @@ -1220,7 +1229,9 @@ class DesktopTasksController( transition: IBinder ): WindowContainerTransaction? { logV("handleFullscreenTaskLaunch") if (isDesktopModeShowing(task.displayId)) { val forceEnterDesktop = DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context) && isFreeformDisplay(task.displayId) if (isDesktopModeShowing(task.displayId) || forceEnterDesktop) { logD("Switch fullscreen task to freeform on transition: taskId=%d", task.taskId) return WindowContainerTransaction().also { wct -> addMoveToDesktopChanges(wct, task) Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +30 −0 Original line number Diff line number Diff line Loading @@ -1665,6 +1665,36 @@ class DesktopTasksControllerTest : ShellTestCase() { wct.assertReorderAt(9, freeformTasks[0], toTop = false) } @Test fun handleRequest_fullscreenTask_noTasks_enforceDesktop_freeformDisplay_returnFreeformWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true) val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM val fullscreenTask = createFullscreenTask() val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask)) assertNotNull(wct, "should handle request") assertThat(wct.changes[fullscreenTask.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_UNDEFINED) assertThat(wct.hierarchyOps).hasSize(1) wct.assertReorderAt(0, fullscreenTask, toTop = true) } @Test fun handleRequest_fullscreenTask_noTasks_enforceDesktop_fullscreenDisplay_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true) val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN val fullscreenTask = createFullscreenTask() val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask)) assertThat(wct).isNull() } @Test fun handleRequest_fullscreenTask_freeformNotVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) Loading Loading
core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -7096,6 +7096,10 @@ <!-- Maximum number of active tasks on a given Desktop Windowing session. Set to 0 for unlimited. --> <integer name="config_maxDesktopWindowingActiveTasks">0</integer> <!-- Whether a display enters desktop mode by default when the windowing mode of the display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM. --> <bool name="config_enterDesktopByDefaultOnFreeformDisplay">false</bool> <!-- Frame rate compatibility value for Wallpaper FRAME_RATE_COMPATIBILITY_MIN (102) is used by default for lower power consumption --> <integer name="config_wallpaperFrameRateCompatibility">102</integer> Loading
core/res/res/values/symbols.xml +4 −0 Original line number Diff line number Diff line Loading @@ -5542,6 +5542,10 @@ <!-- Maximum number of active tasks on a given Desktop Windowing session. Set to 0 for unlimited. --> <java-symbol type="integer" name="config_maxDesktopWindowingActiveTasks"/> <!-- Whether a display enters desktop mode by default when the windowing mode of the display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM. --> <java-symbol type="bool" name="config_enterDesktopByDefaultOnFreeformDisplay" /> <!-- Frame rate compatibility value for Wallpaper --> <java-symbol type="integer" name="config_wallpaperFrameRateCompatibility" /> Loading
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java +23 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,16 @@ public class DesktopModeStatus { /** The number of [WindowDecorViewHost] instances to warm up on system start. */ private static final int WINDOW_DECOR_PRE_WARM_SIZE = 2; /** * Sysprop declaring whether to enters desktop mode by default when the windowing mode of the * display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM. * * <p>If it is not defined, then {@code R.integer.config_enterDesktopByDefaultOnFreeformDisplay} * is used. */ public static final String ENTER_DESKTOP_BY_DEFAULT_ON_FREEFORM_DISPLAY_SYS_PROP = "persist.wm.debug.enter_desktop_by_default_on_freeform_display"; /** * Sysprop declaring the maximum number of Tasks to show in Desktop Mode at any one time. * Loading Loading @@ -223,6 +233,19 @@ public class DesktopModeStatus { return !enforceDeviceRestrictions() || isDesktopModeSupported(context); } /** * Return {@code true} if a display should enter desktop mode by default when the windowing mode * of the display's root [TaskDisplayArea] is set to WINDOWING_MODE_FREEFORM. */ public static boolean enterDesktopByDefaultOnFreeformDisplay(@NonNull Context context) { if (!Flags.enterDesktopByDefaultOnFreeformDisplays()) { return false; } return SystemProperties.getBoolean(ENTER_DESKTOP_BY_DEFAULT_ON_FREEFORM_DISPLAY_SYS_PROP, context.getResources().getBoolean( R.bool.config_enterDesktopByDefaultOnFreeformDisplay)); } /** Dumps DesktopModeStatus flags and configs. */ public static void dump(PrintWriter pw, String prefix, Context context) { String innerPrefix = prefix + " "; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +12 −1 Original line number Diff line number Diff line Loading @@ -303,6 +303,15 @@ class DesktopTasksController( private fun getSplitFocusedTask(task1: RunningTaskInfo, task2: RunningTaskInfo) = if (task1.taskId == task2.parentTaskId) task2 else task1 private fun isFreeformDisplay(displayId: Int): Boolean { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId) requireNotNull(tdaInfo) { "This method can only be called with the ID of a display having non-null DisplayArea." } val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode return tdaWindowingMode == WINDOWING_MODE_FREEFORM } /** Moves task to desktop mode if task is running, else launches it in desktop mode. */ fun moveTaskToDesktop( taskId: Int, Loading Loading @@ -1220,7 +1229,9 @@ class DesktopTasksController( transition: IBinder ): WindowContainerTransaction? { logV("handleFullscreenTaskLaunch") if (isDesktopModeShowing(task.displayId)) { val forceEnterDesktop = DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context) && isFreeformDisplay(task.displayId) if (isDesktopModeShowing(task.displayId) || forceEnterDesktop) { logD("Switch fullscreen task to freeform on transition: taskId=%d", task.taskId) return WindowContainerTransaction().also { wct -> addMoveToDesktopChanges(wct, task) Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +30 −0 Original line number Diff line number Diff line Loading @@ -1665,6 +1665,36 @@ class DesktopTasksControllerTest : ShellTestCase() { wct.assertReorderAt(9, freeformTasks[0], toTop = false) } @Test fun handleRequest_fullscreenTask_noTasks_enforceDesktop_freeformDisplay_returnFreeformWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true) val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM val fullscreenTask = createFullscreenTask() val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask)) assertNotNull(wct, "should handle request") assertThat(wct.changes[fullscreenTask.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_UNDEFINED) assertThat(wct.hierarchyOps).hasSize(1) wct.assertReorderAt(0, fullscreenTask, toTop = true) } @Test fun handleRequest_fullscreenTask_noTasks_enforceDesktop_fullscreenDisplay_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true) val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN val fullscreenTask = createFullscreenTask() val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask)) assertThat(wct).isNull() } @Test fun handleRequest_fullscreenTask_freeformNotVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) Loading