From ca43bb061b4071e8933a8d22fceb493663000971 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Wed, 21 Jul 2021 12:12:22 +0800 Subject: [PATCH] Providing caller's token when starting activity in TaskFragment NEW_TASK flag was added by ATMS when #startActivityInTaskFragment is called because the activity was started without source record. Bug: 193846941 Test: starting CCT in sample app Change-Id: Ida26034324f7ff761f1e688403d78959a01f010d --- .../android/window/WindowContainerTransaction.java | 11 +++++++++-- .../organizer/JetpackTaskFragmentOrganizer.java | 3 ++- .../android/server/wm/ActivityStartController.java | 6 +++++- .../android/server/wm/WindowOrganizerController.java | 3 ++- .../wm/TaskFragmentOrganizerControllerTest.java | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 3c360fb99f42b..095be8c00419e 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -443,6 +443,7 @@ public final class WindowContainerTransaction implements Parcelable { * Starts an activity in the TaskFragment. * @param fragmentToken client assigned unique token to create TaskFragment with specified in * {@link TaskFragmentCreationParams#fragmentToken}. + * @param callerToken the activity token that initialized the activity launch. * @param activityIntent intent to start the activity. * @param activityOptions ActivityOptions to start the activity with. * @see android.content.Context#startActivity(Intent, Bundle). @@ -450,12 +451,13 @@ public final class WindowContainerTransaction implements Parcelable { */ @NonNull public WindowContainerTransaction startActivityInTaskFragment( - @NonNull IBinder fragmentToken, @NonNull Intent activityIntent, - @Nullable Bundle activityOptions) { + @NonNull IBinder fragmentToken, @NonNull IBinder callerToken, + @NonNull Intent activityIntent, @Nullable Bundle activityOptions) { final HierarchyOp hierarchyOp = new HierarchyOp.Builder( HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT) .setContainer(fragmentToken) + .setReparentContainer(callerToken) .setActivityIntent(activityIntent) .setLaunchOptions(activityOptions) .build(); @@ -1060,6 +1062,11 @@ public final class WindowContainerTransaction implements Parcelable { return mReparent; } + @NonNull + public IBinder getCallingActivity() { + return mReparent; + } + public boolean getToTop() { return mToTop; } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java index 48d78cf10a2af..d84554b59c2aa 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java @@ -175,7 +175,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { final TaskFragmentCreationParams fragmentOptions = createFragmentOptions(fragmentToken, ownerToken, bounds, windowingMode); wct.createTaskFragment(fragmentOptions) - .startActivityInTaskFragment(fragmentToken, activityIntent, activityOptions); + .startActivityInTaskFragment(fragmentToken, ownerToken, activityIntent, + activityOptions); } TaskFragmentCreationParams createFragmentOptions(IBinder fragmentToken, IBinder ownerToken, diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index c3cd61ac8678c..b71ad2ea71021 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -495,13 +495,17 @@ public class ActivityStartController { * @param taskFragment TaskFragment {@link TaskFragment} to start the activity in. * @param activityIntent intent to start the activity. * @param activityOptions ActivityOptions to start the activity with. + * @param resultTo the caller activity * @return the start result. */ int startActivityInTaskFragment(@NonNull TaskFragment taskFragment, - @NonNull Intent activityIntent, @Nullable Bundle activityOptions) { + @NonNull Intent activityIntent, @Nullable Bundle activityOptions, + @Nullable IBinder resultTo) { return obtainStarter(activityIntent, "startActivityInTaskFragment") .setActivityOptions(activityOptions) .setInTaskFragment(taskFragment) + .setResultTo(resultTo) + .setRequestCode(-1) .setCallingUid(Binder.getCallingUid()) .setCallingPid(Binder.getCallingPid()) .execute(); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index e31b1302a8918..1788a527147bb 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -683,7 +683,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub final Bundle activityOptions = hop.getLaunchOptions(); final TaskFragment tf = mLaunchTaskFragments.get(fragmentToken); final int result = mService.getActivityStartController() - .startActivityInTaskFragment(tf, activityIntent, activityOptions); + .startActivityInTaskFragment(tf, activityIntent, activityOptions, + hop.getCallingActivity()); if (!isStartResultSuccessful(result)) { final Throwable exception = new ActivityNotFoundException("start activity in taskFragment failed"); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index 3dd3e81006eff..025da846245dc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -319,7 +319,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment. mTransaction.createTaskFragment(mock(TaskFragmentCreationParams.class)); mTransaction.startActivityInTaskFragment( - mFragmentToken, new Intent(), null /* activityOptions */); + mFragmentToken, null /* callerToken */, new Intent(), null /* activityOptions */); mTransaction.reparentActivityToTaskFragment(mFragmentToken, mock(IBinder.class)); // It is expected to fail for the mock TaskFragmentCreationParams. It is ok as we are