diff options
| author | 2021-01-21 13:42:32 +0000 | |
|---|---|---|
| committer | 2021-01-21 13:42:32 +0000 | |
| commit | 17d13191a16c6699e8f792d7b719634ac6e5c13c (patch) | |
| tree | e95b22cc6ff288ea3f360468c31025dc7ea03498 | |
| parent | f7e2d64c489968d56566eaf7c96881da570990a1 (diff) | |
| parent | b819178d2ffd07c3f32287e65ee1fb3c5b7a34a6 (diff) | |
Merge "Add support for ActivityOptions#setLaunchRootTask"
6 files changed, 74 insertions, 12 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index d0d5df91a2a3..baf21eda6725 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -199,6 +199,14 @@ public class ActivityOptions { "android.activity.launchTaskDisplayAreaToken"; /** + * The root task token the activity should be launched into. + * @see #setLaunchRootTask(WindowContainerToken) + * @hide + */ + public static final String KEY_LAUNCH_ROOT_TASK_TOKEN = + "android.activity.launchRootTaskToken"; + + /** * The windowing mode the activity should be launched into. * @hide */ @@ -306,7 +314,7 @@ public class ActivityOptions { * @see #setLaunchCookie * @hide */ - private static final String KEY_LAUNCH_COOKIE = "android.activity.launchCookie"; + public static final String KEY_LAUNCH_COOKIE = "android.activity.launchCookie"; /** @hide */ public static final int ANIM_UNDEFINED = -1; @@ -362,6 +370,7 @@ public class ActivityOptions { private int mLaunchDisplayId = INVALID_DISPLAY; private int mCallerDisplayId = INVALID_DISPLAY; private WindowContainerToken mLaunchTaskDisplayArea; + private WindowContainerToken mLaunchRootTask; @WindowConfiguration.WindowingMode private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED; @WindowConfiguration.ActivityType @@ -1050,6 +1059,7 @@ public class ActivityOptions { mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY); mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY); mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN); + mLaunchRootTask = opts.getParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN); mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED); mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED); mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1); @@ -1342,6 +1352,17 @@ public class ActivityOptions { } /** @hide */ + public WindowContainerToken getLaunchRootTask() { + return mLaunchRootTask; + } + + /** @hide */ + public ActivityOptions setLaunchRootTask(WindowContainerToken windowContainerToken) { + mLaunchRootTask = windowContainerToken; + return this; + } + + /** @hide */ public int getLaunchWindowingMode() { return mLaunchWindowingMode; } @@ -1692,6 +1713,9 @@ public class ActivityOptions { if (mLaunchTaskDisplayArea != null) { b.putParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, mLaunchTaskDisplayArea); } + if (mLaunchRootTask != null) { + b.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, mLaunchRootTask); + } if (mLaunchWindowingMode != WINDOWING_MODE_UNDEFINED) { b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode); } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index e67210e42cc8..3489d503e499 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2340,6 +2340,7 @@ class ActivityStarter { mDoResume = false; mAvoidMoveToFront = true; } + mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); } mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null; diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index d8b1e188e34a..2dd22e95bf32 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2858,6 +2858,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final WindowContainerToken daToken = options.getLaunchTaskDisplayArea(); taskDisplayArea = daToken != null ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; + + final Task rootTask = Task.fromWindowContainerToken(options.getLaunchRootTask()); + if (rootTask != null) { + return rootTask; + } } // First preference for stack goes to the task Id set in the activity options. Use the stack @@ -3032,7 +3037,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final int activityType = options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED ? options.getLaunchActivityType() : r.getActivityType(); - return taskDisplayArea.createRootTask(windowingMode, activityType, true /*onTop*/); + return taskDisplayArea.createRootTask( + windowingMode, activityType, true /*onTop*/, options); } return null; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 2295ee35a4fb..91fc38145af1 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -209,6 +209,7 @@ import android.view.WindowManager.TransitionOldType; import android.window.ITaskOrganizer; import android.window.StartingWindowInfo; import android.window.TaskSnapshot; +import android.window.WindowContainerToken; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -880,6 +881,11 @@ class Task extends WindowContainer<WindowContainer> { EventLogTags.writeWmTaskCreated(mTaskId, isRootTask() ? INVALID_TASK_ID : getRootTaskId()); } + static Task fromWindowContainerToken(WindowContainerToken token) { + if (token == null) return null; + return fromBinder(token.asBinder()).asTask(); + } + Task reuseAsLeafTask(IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, Intent intent, ActivityInfo info, ActivityRecord activity) { voiceSession = _voiceSession; @@ -7380,6 +7386,7 @@ class Task extends WindowContainer<WindowContainer> { task = new Task.Builder(mAtmService) .setTaskId(taskId) .setActivityInfo(info) + .setActivityOptions(options) .setIntent(intent) .setVoiceSession(voiceSession) .setVoiceInteractor(voiceInteractor) @@ -7819,6 +7826,7 @@ class Task extends WindowContainer<WindowContainer> { private int mMinWidth = INVALID_MIN_SIZE; private int mMinHeight = INVALID_MIN_SIZE; private ActivityInfo mActivityInfo; + private ActivityOptions mActivityOptions; private IVoiceInteractionSession mVoiceSession; private IVoiceInteractor mVoiceInteractor; private int mActivityType; @@ -7872,6 +7880,11 @@ class Task extends WindowContainer<WindowContainer> { return this; } + Builder setActivityOptions(ActivityOptions opts) { + mActivityOptions = opts; + return this; + } + Builder setVoiceSession(IVoiceInteractionSession voiceSession) { mVoiceSession = voiceSession; return this; @@ -8078,7 +8091,7 @@ class Task extends WindowContainer<WindowContainer> { // Task created by organizer are added as root. final Task launchRootTask = mCreatedByOrganizer - ? null : tda.getLaunchRootTask(mWindowingMode, mActivityType); + ? null : tda.getLaunchRootTask(mWindowingMode, mActivityType, mActivityOptions); if (launchRootTask != null) { // Since this task will be put into a root task, its windowingMode will be // inherited. diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 0136c010429b..74d5f1fd1054 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -48,6 +48,7 @@ import android.os.UserHandle; import android.util.IntArray; import android.util.Slog; import android.view.SurfaceControl; +import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import com.android.internal.annotations.VisibleForTesting; @@ -997,11 +998,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { * Returns an existing stack compatible with the windowing mode and activity type or creates one * if a compatible stack doesn't exist. * - * @see #getOrCreateRootTask(int, int, boolean, Intent, Task) + * @see #getOrCreateRootTask(int, int, boolean, Intent, Task, ActivityOptions) */ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop) { return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */, - null /* candidateTask */); + null /* candidateTask */, null /* options */); } /** @@ -1014,7 +1015,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { * @see #createRootTask(int, int, boolean) */ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop, - Intent intent, Task candidateTask) { + Intent intent, Task candidateTask, ActivityOptions options) { // Need to pass in a determined windowing mode to see if a new stack should be created, // so use its parent's windowing mode if it is undefined. if (!alwaysCreateRootTask( @@ -1027,7 +1028,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } else if (candidateTask != null) { final Task stack = candidateTask; final int position = onTop ? POSITION_TOP : POSITION_BOTTOM; - final Task launchRootTask = getLaunchRootTask(windowingMode, activityType); + final Task launchRootTask = getLaunchRootTask(windowingMode, activityType, options); if (launchRootTask != null) { if (stack.getParent() == null) { @@ -1054,6 +1055,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { .setOnTop(onTop) .setParent(this) .setIntent(intent) + .setActivityOptions(options) .build(); } @@ -1074,7 +1076,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { // it's display's windowing mode. windowingMode = validateWindowingMode(windowingMode, r, candidateTask, activityType); return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */, - candidateTask); + candidateTask, options); } @VisibleForTesting @@ -1082,6 +1084,10 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { return mAtmService.mTaskSupervisor.getNextTaskIdForUser(); } + Task createRootTask(int windowingMode, int activityType, boolean onTop) { + return createRootTask(windowingMode, activityType, onTop, null /* activityOptions */); + } + /** * A convinenit method of creating a root task by providing windowing mode and activity type * on this display. @@ -1095,14 +1101,16 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}. * @param onTop If true the root task will be created at the top of the display, * else at the bottom. + * @param opts The activity options. * @return The newly created root task. */ - Task createRootTask(int windowingMode, int activityType, boolean onTop) { + Task createRootTask(int windowingMode, int activityType, boolean onTop, ActivityOptions opts) { return new Task.Builder(mAtmService) .setWindowingMode(windowingMode) .setActivityType(activityType) .setParent(this) .setOnTop(onTop) + .setActivityOptions(opts) .build(); } @@ -1134,7 +1142,16 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } } - Task getLaunchRootTask(int windowingMode, int activityType) { + Task getLaunchRootTask(int windowingMode, int activityType, ActivityOptions options) { + // Try to use the launch root task in options if available. + if (options != null) { + final Task launchRootTask = Task.fromWindowContainerToken(options.getLaunchRootTask()); + // We only allow this for created by organizer tasks. + if (launchRootTask != null && launchRootTask.mCreatedByOrganizer) { + return launchRootTask; + } + } + for (int i = mLaunchRootTasks.size() - 1; i >= 0; --i) { if (mLaunchRootTasks.get(i).contains(windowingMode, activityType)) { return mLaunchRootTasks.get(i).task; @@ -1866,7 +1883,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { // Reparent task to corresponding launch root or display area. final WindowContainer launchRoot = task.supportsSplitScreenWindowingMode() ? toDisplayArea.getLaunchRootTask( - task.getWindowingMode(), task.getActivityType()) + task.getWindowingMode(), task.getActivityType(), null /* options */) : null; task.reparent(launchRoot == null ? toDisplayArea : launchRoot, POSITION_TOP); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index 10d2da00a852..d83e9c21fae7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -352,7 +352,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { boolean reuseCandidate) { final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); final Task rootTask = taskDisplayArea.getOrCreateRootTask(windowingMode, activityType, - false /* onTop */, null /* intent */, candidateTask /* candidateTask */); + false /* onTop */, null /* intent */, candidateTask /* candidateTask */, + null /* activityOptions */); assertEquals(reuseCandidate, rootTask == candidateTask); } } |