diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 95899a63b72e8..7da31aa7d03a0 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -100,6 +100,8 @@
8dp
6dp
+
+ 200dp
16dp
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index 35a4f33ecf723..9374da4c4faba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -56,9 +56,6 @@ import com.android.wm.shell.common.TriangleShape;
* transform into the 'new' dot, which is used during flyout dismiss animations/gestures.
*/
public class BubbleFlyoutView extends FrameLayout {
- /** Max width of the flyout, in terms of percent of the screen width. */
- private static final float FLYOUT_MAX_WIDTH_PERCENT = .6f;
-
/** Translation Y of fade animation. */
private static final float FLYOUT_FADE_Y = 40f;
@@ -68,6 +65,8 @@ public class BubbleFlyoutView extends FrameLayout {
// Whether the flyout view should show a pointer to the bubble.
private static final boolean SHOW_POINTER = false;
+ private BubblePositioner mPositioner;
+
private final int mFlyoutPadding;
private final int mFlyoutSpaceFromBubble;
private final int mPointerSize;
@@ -156,10 +155,11 @@ public class BubbleFlyoutView extends FrameLayout {
/** Callback to run when the flyout is hidden. */
@Nullable private Runnable mOnHide;
- public BubbleFlyoutView(Context context) {
+ public BubbleFlyoutView(Context context, BubblePositioner positioner) {
super(context);
- LayoutInflater.from(context).inflate(R.layout.bubble_flyout, this, true);
+ mPositioner = positioner;
+ LayoutInflater.from(context).inflate(R.layout.bubble_flyout, this, true);
mFlyoutTextContainer = findViewById(R.id.bubble_flyout_text_container);
mSenderText = findViewById(R.id.bubble_flyout_name);
mSenderAvatar = findViewById(R.id.bubble_flyout_avatar);
@@ -230,11 +230,11 @@ public class BubbleFlyoutView extends FrameLayout {
/*
* Fade animation for consecutive flyouts.
*/
- void animateUpdate(Bubble.FlyoutMessage flyoutMessage, float parentWidth, PointF stackPos,
+ void animateUpdate(Bubble.FlyoutMessage flyoutMessage, PointF stackPos,
boolean hideDot, Runnable onHide) {
mOnHide = onHide;
final Runnable afterFadeOut = () -> {
- updateFlyoutMessage(flyoutMessage, parentWidth);
+ updateFlyoutMessage(flyoutMessage);
// Wait for TextViews to layout with updated height.
post(() -> {
fade(true /* in */, stackPos, hideDot, () -> {} /* after */);
@@ -266,7 +266,7 @@ public class BubbleFlyoutView extends FrameLayout {
.withEndAction(afterFade);
}
- private void updateFlyoutMessage(Bubble.FlyoutMessage flyoutMessage, float parentWidth) {
+ private void updateFlyoutMessage(Bubble.FlyoutMessage flyoutMessage) {
final Drawable senderAvatar = flyoutMessage.senderAvatar;
if (senderAvatar != null && flyoutMessage.isGroupChat) {
mSenderAvatar.setVisibility(VISIBLE);
@@ -278,8 +278,7 @@ public class BubbleFlyoutView extends FrameLayout {
mSenderText.setTranslationX(0);
}
- final int maxTextViewWidth =
- (int) (parentWidth * FLYOUT_MAX_WIDTH_PERCENT) - mFlyoutPadding * 2;
+ final int maxTextViewWidth = (int) mPositioner.getMaxFlyoutSize() - mFlyoutPadding * 2;
// Name visibility
if (!TextUtils.isEmpty(flyoutMessage.senderName)) {
@@ -328,22 +327,20 @@ public class BubbleFlyoutView extends FrameLayout {
void setupFlyoutStartingAsDot(
Bubble.FlyoutMessage flyoutMessage,
PointF stackPos,
- float parentWidth,
boolean arrowPointingLeft,
int dotColor,
@Nullable Runnable onLayoutComplete,
@Nullable Runnable onHide,
float[] dotCenter,
- boolean hideDot,
- BubblePositioner positioner) {
+ boolean hideDot) {
- mBubbleSize = positioner.getBubbleSize();
+ mBubbleSize = mPositioner.getBubbleSize();
mOriginalDotSize = SIZE_PERCENTAGE * mBubbleSize;
mNewDotRadius = (DOT_SCALE * mOriginalDotSize) / 2f;
mNewDotSize = mNewDotRadius * 2f;
- updateFlyoutMessage(flyoutMessage, parentWidth);
+ updateFlyoutMessage(flyoutMessage);
mArrowPointingLeft = arrowPointingLeft;
mDotColor = dotColor;
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 27e20120a0e5d..df804ec174d38 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
@@ -61,10 +61,16 @@ public class BubblePositioner {
public static final int NUM_VISIBLE_WHEN_RESTING = 2;
/** Indicates a bubble's height should be the maximum available space. **/
public static final int MAX_HEIGHT = -1;
+ /** The max percent of screen width to use for the flyout on large screens. */
+ public static final float FLYOUT_MAX_WIDTH_PERCENT_LARGE_SCREEN = 0.3f;
+ /** The max percent of screen width to use for the flyout on phone. */
+ public static final float FLYOUT_MAX_WIDTH_PERCENT = 0.6f;
+
private Context mContext;
private WindowManager mWindowManager;
private Rect mPositionRect;
+ private Rect mScreenRect;
private @Surface.Rotation int mRotation = Surface.ROTATION_0;
private Insets mInsets;
private int mDefaultMaxBubbles;
@@ -80,6 +86,7 @@ public class BubblePositioner {
private int mManageButtonHeight;
private int mExpandedViewMinHeight;
private int mOverflowHeight;
+ private int mMinimumFlyoutWidthLargeScreen;
private PointF mPinLocation;
private PointF mRestingStackPosition;
@@ -148,6 +155,7 @@ public class BubblePositioner {
mRotation = rotation;
mInsets = insets;
+ mScreenRect = new Rect(bounds);
mPositionRect = new Rect(bounds);
mPositionRect.left += mInsets.left;
mPositionRect.top += mInsets.top;
@@ -168,6 +176,8 @@ public class BubblePositioner {
mManageButtonHeight = res.getDimensionPixelSize(R.dimen.bubble_manage_button_total_height);
mExpandedViewMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height);
mOverflowHeight = res.getDimensionPixelSize(R.dimen.bubble_overflow_height);
+ mMinimumFlyoutWidthLargeScreen = res.getDimensionPixelSize(
+ R.dimen.bubbles_flyout_min_width_large_screen);
mMaxBubbles = calculateMaxBubbles();
@@ -423,6 +433,17 @@ public class BubblePositioner {
return rowStart + positionInBar;
}
+ /**
+ * @return the width of the bubble flyout (message originating from the bubble).
+ */
+ public float getMaxFlyoutSize() {
+ if (isLargeScreen()) {
+ return Math.max(mScreenRect.width() * FLYOUT_MAX_WIDTH_PERCENT_LARGE_SCREEN,
+ mMinimumFlyoutWidthLargeScreen);
+ }
+ return mScreenRect.width() * FLYOUT_MAX_WIDTH_PERCENT;
+ }
+
/**
* Sets the stack's most recent position along the edge of the screen. This is saved when the
* last bubble is removed, so that the stack can be restored in its previous position.
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 9ca107e92654b..8f2df4ab39722 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
@@ -1186,7 +1186,7 @@ public class BubbleStackView extends FrameLayout
if (mFlyout != null) {
removeView(mFlyout);
}
- mFlyout = new BubbleFlyoutView(getContext());
+ mFlyout = new BubbleFlyoutView(getContext(), mPositioner);
mFlyout.setVisibility(GONE);
mFlyout.setOnClickListener(mFlyoutClickListener);
mFlyout.setOnTouchListener(mFlyoutTouchListener);
@@ -2423,20 +2423,19 @@ public class BubbleStackView extends FrameLayout
if (mFlyout.getVisibility() == View.VISIBLE) {
- mFlyout.animateUpdate(bubble.getFlyoutMessage(), getWidth(),
+ mFlyout.animateUpdate(bubble.getFlyoutMessage(),
mStackAnimationController.getStackPosition(), !bubble.showDot(),
mAfterFlyoutHidden /* onHide */);
} else {
mFlyout.setVisibility(INVISIBLE);
mFlyout.setupFlyoutStartingAsDot(bubble.getFlyoutMessage(),
- mStackAnimationController.getStackPosition(), getWidth(),
+ mStackAnimationController.getStackPosition(),
mStackAnimationController.isStackOnLeftSide(),
bubble.getIconView().getDotColor() /* dotColor */,
expandFlyoutAfterDelay /* onLayoutComplete */,
mAfterFlyoutHidden /* onHide */,
bubble.getIconView().getDotCenter(),
- !bubble.showDot(),
- mPositioner);
+ !bubble.showDot());
}
mFlyout.bringToFront();
});
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
index 6644eaf28a62b..5c1bcb9753a4f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
@@ -63,7 +63,7 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
mFlyoutMessage.senderName = "Josh";
mFlyoutMessage.message = "Hello";
- mFlyout = new BubbleFlyoutView(getContext());
+ mFlyout = new BubbleFlyoutView(getContext(), mPositioner);
mFlyoutText = mFlyout.findViewById(R.id.bubble_flyout_text);
mSenderName = mFlyout.findViewById(R.id.bubble_flyout_name);
@@ -75,9 +75,8 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
public void testShowFlyout_isVisible() {
mFlyout.setupFlyoutStartingAsDot(
mFlyoutMessage,
- new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
- false,
- mPositioner);
+ new PointF(100, 100), true, Color.WHITE, null, null, mDotCenter,
+ false);
mFlyout.setVisibility(View.VISIBLE);
assertEquals("Hello", mFlyoutText.getText());
@@ -89,9 +88,8 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
public void testFlyoutHide_runsCallback() {
Runnable after = mock(Runnable.class);
mFlyout.setupFlyoutStartingAsDot(mFlyoutMessage,
- new PointF(100, 100), 500, true, Color.WHITE, null, after, mDotCenter,
- false,
- mPositioner);
+ new PointF(100, 100), true, Color.WHITE, null, after, mDotCenter,
+ false);
mFlyout.hideFlyout();
verify(after).run();
@@ -100,9 +98,8 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
@Test
public void testSetCollapsePercent() {
mFlyout.setupFlyoutStartingAsDot(mFlyoutMessage,
- new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
- false,
- mPositioner);
+ new PointF(100, 100), true, Color.WHITE, null, null, mDotCenter,
+ false);
mFlyout.setVisibility(View.VISIBLE);
mFlyout.setCollapsePercent(1f);