Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8659858 authored by Shivam Agrawal's avatar Shivam Agrawal
Browse files

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
parent 39c6eaa6
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -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();
@@ -824,6 +832,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
+1 −1
Original line number Diff line number Diff line
@@ -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) {
+1 −1
Original line number Diff line number Diff line
@@ -2264,7 +2264,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
                mFragmentToken,
                mRemoteToken.toWindowContainerToken(),
                getConfiguration(),
                getChildCount() == 0,
                runningActivityCount[0] == 0,
                runningActivityCount[0],
                isVisible(),
                childActivities,