summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Wale Ogunwale <ogunwale@google.com> 2021-01-21 13:42:32 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-01-21 13:42:32 +0000
commit17d13191a16c6699e8f792d7b719634ac6e5c13c (patch)
treee95b22cc6ff288ea3f360468c31025dc7ea03498
parentf7e2d64c489968d56566eaf7c96881da570990a1 (diff)
parentb819178d2ffd07c3f32287e65ee1fb3c5b7a34a6 (diff)
Merge "Add support for ActivityOptions#setLaunchRootTask"
-rw-r--r--core/java/android/app/ActivityOptions.java26
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java1
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java8
-rw-r--r--services/core/java/com/android/server/wm/Task.java15
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java33
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java3
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);
}
}