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

Commit 2bb52288 authored by Louis Chang's avatar Louis Chang
Browse files

Backup the activities to finish on TaskFragmentContainer exits

Also remove a few TODOs.
- Split rule tag could still be null for apps using earlier
  WM Jetpack library.
- No more plans to enable the feature internally as the flag
  enters next-food.

Bug: 289875940
Test: verified on sample app
Flag: com.android.window.flags.ae_back_stack_restore
Change-Id: I526ad7a97fd7f35a11367508a9c1bcc3984aef67
parent 662f37ea
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ class BackupHelper {
     */
    void scheduleBackup() {
        if (!mSaveEmbeddingState) {
            // TODO(b/289875940): enabled internally for broader testing.
            return;
        }

+0 −1
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ class ParcelableSplitContainerData implements Parcelable {
    @NonNull
    private final IBinder mSecondaryContainerToken;

    // TODO(b/289875940): making this as non-null once the tag can be auto-generated from the rule.
    @Nullable
    final String mSplitRuleTag;

+11 −1
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@ import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
 * This class holds the Parcelable data of a {@link TaskFragmentContainer}.
 */
@@ -61,6 +64,12 @@ class ParcelableTaskFragmentContainerData implements Parcelable {
    @NonNull
    final Rect mLastRequestedBounds;

    /**
     * Individual associated activity tokens in different containers that should be finished on
     * exit.
     */
    final List<IBinder> mActivitiesToFinishOnExit = new ArrayList<>();

    ParcelableTaskFragmentContainerData(@NonNull IBinder token, @Nullable String overlayTag,
            @Nullable IBinder associatedActivityToken) {
        mToken = token;
@@ -74,6 +83,7 @@ class ParcelableTaskFragmentContainerData implements Parcelable {
        mOverlayTag = in.readString();
        mAssociatedActivityToken = in.readStrongBinder();
        mLastRequestedBounds = in.readTypedObject(Rect.CREATOR);
        in.readBinderList(mActivitiesToFinishOnExit);
    }

    public static final Creator<ParcelableTaskFragmentContainerData> CREATOR = new Creator<>() {
@@ -99,7 +109,7 @@ class ParcelableTaskFragmentContainerData implements Parcelable {
        dest.writeString(mOverlayTag);
        dest.writeStrongBinder(mAssociatedActivityToken);
        dest.writeTypedObject(mLastRequestedBounds, flags);
        dest.writeBinderList(mActivitiesToFinishOnExit);
    }

}
+12 −2
Original line number Diff line number Diff line
@@ -98,10 +98,20 @@ class SplitContainer {
        mCurrentSplitAttributes = mDefaultSplitAttributes;

        if (shouldFinishPrimaryWithSecondary(splitRule)) {
            mSecondaryContainer.addContainerToFinishOnExit(mPrimaryContainer);
            addContainerToFinishOnExitWhenRestore(mSecondaryContainer, mPrimaryContainer);
        }
        if (shouldFinishSecondaryWithPrimary(splitRule)) {
            mPrimaryContainer.addContainerToFinishOnExit(mSecondaryContainer);
            addContainerToFinishOnExitWhenRestore(mPrimaryContainer, mSecondaryContainer);
        }
    }

    private void addContainerToFinishOnExitWhenRestore(
            @NonNull TaskFragmentContainer containerToAdd,
            @NonNull TaskFragmentContainer containerToFinish) {
        // If an activity was already added to be finished after the restoration, then that's it.
        // Otherwise, add the container to finish on exit.
        if (!containerToAdd.hasActivityToFinishOnExit(containerToFinish)) {
            containerToAdd.addContainerToFinishOnExit(containerToFinish);
        }
    }

+20 −14
Original line number Diff line number Diff line
@@ -95,12 +95,6 @@ class TaskFragmentContainer {
    private final List<TaskFragmentContainer> mContainersToFinishOnExit =
            new ArrayList<>();

    /**
     * Individual associated activity tokens in different containers that should be finished on
     * exit.
     */
    private final List<IBinder> mActivitiesToFinishOnExit = new ArrayList<>();

    /**
     * The launch options that was used to create this container. Must not {@link Bundle#isEmpty()}
     * for {@link #isOverlay()} container.
@@ -114,7 +108,6 @@ class TaskFragmentContainer {
    /**
     * Windowing mode that was requested last via {@link android.window.WindowContainerTransaction}.
     */
    // TODO(b/289875940): review this and other field that might need to be moved in the base class.
    @WindowingMode
    private int mLastRequestedWindowingMode = WINDOWING_MODE_UNDEFINED;

@@ -443,7 +436,7 @@ class TaskFragmentContainer {
            // Remove the activity now because there can be a delay before the server callback.
            mInfo.getActivities().remove(activityToken);
        }
        mActivitiesToFinishOnExit.remove(activityToken);
        mParcelableData.mActivitiesToFinishOnExit.remove(activityToken);
        finishSelfWithActivityIfNeeded(wct, activityToken);
    }

@@ -624,7 +617,20 @@ class TaskFragmentContainer {
        if (mIsFinished) {
            return;
        }
        mActivitiesToFinishOnExit.add(activityToFinish.getActivityToken());
        mParcelableData.mActivitiesToFinishOnExit.add(activityToFinish.getActivityToken());
    }

    /**
     * Returns {@code true} if an Activity from the given {@code container} was added to be
     * finished on exit. Otherwise, return {@code false}.
     */
    boolean hasActivityToFinishOnExit(@NonNull TaskFragmentContainer container) {
        for (IBinder activity : mParcelableData.mActivitiesToFinishOnExit) {
            if (container.hasActivity(activity)) {
                return true;
            }
        }
        return false;
    }

    /**
@@ -634,7 +640,7 @@ class TaskFragmentContainer {
        if (mIsFinished) {
            return;
        }
        mActivitiesToFinishOnExit.remove(activityToRemove.getActivityToken());
        mParcelableData.mActivitiesToFinishOnExit.remove(activityToRemove.getActivityToken());
    }

    /** Removes all dependencies that should be finished when this container is finished. */
@@ -643,7 +649,7 @@ class TaskFragmentContainer {
            return;
        }
        mContainersToFinishOnExit.clear();
        mActivitiesToFinishOnExit.clear();
        mParcelableData.mActivitiesToFinishOnExit.clear();
    }

    /**
@@ -721,7 +727,7 @@ class TaskFragmentContainer {
        mContainersToFinishOnExit.clear();

        // Finish associated activities
        for (IBinder activityToken : mActivitiesToFinishOnExit) {
        for (IBinder activityToken : mParcelableData.mActivitiesToFinishOnExit) {
            final Activity activity = mController.getActivity(activityToken);
            if (activity == null || activity.isFinishing()
                    || controller.shouldRetainAssociatedActivity(this, activity)) {
@@ -729,7 +735,7 @@ class TaskFragmentContainer {
            }
            wct.finishActivity(activity.getActivityToken());
        }
        mActivitiesToFinishOnExit.clear();
        mParcelableData.mActivitiesToFinishOnExit.clear();
    }

    @GuardedBy("mController.mLock")
@@ -1082,7 +1088,7 @@ class TaskFragmentContainer {
                + " pendingAppearedActivities=" + mPendingAppearedActivities
                + (includeContainersToFinishOnExit ? " containersToFinishOnExit="
                + containersToFinishOnExitToString() : "")
                + " activitiesToFinishOnExit=" + mActivitiesToFinishOnExit
                + " activitiesToFinishOnExit=" + mParcelableData.mActivitiesToFinishOnExit
                + " info=" + mInfo
                + "}";
    }