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

Commit dc6e0ff9 authored by Louis Chang's avatar Louis Chang
Browse files

Abort AE saved state restoration if it is too late

Abort the AE saved state restoration if it is not yet able
to be restored before any Activity#onCreate to be called.

And start the Task root activity as a fresh restart as a
fallback approach. Note that this may not always be correct
(for example, an new Activity was expected to be started
on the reused Task, but is now showing the Task root activity),
but it should be a minimum fallback in case the app is not
following the best practice to set up the embedding rules
in Application#onCreate.

Bug: 289875940
Test: verified on demo app
Flag: com.android.window.flags.ae_back_stack_restore
Change-Id: If7d33ec66a2476adf24892e54a4856db9b3d020a
parent 64358d6a
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -142,6 +142,19 @@ class BackupHelper {
        }
    }

    void abortTaskContainerRebuilding(@NonNull WindowContainerTransaction wct) {
        // Clean-up the legacy states in the system
        for (int i = mTaskFragmentInfos.size() - 1; i >= 0; i--) {
            final TaskFragmentInfo info = mTaskFragmentInfos.valueAt(i);
            mPresenter.deleteTaskFragment(wct, info.getFragmentToken());
        }
        mPresenter.setSavedState(new Bundle());

        mParcelableTaskContainerDataList.clear();
        mTaskFragmentInfos.clear();
        mTaskFragmentParentInfos.clear();
    }

    boolean hasPendingStateToRestore() {
        return !mParcelableTaskContainerDataList.isEmpty();
    }
@@ -196,6 +209,7 @@ class BackupHelper {

            mController.onTaskFragmentParentRestored(wct, taskContainer.getTaskId(),
                    mTaskFragmentParentInfos.get(taskContainer.getTaskId()));
            mTaskFragmentParentInfos.remove(taskContainer.getTaskId());
            restoredAny = true;
        }

+32 −1
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import static androidx.window.extensions.embedding.TaskFragmentContainer.Overlay
import android.annotation.CallbackExecutor;
import android.app.Activity;
import android.app.ActivityClient;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.AppGlobals;
@@ -280,7 +281,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            mSplitRules.clear();
            mSplitRules.addAll(rules);

            if (!Flags.aeBackStackRestore() || !mPresenter.isRebuildTaskContainersNeeded()) {
            if (!Flags.aeBackStackRestore() || !mPresenter.isWaitingToRebuildTaskContainers()) {
                return;
            }

@@ -2893,6 +2894,36 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                return;
            }
            synchronized (mLock) {
                if (mPresenter.isWaitingToRebuildTaskContainers()) {
                    Log.w(TAG, "Rebuilding aborted, clean up and restart");

                    // 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?
                    final TransactionRecord transactionRecord =
                            mTransactionManager.startNewTransaction();
                    final WindowContainerTransaction wct = transactionRecord.getTransaction();
                    mPresenter.abortTaskContainerRebuilding(wct);
                    transactionRecord.apply(false /* shouldApplyIndependently */);

                    // Start the Task root activity.
                    if (taskIntent != null) {
                        activity.startActivity(taskIntent);
                    }
                    return;
                }

                final IBinder activityToken = activity.getActivityToken();
                final IBinder initialTaskFragmentToken =
                        getTaskFragmentTokenFromActivityClientRecord(activity);
+5 −1
Original line number Diff line number Diff line
@@ -187,10 +187,14 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        mBackupHelper.scheduleBackup();
    }

    boolean isRebuildTaskContainersNeeded() {
    boolean isWaitingToRebuildTaskContainers() {
        return mBackupHelper.hasPendingStateToRestore();
    }

    void abortTaskContainerRebuilding(@NonNull WindowContainerTransaction wct) {
        mBackupHelper.abortTaskContainerRebuilding(wct);
    }

    boolean rebuildTaskContainers(@NonNull WindowContainerTransaction wct,
            @NonNull Set<EmbeddingRule> rules) {
        return mBackupHelper.rebuildTaskContainers(wct, rules);
+1 −1
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ class TaskContainer {
        mSplitController = splitController;
        for (ParcelableTaskFragmentContainerData tfData :
                data.getParcelableTaskFragmentContainerDataList()) {
            final TaskFragmentInfo info = taskFragmentInfoMap.get(tfData.mToken);
            final TaskFragmentInfo info = taskFragmentInfoMap.remove(tfData.mToken);
            if (info != null && !info.isEmpty()) {
                final TaskFragmentContainer container =
                        new TaskFragmentContainer(tfData, splitController, this);