Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 980f985f authored by Mady Mellor's avatar Mady Mellor
Browse files

Hook up drag-to-fullscreen from the bubble bar expanded view

This is behind the fullscreen flag and uses the new drop
target manager to show the drop zones for moving left/right
and to fullscreen.

This is probably not the ideal way to do things, but I wanted
to get this behavior in the build for next week!

Flag: com.android.wm.shell.enable_bubble_to_fullscreen
Test: atest DropTargetManagerTest
Test: manual - drag the bubble expanded view around and
               observe the drop targets
Test: manual - drag the bubble expanded view to the opposite
               side without releasing, drag to fullscreen and
               release, get a new bubble => make sure it's on
               the correct side
Bug: 388857737
Change-Id: Id07e4bbfc79766124f7e162d020181e451baece8
parent a808c906
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import com.android.wm.shell.shared.R
class DropTargetManager(
    private val context: Context,
    private val container: FrameLayout,
    private val isLayoutRtl: Boolean,
    private val dragZoneChangedListener: DragZoneChangedListener,
) {

@@ -41,6 +40,7 @@ class DropTargetManager(
    private val dropTargetView = DropTargetView(context)
    private var animator: ValueAnimator? = null
    private var morphRect: RectF = RectF(0f, 0f, 0f, 0f)
    private val isLayoutRtl = container.isLayoutRtl

    private companion object {
        const val MORPH_ANIM_DURATION = 250L
@@ -80,9 +80,11 @@ class DropTargetManager(

    /** Called when the drag ended. */
    fun onDragEnded() {
        val dropState = state ?: return
        startFadeAnimation(from = dropTargetView.alpha, to = 0f) {
            container.removeView(dropTargetView)
        }
        dragZoneChangedListener.onDragEnded(dropState.currentDragZone)
        state = null
    }

@@ -156,6 +158,9 @@ class DropTargetManager(

        /** Called when the object was dragged to a different drag zone. */
        fun onDragZoneChanged(from: DragZone, to: DragZone)

        /** Called when the drag has ended with the zone it ended in. */
        fun onDragEnded(zone: DragZone)
    }

    private fun Animator.doOnEnd(onEnd: () -> Unit) {
+5 −0
Original line number Diff line number Diff line
@@ -136,6 +136,11 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider {
        updateInternal(mRotation, deviceConfig.getInsets(), deviceConfig.getWindowBounds());
    }

    /** Returns the device config being used. */
    public DeviceConfig getCurrentConfig() {
        return mDeviceConfig;
    }

    @VisibleForTesting
    public void updateInternal(int rotation, Insets insets, Rect bounds) {
        BubbleStackView.RelativeStackPosition prevStackPosition = null;
+31 −3
Original line number Diff line number Diff line
@@ -21,7 +21,11 @@ import android.view.MotionEvent
import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.wm.shell.bubbles.BubblePositioner
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
import com.android.wm.shell.shared.bubbles.DismissView
import com.android.wm.shell.shared.bubbles.DragZoneFactory
import com.android.wm.shell.shared.bubbles.DraggedObject
import com.android.wm.shell.shared.bubbles.DropTargetManager
import com.android.wm.shell.shared.bubbles.RelativeTouchListener
import com.android.wm.shell.shared.magnetictarget.MagnetizedObject

@@ -33,6 +37,8 @@ class BubbleBarExpandedViewDragController(
    private val animationHelper: BubbleBarAnimationHelper,
    private val bubblePositioner: BubblePositioner,
    private val pinController: BubbleExpandedViewPinController,
    private val dropTargetManager: DropTargetManager?,
    private val dragZoneFactory: DragZoneFactory?,
    @get:VisibleForTesting val dragListener: DragListener,
) {

@@ -97,7 +103,21 @@ class BubbleBarExpandedViewDragController(
        override fun onDown(v: View, ev: MotionEvent): Boolean {
            // While animating, don't allow new touch events
            if (expandedView.isAnimating) return false
            if (dropTargetManager != null && dragZoneFactory != null) {
                val draggedObject = DraggedObject.ExpandedView(
                    if (bubblePositioner.isBubbleBarOnLeft) {
                        BubbleBarLocation.LEFT
                    } else {
                        BubbleBarLocation.RIGHT
                    }
                )
                dropTargetManager.onDragStarted(
                    draggedObject,
                    dragZoneFactory.createSortedDragZones(draggedObject)
                )
            } else {
                pinController.onDragStart(bubblePositioner.isBubbleBarOnLeft)
            }
            isDragged = true
            return true
        }
@@ -117,8 +137,12 @@ class BubbleBarExpandedViewDragController(
            expandedView.translationX = expandedViewInitialTranslationX + dx
            expandedView.translationY = expandedViewInitialTranslationY + dy
            dismissView.show()
            if (dropTargetManager != null) {
                dropTargetManager.onDragUpdated(ev.rawX.toInt(), ev.rawY.toInt())
            } else {
                pinController.onDragUpdate(ev.rawX, ev.rawY)
            }
        }

        override fun onUp(
            v: View,
@@ -140,7 +164,11 @@ class BubbleBarExpandedViewDragController(

        private fun finishDrag() {
            if (!isStuckToDismiss) {
                if (dropTargetManager != null) {
                    dropTargetManager.onDragEnded()
                } else {
                    pinController.onDragEnd()
                }
                dragListener.onReleased(inDismiss = false)
                animationHelper.animateToRestPosition()
                dismissView.hide()
+77 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceControl;
import android.view.TouchDelegate;
@@ -48,9 +49,13 @@ import com.android.wm.shell.bubbles.BubbleViewProvider;
import com.android.wm.shell.bubbles.DismissViewUtils;
import com.android.wm.shell.bubbles.bar.BubbleBarExpandedViewDragController.DragListener;
import com.android.wm.shell.shared.bubbles.BaseBubblePinController;
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.DismissView;
import com.android.wm.shell.shared.bubbles.DragZone;
import com.android.wm.shell.shared.bubbles.DragZoneFactory;
import com.android.wm.shell.shared.bubbles.DropTargetManager;

import kotlin.Unit;

@@ -76,6 +81,10 @@ public class BubbleBarLayerView extends FrameLayout
    private final BubbleEducationViewController mEducationViewController;
    private final View mScrimView;
    private final BubbleExpandedViewPinController mBubbleExpandedViewPinController;
    @Nullable
    private DropTargetManager mDropTargetManager = null;
    @Nullable
    private DragZoneFactory mDragZoneFactory = null;

    @Nullable
    private BubbleViewProvider mExpandedBubble;
@@ -123,8 +132,72 @@ public class BubbleBarLayerView extends FrameLayout

        mBubbleExpandedViewPinController = new BubbleExpandedViewPinController(
                context, this, mPositioner);
        mBubbleExpandedViewPinController.setListener(new LocationChangeListener());
        LocationChangeListener locationChangeListener = new LocationChangeListener();
        mBubbleExpandedViewPinController.setListener(locationChangeListener);

        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
            mDropTargetManager = new DropTargetManager(context, this,
                    new DropTargetManager.DragZoneChangedListener() {
                        private DragZone mLastBubbleLocationDragZone = null;
                        private BubbleBarLocation mInitialLocation = null;
                        @Override
                        public void onDragEnded(@NonNull DragZone zone) {
                            if (mExpandedBubble == null || !(mExpandedBubble instanceof Bubble)) {
                                Log.w(TAG, "dropped invalid bubble: " + mExpandedBubble);
                                return;
                            }
                            if (zone instanceof DragZone.FullScreen) {
                                ((Bubble) mExpandedBubble).getTaskView().moveToFullscreen();
                                // Make sure location change listener is updated with the initial
                                // location -- even if we "switched sides" during the drag, since
                                // we've ended up in fullscreen, the location shouldn't change.
                                locationChangeListener.onRelease(mInitialLocation);
                            } else if (zone instanceof DragZone.Bubble.Left) {
                                locationChangeListener.onRelease(BubbleBarLocation.LEFT);
                            } else if (zone instanceof DragZone.Bubble.Right) {
                                locationChangeListener.onRelease(BubbleBarLocation.RIGHT);
                            }
                        }

                        @Override
                        public void onInitialDragZoneSet(@NonNull DragZone dragZone) {
                            mInitialLocation = dragZone instanceof DragZone.Bubble.Left
                                    ? BubbleBarLocation.LEFT
                                    : BubbleBarLocation.RIGHT;
                            locationChangeListener.onStart(mInitialLocation);
                        }

                        @Override
                        public void onDragZoneChanged(@NonNull DragZone from,
                                @NonNull DragZone to) {
                            final boolean isBubbleLeft = to instanceof DragZone.Bubble.Left;
                            final boolean isBubbleRight = to instanceof DragZone.Bubble.Right;
                            if ((isBubbleLeft || isBubbleRight)
                                    && to != mLastBubbleLocationDragZone) {
                                mLastBubbleLocationDragZone = to;
                                locationChangeListener.onChange(isBubbleLeft
                                        ? BubbleBarLocation.LEFT
                                        : BubbleBarLocation.RIGHT);

                            }
                        }
                    });
            // TODO - currently only fullscreen is supported, should enable for split & desktop
            mDragZoneFactory = new DragZoneFactory(context, mPositioner.getCurrentConfig(),
                    new DragZoneFactory.SplitScreenModeChecker() {
                        @NonNull
                        @Override
                        public SplitScreenMode getSplitScreenMode() {
                            return SplitScreenMode.NONE;
                        }
                    },
                    new DragZoneFactory.DesktopWindowModeChecker() {
                        @Override
                        public boolean isSupported() {
                            return false;
                        }
                    });
        }
        setOnClickListener(view -> hideModalOrCollapse());
    }

@@ -272,6 +345,8 @@ public class BubbleBarLayerView extends FrameLayout
                    mAnimationHelper,
                    mPositioner,
                    mBubbleExpandedViewPinController,
                    mDropTargetManager,
                    mDragZoneFactory,
                    dragListener);

            addView(mExpandedView, new LayoutParams(width, height, Gravity.LEFT));
+22 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ class DropTargetManagerTest {
        container = FrameLayout(context)
        dragZoneChangedListener = FakeDragZoneChangedListener()
        dropTargetManager =
            DropTargetManager(context, container, isLayoutRtl = false, dragZoneChangedListener)
            DropTargetManager(context, container, dragZoneChangedListener)
    }

    @Test
@@ -227,6 +227,22 @@ class DropTargetManagerTest {
        assertThat(container.childCount).isEqualTo(0)
    }

    @Test
    fun onDragEnded_dropTargetNotifies() {
        dropTargetManager.onDragStarted(
            DraggedObject.Bubble(BubbleBarLocation.LEFT),
            listOf(bubbleLeftDragZone, bubbleRightDragZone, dismissDragZone)
        )
        InstrumentationRegistry.getInstrumentation().runOnMainSync {
            dropTargetManager.onDragUpdated(
                bubbleRightDragZone.bounds.centerX(),
                bubbleRightDragZone.bounds.centerY()
            )
            dropTargetManager.onDragEnded()
        }
        assertThat(dragZoneChangedListener.endedDragZone).isEqualTo(bubbleRightDragZone)
    }

    @Test
    fun startNewDrag_beforeDropTargetRemoved() {
        dropTargetManager.onDragStarted(
@@ -330,6 +346,7 @@ class DropTargetManagerTest {
        var initialDragZone: DragZone? = null
        var fromDragZone: DragZone? = null
        var toDragZone: DragZone? = null
        var endedDragZone: DragZone? = null

        override fun onInitialDragZoneSet(dragZone: DragZone) {
            initialDragZone = dragZone
@@ -339,5 +356,9 @@ class DropTargetManagerTest {
            fromDragZone = from
            toDragZone = to
        }

        override fun onDragEnded(zone: DragZone) {
            endedDragZone = zone
        }
    }
}