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:
@@ -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
|
||||
// used without security checks
|
||||
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;
|
||||
@UnsupportedAppUsage
|
||||
Intent intent;
|
||||
@@ -618,7 +621,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
PersistableBundle persistentState, List<ResultInfo> pendingResults,
|
||||
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
|
||||
boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client,
|
||||
IBinder assistToken, IBinder shareableActivityToken, boolean launchedFromBubble) {
|
||||
IBinder assistToken, IBinder shareableActivityToken, boolean launchedFromBubble,
|
||||
IBinder initialTaskFragmentToken) {
|
||||
this.token = token;
|
||||
this.assistToken = assistToken;
|
||||
this.shareableActivityToken = shareableActivityToken;
|
||||
@@ -639,6 +643,7 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
compatInfo);
|
||||
mActivityOptions = activityOptions;
|
||||
mLaunchedFromBubble = launchedFromBubble;
|
||||
mInitialTaskFragmentToken = initialTaskFragmentToken;
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
private IBinder mAssistToken;
|
||||
private IBinder mShareableActivityToken;
|
||||
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
|
||||
* 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,
|
||||
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
|
||||
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
|
||||
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble);
|
||||
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
|
||||
mTaskFragmentToken);
|
||||
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
@@ -119,7 +121,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
|
||||
boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken,
|
||||
IActivityClientController activityClientController, IBinder shareableActivityToken,
|
||||
boolean launchedFromBubble) {
|
||||
boolean launchedFromBubble, IBinder taskFragmentToken) {
|
||||
LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
|
||||
if (instance == null) {
|
||||
instance = new LaunchActivityItem();
|
||||
@@ -128,7 +130,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
voiceInteractor, procState, state, persistentState, pendingResults,
|
||||
pendingNewIntents, activityOptions, isForward, profilerInfo, assistToken,
|
||||
activityClientController, shareableActivityToken,
|
||||
launchedFromBubble);
|
||||
launchedFromBubble, taskFragmentToken);
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -136,7 +138,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
@Override
|
||||
public void recycle() {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -166,6 +168,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
dest.writeStrongInterface(mActivityClientController);
|
||||
dest.writeStrongBinder(mShareableActivityToken);
|
||||
dest.writeBoolean(mLaunchedFromBubble);
|
||||
dest.writeStrongBinder(mTaskFragmentToken);
|
||||
}
|
||||
|
||||
/** Read from Parcel. */
|
||||
@@ -184,7 +187,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
in.readStrongBinder(),
|
||||
IActivityClientController.Stub.asInterface(in.readStrongBinder()),
|
||||
in.readStrongBinder(),
|
||||
in.readBoolean());
|
||||
in.readBoolean(),
|
||||
in.readStrongBinder());
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<LaunchActivityItem> CREATOR =
|
||||
@@ -222,7 +226,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
&& mIsForward == other.mIsForward
|
||||
&& Objects.equals(mProfilerInfo, other.mProfilerInfo)
|
||||
&& Objects.equals(mAssistToken, other.mAssistToken)
|
||||
&& Objects.equals(mShareableActivityToken, other.mShareableActivityToken);
|
||||
&& Objects.equals(mShareableActivityToken, other.mShareableActivityToken)
|
||||
&& Objects.equals(mTaskFragmentToken, other.mTaskFragmentToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -244,6 +249,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
result = 31 * result + Objects.hashCode(mProfilerInfo);
|
||||
result = 31 * result + Objects.hashCode(mAssistToken);
|
||||
result = 31 * result + Objects.hashCode(mShareableActivityToken);
|
||||
result = 31 * result + Objects.hashCode(mTaskFragmentToken);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -291,7 +297,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
|
||||
ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo,
|
||||
IBinder assistToken, IActivityClientController activityClientController,
|
||||
IBinder shareableActivityToken, boolean launchedFromBubble) {
|
||||
IBinder shareableActivityToken, boolean launchedFromBubble, IBinder taskFragmentToken) {
|
||||
instance.mIntent = intent;
|
||||
instance.mIdent = ident;
|
||||
instance.mInfo = info;
|
||||
@@ -312,5 +318,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
instance.mActivityClientController = activityClientController;
|
||||
instance.mShareableActivityToken = shareableActivityToken;
|
||||
instance.mLaunchedFromBubble = launchedFromBubble;
|
||||
instance.mTaskFragmentToken = taskFragmentToken;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ public class ObjectPoolTests {
|
||||
.setPendingResults(resultInfoList()).setPendingNewIntents(referrerIntentList())
|
||||
.setIsForward(true).setAssistToken(assistToken)
|
||||
.setShareableActivityToken(shareableActivityToken)
|
||||
.build();
|
||||
.setTaskFragmentToken(new Binder()).build();
|
||||
|
||||
LaunchActivityItem emptyItem = new LaunchActivityItemBuilder().build();
|
||||
LaunchActivityItem item = itemSupplier.get();
|
||||
|
||||
@@ -110,6 +110,7 @@ class TestUtils {
|
||||
private IBinder mAssistToken;
|
||||
private IBinder mShareableActivityToken;
|
||||
private boolean mLaunchedFromBubble;
|
||||
private IBinder mTaskFragmentToken;
|
||||
|
||||
LaunchActivityItemBuilder setIntent(Intent intent) {
|
||||
mIntent = intent;
|
||||
@@ -206,13 +207,18 @@ class TestUtils {
|
||||
return this;
|
||||
}
|
||||
|
||||
LaunchActivityItemBuilder setTaskFragmentToken(IBinder taskFragmentToken) {
|
||||
mTaskFragmentToken = taskFragmentToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
LaunchActivityItem build() {
|
||||
return LaunchActivityItem.obtain(mIntent, mIdent, mInfo,
|
||||
mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor,
|
||||
mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents,
|
||||
mActivityOptions, mIsForward, mProfilerInfo, mAssistToken,
|
||||
null /* activityClientController */, mShareableActivityToken,
|
||||
mLaunchedFromBubble);
|
||||
mLaunchedFromBubble, mTaskFragmentToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ public class TransactionParcelTests {
|
||||
.setPendingResults(resultInfoList()).setActivityOptions(ActivityOptions.makeBasic())
|
||||
.setPendingNewIntents(referrerIntentList()).setIsForward(true)
|
||||
.setAssistToken(new Binder()).setShareableActivityToken(new Binder())
|
||||
.setTaskFragmentToken(new Binder())
|
||||
.build();
|
||||
|
||||
writeAndPrepareForReading(item);
|
||||
|
||||
@@ -345,7 +345,7 @@ public class ActivityThreadClientTest {
|
||||
null /* pendingResults */, null /* pendingNewIntents */,
|
||||
null /* activityOptions */, true /* isForward */, null /* profilerInfo */,
|
||||
mThread /* client */, null /* asssitToken */, null /* shareableActivityToken */,
|
||||
false /* launchedFromBubble */);
|
||||
false /* launchedFromBubble */, null /* taskfragmentToken */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -615,14 +615,22 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateCallbackIfNecessary() {
|
||||
updateCallbackIfNecessary(true /* deferCallbackUntilAllActivitiesCreated */);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
return;
|
||||
}
|
||||
if (!allActivitiesCreated()) {
|
||||
if (deferCallbackUntilAllActivitiesCreated && !allActivitiesCreated()) {
|
||||
return;
|
||||
}
|
||||
List<SplitInfo> currentSplitStates = getActiveSplitStates();
|
||||
@@ -837,6 +845,36 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
|
||||
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
|
||||
public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) {
|
||||
// Calling after Activity#onCreate is complete to allow the app launch something
|
||||
|
||||
@@ -120,7 +120,7 @@ class TaskFragmentContainer {
|
||||
}
|
||||
|
||||
ActivityStack toActivityStack() {
|
||||
return new ActivityStack(collectActivities(), mInfo.getRunningActivityCount() == 0);
|
||||
return new ActivityStack(collectActivities(), isEmpty());
|
||||
}
|
||||
|
||||
void addPendingAppearedActivity(@NonNull Activity pendingAppearedActivity) {
|
||||
|
||||
@@ -897,6 +897,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
|
||||
proc.getThread(), r.token);
|
||||
|
||||
final boolean isTransitionForward = r.isTransitionForward();
|
||||
final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
|
||||
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
|
||||
System.identityHashCode(r), r.info,
|
||||
// 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(),
|
||||
results, newIntents, r.takeOptions(), isTransitionForward,
|
||||
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
|
||||
r.shareableActivityToken, r.getLaunchedFromBubble()));
|
||||
r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
|
||||
|
||||
// Set desired final state.
|
||||
final ActivityLifecycleItem lifecycleItem;
|
||||
|
||||
@@ -2262,7 +2262,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
mFragmentToken,
|
||||
mRemoteToken.toWindowContainerToken(),
|
||||
getConfiguration(),
|
||||
getChildCount() == 0,
|
||||
runningActivityCount[0] == 0,
|
||||
runningActivityCount[0],
|
||||
isVisible(),
|
||||
childActivities,
|
||||
|
||||
Reference in New Issue
Block a user