From a0786f3fc756589897b4b660e72461e5a51f88df Mon Sep 17 00:00:00 2001 From: mattsziklay Date: Fri, 28 Jul 2023 16:00:49 -0700 Subject: [PATCH] Allow entering split screen on an app currently open in desktop mode. Registers a SplitScreenListener to perform necessary windowing changes when split is requested for an app currently open in desktop mode. Test: Manual; open a task in desktop, go to overview, perform a split transition where the second app is the one open in desktop. Bug: 279586624 Change-Id: Ib00e0fe5d0dd0dfa49b025d78de994fd68af2145 --- .../common/split/SplitScreenConstants.java | 4 +++- .../desktopmode/DesktopTasksController.kt | 19 +++++++++++++++++++ .../DesktopModeWindowDecorViewModel.java | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java index ef93a336305fb..be1b9b1227de2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java @@ -16,6 +16,7 @@ package com.android.wm.shell.common.split; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; @@ -60,7 +61,8 @@ public class SplitScreenConstants { public static final int[] CONTROLLED_WINDOWING_MODES = {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED}; public static final int[] CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE = - {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW}; + {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW, + WINDOWING_MODE_FREEFORM}; /** Flag applied to a transition change to identify it as a divider bar for animation. */ public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM; 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 1d46e755ec9d6..633f627e8e71a 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 @@ -18,6 +18,7 @@ package com.android.wm.shell.desktopmode import android.R import android.app.ActivityManager.RunningTaskInfo +import android.app.WindowConfiguration import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM @@ -301,6 +302,24 @@ class DesktopTasksController( } } + /** Move a desktop app to split screen. */ + fun moveToSplit(task: RunningTaskInfo) { + KtProtoLog.v( + WM_SHELL_DESKTOP_MODE, + "DesktopTasksController: moveToSplit taskId=%d", + task.taskId + ) + val wct = WindowContainerTransaction() + wct.setWindowingMode(task.token, WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW) + wct.setBounds(task.token, null) + wct.setDensityDpi(task.token, getDefaultDensityDpi()) + if (Transitions.ENABLE_SHELL_TRANSITIONS) { + transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */) + } else { + shellTaskOrganizer.applyTransaction(wct) + } + } + /** * The second part of the animated move to desktop transition, called after * {@link startMoveToDesktop}. Move a task to fullscreen after being dragged from fullscreen diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 2be7a491fdf20..29fff03500a58 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -71,6 +71,7 @@ import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; +import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.sysui.KeyguardChangeListener; import com.android.wm.shell.sysui.ShellController; @@ -200,6 +201,19 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { @Override public void setSplitScreenController(SplitScreenController splitScreenController) { mSplitScreenController = splitScreenController; + mSplitScreenController.registerSplitScreenListener(new SplitScreen.SplitScreenListener() { + @Override + public void onTaskStageChanged(int taskId, int stage, boolean visible) { + if (visible) { + DesktopModeWindowDecoration decor = mWindowDecorByTaskId.get(taskId); + if (decor != null && DesktopModeStatus.isActive(mContext) + && decor.mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { + mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false)); + mDesktopTasksController.ifPresent(c -> c.moveToSplit(decor.mTaskInfo)); + } + } + } + }); } @Override