diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java index 1f3c4839ab..c1c76d0a01 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java @@ -220,7 +220,7 @@ public class BubbleBarController extends IBubblesListener.Stub { mBubbleStashedHandleViewController.setHiddenForBubbles( !sBubbleBarEnabled || mBubbles.isEmpty()); mBubbleBarViewController.setUpdateSelectedBubbleAfterCollapse( - key -> setSelectedBubble(mBubbles.get(key))); + key -> setSelectedBubbleInternal(mBubbles.get(key))); }); } @@ -390,7 +390,7 @@ public class BubbleBarController extends IBubblesListener.Stub { } } if (bubbleToSelect != null) { - setSelectedBubble(bubbleToSelect); + setSelectedBubbleInternal(bubbleToSelect); if (previouslySelectedBubble == null) { mBubbleStashController.animateToInitialState(update.expanded); } @@ -409,8 +409,7 @@ public class BubbleBarController extends IBubblesListener.Stub { if (update.bubbleBarLocation != mBubbleBarViewController.getBubbleBarLocation()) { // Animate when receiving updates. Skip it if we received the initial state. boolean animate = !update.initialState; - mBubbleBarViewController.setBubbleBarLocation(update.bubbleBarLocation, animate); - mBubbleStashController.setBubbleBarLocation(update.bubbleBarLocation); + updateBubbleBarLocationInternal(update.bubbleBarLocation, animate); } } } @@ -436,7 +435,7 @@ public class BubbleBarController extends IBubblesListener.Stub { /** Updates the currently selected bubble for launcher views and tells WMShell to show it. */ public void showAndSelectBubble(BubbleBarItem b) { if (DEBUG) Log.w(TAG, "showingSelectedBubble: " + b.getKey()); - setSelectedBubble(b); + setSelectedBubbleInternal(b); showSelectedBubble(); } @@ -445,7 +444,7 @@ public class BubbleBarController extends IBubblesListener.Stub { * WMShell that the selection has changed, that should go through either * {@link #showSelectedBubble()} or {@link #showAndSelectBubble(BubbleBarItem)}. */ - private void setSelectedBubble(BubbleBarItem b) { + private void setSelectedBubbleInternal(BubbleBarItem b) { if (!Objects.equals(b, mSelectedBubble)) { if (DEBUG) Log.w(TAG, "selectingBubble: " + b.getKey()); mSelectedBubble = b; @@ -464,6 +463,21 @@ public class BubbleBarController extends IBubblesListener.Stub { return null; } + /** + * Set a new bubble bar location. + *
+ * Updates the value locally in Launcher and in WMShell.
+ */
+ public void updateBubbleBarLocation(BubbleBarLocation location) {
+ updateBubbleBarLocationInternal(location, false /* animate */);
+ mSystemUiProxy.setBubbleBarLocation(location);
+ }
+
+ private void updateBubbleBarLocationInternal(BubbleBarLocation location, boolean animate) {
+ mBubbleBarViewController.setBubbleBarLocation(location, animate);
+ mBubbleStashController.setBubbleBarLocation(location);
+ }
+
//
// Loading data for the bubbles
//
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index 4ca7c89127..c27e9f1287 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -24,7 +24,9 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.content.Context;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.LayoutDirection;
@@ -108,6 +110,7 @@ public class BubbleBarView extends FrameLayout {
private final float mIconSize;
// The elevation of the bubbles within the bar
private final float mBubbleElevation;
+ private final float mDragElevation;
private final int mPointerSize;
// Whether the bar is expanded (i.e. the bubble activity is being displayed).
@@ -138,11 +141,15 @@ public class BubbleBarView extends FrameLayout {
@Nullable
private Consumer
+ * Bubble bar is laid out on left or right side of the screen. When it is being dragged to
+ * the opposite side, the resting position should be on that side. Calculate any additional
+ * translation that may be required to move the bubble bar to the new side.
+ *
+ * @param restingPosition relative resting position of the bubble bar from the laid out position
+ */
+ @SuppressLint("RtlHardcoded")
+ void adjustRelativeRestingPosition(PointF restingPosition) {
+ final boolean locationOnLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
+ // Bubble bar is placed left or right with gravity. Check where it is currently.
+ final int absoluteGravity = Gravity.getAbsoluteGravity(
+ ((LayoutParams) getLayoutParams()).gravity, getLayoutDirection());
+ final boolean gravityOnLeft =
+ (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT;
+
+ // Bubble bar is pinned to the same side per gravity and the desired location.
+ // Resting translation does not need to be adjusted.
+ if (locationOnLeft == gravityOnLeft) {
+ return;
+ }
+
+ // Bubble bar is laid out on left or right side of the screen. And the desired new
+ // location is on the other side. Calculate x translation value required to shift the
+ // bubble bar from one side to the other.
+ float x = getDistanceFromOtherSide();
+ if (locationOnLeft) {
+ // New location is on the left, shift left
+ // before -> |......ooo.| after -> |.ooo......|
+ restingPosition.x = -x;
+ } else {
+ // New location is on the right, shift right
+ // before -> |.ooo......| after -> |......ooo.|
+ restingPosition.x = x;
+ }
+ }
+
+ private float getDistanceFromOtherSide() {
+ // Calculate the shift needed to position the bubble bar on the other side
+ int displayWidth = getResources().getDisplayMetrics().widthPixels;
+ int margin = 0;
+ if (getLayoutParams() instanceof MarginLayoutParams lp) {
+ margin += lp.leftMargin;
+ margin += lp.rightMargin;
+ }
+ return (float) (displayWidth - getWidth() - margin);
+ }
+
private void setBubbleBarLocationInternal(BubbleBarLocation bubbleBarLocation) {
if (bubbleBarLocation != mBubbleBarLocation) {
mBubbleBarLocation = bubbleBarLocation;
- onBubbleBarLocationChanged();
- invalidate();
+ if (mDragging) {
+ mLocationChangePending = true;
+ } else {
+ onBubbleBarLocationChanged();
+ invalidate();
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
index dab7d9d07a..5ffc6d830a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
@@ -25,7 +25,6 @@ import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.R;
import com.android.launcher3.taskbar.TaskbarActivityContext;
/**
@@ -55,9 +54,8 @@ public class BubbleDragController {
mBubbleBarViewController = bubbleControllers.bubbleBarViewController;
mBubbleDismissController = bubbleControllers.bubbleDismissController;
mBubbleBarPinController = bubbleControllers.bubbleBarPinController;
- mBubbleBarPinController.setListener(location -> {
- // TODO(b/330585397): update bubble bar location in shell
- });
+ mBubbleBarPinController.setListener(
+ bubbleControllers.bubbleBarController::updateBubbleBarLocation);
mBubbleDismissController.setListener(
stuck -> mBubbleBarPinController.setDropTargetHidden(stuck));
}
@@ -96,11 +94,8 @@ public class BubbleDragController {
@SuppressLint("ClickableViewAccessibility")
public void setupBubbleBarView(@NonNull BubbleBarView bubbleBarView) {
PointF initialRelativePivot = new PointF();
- final int restingElevation = bubbleBarView.getResources().getDimensionPixelSize(
- R.dimen.bubblebar_elevation);
- final int dragElevation = bubbleBarView.getResources().getDimensionPixelSize(
- R.dimen.bubblebar_drag_elevation);
bubbleBarView.setOnTouchListener(new BubbleTouchListener() {
+
@Override
protected boolean onTouchDown(@NonNull View view, @NonNull MotionEvent event) {
if (bubbleBarView.isExpanded()) return false;
@@ -114,7 +109,7 @@ public class BubbleDragController {
// By default the bubble bar view pivot is in bottom right corner, while dragging
// it should be centered in order to align it with the dismiss target view
bubbleBarView.setRelativePivot(/* x = */ 0.5f, /* y = */ 0.5f);
- bubbleBarView.setElevation(dragElevation);
+ bubbleBarView.setIsDragging(true);
mBubbleBarPinController.onDragStart(
bubbleBarView.getBubbleBarLocation().isOnLeft(bubbleBarView.isLayoutRtl()));
}
@@ -138,7 +133,14 @@ public class BubbleDragController {
void onDragEnd() {
// Restoring the initial pivot for the bubble bar view
bubbleBarView.setRelativePivot(initialRelativePivot.x, initialRelativePivot.y);
- bubbleBarView.setElevation(restingElevation);
+ bubbleBarView.setIsDragging(false);
+ }
+
+ @Override
+ protected PointF getRestingPosition() {
+ PointF restingPosition = super.getRestingPosition();
+ bubbleBarView.adjustRelativeRestingPosition(restingPosition);
+ return restingPosition;
}
});
}
@@ -226,6 +228,13 @@ public class BubbleDragController {
protected void onDragDismiss() {
}
+ /**
+ * Get the resting position of the view when drag is released
+ */
+ protected PointF getRestingPosition() {
+ return mViewInitialPosition;
+ }
+
@Override
@SuppressLint("ClickableViewAccessibility")
public boolean onTouch(@NonNull View view, @NonNull MotionEvent event) {
@@ -353,7 +362,7 @@ public class BubbleDragController {
mAnimator.animateDismiss(mViewInitialPosition, onComplete);
} else {
onDragRelease();
- mAnimator.animateToInitialState(mViewInitialPosition, getCurrentVelocity(),
+ mAnimator.animateToInitialState(getRestingPosition(), getCurrentVelocity(),
onComplete);
}
mBubbleDismissController.hideDismissView();
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index b6272dad87..3c3307ac59 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -82,6 +82,7 @@ import com.android.systemui.unfold.progress.IUnfoldTransitionListener;
import com.android.wm.shell.back.IBackAnimation;
import com.android.wm.shell.bubbles.IBubbles;
import com.android.wm.shell.bubbles.IBubblesListener;
+import com.android.wm.shell.common.bubbles.BubbleBarLocation;
import com.android.wm.shell.common.pip.IPip;
import com.android.wm.shell.common.pip.IPipAnimationListener;
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
@@ -808,6 +809,18 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle {
}
}
+ /**
+ * Tells SysUI to update the bubble bar location to the new location.
+ * @param location new location for the bubble bar
+ */
+ public void setBubbleBarLocation(BubbleBarLocation location) {
+ try {
+ mBubbles.setBubbleBarLocation(location);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call setBubbleBarLocation");
+ }
+ }
+
//
// Splitscreen
//