summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt44
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java6
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java5
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java9
8 files changed, 134 insertions, 0 deletions
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index ed43b8190f93..d463b62e62a3 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -376,4 +376,10 @@ oneway interface IStatusBar
* @param packageName of the session for which the output switcher is shown.
*/
void showMediaOutputSwitcher(String packageName);
+
+ /** Enters desktop mode.
+ *
+ * @param displayId the id of the current display.
+ */
+ void enterDesktop(int displayId);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java
index e732a0354806..8305fa6b0fbf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java
@@ -47,4 +47,8 @@ public interface DesktopMode {
default void addDesktopGestureExclusionRegionListener(Consumer<Region> listener,
Executor callbackExecutor) { }
+
+ /** Called when requested to go to desktop mode from the current focused app. */
+ void enterDesktop(int displayId);
+
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 11304ec587e7..6de5d741f436 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -21,6 +21,7 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.app.WindowConfiguration.WindowingMode
import android.content.Context
@@ -240,6 +241,43 @@ class DesktopTasksController(
return desktopModeTaskRepository.getVisibleTaskCount(displayId)
}
+ /** Enter desktop by using the focused task in given `displayId` */
+ fun enterDesktop(displayId: Int) {
+ val allFocusedTasks =
+ shellTaskOrganizer.getRunningTasks(displayId).filter { taskInfo ->
+ taskInfo.isFocused &&
+ (taskInfo.windowingMode == WINDOWING_MODE_FULLSCREEN ||
+ taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW) &&
+ taskInfo.activityType != ACTIVITY_TYPE_HOME
+ }
+ if (allFocusedTasks.isNotEmpty()) {
+ when (allFocusedTasks.size) {
+ 2 -> {
+ // Split-screen case where there are two focused tasks, then we find the child
+ // task to move to desktop.
+ val splitFocusedTask = findChildFocusedTask(allFocusedTasks)
+ moveToDesktop(splitFocusedTask)
+ }
+ 1 -> {
+ // Fullscreen case where we move the current focused task.
+ moveToDesktop(allFocusedTasks[0].taskId)
+ }
+ else -> {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: Cannot enter desktop expected less " +
+ "than 3 focused tasks but found " + allFocusedTasks.size
+ )
+ }
+ }
+ }
+ }
+
+ private fun findChildFocusedTask(allFocusedTasks: List<RunningTaskInfo>): RunningTaskInfo {
+ if (allFocusedTasks[0].taskId == allFocusedTasks[1].parentTaskId) return allFocusedTasks[1]
+ return allFocusedTasks[0]
+ }
+
/** Move a task with given `taskId` to desktop */
fun moveToDesktop(
taskId: Int,
@@ -1012,6 +1050,12 @@ class DesktopTasksController(
this@DesktopTasksController.setTaskRegionListener(listener, callbackExecutor)
}
}
+
+ override fun enterDesktop(displayId: Int) {
+ mainExecutor.execute {
+ this@DesktopTasksController.enterDesktop(displayId)
+ }
+ }
}
/** The interface for calls from outside the host process. */
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 63618f4d0673..cb64c52444ac 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -734,6 +734,46 @@ class DesktopTasksControllerTest : ShellTestCase() {
shellExecutor.flushAll()
verify(launchAdjacentController).launchAdjacentEnabled = true
}
+ @Test
+ fun enterDesktop_fullscreenTaskIsMovedToDesktop() {
+ val task1 = setUpFullscreenTask()
+ val task2 = setUpFullscreenTask()
+ val task3 = setUpFullscreenTask()
+
+ task1.isFocused = true
+ task2.isFocused = false
+ task3.isFocused = false
+
+ controller.enterDesktop(DEFAULT_DISPLAY)
+
+ val wct = getLatestMoveToDesktopWct()
+ assertThat(wct.changes[task1.token.asBinder()]?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+
+ @Test
+ fun enterDesktop_splitScreenTaskIsMovedToDesktop() {
+ val task1 = setUpSplitScreenTask()
+ val task2 = setUpFullscreenTask()
+ val task3 = setUpFullscreenTask()
+ val task4 = setUpSplitScreenTask()
+
+ task1.isFocused = true
+ task2.isFocused = false
+ task3.isFocused = false
+ task4.isFocused = true
+
+ task4.parentTaskId = task1.taskId
+
+ controller.enterDesktop(DEFAULT_DISPLAY)
+
+ val wct = getLatestMoveToDesktopWct()
+ assertThat(wct.changes[task4.token.asBinder()]?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ verify(splitScreenController).prepareExitSplitScreen(any(), anyInt(),
+ eq(SplitScreenController.EXIT_REASON_DESKTOP_MODE)
+ )
+ }
private fun setUpFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
val task = createFreeformTask(displayId)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index ffb11dd3cf92..ca19f71bd391 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -177,6 +177,7 @@ public class CommandQueue extends IStatusBar.Stub implements
private static final int MSG_CONFIRM_IMMERSIVE_PROMPT = 77 << MSG_SHIFT;
private static final int MSG_IMMERSIVE_CHANGED = 78 << MSG_SHIFT;
private static final int MSG_SET_QS_TILES = 79 << MSG_SHIFT;
+ private static final int MSG_ENTER_DESKTOP = 80 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1;
@@ -520,6 +521,11 @@ public class CommandQueue extends IStatusBar.Stub implements
* @see IStatusBar#immersiveModeChanged
*/
default void immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode) {}
+
+ /**
+ * @see IStatusBar#enterDesktop(int)
+ */
+ default void enterDesktop(int displayId) {}
}
@VisibleForTesting
@@ -1420,6 +1426,13 @@ public class CommandQueue extends IStatusBar.Stub implements
mHandler.obtainMessage(MSG_GO_TO_FULLSCREEN_FROM_SPLIT).sendToTarget();
}
+ @Override
+ public void enterDesktop(int displayId) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = displayId;
+ mHandler.obtainMessage(MSG_ENTER_DESKTOP, args).sendToTarget();
+ }
+
private final class H extends Handler {
private H(Looper l) {
super(l);
@@ -1914,6 +1927,13 @@ public class CommandQueue extends IStatusBar.Stub implements
mCallbacks.get(i).immersiveModeChanged(rootDisplayAreaId, isImmersiveMode);
}
break;
+ case MSG_ENTER_DESKTOP:
+ args = (SomeArgs) msg.obj;
+ int displayId = args.argi1;
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).enterDesktop(displayId);
+ }
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index e8325065c219..15e0965c16fe 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -356,6 +356,12 @@ public final class WMShell implements
// TODO(b/278084491): update sysui state for changes on other displays
}
}, mSysUiMainExecutor);
+ mCommandQueue.addCallback(new CommandQueue.Callbacks() {
+ @Override
+ public void enterDesktop(int displayId) {
+ desktopMode.enterDesktop(displayId);
+ }
+ });
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index a4c6959f8ad5..3c6baa873eca 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -255,4 +255,9 @@ public interface StatusBarManagerInternal {
* @param tile the ComponentName of the {@link android.service.quicksettings.TileService}
*/
void removeQsTile(ComponentName tile);
+
+ /**
+ * Called when requested to enter desktop from an app.
+ */
+ void enterDesktop(int displayId);
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index fd316eaf9b96..14c38bde6621 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -830,6 +830,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
+ public void enterDesktop(int displayId) {
+ IStatusBar bar = mBar;
+ if (bar != null) {
+ try {
+ bar.enterDesktop(displayId);
+ } catch (RemoteException ex) { }
+ }
+ }
+ @Override
public void showMediaOutputSwitcher(String packageName) {
IStatusBar bar = mBar;
if (bar != null) {