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

Commit d4a59b9c authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Checks SplitAttributes when reusing container" into udc-dev

parents 2af97cb1 1af8ee5b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ public final class WindowMetrics {
        return WindowMetrics.class.getSimpleName() + ":{"
                + "bounds=" + mBounds
                + ", windowInsets=" + mWindowInsets
                + ", density" + mDensity
                + ", density=" + mDensity
                + "}";
    }
}
+36 −12
Original line number Diff line number Diff line
@@ -40,7 +40,9 @@ import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceh
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent;
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
import static androidx.window.extensions.embedding.SplitPresenter.getActivitiesMinDimensionsPair;
import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair;
import static androidx.window.extensions.embedding.SplitPresenter.getTaskWindowMetrics;
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSplit;

import android.app.Activity;
@@ -1037,9 +1039,15 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        final TaskFragmentContainer primaryContainer = getContainerWithActivity(
                primaryActivity);
        final SplitContainer splitContainer = getActiveSplitForContainer(primaryContainer);
        final WindowMetrics taskWindowMetrics = mPresenter.getTaskWindowMetrics(primaryActivity);
        final TaskContainer.TaskProperties taskProperties = mPresenter
                .getTaskProperties(primaryActivity);
        final SplitAttributes calculatedSplitAttributes = mPresenter.computeSplitAttributes(
                taskProperties, splitRule, splitRule.getDefaultSplitAttributes(),
                getActivitiesMinDimensionsPair(primaryActivity, secondaryActivity));
        if (splitContainer != null && primaryContainer == splitContainer.getPrimaryContainer()
                && canReuseContainer(splitRule, splitContainer.getSplitRule(), taskWindowMetrics)) {
                && canReuseContainer(splitRule, splitContainer.getSplitRule(),
                        getTaskWindowMetrics(taskProperties.getConfiguration()),
                        calculatedSplitAttributes, splitContainer.getCurrentSplitAttributes())) {
            // Can launch in the existing secondary container if the rules share the same
            // presentation.
            final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
@@ -1058,7 +1066,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            }
        }
        // Create new split pair.
        mPresenter.createNewSplitContainer(wct, primaryActivity, secondaryActivity, splitRule);
        mPresenter.createNewSplitContainer(wct, primaryActivity, secondaryActivity, splitRule,
                calculatedSplitAttributes);
        return true;
    }

@@ -1283,9 +1292,16 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        }
        final TaskFragmentContainer existingContainer = getContainerWithActivity(primaryActivity);
        final SplitContainer splitContainer = getActiveSplitForContainer(existingContainer);
        final WindowMetrics taskWindowMetrics = mPresenter.getTaskWindowMetrics(primaryActivity);
        final TaskContainer.TaskProperties taskProperties = mPresenter
                .getTaskProperties(primaryActivity);
        final WindowMetrics taskWindowMetrics = getTaskWindowMetrics(
                taskProperties.getConfiguration());
        final SplitAttributes calculatedSplitAttributes = mPresenter.computeSplitAttributes(
                taskProperties, splitRule, splitRule.getDefaultSplitAttributes(),
                getActivityIntentMinDimensionsPair(primaryActivity, intent));
        if (splitContainer != null && existingContainer == splitContainer.getPrimaryContainer()
                && (canReuseContainer(splitRule, splitContainer.getSplitRule(), taskWindowMetrics)
                && (canReuseContainer(splitRule, splitContainer.getSplitRule(), taskWindowMetrics,
                        calculatedSplitAttributes, splitContainer.getCurrentSplitAttributes())
                // TODO(b/231845476) we should always respect clearTop.
                || !respectClearTop)
                && mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity,
@@ -1296,7 +1312,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        }
        // Create a new TaskFragment to split with the primary activity for the new activity.
        return mPresenter.createNewSplitWithEmptySideContainer(wct, primaryActivity, intent,
                splitRule);
                splitRule, calculatedSplitAttributes);
    }

    /**
@@ -2273,21 +2289,29 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    }

    /**
     * If the two rules have the same presentation, we can reuse the same {@link SplitContainer} if
     * there is any.
     * If the two rules have the same presentation, and the calculated {@link SplitAttributes}
     * matches the {@link SplitAttributes} of {@link SplitContainer}, we can reuse the same
     * {@link SplitContainer} if there is any.
     */
    private static boolean canReuseContainer(@NonNull SplitRule rule1, @NonNull SplitRule rule2,
            @NonNull WindowMetrics parentWindowMetrics) {
            @NonNull WindowMetrics parentWindowMetrics,
            @NonNull SplitAttributes calculatedSplitAttributes,
            @NonNull SplitAttributes containerSplitAttributes) {
        if (!isContainerReusableRule(rule1) || !isContainerReusableRule(rule2)) {
            return false;
        }
        return haveSamePresentation((SplitPairRule) rule1, (SplitPairRule) rule2,
                parentWindowMetrics);
        return areRulesSamePresentation((SplitPairRule) rule1, (SplitPairRule) rule2,
                parentWindowMetrics)
                // Besides rules, we should also check whether the SplitContainer's splitAttributes
                // matches the current splitAttributes or not. The splitAttributes may change
                // if the app chooses different SplitAttributes calculator function before a new
                // activity is started even they match the same splitRule.
                && calculatedSplitAttributes.equals(containerSplitAttributes);
    }

    /** Whether the two rules have the same presentation. */
    @VisibleForTesting
    static boolean haveSamePresentation(@NonNull SplitPairRule rule1,
    static boolean areRulesSamePresentation(@NonNull SplitPairRule rule1,
            @NonNull SplitPairRule rule2, @NonNull WindowMetrics parentWindowMetrics) {
        if (rule1.getTag() != null || rule2.getTag() != null) {
            // Tag must be unique if it is set. We don't want to reuse the container if the rules
+6 −12
Original line number Diff line number Diff line
@@ -174,12 +174,9 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
    @NonNull
    TaskFragmentContainer createNewSplitWithEmptySideContainer(
            @NonNull WindowContainerTransaction wct, @NonNull Activity primaryActivity,
            @NonNull Intent secondaryIntent, @NonNull SplitPairRule rule) {
            @NonNull Intent secondaryIntent, @NonNull SplitPairRule rule,
            @NonNull SplitAttributes splitAttributes) {
        final TaskProperties taskProperties = getTaskProperties(primaryActivity);
        final Pair<Size, Size> minDimensionsPair = getActivityIntentMinDimensionsPair(
                primaryActivity, secondaryIntent);
        final SplitAttributes splitAttributes = computeSplitAttributes(taskProperties, rule,
                rule.getDefaultSplitAttributes(), minDimensionsPair);
        final Rect primaryRelBounds = getRelBoundsForPosition(POSITION_START, taskProperties,
                splitAttributes);
        final TaskFragmentContainer primaryContainer = prepareContainerForActivity(wct,
@@ -217,15 +214,12 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
     *                          same container as the primary activity, a new container will be
     *                          created and the activity will be re-parented to it.
     * @param rule The split rule to be applied to the container.
     * @param splitAttributes The {@link SplitAttributes} to apply
     */
    void createNewSplitContainer(@NonNull WindowContainerTransaction wct,
            @NonNull Activity primaryActivity, @NonNull Activity secondaryActivity,
            @NonNull SplitPairRule rule) {
            @NonNull SplitPairRule rule, @NonNull SplitAttributes splitAttributes) {
        final TaskProperties taskProperties = getTaskProperties(primaryActivity);
        final Pair<Size, Size> minDimensionsPair = getActivitiesMinDimensionsPair(primaryActivity,
                secondaryActivity);
        final SplitAttributes splitAttributes = computeSplitAttributes(taskProperties, rule,
                rule.getDefaultSplitAttributes(), minDimensionsPair);
        final Rect primaryRelBounds = getRelBoundsForPosition(POSITION_START, taskProperties,
                splitAttributes);
        final TaskFragmentContainer primaryContainer = prepareContainerForActivity(wct,
@@ -654,7 +648,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
    }

    @NonNull
    private static Pair<Size, Size> getActivitiesMinDimensionsPair(
    static Pair<Size, Size> getActivitiesMinDimensionsPair(
            @NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) {
        return new Pair<>(getMinDimensions(primaryActivity), getMinDimensions(secondaryActivity));
    }
@@ -1027,7 +1021,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
    }

    @NonNull
    private static WindowMetrics getTaskWindowMetrics(@NonNull Configuration taskConfiguration) {
    static WindowMetrics getTaskWindowMetrics(@NonNull Configuration taskConfiguration) {
        final Rect taskBounds = taskConfiguration.windowConfiguration.getBounds();
        // TODO(b/190433398): Supply correct insets.
        final float density = taskConfiguration.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+4 −6
Original line number Diff line number Diff line
@@ -565,7 +565,6 @@ public class SplitControllerTest {
        assertNotNull(mSplitController.getActiveSplitForContainers(primaryContainer, container));
        assertTrue(primaryContainer.areLastRequestedBoundsEqual(null));
        assertTrue(container.areLastRequestedBoundsEqual(null));
        assertEquals(container, mSplitController.getContainerWithActivity(secondaryActivity));
    }

    @Test
@@ -1008,9 +1007,8 @@ public class SplitControllerTest {

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

    @Test
@@ -1215,7 +1213,7 @@ public class SplitControllerTest {
                .build();

        assertTrue("Rules must have same presentation if tags are null and has same properties.",
                SplitController.haveSamePresentation(splitRule1, splitRule2,
                SplitController.areRulesSamePresentation(splitRule1, splitRule2,
                        new WindowMetrics(TASK_BOUNDS, WindowInsets.CONSUMED)));

        splitRule2 = createSplitPairRuleBuilder(
@@ -1230,7 +1228,7 @@ public class SplitControllerTest {

        assertFalse("Rules must have different presentations if tags are not equal regardless"
                        + "of other properties",
                SplitController.haveSamePresentation(splitRule1, splitRule2,
                SplitController.areRulesSamePresentation(splitRule1, splitRule2,
                        new WindowMetrics(TASK_BOUNDS, WindowInsets.CONSUMED)));
    }

+2 −1
Original line number Diff line number Diff line
@@ -678,7 +678,8 @@ public class SplitPresenterTest {
                .setShouldClearTop(false)
                .build();

        mPresenter.createNewSplitContainer(mTransaction, mActivity, secondaryActivity, rule);
        mPresenter.createNewSplitContainer(mTransaction, mActivity, secondaryActivity, rule,
                SPLIT_ATTRIBUTES);

        assertEquals(primaryTf, mController.getContainerWithActivity(mActivity));
        final TaskFragmentContainer secondaryTf = mController.getContainerWithActivity(