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

Commit 20579de6 authored by Louis Chang's avatar Louis Chang Committed by Automerger Merge Worker
Browse files

Merge "Prevent activity being destroyed immediately if embedded" into sc-v2-dev am: eec6c21e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15537319

Change-Id: Ia84d2e44c707eab2975f50344a5e5f6f43e88213
parents 05a96f6a eec6c21e
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
@@ -516,11 +516,13 @@ public final class WindowContainerTransaction implements Parcelable {
     */
    @NonNull
    public WindowContainerTransaction setAdjacentTaskFragments(
            @NonNull IBinder fragmentToken1, @Nullable IBinder fragmentToken2) {
            @NonNull IBinder fragmentToken1, @Nullable IBinder fragmentToken2,
            @Nullable TaskFragmentAdjacentOptions options) {
        final HierarchyOp hierarchyOp =
                new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS)
                        .setContainer(fragmentToken1)
                        .setReparentContainer(fragmentToken2)
                        .setLaunchOptions(options != null ? options.toBundle() : null)
                        .build();
        mHierarchyOps.add(hierarchyOp);
        return this;
@@ -1298,4 +1300,52 @@ public final class WindowContainerTransaction implements Parcelable {
            }
        }
    }

    /**
     * Helper class for building an options Bundle that can be used to set adjacent rules of
     * TaskFragments.
     * @hide
     */
    public static class TaskFragmentAdjacentOptions {
        private static final String DELAY_PRIMARY_LAST_ACTIVITY_REMOVAL =
                "android:transaction.adjacent.option.delay_primary_removal";
        private static final String DELAY_SECONDARY_LAST_ACTIVITY_REMOVAL =
                "android:transaction.adjacent.option.delay_secondary_removal";

        private boolean mDelayPrimaryLastActivityRemoval;
        private boolean mDelaySecondaryLastActivityRemoval;

        public TaskFragmentAdjacentOptions() {
        }

        public TaskFragmentAdjacentOptions(@NonNull Bundle bundle) {
            mDelayPrimaryLastActivityRemoval = bundle.getBoolean(
                    DELAY_PRIMARY_LAST_ACTIVITY_REMOVAL);
            mDelaySecondaryLastActivityRemoval = bundle.getBoolean(
                    DELAY_SECONDARY_LAST_ACTIVITY_REMOVAL);
        }

        public void setDelayPrimaryLastActivityRemoval(boolean delay) {
            mDelayPrimaryLastActivityRemoval = delay;
        }

        public void setDelaySecondaryLastActivityRemoval(boolean delay) {
            mDelaySecondaryLastActivityRemoval = delay;
        }

        public boolean isDelayPrimaryLastActivityRemoval() {
            return mDelayPrimaryLastActivityRemoval;
        }

        public boolean isDelaySecondaryLastActivityRemoval() {
            return mDelaySecondaryLastActivityRemoval;
        }

        Bundle toBundle() {
            final Bundle b = new Bundle();
            b.putBoolean(DELAY_PRIMARY_LAST_ACTIVITY_REMOVAL, mDelayPrimaryLastActivityRemoval);
            b.putBoolean(DELAY_SECONDARY_LAST_ACTIVITY_REMOVAL, mDelaySecondaryLastActivityRemoval);
            return b;
        }
    }
}
+19 −3
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.window.WindowContainerTransaction;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.window.extensions.embedding.SplitRule;

import java.util.Map;
import java.util.concurrent.Executor;
@@ -100,7 +101,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
            @NonNull IBinder launchingFragmentToken, @NonNull Rect launchingFragmentBounds,
            @NonNull Activity launchingActivity, @NonNull IBinder secondaryFragmentToken,
            @NonNull Rect secondaryFragmentBounds, @NonNull Intent activityIntent,
            @Nullable Bundle activityOptions) {
            @Nullable Bundle activityOptions, @NonNull SplitRule rule) {
        final IBinder ownerToken = launchingActivity.getActivityToken();

        // Create or resize the launching TaskFragment.
@@ -117,7 +118,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
                activityOptions);

        // Set adjacent to each other so that the containers below will be invisible.
        wct.setAdjacentTaskFragments(launchingFragmentToken, secondaryFragmentToken);
        setAdjacentTaskFragments(wct, launchingFragmentToken, secondaryFragmentToken, rule);
    }

    /**
@@ -127,7 +128,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
     */
    void expandTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
        resizeTaskFragment(wct, fragmentToken, new Rect());
        wct.setAdjacentTaskFragments(fragmentToken, null);
        setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
    }

    /**
@@ -187,6 +188,21 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
        wct.startActivityInTaskFragment(fragmentToken, ownerToken, activityIntent, activityOptions);
    }

    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder primary, @Nullable IBinder secondary, @Nullable SplitRule splitRule) {
        WindowContainerTransaction.TaskFragmentAdjacentOptions adjacentOptions = null;
        final boolean finishSecondaryWithPrimary =
                splitRule != null && SplitContainer.shouldFinishSecondaryWithPrimary(splitRule);
        final boolean finishPrimaryWithSecondary =
                splitRule != null && SplitContainer.shouldFinishPrimaryWithSecondary(splitRule);
        if (finishSecondaryWithPrimary || finishPrimaryWithSecondary) {
            adjacentOptions = new WindowContainerTransaction.TaskFragmentAdjacentOptions();
            adjacentOptions.setDelayPrimaryLastActivityRemoval(finishSecondaryWithPrimary);
            adjacentOptions.setDelaySecondaryLastActivityRemoval(finishPrimaryWithSecondary);
        }
        wct.setAdjacentTaskFragments(primary, secondary, adjacentOptions);
    }

    TaskFragmentCreationParams createFragmentOptions(IBinder fragmentToken, IBinder ownerToken,
            Rect bounds, @WindowingMode int windowingMode) {
        if (mFragmentInfos.containsKey(fragmentToken)) {
+16 −8
Original line number Diff line number Diff line
@@ -39,16 +39,10 @@ class SplitContainer {
        mSecondaryContainer = secondaryContainer;
        mSplitRule = splitRule;

        final boolean isPlaceholderContainer = isPlaceholderContainer();
        final boolean shouldFinishPrimaryWithSecondary = (mSplitRule instanceof SplitPairRule)
                && ((SplitPairRule) mSplitRule).shouldFinishPrimaryWithSecondary();
        final boolean shouldFinishSecondaryWithPrimary = (mSplitRule instanceof SplitPairRule)
                && ((SplitPairRule) mSplitRule).shouldFinishSecondaryWithPrimary();

        if (shouldFinishPrimaryWithSecondary || isPlaceholderContainer) {
        if (shouldFinishPrimaryWithSecondary(splitRule)) {
            mSecondaryContainer.addActivityToFinishOnExit(primaryActivity);
        }
        if (shouldFinishSecondaryWithPrimary || isPlaceholderContainer) {
        if (shouldFinishSecondaryWithPrimary(splitRule)) {
            mPrimaryContainer.addContainerToFinishOnExit(mSecondaryContainer);
        }
    }
@@ -71,4 +65,18 @@ class SplitContainer {
    boolean isPlaceholderContainer() {
        return (mSplitRule instanceof SplitPlaceholderRule);
    }

    static boolean shouldFinishPrimaryWithSecondary(@NonNull SplitRule splitRule) {
        final boolean isPlaceholderContainer = splitRule instanceof SplitPlaceholderRule;
        final boolean shouldFinishPrimaryWithSecondary = (splitRule instanceof SplitPairRule)
                && ((SplitPairRule) splitRule).shouldFinishPrimaryWithSecondary();
        return shouldFinishPrimaryWithSecondary || isPlaceholderContainer;
    }

    static boolean shouldFinishSecondaryWithPrimary(@NonNull SplitRule splitRule) {
        final boolean isPlaceholderContainer = splitRule instanceof SplitPlaceholderRule;
        final boolean shouldFinishSecondaryWithPrimary = (splitRule instanceof SplitPairRule)
                && ((SplitPairRule) splitRule).shouldFinishSecondaryWithPrimary();
        return shouldFinishSecondaryWithPrimary || isPlaceholderContainer;
    }
}
+5 −5
Original line number Diff line number Diff line
@@ -109,8 +109,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        secondaryContainer.setLastRequestedBounds(secondaryRectBounds);

        // Set adjacent to each other so that the containers below will be invisible.
        wct.setAdjacentTaskFragments(
                primaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken());
        setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
                secondaryContainer.getTaskFragmentToken(), rule);

        mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule);

@@ -144,8 +144,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
                secondaryActivity, secondaryRectBounds, primaryContainer);

        // Set adjacent to each other so that the containers below will be invisible.
        wct.setAdjacentTaskFragments(
                primaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken());
        setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
                secondaryContainer.getTaskFragmentToken(), rule);

        mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule);

@@ -212,7 +212,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
                rule);
        startActivityToSide(wct, primaryContainer.getTaskFragmentToken(), primaryRectBounds,
                launchingActivity, secondaryContainer.getTaskFragmentToken(), secondaryRectBounds,
                activityIntent, activityOptions);
                activityIntent, activityOptions, rule);
        applyTransaction(wct);

        primaryContainer.setLastRequestedBounds(primaryRectBounds);
+15 −1
Original line number Diff line number Diff line
@@ -3234,6 +3234,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // TODO(b/137329632): find the next activity directly underneath this one, not just anywhere
        final ActivityRecord next = getDisplayArea().topRunningActivity(
                true /* considerKeyguardState */);

        // If the finishing activity is the last activity of a organized TaskFragment and has an
        // adjacent TaskFragment, check if the activity removal should be delayed.
        boolean delayRemoval = false;
        final TaskFragment taskFragment = getTaskFragment();
        if (next != null && taskFragment != null && taskFragment.isEmbedded()) {
            final TaskFragment organized = taskFragment.getOrganizedTaskFragment();
            final TaskFragment adjacent =
                    organized != null ? organized.getAdjacentTaskFragment() : null;
            if (adjacent != null && organized.topRunningActivity() == null) {
                delayRemoval = organized.isDelayLastActivityRemoval();
            }
        }

        // isNextNotYetVisible is to check if the next activity is invisible, or it has been
        // requested to be invisible but its windows haven't reported as invisible.  If so, it
        // implied that the current finishing activity should be added into stopping list rather
@@ -3248,7 +3262,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }

        if (isCurrentVisible) {
            if (isNextNotYetVisible) {
            if (isNextNotYetVisible || delayRemoval) {
                // Add this activity to the list of stopping activities. It will be processed and
                // destroyed when the next activity reports idle.
                addToStopping(false /* scheduleIdle */, false /* idleDelayed */,
Loading