Merge "Fix issues in RTL." into rvc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 0690907..8a2c101 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -798,6 +798,8 @@
                 mBubbleIconFactory = new BubbleIconFactory(mContext);
                 mStackView.onDisplaySizeChanged();
             }
+
+            mStackView.onLayoutDirectionChanged();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index fee7847..790d6a2 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -316,6 +316,10 @@
 
             return false;
         });
+
+        // BubbleStackView is forced LTR, but we want to respect the locale for expanded view layout
+        // so the Manage button appears on the right.
+        setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
     }
 
     private String getBubbleKey() {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
index e12b325..8c76cda 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
@@ -186,6 +186,9 @@
             }
         });
 
+        // Use locale direction so the text is aligned correctly.
+        setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
+
         mBgPaint.setColor(mFloatingBackgroundColor);
 
         mLeftTriangleShape =
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index fb081e2..dfa71ba 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -723,6 +723,12 @@
 
         setUpUserEducation();
 
+        // Force LTR by default since most of the Bubbles UI is positioned manually by the user, or
+        // is centered. It greatly simplifies translation positioning/animations. Views that will
+        // actually lay out differently in RTL, such as the flyout and expanded view, will set their
+        // layout direction to LOCALE.
+        setLayoutDirection(LAYOUT_DIRECTION_LTR);
+
         mBubbleContainer = new PhysicsAnimationLayout(context);
         mBubbleContainer.setActiveController(mStackAnimationController);
         mBubbleContainer.setElevation(elevation);
@@ -961,6 +967,9 @@
 
         mManageSettingsIcon = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_icon);
         mManageSettingsText = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_name);
+
+        // The menu itself should respect locale direction so the icons are on the correct side.
+        mManageMenu.setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
         addView(mManageMenu);
     }
 
@@ -1084,6 +1093,16 @@
         mShowingManage = false;
     }
 
+    /** Tells the views with locale-dependent layout direction to resolve the new direction. */
+    public void onLayoutDirectionChanged() {
+        mManageMenu.resolveLayoutDirection();
+        mFlyout.resolveLayoutDirection();
+
+        if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+            mExpandedBubble.getExpandedView().resolveLayoutDirection();
+        }
+    }
+
     /** Respond to the display size change by recalculating view size and location. */
     public void onDisplaySizeChanged() {
         setUpOverflow();
@@ -2095,16 +2114,21 @@
 
         mExpandedBubble.getExpandedView().getManageButtonBoundsOnScreen(mTempRect);
 
-        // When the menu is open, it should be at these coordinates. This will make the menu's
-        // bottom left corner match up with the button's bottom left corner.
-        final float targetX = mTempRect.left;
+        final boolean isLtr =
+                getResources().getConfiguration().getLayoutDirection() == LAYOUT_DIRECTION_LTR;
+
+        // When the menu is open, it should be at these coordinates. The menu pops out to the right
+        // in LTR and to the left in RTL.
+        final float targetX = isLtr ? mTempRect.left : mTempRect.right - mManageMenu.getWidth();
         final float targetY = mTempRect.bottom - mManageMenu.getHeight();
 
+        final float xOffsetForAnimation = (isLtr ? 1 : -1) * mManageMenu.getWidth() / 4f;
+
         if (show) {
             mManageMenu.setScaleX(0.5f);
             mManageMenu.setScaleY(0.5f);
-            mManageMenu.setTranslationX(targetX - mManageMenu.getWidth() / 4);
-            mManageMenu.setTranslationY(targetY + mManageMenu.getHeight() / 4);
+            mManageMenu.setTranslationX(targetX - xOffsetForAnimation);
+            mManageMenu.setTranslationY(targetY + mManageMenu.getHeight() / 4f);
             mManageMenu.setAlpha(0f);
 
             PhysicsAnimator.getInstance(mManageMenu)
@@ -2121,8 +2145,8 @@
                     .spring(DynamicAnimation.ALPHA, 0f)
                     .spring(DynamicAnimation.SCALE_X, 0.5f)
                     .spring(DynamicAnimation.SCALE_Y, 0.5f)
-                    .spring(DynamicAnimation.TRANSLATION_X, targetX - mManageMenu.getWidth() / 4)
-                    .spring(DynamicAnimation.TRANSLATION_Y, targetY + mManageMenu.getHeight() / 4)
+                    .spring(DynamicAnimation.TRANSLATION_X, targetX - xOffsetForAnimation)
+                    .spring(DynamicAnimation.TRANSLATION_Y, targetY + mManageMenu.getHeight() / 4f)
                     .withEndActions(() -> mManageMenu.setVisibility(View.INVISIBLE))
                     .start();
         }