Merge changes from topic "embedding-race-condition" into tm-dev am: 87550b067a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17494165

Change-Id: I09ec1ea3f0c867c29018199fd5895ae6a8a04b7d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Shivam Agrawal
2022-04-05 19:46:46 +00:00
committed by Automerger Merge Worker
10 changed files with 74 additions and 16 deletions

View File

@@ -536,6 +536,9 @@ public final class ActivityThread extends ClientTransactionHandler
// A reusable token for other purposes, e.g. content capture, translation. It shouldn't be // A reusable token for other purposes, e.g. content capture, translation. It shouldn't be
// used without security checks // used without security checks
public IBinder shareableActivityToken; public IBinder shareableActivityToken;
// The token of the initial TaskFragment that embedded this activity. Do not rely on it
// after creation because the activity could be reparented.
@Nullable public IBinder mInitialTaskFragmentToken;
int ident; int ident;
@UnsupportedAppUsage @UnsupportedAppUsage
Intent intent; Intent intent;
@@ -618,7 +621,8 @@ public final class ActivityThread extends ClientTransactionHandler
PersistableBundle persistentState, List<ResultInfo> pendingResults, PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions, List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client, boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client,
IBinder assistToken, IBinder shareableActivityToken, boolean launchedFromBubble) { IBinder assistToken, IBinder shareableActivityToken, boolean launchedFromBubble,
IBinder initialTaskFragmentToken) {
this.token = token; this.token = token;
this.assistToken = assistToken; this.assistToken = assistToken;
this.shareableActivityToken = shareableActivityToken; this.shareableActivityToken = shareableActivityToken;
@@ -639,6 +643,7 @@ public final class ActivityThread extends ClientTransactionHandler
compatInfo); compatInfo);
mActivityOptions = activityOptions; mActivityOptions = activityOptions;
mLaunchedFromBubble = launchedFromBubble; mLaunchedFromBubble = launchedFromBubble;
mInitialTaskFragmentToken = initialTaskFragmentToken;
init(); init();
} }

View File

@@ -72,6 +72,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
private IBinder mAssistToken; private IBinder mAssistToken;
private IBinder mShareableActivityToken; private IBinder mShareableActivityToken;
private boolean mLaunchedFromBubble; private boolean mLaunchedFromBubble;
private IBinder mTaskFragmentToken;
/** /**
* It is only non-null if the process is the first time to launch activity. It is only an * It is only non-null if the process is the first time to launch activity. It is only an
* optimization for quick look up of the interface so the field is ignored for comparison. * optimization for quick look up of the interface so the field is ignored for comparison.
@@ -95,7 +96,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo, mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble); client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
mTaskFragmentToken);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */); client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
} }
@@ -119,7 +121,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions, List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken, boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken,
IActivityClientController activityClientController, IBinder shareableActivityToken, IActivityClientController activityClientController, IBinder shareableActivityToken,
boolean launchedFromBubble) { boolean launchedFromBubble, IBinder taskFragmentToken) {
LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class); LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
if (instance == null) { if (instance == null) {
instance = new LaunchActivityItem(); instance = new LaunchActivityItem();
@@ -128,7 +130,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
voiceInteractor, procState, state, persistentState, pendingResults, voiceInteractor, procState, state, persistentState, pendingResults,
pendingNewIntents, activityOptions, isForward, profilerInfo, assistToken, pendingNewIntents, activityOptions, isForward, profilerInfo, assistToken,
activityClientController, shareableActivityToken, activityClientController, shareableActivityToken,
launchedFromBubble); launchedFromBubble, taskFragmentToken);
return instance; return instance;
} }
@@ -136,7 +138,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
@Override @Override
public void recycle() { public void recycle() {
setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null, setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null,
null, false, null, null, null, null, false); null, false, null, null, null, null, false, null);
ObjectPool.recycle(this); ObjectPool.recycle(this);
} }
@@ -166,6 +168,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
dest.writeStrongInterface(mActivityClientController); dest.writeStrongInterface(mActivityClientController);
dest.writeStrongBinder(mShareableActivityToken); dest.writeStrongBinder(mShareableActivityToken);
dest.writeBoolean(mLaunchedFromBubble); dest.writeBoolean(mLaunchedFromBubble);
dest.writeStrongBinder(mTaskFragmentToken);
} }
/** Read from Parcel. */ /** Read from Parcel. */
@@ -184,7 +187,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
in.readStrongBinder(), in.readStrongBinder(),
IActivityClientController.Stub.asInterface(in.readStrongBinder()), IActivityClientController.Stub.asInterface(in.readStrongBinder()),
in.readStrongBinder(), in.readStrongBinder(),
in.readBoolean()); in.readBoolean(),
in.readStrongBinder());
} }
public static final @NonNull Creator<LaunchActivityItem> CREATOR = public static final @NonNull Creator<LaunchActivityItem> CREATOR =
@@ -222,7 +226,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
&& mIsForward == other.mIsForward && mIsForward == other.mIsForward
&& Objects.equals(mProfilerInfo, other.mProfilerInfo) && Objects.equals(mProfilerInfo, other.mProfilerInfo)
&& Objects.equals(mAssistToken, other.mAssistToken) && Objects.equals(mAssistToken, other.mAssistToken)
&& Objects.equals(mShareableActivityToken, other.mShareableActivityToken); && Objects.equals(mShareableActivityToken, other.mShareableActivityToken)
&& Objects.equals(mTaskFragmentToken, other.mTaskFragmentToken);
} }
@Override @Override
@@ -244,6 +249,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
result = 31 * result + Objects.hashCode(mProfilerInfo); result = 31 * result + Objects.hashCode(mProfilerInfo);
result = 31 * result + Objects.hashCode(mAssistToken); result = 31 * result + Objects.hashCode(mAssistToken);
result = 31 * result + Objects.hashCode(mShareableActivityToken); result = 31 * result + Objects.hashCode(mShareableActivityToken);
result = 31 * result + Objects.hashCode(mTaskFragmentToken);
return result; return result;
} }
@@ -291,7 +297,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo, ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo,
IBinder assistToken, IActivityClientController activityClientController, IBinder assistToken, IActivityClientController activityClientController,
IBinder shareableActivityToken, boolean launchedFromBubble) { IBinder shareableActivityToken, boolean launchedFromBubble, IBinder taskFragmentToken) {
instance.mIntent = intent; instance.mIntent = intent;
instance.mIdent = ident; instance.mIdent = ident;
instance.mInfo = info; instance.mInfo = info;
@@ -312,5 +318,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
instance.mActivityClientController = activityClientController; instance.mActivityClientController = activityClientController;
instance.mShareableActivityToken = shareableActivityToken; instance.mShareableActivityToken = shareableActivityToken;
instance.mLaunchedFromBubble = launchedFromBubble; instance.mLaunchedFromBubble = launchedFromBubble;
instance.mTaskFragmentToken = taskFragmentToken;
} }
} }

View File

@@ -157,7 +157,7 @@ public class ObjectPoolTests {
.setPendingResults(resultInfoList()).setPendingNewIntents(referrerIntentList()) .setPendingResults(resultInfoList()).setPendingNewIntents(referrerIntentList())
.setIsForward(true).setAssistToken(assistToken) .setIsForward(true).setAssistToken(assistToken)
.setShareableActivityToken(shareableActivityToken) .setShareableActivityToken(shareableActivityToken)
.build(); .setTaskFragmentToken(new Binder()).build();
LaunchActivityItem emptyItem = new LaunchActivityItemBuilder().build(); LaunchActivityItem emptyItem = new LaunchActivityItemBuilder().build();
LaunchActivityItem item = itemSupplier.get(); LaunchActivityItem item = itemSupplier.get();

View File

@@ -110,6 +110,7 @@ class TestUtils {
private IBinder mAssistToken; private IBinder mAssistToken;
private IBinder mShareableActivityToken; private IBinder mShareableActivityToken;
private boolean mLaunchedFromBubble; private boolean mLaunchedFromBubble;
private IBinder mTaskFragmentToken;
LaunchActivityItemBuilder setIntent(Intent intent) { LaunchActivityItemBuilder setIntent(Intent intent) {
mIntent = intent; mIntent = intent;
@@ -206,13 +207,18 @@ class TestUtils {
return this; return this;
} }
LaunchActivityItemBuilder setTaskFragmentToken(IBinder taskFragmentToken) {
mTaskFragmentToken = taskFragmentToken;
return this;
}
LaunchActivityItem build() { LaunchActivityItem build() {
return LaunchActivityItem.obtain(mIntent, mIdent, mInfo, return LaunchActivityItem.obtain(mIntent, mIdent, mInfo,
mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor,
mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents, mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents,
mActivityOptions, mIsForward, mProfilerInfo, mAssistToken, mActivityOptions, mIsForward, mProfilerInfo, mAssistToken,
null /* activityClientController */, mShareableActivityToken, null /* activityClientController */, mShareableActivityToken,
mLaunchedFromBubble); mLaunchedFromBubble, mTaskFragmentToken);
} }
} }
} }

View File

@@ -203,6 +203,7 @@ public class TransactionParcelTests {
.setPendingResults(resultInfoList()).setActivityOptions(ActivityOptions.makeBasic()) .setPendingResults(resultInfoList()).setActivityOptions(ActivityOptions.makeBasic())
.setPendingNewIntents(referrerIntentList()).setIsForward(true) .setPendingNewIntents(referrerIntentList()).setIsForward(true)
.setAssistToken(new Binder()).setShareableActivityToken(new Binder()) .setAssistToken(new Binder()).setShareableActivityToken(new Binder())
.setTaskFragmentToken(new Binder())
.build(); .build();
writeAndPrepareForReading(item); writeAndPrepareForReading(item);

View File

@@ -345,7 +345,7 @@ public class ActivityThreadClientTest {
null /* pendingResults */, null /* pendingNewIntents */, null /* pendingResults */, null /* pendingNewIntents */,
null /* activityOptions */, true /* isForward */, null /* profilerInfo */, null /* activityOptions */, true /* isForward */, null /* profilerInfo */,
mThread /* client */, null /* asssitToken */, null /* shareableActivityToken */, mThread /* client */, null /* asssitToken */, null /* shareableActivityToken */,
false /* launchedFromBubble */); false /* launchedFromBubble */, null /* taskfragmentToken */);
} }
@Override @Override

View File

@@ -615,14 +615,22 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return null; return null;
} }
private void updateCallbackIfNecessary() {
updateCallbackIfNecessary(true /* deferCallbackUntilAllActivitiesCreated */);
}
/** /**
* Notifies listeners about changes to split states if necessary. * Notifies listeners about changes to split states if necessary.
*
* @param deferCallbackUntilAllActivitiesCreated boolean to indicate whether the split info
* callback should be deferred until all the
* organized activities have been created.
*/ */
private void updateCallbackIfNecessary() { private void updateCallbackIfNecessary(boolean deferCallbackUntilAllActivitiesCreated) {
if (mEmbeddingCallback == null) { if (mEmbeddingCallback == null) {
return; return;
} }
if (!allActivitiesCreated()) { if (deferCallbackUntilAllActivitiesCreated && !allActivitiesCreated()) {
return; return;
} }
List<SplitInfo> currentSplitStates = getActiveSplitStates(); List<SplitInfo> currentSplitStates = getActiveSplitStates();
@@ -837,6 +845,36 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter { private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
@Override
public void onActivityPreCreated(Activity activity, Bundle savedInstanceState) {
final IBinder activityToken = activity.getActivityToken();
final IBinder initialTaskFragmentToken = ActivityThread.currentActivityThread()
.getActivityClient(activityToken).mInitialTaskFragmentToken;
// If the activity is not embedded, then it will not have an initial task fragment token
// so no further action is needed.
if (initialTaskFragmentToken == null) {
return;
}
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i)
.mContainers;
for (int j = containers.size() - 1; j >= 0; j--) {
final TaskFragmentContainer container = containers.get(j);
if (!container.hasActivity(activityToken)
&& container.getTaskFragmentToken().equals(initialTaskFragmentToken)) {
// The onTaskFragmentInfoChanged callback containing this activity has not
// reached the client yet, so add the activity to the pending appeared
// activities and send a split info callback to the client before
// {@link Activity#onCreate} is called.
container.addPendingAppearedActivity(activity);
updateCallbackIfNecessary(
false /* deferCallbackUntilAllActivitiesCreated */);
return;
}
}
}
}
@Override @Override
public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) { public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) {
// Calling after Activity#onCreate is complete to allow the app launch something // Calling after Activity#onCreate is complete to allow the app launch something

View File

@@ -120,7 +120,7 @@ class TaskFragmentContainer {
} }
ActivityStack toActivityStack() { ActivityStack toActivityStack() {
return new ActivityStack(collectActivities(), mInfo.getRunningActivityCount() == 0); return new ActivityStack(collectActivities(), isEmpty());
} }
void addPendingAppearedActivity(@NonNull Activity pendingAppearedActivity) { void addPendingAppearedActivity(@NonNull Activity pendingAppearedActivity) {

View File

@@ -897,6 +897,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
proc.getThread(), r.token); proc.getThread(), r.token);
final boolean isTransitionForward = r.isTransitionForward(); final boolean isTransitionForward = r.isTransitionForward();
final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info, System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global // TODO: Have this take the merged configuration instead of separate global
@@ -907,7 +908,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(), proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
results, newIntents, r.takeOptions(), isTransitionForward, results, newIntents, r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController, proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.shareableActivityToken, r.getLaunchedFromBubble())); r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
// Set desired final state. // Set desired final state.
final ActivityLifecycleItem lifecycleItem; final ActivityLifecycleItem lifecycleItem;

View File

@@ -2262,7 +2262,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mFragmentToken, mFragmentToken,
mRemoteToken.toWindowContainerToken(), mRemoteToken.toWindowContainerToken(),
getConfiguration(), getConfiguration(),
getChildCount() == 0, runningActivityCount[0] == 0,
runningActivityCount[0], runningActivityCount[0],
isVisible(), isVisible(),
childActivities, childActivities,