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

Commit c49e1919 authored by Jiaming Liu's avatar Jiaming Liu Committed by Android (Google) Code Review
Browse files

Merge "[Divider] Fix wrong drag handle position for RTL layout" into main

parents 6fdf7401 53a48bf6
Loading
Loading
Loading
Loading
+68 −69
Original line number Diff line number Diff line
@@ -200,6 +200,10 @@ class DividerPresenter implements View.OnTouchListener {
            }

            // At this point, a divider is required.
            final TaskFragmentContainer primaryContainer =
                    topSplitContainer.getPrimaryContainer();
            final TaskFragmentContainer secondaryContainer =
                    topSplitContainer.getSecondaryContainer();

            // Create the decor surface if one is not available yet.
            final SurfaceControl decorSurface = parentInfo.getDecorSurface();
@@ -207,41 +211,44 @@ class DividerPresenter implements View.OnTouchListener {
                // Clean up when the decor surface is currently unavailable.
                removeDivider();
                // Request to create the decor surface
                createOrMoveDecorSurfaceLocked(wct, topSplitContainer.getPrimaryContainer());
                createOrMoveDecorSurfaceLocked(wct, primaryContainer);
                return;
            }

            // Update the decor surface owner if needed.
            boolean isDraggableExpandType =
                    SplitAttributesHelper.isDraggableExpandType(splitAttributes);
            final TaskFragmentContainer decorSurfaceOwnerContainer = isDraggableExpandType
                    ? topSplitContainer.getSecondaryContainer()
                    : topSplitContainer.getPrimaryContainer();
            final TaskFragmentContainer decorSurfaceOwnerContainer =
                    isDraggableExpandType ? secondaryContainer : primaryContainer;

            if (!Objects.equals(
                    mDecorSurfaceOwner, decorSurfaceOwnerContainer.getTaskFragmentToken())) {
                createOrMoveDecorSurfaceLocked(wct, decorSurfaceOwnerContainer);
            }
            final boolean isVerticalSplit = isVerticalSplit(topSplitContainer);
            final boolean isReversedLayout = isReversedLayout(
                    topSplitContainer.getCurrentSplitAttributes(),
                    parentInfo.getConfiguration());

            final Configuration parentConfiguration = parentInfo.getConfiguration();
            final Rect taskBounds = parentConfiguration.windowConfiguration.getBounds();
            final boolean isVerticalSplit = isVerticalSplit(splitAttributes);
            final boolean isReversedLayout = isReversedLayout(splitAttributes, parentConfiguration);
            final int dividerWidthPx = getDividerWidthPx(dividerAttributes);

            updateProperties(
                    new Properties(
                            parentInfo.getConfiguration(),
                            parentConfiguration,
                            dividerAttributes,
                            decorSurface,
                            getInitialDividerPosition(
                                    topSplitContainer, isVerticalSplit, isReversedLayout),
                                    primaryContainer, secondaryContainer, taskBounds,
                                    dividerWidthPx, isDraggableExpandType, isVerticalSplit,
                                    isReversedLayout),
                            isVerticalSplit,
                            isReversedLayout,
                            parentInfo.getDisplayId(),
                            isDraggableExpandType,
                            getContainerBackgroundColor(topSplitContainer.getPrimaryContainer(),
                                    DEFAULT_PRIMARY_VEIL_COLOR),
                            getContainerBackgroundColor(topSplitContainer.getSecondaryContainer(),
                                    DEFAULT_SECONDARY_VEIL_COLOR)
                            getContainerBackgroundColor(
                                    primaryContainer, DEFAULT_PRIMARY_VEIL_COLOR),
                            getContainerBackgroundColor(
                                    secondaryContainer, DEFAULT_SECONDARY_VEIL_COLOR)
                    ));
        }
    }
@@ -338,32 +345,31 @@ class DividerPresenter implements View.OnTouchListener {

    @VisibleForTesting
    static int getInitialDividerPosition(
            @NonNull SplitContainer splitContainer,
            @NonNull TaskFragmentContainer primaryContainer,
            @NonNull TaskFragmentContainer secondaryContainer,
            @NonNull Rect taskBounds,
            int dividerWidthPx,
            boolean isDraggableExpandType,
            boolean isVerticalSplit,
            boolean isReversedLayout) {
        final Rect primaryBounds =
                splitContainer.getPrimaryContainer().getLastRequestedBounds();
        final Rect secondaryBounds =
                splitContainer.getSecondaryContainer().getLastRequestedBounds();
        final SplitAttributes splitAttributes = splitContainer.getCurrentSplitAttributes();

        if (SplitAttributesHelper.isDraggableExpandType(splitAttributes)) {
            // If the container is fully expanded by dragging the divider, we display the divider
            // on the edge.
            final int dividerWidth = getDividerWidthPx(splitAttributes.getDividerAttributes());
        if (isDraggableExpandType) {
            // If the secondary container is fully expanded by dragging the divider, we display the
            // divider on the edge.
            final int fullyExpandedPosition = isVerticalSplit
                    ? primaryBounds.right - dividerWidth
                    : primaryBounds.bottom - dividerWidth;
                    ? taskBounds.width() - dividerWidthPx
                    : taskBounds.height() - dividerWidthPx;
            return isReversedLayout ? fullyExpandedPosition : 0;
        } else {
            final Rect primaryBounds = primaryContainer.getLastRequestedBounds();
            final Rect secondaryBounds = secondaryContainer.getLastRequestedBounds();
            return isVerticalSplit
                    ? Math.min(primaryBounds.right, secondaryBounds.right)
                    : Math.min(primaryBounds.bottom, secondaryBounds.bottom);
        }
    }

    private static boolean isVerticalSplit(@NonNull SplitContainer splitContainer) {
        final int layoutDirection = splitContainer.getCurrentSplitAttributes().getLayoutDirection();
    private static boolean isVerticalSplit(@NonNull SplitAttributes splitAttributes) {
        final int layoutDirection = splitAttributes.getLayoutDirection();
        switch (layoutDirection) {
            case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT:
            case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT:
@@ -510,7 +516,7 @@ class DividerPresenter implements View.OnTouchListener {
            if (mProperties != null && mRenderer != null) {
                final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds();
                mDividerPosition = calculateDividerPosition(
                        event, taskBounds, mRenderer.mDividerWidthPx,
                        event, taskBounds, mProperties.mDividerWidthPx,
                        mProperties.mDividerAttributes, mProperties.mIsVerticalSplit,
                        calculateMinPosition(), calculateMaxPosition());
                mRenderer.setDividerPosition(mDividerPosition);
@@ -676,8 +682,8 @@ class DividerPresenter implements View.OnTouchListener {
        final int minPosition = calculateMinPosition();
        final int maxPosition = calculateMaxPosition();
        final int fullyExpandedPosition = mProperties.mIsVerticalSplit
                ? taskBounds.right - mRenderer.mDividerWidthPx
                : taskBounds.bottom - mRenderer.mDividerWidthPx;
                ? taskBounds.width() - mProperties.mDividerWidthPx
                : taskBounds.height() - mProperties.mDividerWidthPx;

        if (isDraggingToFullscreenAllowed(mProperties.mDividerAttributes)) {
            final float displayDensity = getDisplayDensity();
@@ -782,7 +788,7 @@ class DividerPresenter implements View.OnTouchListener {
    private int calculateMinPosition() {
        return calculateMinPosition(
                mProperties.mConfiguration.windowConfiguration.getBounds(),
                mRenderer.mDividerWidthPx, mProperties.mDividerAttributes,
                mProperties.mDividerWidthPx, mProperties.mDividerAttributes,
                mProperties.mIsVerticalSplit, mProperties.mIsReversedLayout);
    }

@@ -790,7 +796,7 @@ class DividerPresenter implements View.OnTouchListener {
    private int calculateMaxPosition() {
        return calculateMaxPosition(
                mProperties.mConfiguration.windowConfiguration.getBounds(),
                mRenderer.mDividerWidthPx, mProperties.mDividerAttributes,
                mProperties.mDividerWidthPx, mProperties.mDividerAttributes,
                mProperties.mIsVerticalSplit, mProperties.mIsReversedLayout);
    }

@@ -828,13 +834,12 @@ class DividerPresenter implements View.OnTouchListener {
     * Returns the new split ratio of the {@link SplitContainer} based on the current divider
     * position.
     */
    float calculateNewSplitRatio(@NonNull SplitContainer topSplitContainer) {
    float calculateNewSplitRatio() {
        synchronized (mLock) {
            return calculateNewSplitRatio(
                    topSplitContainer,
                    mDividerPosition,
                    mProperties.mConfiguration.windowConfiguration.getBounds(),
                    mRenderer.mDividerWidthPx,
                    mProperties.mDividerWidthPx,
                    mProperties.mIsVerticalSplit,
                    mProperties.mIsReversedLayout,
                    calculateMinPosition(),
@@ -854,13 +859,12 @@ class DividerPresenter implements View.OnTouchListener {
     * Returns the new split ratio of the {@link SplitContainer} based on the current divider
     * position.
     *
     * @param topSplitContainer the {@link SplitContainer} for which to compute the split ratio.
     * @param dividerPosition the divider position. See {@link #mDividerPosition}.
     * @param taskBounds the task bounds
     * @param dividerWidthPx the width of the divider in pixels.
     * @param isVerticalSplit if {@code true}, the split is a vertical split. If {@code false}, the
     *                        split is a horizontal split. See
     *                        {@link #isVerticalSplit(SplitContainer)}.
     *                        {@link #isVerticalSplit(SplitAttributes)}.
     * @param isReversedLayout if {@code true}, the split layout is reversed, i.e. right-to-left or
     *                         bottom-to-top. If {@code false}, the split is not reversed, i.e.
     *                         left-to-right or top-to-bottom. See
@@ -871,7 +875,6 @@ class DividerPresenter implements View.OnTouchListener {
     */
    @VisibleForTesting
    static float calculateNewSplitRatio(
            @NonNull SplitContainer topSplitContainer,
            int dividerPosition,
            @NonNull Rect taskBounds,
            int dividerWidthPx,
@@ -896,8 +899,6 @@ class DividerPresenter implements View.OnTouchListener {
            dividerPosition = Math.clamp(dividerPosition, minPosition, maxPosition);
        }

        final TaskFragmentContainer primaryContainer = topSplitContainer.getPrimaryContainer();
        final Rect origPrimaryBounds = primaryContainer.getLastRequestedBounds();
        final int usableSize = isVerticalSplit
                ? taskBounds.width() - dividerWidthPx
                : taskBounds.height() - dividerWidthPx;
@@ -905,13 +906,13 @@ class DividerPresenter implements View.OnTouchListener {
        final float newRatio;
        if (isVerticalSplit) {
            final int newPrimaryWidth = isReversedLayout
                    ? (origPrimaryBounds.right - (dividerPosition + dividerWidthPx))
                    : (dividerPosition - origPrimaryBounds.left);
                    ? taskBounds.width() - (dividerPosition + dividerWidthPx)
                    : dividerPosition;
            newRatio = 1.0f * newPrimaryWidth / usableSize;
        } else {
            final int newPrimaryHeight = isReversedLayout
                    ? (origPrimaryBounds.bottom - (dividerPosition + dividerWidthPx))
                    : (dividerPosition - origPrimaryBounds.top);
                    ? taskBounds.height() - (dividerPosition + dividerWidthPx)
                    : dividerPosition;
            newRatio = 1.0f * newPrimaryHeight / usableSize;
        }
        return newRatio;
@@ -966,6 +967,7 @@ class DividerPresenter implements View.OnTouchListener {
        private final boolean mIsDraggableExpandType;
        private final Color mPrimaryVeilColor;
        private final Color mSecondaryVeilColor;
        private final int mDividerWidthPx;

        @VisibleForTesting
        Properties(
@@ -989,6 +991,7 @@ class DividerPresenter implements View.OnTouchListener {
            mIsDraggableExpandType = isDraggableExpandType;
            mPrimaryVeilColor = primaryVeilColor;
            mSecondaryVeilColor = secondaryVeilColor;
            mDividerWidthPx = getDividerWidthPx(dividerAttributes);
        }

        /**
@@ -1055,7 +1058,6 @@ class DividerPresenter implements View.OnTouchListener {
        private final View.OnTouchListener mListener;
        @NonNull
        private Properties mProperties;
        private int mDividerWidthPx;
        private int mHandleWidthPx;
        @Nullable
        private SurfaceControl mPrimaryVeil;
@@ -1095,7 +1097,6 @@ class DividerPresenter implements View.OnTouchListener {
        /** Updates the divider when initializing or when properties are changed */
        @VisibleForTesting
        void update() {
            mDividerWidthPx = getDividerWidthPx(mProperties.mDividerAttributes);
            mDividerPosition = mProperties.mInitialDividerPosition;
            mWindowlessWindowManager.setConfiguration(mProperties.mConfiguration);

@@ -1161,15 +1162,17 @@ class DividerPresenter implements View.OnTouchListener {
                // When the divider drag handle width is larger than the divider width, the position
                // of the divider surface is adjusted so that it is large enough to host both the
                // divider line and the divider drag handle.
                mDividerSurfaceWidthPx = Math.max(mDividerWidthPx, mHandleWidthPx);
                dividerSurfacePosition =
                        mProperties.mIsReversedLayout
                mDividerSurfaceWidthPx = Math.max(mProperties.mDividerWidthPx, mHandleWidthPx);
                dividerSurfacePosition = mProperties.mIsReversedLayout
                        ? mDividerPosition
                                : mDividerPosition + mDividerWidthPx - mDividerSurfaceWidthPx;
                dividerSurfacePosition = Math.clamp(dividerSurfacePosition, 0,
                        mProperties.mIsVerticalSplit ? taskBounds.width() : taskBounds.height());
                        : mDividerPosition + mProperties.mDividerWidthPx - mDividerSurfaceWidthPx;
                dividerSurfacePosition =
                        Math.clamp(dividerSurfacePosition, 0,
                                mProperties.mIsVerticalSplit
                                        ? taskBounds.width() - mDividerSurfaceWidthPx
                                        : taskBounds.height() - mDividerSurfaceWidthPx);
            } else {
                mDividerSurfaceWidthPx = mDividerWidthPx;
                mDividerSurfaceWidthPx = mProperties.mDividerWidthPx;
                dividerSurfacePosition = mDividerPosition;
            }

@@ -1182,16 +1185,9 @@ class DividerPresenter implements View.OnTouchListener {
            }

            // Update divider line position in the surface
            if (!mProperties.mIsReversedLayout) {
            final int offset = mDividerPosition - dividerSurfacePosition;
            mDividerLine.setX(mProperties.mIsVerticalSplit ? offset : 0);
            mDividerLine.setY(mProperties.mIsVerticalSplit ? 0 : offset);
            } else {
                // For reversed layout, the divider line is always at the start of the divider
                // surface.
                mDividerLine.setX(0);
                mDividerLine.setY(0);
            }

            if (mIsDragging) {
                updateVeils(t);
@@ -1241,8 +1237,10 @@ class DividerPresenter implements View.OnTouchListener {
            final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds();
            mDividerLine.setLayoutParams(
                    mProperties.mIsVerticalSplit
                            ? new FrameLayout.LayoutParams(mDividerWidthPx, taskBounds.height())
                            : new FrameLayout.LayoutParams(taskBounds.width(), mDividerWidthPx)
                            ? new FrameLayout.LayoutParams(
                                    mProperties.mDividerWidthPx, taskBounds.height())
                            : new FrameLayout.LayoutParams(
                                    taskBounds.width(), mProperties.mDividerWidthPx)
            );
            if (mProperties.mDividerAttributes.getDividerType()
                    == DividerAttributes.DIVIDER_TYPE_DRAGGABLE) {
@@ -1352,13 +1350,14 @@ class DividerPresenter implements View.OnTouchListener {
            Rect secondaryBounds;
            if (mProperties.mIsVerticalSplit) {
                final Rect boundsLeft = new Rect(0, 0, mDividerPosition, taskBounds.height());
                final Rect boundsRight = new Rect(mDividerPosition + mDividerWidthPx, 0,
                final Rect boundsRight = new Rect(mDividerPosition + mProperties.mDividerWidthPx, 0,
                        taskBounds.width(), taskBounds.height());
                primaryBounds = mProperties.mIsReversedLayout ? boundsRight : boundsLeft;
                secondaryBounds = mProperties.mIsReversedLayout ? boundsLeft : boundsRight;
            } else {
                final Rect boundsTop = new Rect(0, 0, taskBounds.width(), mDividerPosition);
                final Rect boundsBottom = new Rect(0, mDividerPosition + mDividerWidthPx,
                final Rect boundsBottom = new Rect(
                        0, mDividerPosition + mProperties.mDividerWidthPx,
                        taskBounds.width(), taskBounds.height());
                primaryBounds = mProperties.mIsReversedLayout ? boundsBottom : boundsTop;
                secondaryBounds = mProperties.mIsReversedLayout ? boundsTop : boundsBottom;
+1 −1
Original line number Diff line number Diff line
@@ -510,7 +510,7 @@ class TaskContainer {
            return;
        }
        final TaskFragmentContainer primaryContainer = topSplitContainer.getPrimaryContainer();
        final float newRatio = dividerPresenter.calculateNewSplitRatio(topSplitContainer);
        final float newRatio = dividerPresenter.calculateNewSplitRatio();

        // If the primary container is fully expanded, we should finish all the associated
        // secondary containers.
+4 −7
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ public class DividerPresenterTest {
                new SplitAttributes.Builder()
                        .setDividerAttributes(DEFAULT_DIVIDER_ATTRIBUTES)
                        .build());
        final Rect mockTaskBounds = new Rect(0, 0, 2000, 1000);
        final TaskFragmentContainer mockPrimaryContainer =
                createMockTaskFragmentContainer(
                        mPrimaryContainerToken, new Rect(0, 0, 950, 1000));
@@ -158,7 +159,9 @@ public class DividerPresenterTest {
                DEFAULT_DIVIDER_ATTRIBUTES,
                mSurfaceControl,
                getInitialDividerPosition(
                        mSplitContainer, true /* isVerticalSplit */, false /* isReversedLayout */),
                        mockPrimaryContainer, mockSecondaryContainer, mockTaskBounds,
                        50 /* divideWidthPx */, false /* isDraggableExpandType */,
                        true /* isVerticalSplit */, false /* isReversedLayout */),
                true /* isVerticalSplit */,
                false /* isReversedLayout */,
                Display.DEFAULT_DISPLAY,
@@ -502,7 +505,6 @@ public class DividerPresenterTest {
        assertEquals(
                0.3f, // Primary is 300px after dragging.
                DividerPresenter.calculateNewSplitRatio(
                        mSplitContainer,
                        dividerPosition,
                        taskBounds,
                        dividerWidthPx,
@@ -518,7 +520,6 @@ public class DividerPresenterTest {
        assertEquals(
                DividerPresenter.RATIO_EXPANDED_SECONDARY,
                DividerPresenter.calculateNewSplitRatio(
                        mSplitContainer,
                        dividerPosition,
                        taskBounds,
                        dividerWidthPx,
@@ -535,7 +536,6 @@ public class DividerPresenterTest {
        assertEquals(
                0.2f, // Adjusted to the minPosition 200
                DividerPresenter.calculateNewSplitRatio(
                        mSplitContainer,
                        dividerPosition,
                        taskBounds,
                        dividerWidthPx,
@@ -569,7 +569,6 @@ public class DividerPresenterTest {
                // After dragging, secondary is [0, 0, 2000, 300]. Primary is [0, 400, 2000, 1100].
                0.7f,
                DividerPresenter.calculateNewSplitRatio(
                        mSplitContainer,
                        dividerPosition,
                        taskBounds,
                        dividerWidthPx,
@@ -587,7 +586,6 @@ public class DividerPresenterTest {
                // The primary (bottom) container is expanded
                DividerPresenter.RATIO_EXPANDED_PRIMARY,
                DividerPresenter.calculateNewSplitRatio(
                        mSplitContainer,
                        dividerPosition,
                        taskBounds,
                        dividerWidthPx,
@@ -605,7 +603,6 @@ public class DividerPresenterTest {
                // Adjusted to minPosition 200, so the primary (bottom) container is 800.
                0.8f,
                DividerPresenter.calculateNewSplitRatio(
                        mSplitContainer,
                        dividerPosition,
                        taskBounds,
                        dividerWidthPx,