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

Commit ab3b6083 authored by Mady Mellor's avatar Mady Mellor
Browse files

Fix an issue where the start position of the stack is wrong in RTL

In RTL, when the stack shown for the first time with user education,
the stack would be positioned offscreen. This is because we were
incorrectly passing the whole screen size in getDefaultStartPosition()

This would work fine when the stack starts on the left, but not in
RTL when it starts on the right and the size of the stack needs to be
subtracted.

To fix this I moved over getAllowableStackPositionRegion into
BubblePositioner and use that when retrieving the starting position.

Test: manual - be in RTL, show user education, observe that the
      stack is fully on screen as expected. Also check in LTR.
Bug: 233402922
Change-Id: Ib8ad2a289f373fdc1c61527c47793461fc34d929
parent 2e16265e
Loading
Loading
Loading
Loading
+44 −1
Original line number Diff line number Diff line
@@ -88,6 +88,9 @@ public class BubblePositioner {
    private int mMaxBubbles;
    private int mBubbleSize;
    private int mSpacingBetweenBubbles;
    private int mBubblePaddingTop;
    private int mBubbleOffscreenAmount;
    private int mStackOffset;

    private int mExpandedViewMinHeight;
    private int mExpandedViewLargeScreenWidth;
@@ -187,6 +190,10 @@ public class BubblePositioner {
        mSpacingBetweenBubbles = res.getDimensionPixelSize(R.dimen.bubble_spacing);
        mDefaultMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
        mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
        mBubbleOffscreenAmount = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen);
        mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);

        if (mIsSmallTablet) {
            mExpandedViewLargeScreenWidth = (int) (bounds.width()
                    * EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT);
@@ -329,6 +336,21 @@ public class BubblePositioner {
                : mBubbleSize;
    }

    /** The amount of padding at the top of the screen that the bubbles avoid when being placed. */
    public int getBubblePaddingTop() {
        return mBubblePaddingTop;
    }

    /** The amount the stack hang off of the screen when collapsed. */
    public int getStackOffScreenAmount() {
        return mBubbleOffscreenAmount;
    }

    /** Offset of bubbles in the stack (i.e. how much they overlap). */
    public int getStackOffset() {
        return mStackOffset;
    }

    /** Size of the visible (non-overlapping) part of the pointer. */
    public int getPointerSize() {
        return mPointerHeight - mPointerOverlap;
@@ -678,7 +700,28 @@ public class BubblePositioner {
        return new BubbleStackView.RelativeStackPosition(
                startOnLeft,
                startingVerticalOffset / mPositionRect.height())
                .getAbsolutePositionInRegion(new RectF(mPositionRect));
                .getAbsolutePositionInRegion(getAllowableStackPositionRegion(
                        1 /* default starts with 1 bubble */));
    }


    /**
     * Returns the region that the stack position must stay within. This goes slightly off the left
     * and right sides of the screen, below the status bar/cutout and above the navigation bar.
     * While the stack position is not allowed to rest outside of these bounds, it can temporarily
     * be animated or dragged beyond them.
     */
    public RectF getAllowableStackPositionRegion(int bubbleCount) {
        final RectF allowableRegion = new RectF(getAvailableRect());
        final int imeHeight = getImeHeight();
        final float bottomPadding = bubbleCount > 1
                ? mBubblePaddingTop + mStackOffset
                : mBubblePaddingTop;
        allowableRegion.left -= mBubbleOffscreenAmount;
        allowableRegion.top += mBubblePaddingTop;
        allowableRegion.right += mBubbleOffscreenAmount - mBubbleSize;
        allowableRegion.bottom -= imeHeight + bottomPadding + mBubbleSize;
        return allowableRegion;
    }

    /**
+3 −3
Original line number Diff line number Diff line
@@ -1296,7 +1296,7 @@ public class BubbleStackView extends FrameLayout
    public void onOrientationChanged() {
        mRelativeStackPositionBeforeRotation = new RelativeStackPosition(
                mPositioner.getRestingPosition(),
                mStackAnimationController.getAllowableStackPositionRegion());
                mPositioner.getAllowableStackPositionRegion(getBubbleCount()));
        addOnLayoutChangeListener(mOrientationChangedListener);
        hideFlyoutImmediate();
    }
@@ -1340,7 +1340,7 @@ public class BubbleStackView extends FrameLayout
            mStackAnimationController.setStackPosition(
                    new RelativeStackPosition(
                            mPositioner.getRestingPosition(),
                            mStackAnimationController.getAllowableStackPositionRegion()));
                            mPositioner.getAllowableStackPositionRegion(getBubbleCount())));
        }
        if (mIsExpanded) {
            updateExpandedView();
@@ -1440,7 +1440,7 @@ public class BubbleStackView extends FrameLayout
        if (super.performAccessibilityActionInternal(action, arguments)) {
            return true;
        }
        final RectF stackBounds = mStackAnimationController.getAllowableStackPositionRegion();
        final RectF stackBounds = mPositioner.getAllowableStackPositionRegion(getBubbleCount());

        // R constants are not final so we cannot use switch-case here.
        if (action == AccessibilityNodeInfo.ACTION_DISMISS) {
+11 −30
Original line number Diff line number Diff line
@@ -185,8 +185,6 @@ public class StackAnimationController extends
     * stack goes offscreen intentionally.
     */
    private int mBubblePaddingTop;
    /** How far offscreen the stack rests. */
    private int mBubbleOffscreen;
    /** Contains display size, orientation, and inset information. */
    private BubblePositioner mPositioner;

@@ -212,7 +210,8 @@ public class StackAnimationController extends
        public Rect getAllowedFloatingBoundsRegion() {
            final Rect floatingBounds = getFloatingBoundsOnScreen();
            final Rect allowableStackArea = new Rect();
            getAllowableStackPositionRegion().roundOut(allowableStackArea);
            mPositioner.getAllowableStackPositionRegion(getBubbleCount())
                    .roundOut(allowableStackArea);
            allowableStackArea.right += floatingBounds.width();
            allowableStackArea.bottom += floatingBounds.height();
            return allowableStackArea;
@@ -349,7 +348,7 @@ public class StackAnimationController extends
                ? velX < ESCAPE_VELOCITY
                : velX < -ESCAPE_VELOCITY;

        final RectF stackBounds = getAllowableStackPositionRegion();
        final RectF stackBounds = mPositioner.getAllowableStackPositionRegion(getBubbleCount());

        // Target X translation (either the left or right side of the screen).
        final float destinationRelativeX = stackShouldFlingLeft
@@ -425,7 +424,7 @@ public class StackAnimationController extends
        }
        final PointF stackPos = getStackPosition();
        final boolean onLeft = mLayout.isFirstChildXLeftOfCenter(stackPos.x);
        final RectF bounds = getAllowableStackPositionRegion();
        final RectF bounds = mPositioner.getAllowableStackPositionRegion(getBubbleCount());

        stackPos.x = onLeft ? bounds.left : bounds.right;
        return stackPos;
@@ -464,7 +463,7 @@ public class StackAnimationController extends

        StackPositionProperty firstBubbleProperty = new StackPositionProperty(property);
        final float currentValue = firstBubbleProperty.getValue(this);
        final RectF bounds = getAllowableStackPositionRegion();
        final RectF bounds = mPositioner.getAllowableStackPositionRegion(getBubbleCount());
        final float min =
                property.equals(DynamicAnimation.TRANSLATION_X)
                        ? bounds.left
@@ -525,7 +524,8 @@ public class StackAnimationController extends
     * of the stack if it's not moving).
     */
    public float animateForImeVisibility(boolean imeVisible) {
        final float maxBubbleY = getAllowableStackPositionRegion().bottom;
        final float maxBubbleY = mPositioner.getAllowableStackPositionRegion(
                getBubbleCount()).bottom;
        float destinationY = UNSET;

        if (imeVisible) {
@@ -567,25 +567,6 @@ public class StackAnimationController extends
        mFloatingContentCoordinator.onContentMoved(mStackFloatingContent);
    }

    /**
     * Returns the region that the stack position must stay within. This goes slightly off the left
     * and right sides of the screen, below the status bar/cutout and above the navigation bar.
     * While the stack position is not allowed to rest outside of these bounds, it can temporarily
     * be animated or dragged beyond them.
     */
    public RectF getAllowableStackPositionRegion() {
        final RectF allowableRegion = new RectF(mPositioner.getAvailableRect());
        final int imeHeight = mPositioner.getImeHeight();
        final float bottomPadding = getBubbleCount() > 1
                ? mBubblePaddingTop + mStackOffset
                : mBubblePaddingTop;
        allowableRegion.left -= mBubbleOffscreen;
        allowableRegion.top += mBubblePaddingTop;
        allowableRegion.right += mBubbleOffscreen - mBubbleSize;
        allowableRegion.bottom -= imeHeight + bottomPadding + mBubbleSize;
        return allowableRegion;
    }

    /** Moves the stack in response to a touch event. */
    public void moveStackFromTouch(float x, float y) {
        // Begin the spring-to-touch catch up animation if needed.
@@ -861,13 +842,12 @@ public class StackAnimationController extends
    @Override
    void onActiveControllerForLayout(PhysicsAnimationLayout layout) {
        Resources res = layout.getResources();
        mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
        mStackOffset = mPositioner.getStackOffset();
        mSwapAnimationOffset = res.getDimensionPixelSize(R.dimen.bubble_swap_animation_offset);
        mMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
        mElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
        mBubbleSize = mPositioner.getBubbleSize();
        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
        mBubbleOffscreen = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen);
        mBubblePaddingTop = mPositioner.getBubblePaddingTop();
    }

    /**
@@ -958,7 +938,8 @@ public class StackAnimationController extends
    }

    public void setStackPosition(BubbleStackView.RelativeStackPosition position) {
        setStackPosition(position.getAbsolutePositionInRegion(getAllowableStackPositionRegion()));
        setStackPosition(position.getAbsolutePositionInRegion(
                mPositioner.getAllowableStackPositionRegion(getBubbleCount())));
    }

    private boolean isStackPositionSet() {