Wire up bubble dragging to DropTargetManager

This change creates DropTargetManager and DragZoneFactory in launcher
and supports dragging individual bubbles between bubble drag zones.

Flag: com.android.wm.shell.enable_bubble_to_fullscreen
Test: manual:
       - drag bubble across different sides and release
       - drag bubble to dismiss
Bug: 393173014
Change-Id: I58b2522baaf6b088bf8484913ba51c03aadfdd8c
This commit is contained in:
Liran Binyamin
2025-03-04 07:50:11 -08:00
parent aee4b11336
commit 32dd27c8aa
2 changed files with 109 additions and 13 deletions
@@ -326,7 +326,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
new BubbleBarViewController(this, bubbleBarView, bubbleBarContainer),
bubbleStashController,
bubbleHandleController,
new BubbleDragController(this),
new BubbleDragController(this, mDragLayer),
new BubbleDismissController(this, mDragLayer),
new BubbleBarPinController(this, mDragLayer,
() -> DisplayController.INSTANCE.get(this).getInfo().currentSize),
@@ -21,6 +21,8 @@ import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -28,7 +30,16 @@ import androidx.dynamicanimation.animation.FloatPropertyCompat;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.wm.shell.shared.bubbles.BaseBubblePinController.LocationChangeListener;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.bubbles.DeviceConfig;
import com.android.wm.shell.shared.bubbles.DragZone;
import com.android.wm.shell.shared.bubbles.DragZoneFactory;
import com.android.wm.shell.shared.bubbles.DragZoneFactory.DesktopWindowModeChecker;
import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker;
import com.android.wm.shell.shared.bubbles.DraggedObject;
import com.android.wm.shell.shared.bubbles.DropTargetManager;
import com.android.wm.shell.shared.bubbles.DropTargetManager.DragZoneChangedListener;
/**
* Controls bubble bar drag interactions.
@@ -76,11 +87,36 @@ public class BubbleDragController {
private BubbleDismissController mBubbleDismissController;
private BubbleBarPinController mBubbleBarPinController;
private BubblePinController mBubblePinController;
private final DropTargetManager mDropTargetManager;
private final DragZoneFactory mDragZoneFactory;
private final BubbleDragZoneChangedListener mBubbleDragZoneChangedListener;
private boolean mIsDragging;
public BubbleDragController(TaskbarActivityContext activity) {
public BubbleDragController(TaskbarActivityContext activity, FrameLayout dropTargetParent) {
mActivity = activity;
WindowManager windowManager =
mActivity.getApplicationContext().getSystemService(WindowManager.class);
DeviceConfig deviceConfig =
DeviceConfig.create(mActivity.getApplicationContext(), windowManager);
SplitScreenModeChecker splitScreenModeChecker = new SplitScreenModeChecker() {
@NonNull
@Override
public SplitScreenMode getSplitScreenMode() {
return SplitScreenMode.NONE;
}
};
DesktopWindowModeChecker desktopWindowModeChecker = new DesktopWindowModeChecker() {
@Override
public boolean isSupported() {
return false;
}
};
mDragZoneFactory = new DragZoneFactory(mActivity.getApplicationContext(), deviceConfig,
splitScreenModeChecker, desktopWindowModeChecker);
mBubbleDragZoneChangedListener = new BubbleDragZoneChangedListener();
mDropTargetManager = new DropTargetManager(mActivity.getApplicationContext(),
dropTargetParent, mBubbleDragZoneChangedListener);
}
/**
@@ -130,47 +166,77 @@ public class BubbleDragController {
}
};
private BubbleBarLocation getBubbleBarLocationDuringDrag() {
return BubbleAnythingFlagHelper.enableBubbleToFullscreen()
? mBubbleDragZoneChangedListener.mBubbleBarLocation
: mReleasedLocation;
}
@Override
void onDragStart() {
mBubblePinController.setListener(mLocationChangeListener);
mBubbleBarViewController.onBubbleDragStart(bubbleView);
mBubblePinController.onDragStart(
mBubbleBarViewController.getBubbleBarLocation().isOnLeft(
bubbleView.isLayoutRtl()));
if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
DraggedObject.Bubble draggedBubble =
new DraggedObject.Bubble(
mBubbleBarViewController.getBubbleBarLocation());
mDropTargetManager.onDragStarted(draggedBubble,
mDragZoneFactory.createSortedDragZones(draggedBubble));
} else {
mBubblePinController.setListener(mLocationChangeListener);
mBubblePinController.onDragStart(
mBubbleBarViewController.getBubbleBarLocation().isOnLeft(
bubbleView.isLayoutRtl()));
}
}
@Override
protected void onDragUpdate(float x, float y, float newTx, float newTy) {
bubbleView.setDragTranslationX(newTx);
bubbleView.setTranslationY(newTy);
mBubblePinController.onDragUpdate(x, y);
if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
mDropTargetManager.onDragUpdated((int) x, (int) y);
} else {
mBubblePinController.onDragUpdate(x, y);
}
}
@Override
protected void onDragRelease() {
mBubblePinController.onDragEnd();
mBubbleBarViewController.onBubbleDragRelease(mReleasedLocation);
if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
mDropTargetManager.onDragEnded();
} else {
mBubblePinController.onDragEnd();
}
mBubbleBarViewController.onBubbleDragRelease(getBubbleBarLocationDuringDrag());
}
@Override
protected void onDragDismiss() {
mBubblePinController.onDragEnd();
if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
mDropTargetManager.onDragEnded();
} else {
mBubblePinController.onDragEnd();
}
mBubbleBarViewController.onBubbleDismissed(bubbleView);
mBubbleBarViewController.onBubbleDragEnd();
}
@Override
void onDragEnd() {
mBubbleBarController.updateBubbleBarLocation(mReleasedLocation,
mBubbleBarController.updateBubbleBarLocation(getBubbleBarLocationDuringDrag(),
BubbleBarLocation.UpdateSource.DRAG_BUBBLE);
mBubbleBarViewController.onBubbleDragEnd();
mBubblePinController.setListener(null);
if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
mDropTargetManager.onDragEnded();
} else {
mBubblePinController.setListener(null);
}
}
@Override
protected PointF getRestingPosition() {
return mBubbleBarViewController.getDraggedBubbleReleaseTranslation(
getInitialPosition(), mReleasedLocation);
getInitialPosition(), getBubbleBarLocationDuringDrag());
}
});
}
@@ -520,4 +586,34 @@ public class BubbleDragController {
return new PointF(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
}
}
private class BubbleDragZoneChangedListener implements DragZoneChangedListener {
private BubbleBarLocation mBubbleBarLocation = BubbleBarLocation.DEFAULT;
@Override
public void onInitialDragZoneSet(@NonNull DragZone dragZone) {
if (dragZone instanceof DragZone.Bubble.Left) {
mBubbleBarLocation = BubbleBarLocation.LEFT;
} else if (dragZone instanceof DragZone.Bubble.Right) {
mBubbleBarLocation = BubbleBarLocation.RIGHT;
}
}
@Override
public void onDragZoneChanged(@NonNull DragZone from, @NonNull DragZone to) {
if (to instanceof DragZone.Bubble.Left
&& mBubbleBarLocation != BubbleBarLocation.LEFT) {
mBubbleBarController.animateBubbleBarLocation(BubbleBarLocation.LEFT);
mBubbleBarLocation = BubbleBarLocation.LEFT;
} else if (to instanceof DragZone.Bubble.Right
&& mBubbleBarLocation != BubbleBarLocation.RIGHT) {
mBubbleBarController.animateBubbleBarLocation(BubbleBarLocation.RIGHT);
mBubbleBarLocation = BubbleBarLocation.RIGHT;
}
}
@Override
public void onDragEnded(@NonNull DragZone zone) {}
}
}