From ab3b6083130067e94c13677b658a31bfef0a0a60 Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Fri, 20 May 2022 22:12:33 +0000 Subject: 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 --- .../android/wm/shell/bubbles/BubblePositioner.java | 45 +++++++++++++++++++++- .../android/wm/shell/bubbles/BubbleStackView.java | 6 +-- .../animation/StackAnimationController.java | 41 ++++++-------------- 3 files changed, 58 insertions(+), 34 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java index 7cfacbcc92f8..e9729e45731b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java @@ -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; } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index b7c5eb06fbfa..0e8dc63943a6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -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) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java index 04af60dd7a03..0a1b4d70fb2b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java @@ -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() { -- cgit v1.2.3-59-g8ed1b