summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Shivam Agrawal <shivamagrawal@google.com> 2022-03-29 22:19:51 -0400
committer Shivam Agrawal <shivamagrawal@google.com> 2022-04-01 13:31:30 -0400
commitd8659858914ba6d66885b4a8202f4876a054463e (patch)
treeed04f41987e6e3c78f87665aadf9ab5eb1ee26b3
parent39c6eaa64ddfbe5eb772a6dc8f6ea5b6b29437f1 (diff)
Send Split Info Callback before Activity#onCreate
The onTaskFragmentInfo callback from the server triggered by the creation of a new activity may not reach the client before Activity#onCreate is called because of undeterministic IPC call order. However, the application should get a split info update that includes the newly launched activity before the Activity#onCreate is called for that activity so that the application knows that the activity will be in a split, which may influence UI decisions. Bug: b/218791665 b/200303250 Test: atest ActivityEmbeddingLaunchTests Change-Id: If69c077db8ca390d41446e1329a448b3dd074293
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java42
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java2
3 files changed, 42 insertions, 4 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 418ff0e7263a..c7d62530a43d 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -602,14 +602,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();
@@ -825,6 +833,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
// first. In case of a configured placeholder activity we want to make sure
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index e49af41d4eac..9a12669f078a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -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) {
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 23df429c3f24..cf32457211af 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2264,7 +2264,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mFragmentToken,
mRemoteToken.toWindowContainerToken(),
getConfiguration(),
- getChildCount() == 0,
+ runningActivityCount[0] == 0,
runningActivityCount[0],
isVisible(),
childActivities,