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

Commit 541bb486 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Avoid duplicated WindowContainerTransaction for TaskFragment"

parents 9ada2918 aa013014
Loading
Loading
Loading
Loading
+29 −13
Original line number Original line Diff line number Diff line
@@ -154,7 +154,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
                activityOptions);
                activityOptions);


        // Set adjacent to each other so that the containers below will be invisible.
        // Set adjacent to each other so that the containers below will be invisible.
        setAdjacentTaskFragments(wct, launchingFragmentToken, secondaryFragmentToken, rule);
        setAdjacentTaskFragmentsWithRule(wct, launchingFragmentToken, secondaryFragmentToken, rule);
        setCompanionTaskFragment(wct, launchingFragmentToken, secondaryFragmentToken, rule,
        setCompanionTaskFragment(wct, launchingFragmentToken, secondaryFragmentToken, rule,
                false /* isStacked */);
                false /* isStacked */);
    }
    }
@@ -167,7 +167,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
    void expandTaskFragment(@NonNull WindowContainerTransaction wct,
    void expandTaskFragment(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder fragmentToken) {
            @NonNull IBinder fragmentToken) {
        resizeTaskFragment(wct, fragmentToken, new Rect());
        resizeTaskFragment(wct, fragmentToken, new Rect());
        setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
        clearAdjacentTaskFragments(wct, fragmentToken);
        updateWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
        updateWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
        updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
        updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
    }
    }
@@ -238,26 +238,37 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
        wct.reparentActivityToTaskFragment(fragmentToken, reparentActivityToken);
        wct.reparentActivityToTaskFragment(fragmentToken, reparentActivityToken);
    }
    }


    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
    /**
            @NonNull IBinder primary, @Nullable IBinder secondary, @Nullable SplitRule splitRule) {
     * Sets the two given TaskFragments as adjacent to each other with respecting the given
        if (secondary == null) {
     * {@link SplitRule} for {@link WindowContainerTransaction.TaskFragmentAdjacentParams}.
            wct.clearAdjacentTaskFragments(primary);
     */
            return;
    void setAdjacentTaskFragmentsWithRule(@NonNull WindowContainerTransaction wct,
        }
            @NonNull IBinder primary, @NonNull IBinder secondary, @NonNull SplitRule splitRule) {

        WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams = null;
        WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams = null;
        final boolean finishSecondaryWithPrimary =
        final boolean finishSecondaryWithPrimary =
                splitRule != null && SplitContainer.shouldFinishSecondaryWithPrimary(splitRule);
                SplitContainer.shouldFinishSecondaryWithPrimary(splitRule);
        final boolean finishPrimaryWithSecondary =
        final boolean finishPrimaryWithSecondary =
                splitRule != null && SplitContainer.shouldFinishPrimaryWithSecondary(splitRule);
                SplitContainer.shouldFinishPrimaryWithSecondary(splitRule);
        if (finishSecondaryWithPrimary || finishPrimaryWithSecondary) {
        if (finishSecondaryWithPrimary || finishPrimaryWithSecondary) {
            adjacentParams = new WindowContainerTransaction.TaskFragmentAdjacentParams();
            adjacentParams = new WindowContainerTransaction.TaskFragmentAdjacentParams();
            adjacentParams.setShouldDelayPrimaryLastActivityRemoval(finishSecondaryWithPrimary);
            adjacentParams.setShouldDelayPrimaryLastActivityRemoval(finishSecondaryWithPrimary);
            adjacentParams.setShouldDelaySecondaryLastActivityRemoval(finishPrimaryWithSecondary);
            adjacentParams.setShouldDelaySecondaryLastActivityRemoval(finishPrimaryWithSecondary);
        }
        }
        setAdjacentTaskFragments(wct, primary, secondary, adjacentParams);
    }

    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder primary, @NonNull IBinder secondary,
            @Nullable WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams) {
        wct.setAdjacentTaskFragments(primary, secondary, adjacentParams);
        wct.setAdjacentTaskFragments(primary, secondary, adjacentParams);
    }
    }


    void clearAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder fragmentToken) {
        // Clear primary will also clear secondary.
        wct.clearAdjacentTaskFragments(fragmentToken);
    }

    void setCompanionTaskFragment(@NonNull WindowContainerTransaction wct,
    void setCompanionTaskFragment(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder primary, @NonNull IBinder secondary, @NonNull SplitRule splitRule,
            @NonNull IBinder primary, @NonNull IBinder secondary, @NonNull SplitRule splitRule,
            boolean isStacked) {
            boolean isStacked) {
@@ -268,7 +279,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
        } else {
        } else {
            finishPrimaryWithSecondary = shouldFinishPrimaryWithSecondary(splitRule);
            finishPrimaryWithSecondary = shouldFinishPrimaryWithSecondary(splitRule);
        }
        }
        wct.setCompanionTaskFragment(primary, finishPrimaryWithSecondary ? secondary : null);
        setCompanionTaskFragment(wct, primary, finishPrimaryWithSecondary ? secondary : null);


        final boolean finishSecondaryWithPrimary;
        final boolean finishSecondaryWithPrimary;
        if (isStacked) {
        if (isStacked) {
@@ -277,7 +288,12 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
        } else {
        } else {
            finishSecondaryWithPrimary = shouldFinishSecondaryWithPrimary(splitRule);
            finishSecondaryWithPrimary = shouldFinishSecondaryWithPrimary(splitRule);
        }
        }
        wct.setCompanionTaskFragment(secondary, finishSecondaryWithPrimary ? primary : null);
        setCompanionTaskFragment(wct, secondary, finishSecondaryWithPrimary ? primary : null);
    }

    void setCompanionTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder primary,
            @Nullable IBinder secondary) {
        wct.setCompanionTaskFragment(primary, secondary);
    }
    }


    void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
    void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
+3 −0
Original line number Original line Diff line number Diff line
@@ -525,6 +525,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            // All overrides will be cleanup.
            // All overrides will be cleanup.
            container.setLastRequestedBounds(null /* bounds */);
            container.setLastRequestedBounds(null /* bounds */);
            container.setLastRequestedWindowingMode(WINDOWING_MODE_UNDEFINED);
            container.setLastRequestedWindowingMode(WINDOWING_MODE_UNDEFINED);
            container.clearLastAdjacentTaskFragment();
            container.setLastCompanionTaskFragment(null /* fragmentToken */);
            container.setLastRequestAnimationParams(TaskFragmentAnimationParams.DEFAULT);
            cleanupForEnterPip(wct, container);
            cleanupForEnterPip(wct, container);
        } else if (wasInPip) {
        } else if (wasInPip) {
            // Exit PIP.
            // Exit PIP.
+64 −7
Original line number Original line Diff line number Diff line
@@ -385,10 +385,9 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        // secondaryContainer could not be finished.
        // secondaryContainer could not be finished.
        boolean isStacked = !shouldShowSplit(splitAttributes);
        boolean isStacked = !shouldShowSplit(splitAttributes);
        if (isStacked) {
        if (isStacked) {
            setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
            clearAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken());
                    null /* secondary */, null /* splitRule */);
        } else {
        } else {
            setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
            setAdjacentTaskFragmentsWithRule(wct, primaryContainer.getTaskFragmentToken(),
                    secondaryContainer.getTaskFragmentToken(), splitRule);
                    secondaryContainer.getTaskFragmentToken(), splitRule);
        }
        }
        setCompanionTaskFragment(wct, primaryContainer.getTaskFragmentToken(),
        setCompanionTaskFragment(wct, primaryContainer.getTaskFragmentToken(),
@@ -425,7 +424,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
                fragmentOptions.getFragmentToken());
                fragmentOptions.getFragmentToken());
        if (container == null) {
        if (container == null) {
            throw new IllegalStateException(
            throw new IllegalStateException(
                    "Creating a task fragment that is not registered with controller.");
                    "Creating a TaskFragment that is not registered with controller.");
        }
        }


        container.setLastRequestedBounds(fragmentOptions.getInitialRelativeBounds());
        container.setLastRequestedBounds(fragmentOptions.getInitialRelativeBounds());
@@ -439,7 +438,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        TaskFragmentContainer container = mController.getContainer(fragmentToken);
        TaskFragmentContainer container = mController.getContainer(fragmentToken);
        if (container == null) {
        if (container == null) {
            throw new IllegalStateException(
            throw new IllegalStateException(
                    "Resizing a task fragment that is not registered with controller.");
                    "Resizing a TaskFragment that is not registered with controller.");
        }
        }


        if (container.areLastRequestedBoundsEqual(relBounds)) {
        if (container.areLastRequestedBoundsEqual(relBounds)) {
@@ -456,7 +455,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
            @NonNull IBinder fragmentToken, @WindowingMode int windowingMode) {
            @NonNull IBinder fragmentToken, @WindowingMode int windowingMode) {
        final TaskFragmentContainer container = mController.getContainer(fragmentToken);
        final TaskFragmentContainer container = mController.getContainer(fragmentToken);
        if (container == null) {
        if (container == null) {
            throw new IllegalStateException("Setting windowing mode for a task fragment that is"
            throw new IllegalStateException("Setting windowing mode for a TaskFragment that is"
                    + " not registered with controller.");
                    + " not registered with controller.");
        }
        }


@@ -474,7 +473,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
            @NonNull IBinder fragmentToken, @NonNull TaskFragmentAnimationParams animationParams) {
            @NonNull IBinder fragmentToken, @NonNull TaskFragmentAnimationParams animationParams) {
        final TaskFragmentContainer container = mController.getContainer(fragmentToken);
        final TaskFragmentContainer container = mController.getContainer(fragmentToken);
        if (container == null) {
        if (container == null) {
            throw new IllegalStateException("Setting animation params for a task fragment that is"
            throw new IllegalStateException("Setting animation params for a TaskFragment that is"
                    + " not registered with controller.");
                    + " not registered with controller.");
        }
        }


@@ -487,6 +486,64 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        super.updateAnimationParams(wct, fragmentToken, animationParams);
        super.updateAnimationParams(wct, fragmentToken, animationParams);
    }
    }


    @Override
    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder primary, @NonNull IBinder secondary,
            @Nullable WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams) {
        final TaskFragmentContainer primaryContainer = mController.getContainer(primary);
        final TaskFragmentContainer secondaryContainer = mController.getContainer(secondary);
        if (primaryContainer == null || secondaryContainer == null) {
            throw new IllegalStateException("setAdjacentTaskFragments on TaskFragment that is"
                    + " not registered with controller.");
        }

        if (primaryContainer.isLastAdjacentTaskFragmentEqual(secondary, adjacentParams)
                && secondaryContainer.isLastAdjacentTaskFragmentEqual(primary, adjacentParams)) {
            // Return early if the same adjacent TaskFragments were already requested
            return;
        }

        primaryContainer.setLastAdjacentTaskFragment(secondary, adjacentParams);
        secondaryContainer.setLastAdjacentTaskFragment(primary, adjacentParams);
        super.setAdjacentTaskFragments(wct, primary, secondary, adjacentParams);
    }

    @Override
    void clearAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder fragmentToken) {
        final TaskFragmentContainer container = mController.getContainer(fragmentToken);
        if (container == null) {
            throw new IllegalStateException("clearAdjacentTaskFragments on TaskFragment that is"
                    + " not registered with controller.");
        }

        if (container.isLastAdjacentTaskFragmentEqual(null /* fragmentToken*/, null /* params */)) {
            // Return early if no adjacent TaskFragment was yet requested
            return;
        }

        container.clearLastAdjacentTaskFragment();
        super.clearAdjacentTaskFragments(wct, fragmentToken);
    }

    @Override
    void setCompanionTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder primary,
            @Nullable IBinder secondary) {
        final TaskFragmentContainer container = mController.getContainer(primary);
        if (container == null) {
            throw new IllegalStateException("setCompanionTaskFragment on TaskFragment that is"
                    + " not registered with controller.");
        }

        if (container.isLastCompanionTaskFragmentEqual(secondary)) {
            // Return early if the same companion TaskFragment was already requested
            return;
        }

        container.setLastCompanionTaskFragment(secondary);
        super.setCompanionTaskFragment(wct, primary, secondary);
    }

    /**
    /**
     * Expands the split container if the current split bounds are smaller than the Activity or
     * Expands the split container if the current split bounds are smaller than the Activity or
     * Intent that is added to the container.
     * Intent that is added to the container.
+82 −5
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Collections;
import java.util.Iterator;
import java.util.Iterator;
import java.util.List;
import java.util.List;
import java.util.Objects;


/**
/**
 * Client-side container for a stack of activities. Corresponds to an instance of TaskFragment
 * Client-side container for a stack of activities. Corresponds to an instance of TaskFragment
@@ -116,6 +117,27 @@ class TaskFragmentContainer {
    @NonNull
    @NonNull
    private TaskFragmentAnimationParams mLastAnimationParams = TaskFragmentAnimationParams.DEFAULT;
    private TaskFragmentAnimationParams mLastAnimationParams = TaskFragmentAnimationParams.DEFAULT;


    /**
     * TaskFragment token that was requested last via
     * {@link android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS}.
     */
    @Nullable
    private IBinder mLastAdjacentTaskFragment;

    /**
     * {@link WindowContainerTransaction.TaskFragmentAdjacentParams} token that was requested last
     * via {@link android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS}.
     */
    @Nullable
    private WindowContainerTransaction.TaskFragmentAdjacentParams mLastAdjacentParams;

    /**
     * TaskFragment token that was requested last via
     * {@link android.window.TaskFragmentOperation#OP_TYPE_SET_COMPANION_TASK_FRAGMENT}.
     */
    @Nullable
    private IBinder mLastCompanionTaskFragment;

    /**
    /**
     * When the TaskFragment has appeared in server, but is empty, we should remove the TaskFragment
     * When the TaskFragment has appeared in server, but is empty, we should remove the TaskFragment
     * if it is still empty after the timeout.
     * if it is still empty after the timeout.
@@ -591,6 +613,7 @@ class TaskFragmentContainer {
    /**
    /**
     * Checks if last requested bounds are equal to the provided value.
     * Checks if last requested bounds are equal to the provided value.
     * The requested bounds are relative bounds in parent coordinate.
     * The requested bounds are relative bounds in parent coordinate.
     * @see WindowContainerTransaction#setRelativeBounds
     */
     */
    boolean areLastRequestedBoundsEqual(@Nullable Rect relBounds) {
    boolean areLastRequestedBoundsEqual(@Nullable Rect relBounds) {
        return (relBounds == null && mLastRequestedBounds.isEmpty())
        return (relBounds == null && mLastRequestedBounds.isEmpty())
@@ -600,6 +623,7 @@ class TaskFragmentContainer {
    /**
    /**
     * Updates the last requested bounds.
     * Updates the last requested bounds.
     * The requested bounds are relative bounds in parent coordinate.
     * The requested bounds are relative bounds in parent coordinate.
     * @see WindowContainerTransaction#setRelativeBounds
     */
     */
    void setLastRequestedBounds(@Nullable Rect relBounds) {
    void setLastRequestedBounds(@Nullable Rect relBounds) {
        if (relBounds == null) {
        if (relBounds == null) {
@@ -609,13 +633,9 @@ class TaskFragmentContainer {
        }
        }
    }
    }


    @NonNull
    Rect getLastRequestedBounds() {
        return mLastRequestedBounds;
    }

    /**
    /**
     * Checks if last requested windowing mode is equal to the provided value.
     * Checks if last requested windowing mode is equal to the provided value.
     * @see WindowContainerTransaction#setWindowingMode
     */
     */
    boolean isLastRequestedWindowingModeEqual(@WindowingMode int windowingMode) {
    boolean isLastRequestedWindowingModeEqual(@WindowingMode int windowingMode) {
        return mLastRequestedWindowingMode == windowingMode;
        return mLastRequestedWindowingMode == windowingMode;
@@ -623,6 +643,7 @@ class TaskFragmentContainer {


    /**
    /**
     * Updates the last requested windowing mode.
     * Updates the last requested windowing mode.
     * @see WindowContainerTransaction#setWindowingMode
     */
     */
    void setLastRequestedWindowingMode(@WindowingMode int windowingModes) {
    void setLastRequestedWindowingMode(@WindowingMode int windowingModes) {
        mLastRequestedWindowingMode = windowingModes;
        mLastRequestedWindowingMode = windowingModes;
@@ -630,6 +651,7 @@ class TaskFragmentContainer {


    /**
    /**
     * Checks if last requested {@link TaskFragmentAnimationParams} are equal to the provided value.
     * Checks if last requested {@link TaskFragmentAnimationParams} are equal to the provided value.
     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ANIMATION_PARAMS
     */
     */
    boolean areLastRequestedAnimationParamsEqual(
    boolean areLastRequestedAnimationParamsEqual(
            @NonNull TaskFragmentAnimationParams animationParams) {
            @NonNull TaskFragmentAnimationParams animationParams) {
@@ -638,11 +660,66 @@ class TaskFragmentContainer {


    /**
    /**
     * Updates the last requested {@link TaskFragmentAnimationParams}.
     * Updates the last requested {@link TaskFragmentAnimationParams}.
     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ANIMATION_PARAMS
     */
     */
    void setLastRequestAnimationParams(@NonNull TaskFragmentAnimationParams animationParams) {
    void setLastRequestAnimationParams(@NonNull TaskFragmentAnimationParams animationParams) {
        mLastAnimationParams = animationParams;
        mLastAnimationParams = animationParams;
    }
    }


    /**
     * Checks if last requested adjacent TaskFragment token and params are equal to the provided
     * values.
     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS
     * @see android.window.TaskFragmentOperation#OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS
     */
    boolean isLastAdjacentTaskFragmentEqual(@Nullable IBinder fragmentToken,
            @Nullable WindowContainerTransaction.TaskFragmentAdjacentParams params) {
        return Objects.equals(mLastAdjacentTaskFragment, fragmentToken)
                && Objects.equals(mLastAdjacentParams, params);
    }

    /**
     * Updates the last requested adjacent TaskFragment token and params.
     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS
     */
    void setLastAdjacentTaskFragment(@NonNull IBinder fragmentToken,
            @NonNull WindowContainerTransaction.TaskFragmentAdjacentParams params) {
        mLastAdjacentTaskFragment = fragmentToken;
        mLastAdjacentParams = params;
    }

    /**
     * Clears the last requested adjacent TaskFragment token and params.
     * @see android.window.TaskFragmentOperation#OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS
     */
    void clearLastAdjacentTaskFragment() {
        final TaskFragmentContainer lastAdjacentTaskFragment = mLastAdjacentTaskFragment != null
                ? mController.getContainer(mLastAdjacentTaskFragment)
                : null;
        mLastAdjacentTaskFragment = null;
        mLastAdjacentParams = null;
        if (lastAdjacentTaskFragment != null) {
            // Clear the previous adjacent TaskFragment as well.
            lastAdjacentTaskFragment.clearLastAdjacentTaskFragment();
        }
    }

    /**
     * Checks if last requested companion TaskFragment token is equal to the provided value.
     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_COMPANION_TASK_FRAGMENT
     */
    boolean isLastCompanionTaskFragmentEqual(@Nullable IBinder fragmentToken) {
        return Objects.equals(mLastCompanionTaskFragment, fragmentToken);
    }

    /**
     * Updates the last requested companion TaskFragment token.
     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_COMPANION_TASK_FRAGMENT
     */
    void setLastCompanionTaskFragment(@Nullable IBinder fragmentToken) {
        mLastCompanionTaskFragment = fragmentToken;
    }

    /** Gets the parent leaf Task id. */
    /** Gets the parent leaf Task id. */
    int getTaskId() {
    int getTaskId() {
        return mTaskContainer.getTaskId();
        return mTaskContainer.getTaskId();
+58 −0
Original line number Original line Diff line number Diff line
@@ -176,6 +176,64 @@ public class SplitPresenterTest {
        verify(mTransaction, never()).setWindowingMode(any(), anyInt());
        verify(mTransaction, never()).setWindowingMode(any(), anyInt());
    }
    }


    @Test
    public void testSetAdjacentTaskFragments() {
        final TaskFragmentContainer container0 = mController.newContainer(mActivity, TASK_ID);
        final TaskFragmentContainer container1 = mController.newContainer(mActivity, TASK_ID);

        mPresenter.setAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken(),
                container1.getTaskFragmentToken(), null /* adjacentParams */);
        verify(mTransaction).setAdjacentTaskFragments(container0.getTaskFragmentToken(),
                container1.getTaskFragmentToken(), null /* adjacentParams */);

        // No request to set the same adjacent TaskFragments.
        clearInvocations(mTransaction);
        mPresenter.setAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken(),
                container1.getTaskFragmentToken(), null /* adjacentParams */);

        verify(mTransaction, never()).setAdjacentTaskFragments(any(), any(), any());
    }

    @Test
    public void testClearAdjacentTaskFragments() {
        final TaskFragmentContainer container0 = mController.newContainer(mActivity, TASK_ID);
        final TaskFragmentContainer container1 = mController.newContainer(mActivity, TASK_ID);

        // No request to clear as it is not set by default.
        mPresenter.clearAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken());
        verify(mTransaction, never()).clearAdjacentTaskFragments(any());

        mPresenter.setAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken(),
                container1.getTaskFragmentToken(), null /* adjacentParams */);
        mPresenter.clearAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken());
        verify(mTransaction).clearAdjacentTaskFragments(container0.getTaskFragmentToken());

        // No request to clear on either of the previous cleared TasKFragments.
        clearInvocations(mTransaction);
        mPresenter.clearAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken());
        mPresenter.clearAdjacentTaskFragments(mTransaction, container1.getTaskFragmentToken());

        verify(mTransaction, never()).clearAdjacentTaskFragments(any());
    }

    @Test
    public void testSetCompanionTaskFragment() {
        final TaskFragmentContainer container0 = mController.newContainer(mActivity, TASK_ID);
        final TaskFragmentContainer container1 = mController.newContainer(mActivity, TASK_ID);

        mPresenter.setCompanionTaskFragment(mTransaction, container0.getTaskFragmentToken(),
                container1.getTaskFragmentToken());
        verify(mTransaction).setCompanionTaskFragment(container0.getTaskFragmentToken(),
                container1.getTaskFragmentToken());

        // No request to set the same adjacent TaskFragments.
        clearInvocations(mTransaction);
        mPresenter.setCompanionTaskFragment(mTransaction, container0.getTaskFragmentToken(),
                container1.getTaskFragmentToken());

        verify(mTransaction, never()).setCompanionTaskFragment(any(), any());
    }

    @Test
    @Test
    public void testUpdateAnimationParams() {
    public void testUpdateAnimationParams() {
        final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
        final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
Loading