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

Commit 411d7156 authored by Louis Chang's avatar Louis Chang Committed by Android (Google) Code Review
Browse files

Merge "Fix ActivityEmbedding flicker test flakiness" into main

parents 768d968b b9065f0e
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -3841,6 +3841,18 @@ public final class ActivityThread extends ClientTransactionHandler
        return activityRecord != null ? activityRecord.activity : null;
    }

    /**
     * Returns the most recent created activity that's still running.
     */
    @Nullable
    public Activity getLastCreatedActivity() {
        if (mActivities.isEmpty()) {
            return null;
        }

        return mActivities.valueAt(mActivities.size() - 1).activity;
    }

    @Override
    public ActivityClientRecord getActivityClient(IBinder token) {
        return mActivities.get(token);
+26 −1
Original line number Diff line number Diff line
@@ -148,8 +148,12 @@ class BackupHelper {
            final TaskFragmentInfo info = mTaskFragmentInfos.valueAt(i);
            mPresenter.deleteTaskFragment(wct, info.getFragmentToken());
        }
        mPresenter.setSavedState(new Bundle());

        removeSavedState();
    }

    private void removeSavedState() {
        mPresenter.setSavedState(new Bundle());
        mParcelableTaskContainerDataList.clear();
        mTaskFragmentInfos.clear();
        mTaskFragmentParentInfos.clear();
@@ -169,6 +173,19 @@ class BackupHelper {
            return false;
        }

        if (mTaskFragmentParentInfos.size() == 0) {
            // No Task left in the WM hierarchy, remove the states and no need to restore.
            if (DEBUG) Log.d(TAG, "Remove save states due to no task to restore.");
            removeSavedState();
            return false;
        }

        final ArrayList<Integer> taskIdsInSystem = new ArrayList<>();
        for (int i = mTaskFragmentParentInfos.size() - 1; i >= 0; --i) {
            final TaskFragmentParentInfo parentInfo = mTaskFragmentParentInfos.valueAt(i);
            taskIdsInSystem.add(parentInfo.getTaskId());
        }

        if (DEBUG) Log.d(TAG, "Rebuilding TaskContainers.");
        final ArrayMap<String, EmbeddingRule> embeddingRuleMap = new ArrayMap<>();
        for (EmbeddingRule rule : rules) {
@@ -190,6 +207,14 @@ class BackupHelper {
            }

            mParcelableTaskContainerDataList.remove(parcelableTaskContainerData);
            if (!taskIdsInSystem.contains(parcelableTaskContainerData.mTaskId)) {
                if (DEBUG) {
                    Log.d(TAG, "Rebuilding TaskContainer abort! Not existed. Task#"
                            + parcelableTaskContainerData.mTaskId);
                }
                continue;
            }

            final TaskContainer taskContainer = new TaskContainer(parcelableTaskContainerData,
                    mController, mTaskFragmentInfos);
            if (DEBUG) Log.d(TAG, "Created TaskContainer " + taskContainer);
+57 −27
Original line number Diff line number Diff line
@@ -239,6 +239,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        mActivityStartMonitor = new ActivityStartMonitor();
        instrumentation.addMonitor(mActivityStartMonitor);
        foldingFeatureProducer.addDataChangedCallback(new FoldingFeatureListener());

        synchronized (mLock) {
            // Abort the restoration if any and the application already has running activities.
            abortRebuildingTaskContainersIfNeeded(null /* launchingActivity */);
        }
    }

    private class FoldingFeatureListener
@@ -285,6 +290,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                return;
            }

            if (abortRebuildingTaskContainersIfNeeded(null /* launchingActivity */)) {
                return;
            }

            try {
                final TransactionRecord transactionRecord =
                        mTransactionManager.startNewTransaction();
@@ -2883,31 +2892,28 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        }
    }

    private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
    @GuardedBy("mLock")
    private boolean abortRebuildingTaskContainersIfNeeded(@Nullable Activity launchingActivity) {
        if (mPresenter == null || !mPresenter.isWaitingToRebuildTaskContainers()) {
            return false;
        }

        @Override
        public void onActivityPreCreated(@NonNull Activity activity,
                @Nullable Bundle savedInstanceState) {
            if (activity.isChild()) {
                // Skip Activity that is child of another Activity (ActivityGroup) because it's
                // window will just be a child of the parent Activity window.
                return;
        final ActivityThread activityThread = ActivityThread.currentActivityThread();
        if (activityThread == null) {
            return false;
        }
            synchronized (mLock) {
                if (mPresenter.isWaitingToRebuildTaskContainers()) {
                    Log.w(TAG, "Rebuilding aborted, clean up and restart");

        final Activity lastCreatedActivity = activityThread.getLastCreatedActivity();
        final Activity activity =
                launchingActivity != null ? launchingActivity : lastCreatedActivity;
        if (activity == null) {
            return false;
        }

        Log.w(TAG, "Rebuilding aborted, clean up.");

        // Retrieve the Task intent.
        final int taskId = getTaskId(activity);
                    Intent taskIntent = null;
                    final ActivityManager am = activity.getSystemService(ActivityManager.class);
                    final List<ActivityManager.AppTask> appTasks = am.getAppTasks();
                    for (ActivityManager.AppTask appTask : appTasks) {
                        if (appTask.getTaskInfo().taskId == taskId) {
                            taskIntent = appTask.getTaskInfo().baseIntent.cloneFilter();
                            break;
                        }
                    }

        // Clean up and abort the restoration
        // TODO(b/369488857): also to remove the non-organized activities in the Task?
@@ -2917,10 +2923,34 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        mPresenter.abortTaskContainerRebuilding(wct);
        transactionRecord.apply(false /* shouldApplyIndependently */);

                    // Start the Task root activity.
                    if (taskIntent != null) {
                        activity.startActivity(taskIntent);
        // Start the Task root activity if the task is now empty.
        ActivityManager.RecentTaskInfo taskInfo = null;
        final ActivityManager am = activity.getSystemService(ActivityManager.class);
        final List<ActivityManager.AppTask> appTasks = am.getAppTasks();
        for (ActivityManager.AppTask appTask : appTasks) {
            if (appTask.getTaskInfo().taskId == taskId) {
                taskInfo = appTask.getTaskInfo();
                break;
            }
        }
        if (taskInfo != null && !taskInfo.isRunning) {
            activity.startActivity(taskInfo.baseIntent.cloneFilter());
        }
        return true;
    }

    private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {

        @Override
        public void onActivityPreCreated(@NonNull Activity activity,
                @Nullable Bundle savedInstanceState) {
            if (activity.isChild()) {
                // Skip Activity that is child of another Activity (ActivityGroup) because it's
                // window will just be a child of the parent Activity window.
                return;
            }
            synchronized (mLock) {
                if (abortRebuildingTaskContainersIfNeeded(activity)) {
                    return;
                }