Update bubble bar location in shell
Send wmshell updates about bubble bar position when it is dragged
across the center divide.
Bug: 330585397
Flag: ACONFIG com.android.wm.shell.enable_bubble_bar DEVELOPMENT
Test: manual
- with bubble bar on home screen
- long press and drag bubble bar around on same side, no drop
target
- release the bubble bar, it snaps back to the original position
- long press and drag bubble bar to other side, see drop target at
the corner
- release bubble bar, it snaps to the new side
- long press and drag bubble bar to other side and back, see the
drop target visible, release, snaps back to the original
position
- repeat above steps from an app, swipe up taskbar for bubble bar
Change-Id: I88faf641b9c07a19cfbb7a1feb8170a64269ac1f
This commit is contained in:
@@ -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.
|
||||
* <p>
|
||||
* 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
|
||||
//
|
||||
|
||||
@@ -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<String> mUpdateSelectedBubbleAfterCollapse;
|
||||
|
||||
private boolean mDragging;
|
||||
|
||||
@Nullable
|
||||
private BubbleView mDraggedBubbleView;
|
||||
|
||||
private int mPreviousLayoutDirection = LayoutDirection.UNDEFINED;
|
||||
|
||||
private boolean mLocationChangePending;
|
||||
|
||||
public BubbleBarView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -163,6 +170,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
|
||||
mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
|
||||
mBubbleElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_elevation);
|
||||
mDragElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_drag_elevation);
|
||||
mPointerSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_pointer_size);
|
||||
|
||||
setClipToPadding(false);
|
||||
@@ -237,12 +245,13 @@ public class BubbleBarView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("RtlHardcoded")
|
||||
private void onBubbleBarLocationChanged() {
|
||||
mLocationChangePending = false;
|
||||
final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
mBubbleBarBackground.setAnchorLeft(onLeft);
|
||||
mRelativePivotX = onLeft ? 0f : 1f;
|
||||
ViewGroup.LayoutParams layoutParams = getLayoutParams();
|
||||
if (layoutParams instanceof LayoutParams lp) {
|
||||
if (getLayoutParams() instanceof LayoutParams lp) {
|
||||
lp.gravity = Gravity.BOTTOM | (onLeft ? Gravity.LEFT : Gravity.RIGHT);
|
||||
setLayoutParams(lp);
|
||||
}
|
||||
@@ -267,11 +276,82 @@ public class BubbleBarView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this view is being currently being dragged
|
||||
*/
|
||||
public void setIsDragging(boolean dragging) {
|
||||
if (mDragging == dragging) {
|
||||
return;
|
||||
}
|
||||
mDragging = dragging;
|
||||
setElevation(dragging ? mDragElevation : mBubbleElevation);
|
||||
if (!dragging && mLocationChangePending) {
|
||||
// During drag finish animation we may update the translation x value to shift the
|
||||
// bubble to the new drop target. Clear the translation here.
|
||||
setTranslationX(0f);
|
||||
onBubbleBarLocationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust resting position for the bubble bar while it is being dragged.
|
||||
* <p>
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user