Loading core/java/android/window/DesktopExperienceFlags.java +3 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,9 @@ public enum DesktopExperienceFlags { LIMIT_SYSTEM_FULLSCREEN_OVERRIDE_TO_DEFAULT_DISPLAY( Flags::limitSystemFullscreenOverrideToDefaultDisplay, false, Flags.FLAG_LIMIT_SYSTEM_FULLSCREEN_OVERRIDE_TO_DEFAULT_DISPLAY), MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE( Flags::moveToNextDisplayShortcutWithProjectedMode, false, Flags.FLAG_MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE), PRESERVE_RECENTS_TASK_CONFIGURATION_ON_RELAUNCH( Flags::preserveRecentsTaskConfigurationOnRelaunch, true, Flags.FLAG_PRESERVE_RECENTS_TASK_CONFIGURATION_ON_RELAUNCH), Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/FakeDesktopState.kt +3 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ class FakeDesktopState : DesktopState { /** Override [canEnterDesktopMode] for a specific display. */ val overrideDesktopModeSupportPerDisplay = mutableMapOf<Int, Boolean>() /** Overrides [isProjectedMode] */ var isProjected: Boolean = false override fun isMultipleDesktopFrontendEnabledOnDisplay(display: Display): Boolean = enableMultipleDesktops && isDesktopModeSupportedOnDisplay(display) Loading @@ -63,7 +65,7 @@ class FakeDesktopState : DesktopState { } override fun isProjectedMode(): Boolean { return false return isProjected } override var overridesShowAppHandle: Boolean = false Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +1 −1 Original line number Diff line number Diff line Loading @@ -1187,7 +1187,7 @@ public abstract class WMShellModule { desktopModeWindowDecorViewModel, desktopTasksController, desktopUserRepositories, inputManager, shellTaskOrganizer, focusTransitionObserver, mainExecutor, displayController)); mainExecutor, displayController, desktopState)); } return Optional.empty(); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt +58 −8 Original line number Diff line number Diff line Loading @@ -18,11 +18,13 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager.RunningTaskInfo import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.content.Context import android.hardware.input.InputManager import android.hardware.input.InputManager.KeyGestureEventHandler import android.hardware.input.KeyGestureEvent import android.os.IBinder import android.view.Display.DEFAULT_DISPLAY import android.window.DesktopExperienceFlags import com.android.internal.protolog.ProtoLog import com.android.wm.shell.ShellTaskOrganizer Loading @@ -32,6 +34,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.Minimiz import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.shared.desktopmode.DesktopState import com.android.wm.shell.transition.FocusTransitionObserver import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel import java.util.Optional Loading @@ -47,6 +50,7 @@ class DesktopModeKeyGestureHandler( private val focusTransitionObserver: FocusTransitionObserver, @ShellMainThread private val mainExecutor: ShellExecutor, private val displayController: DisplayController, private val desktopState: DesktopState, ) : KeyGestureEventHandler { init { Loading @@ -69,18 +73,11 @@ class DesktopModeKeyGestureHandler( when (event.keyGestureType) { KeyGestureEvent.KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY -> { logV("Key gesture MOVE_TO_NEXT_DISPLAY is handled") getGloballyFocusedDesktopTask()?.let { logV("Found globally focused desktop task to move: ${it.taskId}") getGloballyFocusedTaskToMoveToNextDisplay()?.let { mainExecutor.execute { desktopTasksController.get().moveToNextDesktopDisplay(it.taskId) } } ?: logW( "No globally focused desktop task to move: " + "globallyFocusedTaskId=%d globallyFocusedDisplayId=%d", focusTransitionObserver.globallyFocusedTaskId, focusTransitionObserver.globallyFocusedDisplayId, ) } KeyGestureEvent.KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK -> { logV("Key gesture SWITCH_TO_PREVIOUS_DESK is handled") Loading Loading @@ -177,6 +174,59 @@ class DesktopModeKeyGestureHandler( } } private fun getGloballyFocusedTaskToMoveToNextDisplay(): RunningTaskInfo? { getGloballyFocusedDesktopTask()?.let { desktopTask -> logV( "getGloballyFocusedTaskToMoveToNextDisplay: Found globally focused desktop task to move: %d", desktopTask.taskId, ) return@getGloballyFocusedTaskToMoveToNextDisplay desktopTask } if (!DesktopExperienceFlags.MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE.isTrue) { logV( "getGloballyFocusedTaskToMoveToNextDisplay: Skip focusing fullscreen task because " + "MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE is disabled" ) return null } if (!desktopState.isProjectedMode()) { logV( "getGloballyFocusedTaskToMoveToNextDisplay: Skip focusing fullscreen task because the device is not " + "in the projected mode" ) return null } if (focusTransitionObserver.globallyFocusedDisplayId != DEFAULT_DISPLAY) { logV( "getGloballyFocusedTaskToMoveToNextDisplay: Skip focusing fullscreen task because the focused " + "display is not default display" ) return null } desktopTasksController .get() .getFocusedNonDesktopTasks(focusTransitionObserver.globallyFocusedDisplayId) .find { it.windowingMode == WINDOWING_MODE_FULLSCREEN } ?.let { fullscreenTask -> logV( "getGloballyFocusedTaskToMoveToNextDisplay: Found globally focused fullscreen task to move: %d", fullscreenTask.taskId, ) return@getGloballyFocusedTaskToMoveToNextDisplay fullscreenTask } logW( "No globally focused task to move: globallyFocusedTaskId=%d globallyFocusedDisplayId=%d", focusTransitionObserver.globallyFocusedTaskId, focusTransitionObserver.globallyFocusedDisplayId, ) return null } private fun logV(msg: String, vararg arguments: Any?) { ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +1 −1 Original line number Diff line number Diff line Loading @@ -459,7 +459,7 @@ class DesktopTasksController( * Returns all focused tasks in full screen or split screen mode in [displayId] excluding home * activity and desk roots. */ private fun getFocusedNonDesktopTasks(displayId: Int): List<RunningTaskInfo> = fun getFocusedNonDesktopTasks(displayId: Int): List<RunningTaskInfo> = shellTaskOrganizer.getRunningTasks(displayId).filter { taskInfo -> val focused = taskInfo.isFocused val isNotDesktop = Loading Loading
core/java/android/window/DesktopExperienceFlags.java +3 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,9 @@ public enum DesktopExperienceFlags { LIMIT_SYSTEM_FULLSCREEN_OVERRIDE_TO_DEFAULT_DISPLAY( Flags::limitSystemFullscreenOverrideToDefaultDisplay, false, Flags.FLAG_LIMIT_SYSTEM_FULLSCREEN_OVERRIDE_TO_DEFAULT_DISPLAY), MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE( Flags::moveToNextDisplayShortcutWithProjectedMode, false, Flags.FLAG_MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE), PRESERVE_RECENTS_TASK_CONFIGURATION_ON_RELAUNCH( Flags::preserveRecentsTaskConfigurationOnRelaunch, true, Flags.FLAG_PRESERVE_RECENTS_TASK_CONFIGURATION_ON_RELAUNCH), Loading
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/FakeDesktopState.kt +3 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ class FakeDesktopState : DesktopState { /** Override [canEnterDesktopMode] for a specific display. */ val overrideDesktopModeSupportPerDisplay = mutableMapOf<Int, Boolean>() /** Overrides [isProjectedMode] */ var isProjected: Boolean = false override fun isMultipleDesktopFrontendEnabledOnDisplay(display: Display): Boolean = enableMultipleDesktops && isDesktopModeSupportedOnDisplay(display) Loading @@ -63,7 +65,7 @@ class FakeDesktopState : DesktopState { } override fun isProjectedMode(): Boolean { return false return isProjected } override var overridesShowAppHandle: Boolean = false Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +1 −1 Original line number Diff line number Diff line Loading @@ -1187,7 +1187,7 @@ public abstract class WMShellModule { desktopModeWindowDecorViewModel, desktopTasksController, desktopUserRepositories, inputManager, shellTaskOrganizer, focusTransitionObserver, mainExecutor, displayController)); mainExecutor, displayController, desktopState)); } return Optional.empty(); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt +58 −8 Original line number Diff line number Diff line Loading @@ -18,11 +18,13 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager.RunningTaskInfo import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.content.Context import android.hardware.input.InputManager import android.hardware.input.InputManager.KeyGestureEventHandler import android.hardware.input.KeyGestureEvent import android.os.IBinder import android.view.Display.DEFAULT_DISPLAY import android.window.DesktopExperienceFlags import com.android.internal.protolog.ProtoLog import com.android.wm.shell.ShellTaskOrganizer Loading @@ -32,6 +34,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.Minimiz import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.shared.desktopmode.DesktopState import com.android.wm.shell.transition.FocusTransitionObserver import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel import java.util.Optional Loading @@ -47,6 +50,7 @@ class DesktopModeKeyGestureHandler( private val focusTransitionObserver: FocusTransitionObserver, @ShellMainThread private val mainExecutor: ShellExecutor, private val displayController: DisplayController, private val desktopState: DesktopState, ) : KeyGestureEventHandler { init { Loading @@ -69,18 +73,11 @@ class DesktopModeKeyGestureHandler( when (event.keyGestureType) { KeyGestureEvent.KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY -> { logV("Key gesture MOVE_TO_NEXT_DISPLAY is handled") getGloballyFocusedDesktopTask()?.let { logV("Found globally focused desktop task to move: ${it.taskId}") getGloballyFocusedTaskToMoveToNextDisplay()?.let { mainExecutor.execute { desktopTasksController.get().moveToNextDesktopDisplay(it.taskId) } } ?: logW( "No globally focused desktop task to move: " + "globallyFocusedTaskId=%d globallyFocusedDisplayId=%d", focusTransitionObserver.globallyFocusedTaskId, focusTransitionObserver.globallyFocusedDisplayId, ) } KeyGestureEvent.KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK -> { logV("Key gesture SWITCH_TO_PREVIOUS_DESK is handled") Loading Loading @@ -177,6 +174,59 @@ class DesktopModeKeyGestureHandler( } } private fun getGloballyFocusedTaskToMoveToNextDisplay(): RunningTaskInfo? { getGloballyFocusedDesktopTask()?.let { desktopTask -> logV( "getGloballyFocusedTaskToMoveToNextDisplay: Found globally focused desktop task to move: %d", desktopTask.taskId, ) return@getGloballyFocusedTaskToMoveToNextDisplay desktopTask } if (!DesktopExperienceFlags.MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE.isTrue) { logV( "getGloballyFocusedTaskToMoveToNextDisplay: Skip focusing fullscreen task because " + "MOVE_TO_NEXT_DISPLAY_SHORTCUT_WITH_PROJECTED_MODE is disabled" ) return null } if (!desktopState.isProjectedMode()) { logV( "getGloballyFocusedTaskToMoveToNextDisplay: Skip focusing fullscreen task because the device is not " + "in the projected mode" ) return null } if (focusTransitionObserver.globallyFocusedDisplayId != DEFAULT_DISPLAY) { logV( "getGloballyFocusedTaskToMoveToNextDisplay: Skip focusing fullscreen task because the focused " + "display is not default display" ) return null } desktopTasksController .get() .getFocusedNonDesktopTasks(focusTransitionObserver.globallyFocusedDisplayId) .find { it.windowingMode == WINDOWING_MODE_FULLSCREEN } ?.let { fullscreenTask -> logV( "getGloballyFocusedTaskToMoveToNextDisplay: Found globally focused fullscreen task to move: %d", fullscreenTask.taskId, ) return@getGloballyFocusedTaskToMoveToNextDisplay fullscreenTask } logW( "No globally focused task to move: globallyFocusedTaskId=%d globallyFocusedDisplayId=%d", focusTransitionObserver.globallyFocusedTaskId, focusTransitionObserver.globallyFocusedDisplayId, ) return null } private fun logV(msg: String, vararg arguments: Any?) { ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +1 −1 Original line number Diff line number Diff line Loading @@ -459,7 +459,7 @@ class DesktopTasksController( * Returns all focused tasks in full screen or split screen mode in [displayId] excluding home * activity and desk roots. */ private fun getFocusedNonDesktopTasks(displayId: Int): List<RunningTaskInfo> = fun getFocusedNonDesktopTasks(displayId: Int): List<RunningTaskInfo> = shellTaskOrganizer.getRunningTasks(displayId).filter { taskInfo -> val focused = taskInfo.isFocused val isNotDesktop = Loading