Merge "Handle the uncontrolled task in split-screen" into tm-qpr-dev am: 9e73750458
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19166690 Change-Id: Id239035fb76ebfc0b7eff00c8686e87a8af93131 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user