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

Commit b5038298 authored by Charles Chen's avatar Charles Chen Committed by Android Build Coastguard Worker
Browse files

Fix exception in expandSplitContainerIfNeeded

The exception is because the client side hasn't received
TaskFragmentInfo yet, so we don't have WindowContainerToken
to change the bounds of TaskFragments.
This CL verifies if we have TaskFragmentInfo before
calling expandTaskFragment. If there's no TaskFragmentInfo,
fallback to create new SplitContainer that fills the task
bounds.

Test: atest WMJetpackUnitTests
Test: manual: reproduce steps mentioned in bug
Bug: 232871351

Merged-In: Id8d122f7d95d1c6a3574b02ddd2b6afbc548f853
Change-Id: I83ee6ea32df485bf78db3b50dec8c92d80be8912
(cherry picked from commit 8bf77af1)
Merged-In: I83ee6ea32df485bf78db3b50dec8c92d80be8912
parent c113a129
Loading
Loading
Loading
Loading
+18 −17
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ import static androidx.window.extensions.embedding.SplitContainer.getFinishSecon
import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule;
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent;
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked;
import static androidx.window.extensions.embedding.SplitPresenter.boundsSmallerThanMinDimensions;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair;
import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions;
import static androidx.window.extensions.embedding.SplitPresenter.getNonEmbeddedActivityBounds;
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide;

import android.app.Activity;
@@ -581,8 +581,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    }

    /** Finds the activity below the given activity. */
    @VisibleForTesting
    @Nullable
    private Activity findActivityBelow(@NonNull Activity activity) {
    Activity findActivityBelow(@NonNull Activity activity) {
        Activity activityBelow = null;
        final TaskFragmentContainer container = getContainerWithActivity(activity);
        if (container != null) {
@@ -620,22 +621,22 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            // Can launch in the existing secondary container if the rules share the same
            // presentation.
            final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
            if (secondaryContainer == getContainerWithActivity(secondaryActivity)
                    && !boundsSmallerThanMinDimensions(secondaryContainer.getLastRequestedBounds(),
                            getMinDimensions(secondaryActivity))) {
            if (secondaryContainer == getContainerWithActivity(secondaryActivity)) {
                // The activity is already in the target TaskFragment.
                return true;
            }
            secondaryContainer.addPendingAppearedActivity(secondaryActivity);
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity,
                    secondaryActivity, null /* secondaryIntent */);
            if (mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity,
                    secondaryActivity, null /* secondaryIntent */)
                    != RESULT_EXPAND_FAILED_NO_TF_INFO) {
                wct.reparentActivityToTaskFragment(
                        secondaryContainer.getTaskFragmentToken(),
                        secondaryActivity.getActivityToken());
                mPresenter.applyTransaction(wct);
                return true;
            }
        }
        // Create new split pair.
        mPresenter.createNewSplitContainer(primaryActivity, secondaryActivity, splitRule);
        return true;
@@ -805,9 +806,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        if (splitContainer != null && existingContainer == splitContainer.getPrimaryContainer()
                && (canReuseContainer(splitRule, splitContainer.getSplitRule())
                // TODO(b/231845476) we should always respect clearTop.
                || !respectClearTop)) {
            mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity,
                    null /* secondaryActivity */, intent);
                || !respectClearTop)
                && mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity,
                        null /* secondaryActivity */, intent) != RESULT_EXPAND_FAILED_NO_TF_INFO) {
            // Can launch in the existing secondary container if the rules share the same
            // presentation.
            return splitContainer.getSecondaryContainer();
@@ -877,7 +878,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                pendingAppearedIntent, taskContainer, this);
        if (!taskContainer.isTaskBoundsInitialized()) {
            // Get the initial bounds before the TaskFragment has appeared.
            final Rect taskBounds = SplitPresenter.getTaskBoundsFromActivity(activityInTask);
            final Rect taskBounds = getNonEmbeddedActivityBounds(activityInTask);
            if (!taskContainer.setTaskBounds(taskBounds)) {
                Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
            }
+61 −8
Original line number Diff line number Diff line
@@ -65,6 +65,41 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
    })
    private @interface Position {}

    /**
     * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
     * Activity, Activity, Intent)}.
     * No need to expand the splitContainer because screen is big enough to
     * {@link #shouldShowSideBySide(Rect, SplitRule, Pair)} and minimum dimensions is satisfied.
     */
    static final int RESULT_NOT_EXPANDED = 0;
    /**
     * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
     * Activity, Activity, Intent)}.
     * The splitContainer should be expanded. It is usually because minimum dimensions is not
     * satisfied.
     * @see #shouldShowSideBySide(Rect, SplitRule, Pair)
     */
    static final int RESULT_EXPANDED = 1;
    /**
     * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
     * Activity, Activity, Intent)}.
     * The splitContainer should be expanded, but the client side hasn't received
     * {@link android.window.TaskFragmentInfo} yet. Fallback to create new expanded SplitContainer
     * instead.
     */
    static final int RESULT_EXPAND_FAILED_NO_TF_INFO = 2;

    /**
     * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
     * Activity, Activity, Intent)}
     */
    @IntDef(value = {
            RESULT_NOT_EXPANDED,
            RESULT_EXPANDED,
            RESULT_EXPAND_FAILED_NO_TF_INFO,
    })
    private @interface ResultCode {}

    private final SplitController mController;

    SplitPresenter(@NonNull Executor executor, SplitController controller) {
@@ -399,15 +434,19 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
    /**
     * Expands the split container if the current split bounds are smaller than the Activity or
     * Intent that is added to the container.
     *
     * @return the {@link ResultCode} based on {@link #shouldShowSideBySide(Rect, SplitRule, Pair)}
     * and if {@link android.window.TaskFragmentInfo} has reported to the client side.
     */
    void expandSplitContainerIfNeeded(@NonNull WindowContainerTransaction wct,
    @ResultCode
    int expandSplitContainerIfNeeded(@NonNull WindowContainerTransaction wct,
            @NonNull SplitContainer splitContainer, @NonNull Activity primaryActivity,
            @Nullable Activity secondaryActivity, @Nullable Intent secondaryIntent) {
        if (secondaryActivity == null && secondaryIntent == null) {
            throw new IllegalArgumentException("Either secondaryActivity or secondaryIntent must be"
                    + " non-null.");
        }
        final Rect taskBounds = getTaskBoundsFromActivity(primaryActivity);
        final Rect taskBounds = getParentContainerBounds(primaryActivity);
        final Pair<Size, Size> minDimensionsPair;
        if (secondaryActivity != null) {
            minDimensionsPair = getActivitiesMinDimensionsPair(primaryActivity, secondaryActivity);
@@ -417,11 +456,17 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        }
        // Expand the splitContainer if minimum dimensions are not satisfied.
        if (!shouldShowSideBySide(taskBounds, splitContainer.getSplitRule(), minDimensionsPair)) {
            expandTaskFragment(wct, splitContainer.getPrimaryContainer()
                    .getTaskFragmentToken());
            expandTaskFragment(wct, splitContainer.getSecondaryContainer()
                    .getTaskFragmentToken());
            // If the client side hasn't received TaskFragmentInfo yet, we can't change TaskFragment
            // bounds. Return failure to create a new SplitContainer which fills task bounds.
            if (splitContainer.getPrimaryContainer().getInfo() == null
                    || splitContainer.getSecondaryContainer().getInfo() == null) {
                return RESULT_EXPAND_FAILED_NO_TF_INFO;
            }
            expandTaskFragment(wct, splitContainer.getPrimaryContainer().getTaskFragmentToken());
            expandTaskFragment(wct, splitContainer.getSecondaryContainer().getTaskFragmentToken());
            return RESULT_EXPANDED;
        }
        return RESULT_NOT_EXPANDED;
    }

    static boolean shouldShowSideBySide(@NonNull Rect parentBounds, @NonNull SplitRule rule) {
@@ -593,11 +638,19 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        if (container != null) {
            return getParentContainerBounds(container);
        }
        return getTaskBoundsFromActivity(activity);
        // Obtain bounds from Activity instead because the Activity hasn't been embedded yet.
        return getNonEmbeddedActivityBounds(activity);
    }

    /**
     * Obtains the bounds from a non-embedded Activity.
     * <p>
     * Note that callers should use {@link #getParentContainerBounds(Activity)} instead for most
     * cases unless we want to obtain task bounds before
     * {@link TaskContainer#isTaskBoundsInitialized()}.
     */
    @NonNull
    static Rect getTaskBoundsFromActivity(@NonNull Activity activity) {
    static Rect getNonEmbeddedActivityBounds(@NonNull Activity activity) {
        final WindowConfiguration windowConfiguration =
                activity.getResources().getConfiguration().windowConfiguration;
        if (!activity.isInMultiWindowMode()) {
+17 −1
Original line number Diff line number Diff line
@@ -58,13 +58,21 @@ public class EmbeddingTestUtils {
    /** Creates a rule to always split the given activity and the given intent. */
    static SplitRule createSplitRule(@NonNull Activity primaryActivity,
            @NonNull Intent secondaryIntent) {
        return createSplitRule(primaryActivity, secondaryIntent, true /* clearTop */);
    }

    /** Creates a rule to always split the given activity and the given intent. */
    static SplitRule createSplitRule(@NonNull Activity primaryActivity,
            @NonNull Intent secondaryIntent, boolean clearTop) {
        final Pair<Activity, Intent> targetPair = new Pair<>(primaryActivity, secondaryIntent);
        return new SplitPairRule.Builder(
                activityPair -> false,
                targetPair::equals,
                w -> true)
                .setSplitRatio(SPLIT_RATIO)
                .setShouldClearTop(true)
                .setShouldClearTop(clearTop)
                .setFinishPrimaryWithSecondary(DEFAULT_FINISH_PRIMARY_WITH_SECONDARY)
                .setFinishSecondaryWithPrimary(DEFAULT_FINISH_SECONDARY_WITH_PRIMARY)
                .build();
    }

@@ -76,6 +84,14 @@ public class EmbeddingTestUtils {
                true /* clearTop */);
    }

    /** Creates a rule to always split the given activities. */
    static SplitRule createSplitRule(@NonNull Activity primaryActivity,
            @NonNull Activity secondaryActivity, boolean clearTop) {
        return createSplitRule(primaryActivity, secondaryActivity,
                DEFAULT_FINISH_PRIMARY_WITH_SECONDARY, DEFAULT_FINISH_SECONDARY_WITH_PRIMARY,
                clearTop);
    }

    /** Creates a rule to always split the given activities with the given finish behaviors. */
    static SplitRule createSplitRule(@NonNull Activity primaryActivity,
            @NonNull Activity secondaryActivity, int finishPrimaryWithSecondary,
+94 −13
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
@@ -436,6 +437,50 @@ public class SplitControllerTest {
        assertTrue(container.areLastRequestedBoundsEqual(null));
    }

    @Test
    public void testResolveStartActivityIntent_shouldExpandSplitContainer() {
        final Intent intent = new Intent().setComponent(
                new ComponentName(ApplicationProvider.getApplicationContext(),
                        MinimumDimensionActivity.class));
        setupSplitRule(mActivity, intent, false /* clearTop */);
        final Activity secondaryActivity = createMockActivity();
        addSplitTaskFragments(mActivity, secondaryActivity, false /* clearTop */);

        final TaskFragmentContainer container = mSplitController.resolveStartActivityIntent(
                mTransaction, TASK_ID, intent, mActivity);
        final TaskFragmentContainer primaryContainer = mSplitController.getContainerWithActivity(
                mActivity);

        assertNotNull(mSplitController.getActiveSplitForContainers(primaryContainer, container));
        assertTrue(primaryContainer.areLastRequestedBoundsEqual(null));
        assertTrue(container.areLastRequestedBoundsEqual(null));
        assertEquals(container, mSplitController.getContainerWithActivity(secondaryActivity));
    }

    @Test
    public void testResolveStartActivityIntent_noInfo_shouldCreateSplitContainer() {
        final Intent intent = new Intent().setComponent(
                new ComponentName(ApplicationProvider.getApplicationContext(),
                        MinimumDimensionActivity.class));
        setupSplitRule(mActivity, intent, false /* clearTop */);
        final Activity secondaryActivity = createMockActivity();
        addSplitTaskFragments(mActivity, secondaryActivity, false /* clearTop */);

        final TaskFragmentContainer secondaryContainer = mSplitController
                .getContainerWithActivity(secondaryActivity);
        secondaryContainer.mInfo = null;

        final TaskFragmentContainer container = mSplitController.resolveStartActivityIntent(
                mTransaction, TASK_ID, intent, mActivity);
        final TaskFragmentContainer primaryContainer = mSplitController.getContainerWithActivity(
                mActivity);

        assertNotNull(mSplitController.getActiveSplitForContainers(primaryContainer, container));
        assertTrue(primaryContainer.areLastRequestedBoundsEqual(null));
        assertTrue(container.areLastRequestedBoundsEqual(null));
        assertNotEquals(container, secondaryContainer);
    }

    @Test
    public void testPlaceActivityInTopContainer() {
        mSplitController.placeActivityInTopContainer(mActivity);
@@ -807,17 +852,12 @@ public class SplitControllerTest {
        final Activity activityBelow = createMockActivity();
        setupSplitRule(activityBelow, mActivity);

        ActivityInfo aInfo = new ActivityInfo();
        final Rect secondaryBounds = getSplitBounds(false /* isPrimary */);
        aInfo.windowLayout = new ActivityInfo.WindowLayout(0, 0, 0, 0, 0,
                secondaryBounds.width() + 1, secondaryBounds.height() + 1);
        doReturn(aInfo).when(mActivity).getActivityInfo();
        doReturn(createActivityInfoWithMinDimensions()).when(mActivity).getActivityInfo();

        final TaskFragmentContainer container = mSplitController.newContainer(activityBelow,
                TASK_ID);
        container.addPendingAppearedActivity(mActivity);

        // Allow to split as primary.
        boolean result = mSplitController.resolveActivityToContainer(mActivity,
                false /* isOnReparent */);

@@ -825,6 +865,27 @@ public class SplitControllerTest {
        assertSplitPair(activityBelow, mActivity, true /* matchParentBounds */);
    }

    @Test
    public void testResolveActivityToContainer_minDimensions_shouldExpandSplitContainer() {
        final Activity primaryActivity = createMockActivity();
        final Activity secondaryActivity = createMockActivity();
        addSplitTaskFragments(primaryActivity, secondaryActivity, false /* clearTop */);

        setupSplitRule(primaryActivity, mActivity, false /* clearTop */);
        doReturn(createActivityInfoWithMinDimensions()).when(mActivity).getActivityInfo();
        doReturn(secondaryActivity).when(mSplitController).findActivityBelow(eq(mActivity));

        clearInvocations(mSplitPresenter);
        boolean result = mSplitController.resolveActivityToContainer(mActivity,
                false /* isOnReparent */);

        assertTrue(result);
        assertSplitPair(primaryActivity, mActivity, true /* matchParentBounds */);
        assertEquals(mSplitController.getContainerWithActivity(secondaryActivity),
                mSplitController.getContainerWithActivity(mActivity));
        verify(mSplitPresenter, never()).createNewSplitContainer(any(), any(), any());
    }

    @Test
    public void testResolveActivityToContainer_inUnknownTaskFragment() {
        doReturn(new Binder()).when(mSplitController).getInitialTaskFragmentToken(mActivity);
@@ -941,23 +1002,41 @@ public class SplitControllerTest {
    /** Setups a rule to always split the given activities. */
    private void setupSplitRule(@NonNull Activity primaryActivity,
            @NonNull Intent secondaryIntent) {
        final SplitRule splitRule = createSplitRule(primaryActivity, secondaryIntent);
        setupSplitRule(primaryActivity, secondaryIntent, true /* clearTop */);
    }

    /** Setups a rule to always split the given activities. */
    private void setupSplitRule(@NonNull Activity primaryActivity,
            @NonNull Intent secondaryIntent, boolean clearTop) {
        final SplitRule splitRule = createSplitRule(primaryActivity, secondaryIntent, clearTop);
        mSplitController.setEmbeddingRules(Collections.singleton(splitRule));
    }

    /** Setups a rule to always split the given activities. */
    private void setupSplitRule(@NonNull Activity primaryActivity,
            @NonNull Activity secondaryActivity) {
        final SplitRule splitRule = createSplitRule(primaryActivity, secondaryActivity);
        setupSplitRule(primaryActivity, secondaryActivity, true /* clearTop */);
    }

    /** Setups a rule to always split the given activities. */
    private void setupSplitRule(@NonNull Activity primaryActivity,
            @NonNull Activity secondaryActivity, boolean clearTop) {
        final SplitRule splitRule = createSplitRule(primaryActivity, secondaryActivity, clearTop);
        mSplitController.setEmbeddingRules(Collections.singleton(splitRule));
    }

    /** Adds a pair of TaskFragments as split for the given activities. */
    private void addSplitTaskFragments(@NonNull Activity primaryActivity,
            @NonNull Activity secondaryActivity) {
        addSplitTaskFragments(primaryActivity, secondaryActivity, true /* clearTop */);
    }

    /** Adds a pair of TaskFragments as split for the given activities. */
    private void addSplitTaskFragments(@NonNull Activity primaryActivity,
            @NonNull Activity secondaryActivity, boolean clearTop) {
        registerSplitPair(createMockTaskFragmentContainer(primaryActivity),
                createMockTaskFragmentContainer(secondaryActivity),
                createSplitRule(primaryActivity, secondaryActivity));
                createSplitRule(primaryActivity, secondaryActivity, clearTop));
    }

    /** Registers the two given TaskFragments as split pair. */
@@ -1008,16 +1087,18 @@ public class SplitControllerTest {
        if (primaryContainer.mInfo != null) {
            final Rect primaryBounds = matchParentBounds ? new Rect()
                    : getSplitBounds(true /* isPrimary */);
            final int windowingMode = matchParentBounds ? WINDOWING_MODE_UNDEFINED
                    : WINDOWING_MODE_MULTI_WINDOW;
            assertTrue(primaryContainer.areLastRequestedBoundsEqual(primaryBounds));
            assertTrue(primaryContainer.isLastRequestedWindowingModeEqual(
                    WINDOWING_MODE_MULTI_WINDOW));
            assertTrue(primaryContainer.isLastRequestedWindowingModeEqual(windowingMode));
        }
        if (secondaryContainer.mInfo != null) {
            final Rect secondaryBounds = matchParentBounds ? new Rect()
                    : getSplitBounds(false /* isPrimary */);
            final int windowingMode = matchParentBounds ? WINDOWING_MODE_UNDEFINED
                    : WINDOWING_MODE_MULTI_WINDOW;
            assertTrue(secondaryContainer.areLastRequestedBoundsEqual(secondaryBounds));
            assertTrue(secondaryContainer.isLastRequestedWindowingModeEqual(
                    WINDOWING_MODE_MULTI_WINDOW));
            assertTrue(secondaryContainer.isLastRequestedWindowingModeEqual(windowingMode));
        }
    }
}
+19 −8
Original line number Diff line number Diff line
@@ -21,11 +21,15 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityInfoWithMinDimensions;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_END;
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_FILL;
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_START;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPANDED;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_NOT_EXPANDED;
import static androidx.window.extensions.embedding.SplitPresenter.getBoundsForPosition;
import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions;
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide;
@@ -51,6 +55,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
import android.util.Size;
@@ -212,26 +217,31 @@ public class SplitPresenterTest {
                mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity,
                        null /* secondaryActivity */, null /* secondaryIntent */));

        mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity,
                secondaryActivity, null /* secondaryIntent */);

        assertEquals(RESULT_NOT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
                splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */));
        verify(mPresenter, never()).expandTaskFragment(any(), any());

        doReturn(createActivityInfoWithMinDimensions()).when(secondaryActivity).getActivityInfo();
        assertEquals(RESULT_EXPAND_FAILED_NO_TF_INFO, mPresenter.expandSplitContainerIfNeeded(
                mTransaction, splitContainer, mActivity, secondaryActivity,
                null /* secondaryIntent */));

        mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity,
                secondaryActivity, null /* secondaryIntent */);
        primaryTf.setInfo(createMockTaskFragmentInfo(primaryTf, mActivity));
        secondaryTf.setInfo(createMockTaskFragmentInfo(secondaryTf, secondaryActivity));

        assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
                splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */));
        verify(mPresenter).expandTaskFragment(eq(mTransaction),
                eq(primaryTf.getTaskFragmentToken()));
        verify(mPresenter).expandTaskFragment(eq(mTransaction),
                eq(secondaryTf.getTaskFragmentToken()));

        clearInvocations(mPresenter);
        mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity,
                null /* secondaryActivity */, new Intent(ApplicationProvider
                        .getApplicationContext(), MinimumDimensionActivity.class));

        assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
                splitContainer, mActivity, null /* secondaryActivity */,
                new Intent(ApplicationProvider.getApplicationContext(),
                        MinimumDimensionActivity.class)));
        verify(mPresenter).expandTaskFragment(eq(mTransaction),
                eq(primaryTf.getTaskFragmentToken()));
        verify(mPresenter).expandTaskFragment(eq(mTransaction),
@@ -246,6 +256,7 @@ public class SplitPresenterTest {
        doReturn(mActivityResources).when(activity).getResources();
        doReturn(activityConfig).when(mActivityResources).getConfiguration();
        doReturn(new ActivityInfo()).when(activity).getActivityInfo();
        doReturn(mock(IBinder.class)).when(activity).getActivityToken();
        return activity;
    }
}