diff --git a/quickstep/res/layout/transient_taskbar.xml b/quickstep/res/layout/transient_taskbar.xml index 6af7cf466c..d212ffdbbe 100644 --- a/quickstep/res/layout/transient_taskbar.xml +++ b/quickstep/res/layout/transient_taskbar.xml @@ -43,7 +43,7 @@ android:layout_width="wrap_content" android:layout_height="@dimen/bubblebar_size" android:layout_gravity="bottom|end" - android:layout_marginEnd="@dimen/transient_taskbar_bottom_margin" + android:layout_marginHorizontal="@dimen/transient_taskbar_bottom_margin" android:paddingEnd="@dimen/taskbar_icon_spacing" android:paddingStart="@dimen/taskbar_icon_spacing" android:visibility="gone" diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java index 6dc7db766e..2b69e96baf 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java @@ -73,6 +73,7 @@ import com.android.launcher3.util.Executors.SimpleThreadFactory; import com.android.quickstep.SystemUiProxy; import com.android.wm.shell.Flags; import com.android.wm.shell.bubbles.IBubblesListener; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; import com.android.wm.shell.common.bubbles.BubbleBarUpdate; import com.android.wm.shell.common.bubbles.BubbleInfo; import com.android.wm.shell.common.bubbles.RemovedBubble; @@ -161,6 +162,7 @@ public class BubbleBarController extends IBubblesListener.Stub { String selectedBubbleKey; String suppressedBubbleKey; String unsuppressedBubbleKey; + BubbleBarLocation bubbleBarLocation; List removedBubbles; List bubbleKeysInOrder; @@ -176,6 +178,7 @@ public class BubbleBarController extends IBubblesListener.Stub { selectedBubbleKey = update.selectedBubbleKey; suppressedBubbleKey = update.suppressedBubbleKey; unsuppressedBubbleKey = update.unsupressedBubbleKey; + bubbleBarLocation = update.bubbleBarLocation; removedBubbles = update.removedBubbles; bubbleKeysInOrder = update.bubbleKeysInOrder; } @@ -400,6 +403,12 @@ public class BubbleBarController extends IBubblesListener.Stub { Log.w(TAG, "expansion was changed but is the same"); } } + if (update.bubbleBarLocation != null) { + if (update.bubbleBarLocation != mBubbleBarViewController.getBubbleBarLocation()) { + mBubbleBarViewController.setBubbleBarLocation(update.bubbleBarLocation); + mBubbleStashController.setBubbleBarLocation(update.bubbleBarLocation); + } + } } /** Tells WMShell to show the currently selected bubble. */ @@ -593,7 +602,7 @@ public class BubbleBarController extends IBubblesListener.Stub { Rect location = new Rect(); // currentBarBounds is only useful for distance from left or right edge. // It contains the current bounds, calculate the expanded bounds. - if (mBarView.isOnLeft()) { + if (mBarView.getBubbleBarLocation().isOnLeft(mBarView.isLayoutRtl())) { location.left = currentBarBounds.left; location.right = (int) (currentBarBounds.left + mBarView.expandedWidth()); } else { diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java index 8f693a6d53..61ae965e16 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -21,7 +21,9 @@ import android.annotation.Nullable; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; +import android.util.LayoutDirection; import android.util.Log; +import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -30,6 +32,7 @@ import android.widget.FrameLayout; import com.android.launcher3.R; import com.android.launcher3.taskbar.TaskbarActivityContext; import com.android.launcher3.views.ActivityContext; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; import java.util.List; import java.util.function.Consumer; @@ -91,6 +94,7 @@ public class BubbleBarView extends FrameLayout { private boolean mIsBarExpanded = false; // The currently selected bubble view. private BubbleView mSelectedBubbleView; + private BubbleBarLocation mBubbleBarLocation = BubbleBarLocation.DEFAULT; // The click listener when the bubble bar is collapsed. private View.OnClickListener mOnClickListener; @@ -114,6 +118,8 @@ public class BubbleBarView extends FrameLayout { @Nullable private BubbleView mDraggedBubbleView; + private int mPreviousLayoutDirection = LayoutDirection.UNDEFINED; + public BubbleBarView(Context context) { this(context, null); } @@ -199,17 +205,42 @@ public class BubbleBarView extends FrameLayout { @Override public void onRtlPropertiesChanged(int layoutDirection) { - // TODO(b/313661121): set this based on bubble bar position and not LTR or RTL - boolean onLeft = layoutDirection == LAYOUT_DIRECTION_RTL; + if (mBubbleBarLocation == BubbleBarLocation.DEFAULT + && mPreviousLayoutDirection != layoutDirection) { + Log.d(TAG, "BubbleBar RTL properties changed, new layoutDirection=" + layoutDirection + + " previous layoutDirection=" + mPreviousLayoutDirection); + mPreviousLayoutDirection = layoutDirection; + onBubbleBarLocationChanged(); + } + } + + private void onBubbleBarLocationChanged() { + final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl()); mBubbleBarBackground.setAnchorLeft(onLeft); mRelativePivotX = onLeft ? 0f : 1f; + ViewGroup.LayoutParams layoutParams = getLayoutParams(); + if (layoutParams instanceof LayoutParams lp) { + lp.gravity = Gravity.BOTTOM | (onLeft ? Gravity.LEFT : Gravity.RIGHT); + setLayoutParams(lp); + } + invalidate(); } /** - * @return true when bar is pinned to the left edge of the screen + * @return current {@link BubbleBarLocation} */ - public boolean isOnLeft() { - return getLayoutDirection() == LAYOUT_DIRECTION_RTL; + public BubbleBarLocation getBubbleBarLocation() { + return mBubbleBarLocation; + } + + /** + * Update {@link BubbleBarLocation} + */ + public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) { + if (bubbleBarLocation != mBubbleBarLocation) { + mBubbleBarLocation = bubbleBarLocation; + onBubbleBarLocationChanged(); + } } /** @@ -290,7 +321,7 @@ public class BubbleBarView extends FrameLayout { int bubbleCount = getChildCount(); final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f; final boolean animate = getVisibility() == VISIBLE; - final boolean onLeft = isOnLeft(); + final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl()); for (int i = 0; i < bubbleCount; i++) { BubbleView bv = (BubbleView) getChildAt(i); bv.setTranslationY(ty); @@ -453,7 +484,7 @@ public class BubbleBarView extends FrameLayout { private float arrowPositionForSelectedWhenExpanded() { final int index = indexOfChild(mSelectedBubbleView); final int bubblePosition; - if (isOnLeft()) { + if (mBubbleBarLocation.isOnLeft(isLayoutRtl())) { // Bubble positions are reversed. First bubble is on the right. bubblePosition = getChildCount() - index - 1; } else { @@ -465,7 +496,7 @@ public class BubbleBarView extends FrameLayout { private float arrowPositionForSelectedWhenCollapsed() { final int index = indexOfChild(mSelectedBubbleView); final int bubblePosition; - if (isOnLeft()) { + if (mBubbleBarLocation.isOnLeft(isLayoutRtl())) { // Bubble positions are reversed. First bubble may be shifted, if there are more // bubbles than the current bubble and overflow. bubblePosition = index == 0 && getChildCount() > 2 ? 1 : 0; diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java index 6bb7b04c98..36e208e401 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java @@ -37,6 +37,7 @@ import com.android.launcher3.taskbar.TaskbarStashController; import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.SystemUiProxy; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; import java.util.List; import java.util.Objects; @@ -168,6 +169,20 @@ public class BubbleBarViewController { return mBubbleBarController.getSelectedBubbleKey() != null; } + /** + * @return current {@link BubbleBarLocation} + */ + public BubbleBarLocation getBubbleBarLocation() { + return mBarView.getBubbleBarLocation(); + } + + /** + * Update bar {@link BubbleBarLocation} + */ + public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) { + mBarView.setBubbleBarLocation(bubbleBarLocation); + } + /** * The bounds of the bubble bar. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java index 09021edb91..e25e58653a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java @@ -31,6 +31,7 @@ import com.android.launcher3.taskbar.TaskbarControllers; import com.android.launcher3.taskbar.TaskbarInsetsController; import com.android.launcher3.taskbar.TaskbarStashController; import com.android.launcher3.util.MultiPropertyFactory; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; /** * Coordinates between controllers such as BubbleBarView and BubbleHandleViewController to @@ -356,4 +357,9 @@ public class BubbleStashController { public boolean isEventOverStashHandle(MotionEvent ev) { return mHandleViewController.isEventOverHandle(ev); } + + /** Set a bubble bar location */ + public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) { + mHandleViewController.setBubbleBarLocation(bubbleBarLocation); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java index f88460ff13..f64517af21 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java @@ -16,7 +16,6 @@ package com.android.launcher3.taskbar.bubbles; import static android.view.View.INVISIBLE; -import static android.view.View.LAYOUT_DIRECTION_RTL; import static android.view.View.VISIBLE; import android.animation.Animator; @@ -39,6 +38,7 @@ import com.android.launcher3.util.Executors; import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiValueAlpha; import com.android.systemui.shared.navigationbar.RegionSamplingHelper; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; /** * Handles properties/data collection, then passes the results to our stashed handle View to render. @@ -119,14 +119,14 @@ public class BubbleStashedHandleViewController { }, Executors.UI_HELPER_EXECUTOR); mStashedHandleView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) -> - updateBounds()); + updateBounds(mBarViewController.getBubbleBarLocation())); } - private void updateBounds() { + private void updateBounds(BubbleBarLocation bubbleBarLocation) { // As more bubbles get added, the icon bounds become larger. To ensure a consistent // handle bar position, we pin it to the edge of the screen. final int stashedCenterY = mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2; - if (isOnLeft()) { + if (bubbleBarLocation.isOnLeft(mStashedHandleView.isLayoutRtl())) { final int left = mBarViewController.getHorizontalMargin(); mStashedHandleBounds.set( left, @@ -149,11 +149,6 @@ public class BubbleStashedHandleViewController { mStashedHandleView.setPivotY(mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2f); } - private boolean isOnLeft() { - // TODO(b/313661121): set this based on bubble bar position and not LTR or RTL - return mStashedHandleView.getLayoutDirection() == LAYOUT_DIRECTION_RTL; - } - public void onDestroy() { mRegionSamplingHelper.stopAndDestroy(); mRegionSamplingHelper = null; @@ -301,4 +296,9 @@ public class BubbleStashedHandleViewController { public boolean containsX(int x) { return x >= mStashedHandleBounds.left && x <= mStashedHandleBounds.right; } + + /** Set a bubble bar location */ + public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) { + updateBounds(bubbleBarLocation); + } }