From 627b8571919669973ff031cbc58a1377b69fe8aa Mon Sep 17 00:00:00 2001 From: Jeff Chang Date: Mon, 19 Sep 2022 19:14:27 +0800 Subject: [PATCH] Launch all activities into the same root task When multiple activities are launched through a PendingIntent, all activities need to be launched onto the same root task. To ensure that, the launch root task information from the passed-in SafeActivityOptions object are used to create a new SafeActivityOptions object for bottom activities. Bug: 243630981 Test: Drag and drop "new conversation" shortcut of Messages to split atest test_selectiveCloneLunchRootTask Change-Id: I437db94f0019cf561464527147da08ccf4ac4cd3 --- .../server/wm/ActivityStartController.java | 6 +++--- .../android/server/wm/SafeActivityOptions.java | 17 +++++++++-------- .../server/wm/SafeActivityOptionsTest.java | 12 +++++++++++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index 30454d45574eb..9f502ab6ca103 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -389,9 +389,9 @@ public class ActivityStartController { SafeActivityOptions bottomOptions = null; if (options != null) { // To ensure the first N-1 activities (N == total # of activities) are also launched - // into the correct display, use a copy of the passed-in options (keeping only - // display-related info) for these activities. - bottomOptions = options.selectiveCloneDisplayOptions(); + // into the correct display and root task, use a copy of the passed-in options (keeping + // only display-related and launch-root-task information) for these activities. + bottomOptions = options.selectiveCloneLaunchOptions(); } try { intents = ArrayUtils.filterNotNull(intents, Intent[]::new); diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java index e69a732b3fdea..6d1b5fa6034dc 100644 --- a/services/core/java/com/android/server/wm/SafeActivityOptions.java +++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java @@ -117,13 +117,13 @@ public class SafeActivityOptions { /** * To ensure that two activities, one using this object, and the other using the - * SafeActivityOptions returned from this function, are launched into the same display through - * ActivityStartController#startActivities, all display-related information, i.e. - * displayAreaToken, launchDisplayId and callerDisplayId, are cloned. + * SafeActivityOptions returned from this function, are launched into the same display/root task + * through ActivityStartController#startActivities, all display-related information, i.e. + * displayAreaToken, launchDisplayId, callerDisplayId and the launch root task are cloned. */ - @Nullable SafeActivityOptions selectiveCloneDisplayOptions() { - final ActivityOptions options = cloneLaunchingDisplayOptions(mOriginalOptions); - final ActivityOptions callerOptions = cloneLaunchingDisplayOptions(mCallerOptions); + @Nullable SafeActivityOptions selectiveCloneLaunchOptions() { + final ActivityOptions options = cloneLaunchingOptions(mOriginalOptions); + final ActivityOptions callerOptions = cloneLaunchingOptions(mCallerOptions); if (options == null && callerOptions == null) { return null; } @@ -136,11 +136,12 @@ public class SafeActivityOptions { return safeOptions; } - private ActivityOptions cloneLaunchingDisplayOptions(ActivityOptions options) { + private ActivityOptions cloneLaunchingOptions(ActivityOptions options) { return options == null ? null : ActivityOptions.makeBasic() .setLaunchTaskDisplayArea(options.getLaunchTaskDisplayArea()) .setLaunchDisplayId(options.getLaunchDisplayId()) - .setCallerDisplayId((options.getCallerDisplayId())); + .setCallerDisplayId(options.getCallerDisplayId()) + .setLaunchRootTask(options.getLaunchRootTask()); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java index e57ad5d9ff8cc..24e932f36f803 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java @@ -57,10 +57,20 @@ public class SafeActivityOptionsTest { .setLaunchTaskDisplayArea(token) .setLaunchDisplayId(launchDisplayId) .setCallerDisplayId(callerDisplayId)) - .selectiveCloneDisplayOptions(); + .selectiveCloneLaunchOptions(); assertSame(clone.getOriginalOptions().getLaunchTaskDisplayArea(), token); assertEquals(clone.getOriginalOptions().getLaunchDisplayId(), launchDisplayId); assertEquals(clone.getOriginalOptions().getCallerDisplayId(), callerDisplayId); } + + @Test + public void test_selectiveCloneLunchRootTask() { + final WindowContainerToken token = mock(WindowContainerToken.class); + final SafeActivityOptions clone = new SafeActivityOptions(ActivityOptions.makeBasic() + .setLaunchRootTask(token)) + .selectiveCloneLaunchOptions(); + + assertSame(clone.getOriginalOptions().getLaunchRootTask(), token); + } }