summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/WindowContainerTransaction.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java20
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java11
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java8
9 files changed, 65 insertions, 29 deletions
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index a87b91d87f1c..3bffa890122a 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -348,8 +348,10 @@ public final class WindowContainerTransaction implements Parcelable {
* @param currentParent of the tasks to perform the operation no.
* {@code null} will perform the operation on the display.
* @param newParent for the tasks. {@code null} will perform the operation on the display.
- * @param windowingModes of the tasks to reparent.
- * @param activityTypes of the tasks to reparent.
+ * @param windowingModes of the tasks to reparent. {@code null} ignore this attribute when
+ * perform the operation.
+ * @param activityTypes of the tasks to reparent. {@code null} ignore this attribute when
+ * perform the operation.
* @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to
* the bottom.
*/
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 9b614875119b..afc706ee9c8e 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
@@ -15,6 +15,11 @@
*/
package com.android.wm.shell.common.split;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+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;
+
import android.annotation.IntDef;
/** Helper utility class of methods and constants that are available to be imported in Launcher. */
@@ -44,4 +49,10 @@ public class SplitScreenConstants {
})
public @interface SplitPosition {
}
+
+ public static final int[] CONTROLLED_ACTIVITY_TYPES = {ACTIVITY_TYPE_STANDARD};
+ 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};
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index 2bfa5db502ce..e7ec15e70c11 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -16,6 +16,9 @@
package com.android.wm.shell.splitscreen;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
+
import android.content.Context;
import android.view.SurfaceSession;
import android.window.WindowContainerToken;
@@ -74,10 +77,10 @@ class MainStage extends StageTaskListener {
if (mRootTaskInfo == null) return;
final WindowContainerToken rootToken = mRootTaskInfo.token;
wct.reparentTasks(
- rootToken,
- null /* newParent */,
- CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
- CONTROLLED_ACTIVITY_TYPES,
- toTop);
+ rootToken,
+ null /* newParent */,
+ null /* windowingModes */,
+ null /* activityTypes */,
+ toTop);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index f92a0d3901b9..8639b36faf4c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -47,8 +47,8 @@ class SideStage extends StageTaskListener {
wct.reparentTasks(
mRootTaskInfo.token,
null /* newParent */,
- CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
- CONTROLLED_ACTIVITY_TYPES,
+ null /* windowingModes */,
+ null /* activityTypes */,
toTop);
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index c8ee010e60e0..47bfaa64c831 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -26,6 +26,8 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -64,6 +66,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -227,6 +230,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
&& mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
}
+ public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+ return taskInfo.supportsMultiWindow
+ && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+ && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
+ }
+
public @SplitPosition int getSplitPosition(int taskId) {
return mStageCoordinator.getSplitPosition(taskId);
}
@@ -463,11 +472,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return Objects.equals(launchingActivity, pairedActivity);
}
- if (mFocusingTaskInfo != null
- // TODO (b/238032411): have an API to determine whether an activity is valid for
- // split screen or not.
- && mFocusingTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
- && mFocusingTaskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD) {
+ if (mFocusingTaskInfo != null && isValidToEnterSplitScreen(mFocusingTaskInfo)) {
return Objects.equals(mFocusingTaskInfo.baseIntent.getComponent(), launchingActivity);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 70d728d90b6a..e19c572c4850 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -87,6 +87,7 @@ import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.WindowManager;
+import android.widget.Toast;
import android.window.DisplayAreaInfo;
import android.window.RemoteTransition;
import android.window.TransitionInfo;
@@ -98,6 +99,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.common.ProtoLog;
import com.android.launcher3.icons.IconProvider;
+import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
@@ -1921,10 +1923,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override
public void onNoLongerSupportMultiWindow() {
if (mMainStage.isActive()) {
+ final Toast splitUnsupportedToast = Toast.makeText(mContext,
+ R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
final boolean isMainStage = mMainStageListener == this;
if (!ENABLE_SHELL_TRANSITIONS) {
StageCoordinator.this.exitSplitScreen(isMainStage ? mMainStage : mSideStage,
EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
+ splitUnsupportedToast.show();
return;
}
@@ -1933,6 +1938,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
prepareExitSplitScreen(stageType, wct);
mSplitTransitions.startDismissTransition(wct,StageCoordinator.this, stageType,
EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
+ splitUnsupportedToast.show();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index cb9e1a39ec52..d17ff7aff667 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -17,12 +17,12 @@
package com.android.wm.shell.splitscreen;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE;
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
import android.annotation.CallSuper;
@@ -40,6 +40,7 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
+import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.SurfaceUtils;
@@ -62,12 +63,6 @@ import java.util.function.Predicate;
class StageTaskListener implements ShellTaskOrganizer.TaskListener {
private static final String TAG = StageTaskListener.class.getSimpleName();
- protected static final int[] CONTROLLED_ACTIVITY_TYPES = {ACTIVITY_TYPE_STANDARD};
- protected static final int[] CONTROLLED_WINDOWING_MODES =
- {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED};
- protected static final int[] CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE =
- {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW};
-
/** Callback interface for listening to changes in a split-screen stage. */
public interface StageListenerCallbacks {
void onRootTaskAppeared();
@@ -212,12 +207,15 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
mRootTaskInfo = taskInfo;
} else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
- if (!taskInfo.supportsMultiWindow) {
- // Leave split screen if the task no longer supports multi window.
+ if (!taskInfo.supportsMultiWindow
+ || !ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+ || !ArrayUtils.contains(CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
+ taskInfo.getWindowingMode())) {
+ // Leave split screen if the task no longer supports multi window or have
+ // uncontrolled task.
mCallbacks.onNoLongerSupportMultiWindow();
return;
}
-
mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
taskInfo.isVisible);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index e9c1acbf7ca0..e3f568732b9d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -18,6 +18,9 @@ package com.android.systemui.shared.recents.model;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
+
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.app.TaskInfo;
@@ -31,6 +34,8 @@ import android.view.ViewDebug;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.util.ArrayUtils;
+
import java.io.PrintWriter;
import java.util.Objects;
@@ -242,8 +247,10 @@ public class Task {
ActivityManager.TaskDescription td = taskInfo.taskDescription;
return new Task(taskKey,
td != null ? td.getPrimaryColor() : 0,
- td != null ? td.getBackgroundColor() : 0,
- taskInfo.supportsMultiWindow, isLocked, td, taskInfo.topActivity);
+ td != null ? td.getBackgroundColor() : 0, taskInfo.supportsMultiWindow
+ && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+ && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()),
+ isLocked, td, taskInfo.topActivity);
}
public Task(TaskKey key) {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 4bbb1b1fb745..6bb5eceec84e 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -1235,8 +1235,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
+ " task=" + task);
return false;
}
- if (!ArrayUtils.contains(hop.getActivityTypes(), task.getActivityType())
- || !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) {
+ if (!ArrayUtils.isEmpty(hop.getActivityTypes())
+ && !ArrayUtils.contains(hop.getActivityTypes(), task.getActivityType())) {
+ return false;
+ }
+ if (!ArrayUtils.isEmpty(hop.getWindowingModes())
+ && !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) {
return false;
}
if (isLockTaskModeViolation(finalNewParent, task, isInLockTaskMode)) {