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
This commit is contained in:
Louis Chang
2021-07-21 12:12:22 +08:00
parent ede423187b
commit ca43bb061b
5 changed files with 19 additions and 6 deletions

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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();

View File

@@ -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");

View File

@@ -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