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

Commit 55aee0ff authored by mpodolian's avatar mpodolian
Browse files

Update logic to cover all the drop target cases in Launcher

Made change that will pass raw drag zone enter events to the Launcher
process.

This will enable launcher to:

- Show pin view if there are no bubbles (no bubble bar present)
- Set bubble showing drop target
- Animate bubble bar location if there are bubbles
- Stash / un-stash the bubble bar if there are bubbles

Test: DragToBubblesZoneChangeListenerTest, DragToBubbleControllerTest
Bug: 411505605
Flag: com.android.wm.shell.enable_create_any_bubble
Change-Id: I1959135d36eaa15fa09497921bddddefef53520c
parent 444b7e2f
Loading
Loading
Loading
Loading
+30 −141
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.clearInvocations
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
@@ -92,6 +91,16 @@ class DragToBubbleControllerTest {
        assertThat(dropTargetView.parent).isEqualTo(dropTargetContainer)
    }

    @Test
    fun dragStarted_isDropHandled_cleared() {
        dragToBubbleController.isDropHandled = true

        dragToBubbleController.onDragStarted()

        // Once drag is started again isDropHandled should be cleared
        assertThat(dragToBubbleController.isDropHandled).isFalse()
    }

    @Test
    fun dragStarted_multipleTimes_dropZoneAddedOnlyOnce() {
        repeat(10) { dragToBubbleController.onDragStarted() }
@@ -117,146 +126,6 @@ class DragToBubbleControllerTest {
        assertThat(dropTargetContainer.childCount).isEqualTo(0)
    }

    @Test
    fun draggedToTheRightDropZone_noBubbles_dropTargetViewShown_bubbleBarDropTargetShowRequested() {
        dragToBubbleController.onDragStarted()

        runOnMainSync {
            dragToBubbleController.onDragUpdate(rightDropRect.centerX(), rightDropRect.centerY())
            animatorTestRule.advanceTimeBy(250)
        }

        assertThat(dropTargetView.alpha).isEqualTo(1f)
        verify(bubbleController).showBubbleBarPinAtLocation(BubbleBarLocation.RIGHT)
        verify(bubbleController, never()).animateBubbleBarLocation(any())
    }

    @Test
    fun draggedToTheRightDropZone_bubbleOnTheRight_dropTargetShown_locationUpdatedNotRequested() {
        prepareBubbleController(hasBubbles = true, bubbleBarLocation = BubbleBarLocation.RIGHT)
        dragToBubbleController.onDragStarted()

        runOnMainSync {
            dragToBubbleController.onDragUpdate(rightDropRect.centerX(), rightDropRect.centerY())
            animatorTestRule.advanceTimeBy(250)
        }

        assertThat(dropTargetView.alpha).isEqualTo(1f)
        verify(bubbleController, never()).showBubbleBarPinAtLocation(any())
        verify(bubbleController, never()).showBubbleBarPinAtLocation(any())
    }

    @Test
    fun draggedToTheLeftDropZone_hasBubblesOnTheRight_bubbleBarLocationChangeRequested() {
        prepareBubbleController(hasBubbles = true, bubbleBarLocation = BubbleBarLocation.RIGHT)
        dragToBubbleController.onDragStarted()

        runOnMainSync {
            dragToBubbleController.onDragUpdate(leftDropRect.centerX(), leftDropRect.centerY())
            animatorTestRule.advanceTimeBy(250)
        }
        verify(bubbleController).animateBubbleBarLocation(BubbleBarLocation.LEFT)
    }

    @Test
    fun draggedToTheLeftDropZone_dragEnded_noBubblesOnTheRight_pinViewHideRequested() {
        val bubbleBarOriginalLocation = BubbleBarLocation.RIGHT
        prepareBubbleController(hasBubbles = false, bubbleBarLocation = bubbleBarOriginalLocation)
        dragToBubbleController.onDragStarted()

        runOnMainSync {
            dragToBubbleController.onDragUpdate(leftDropRect.centerX(), leftDropRect.centerY())
            dragToBubbleController.onDragEnded()
        }

        verify(bubbleController).showBubbleBarPinAtLocation(BubbleBarLocation.LEFT)
        verify(bubbleController).showBubbleBarPinAtLocation(null)
        assertThat(dropTargetContainer.childCount).isEqualTo(1)

        runOnMainSync { animatorTestRule.advanceTimeBy(250) }
        assertThat(dropTargetContainer.childCount).isEqualTo(0)
    }

    @Test
    fun draggedToTheLeftDropZone_dragEnded_hasBubblesOnTheRight_locationRestored() {
        val bubbleBarOriginalLocation = BubbleBarLocation.RIGHT
        prepareBubbleController(hasBubbles = true, bubbleBarLocation = bubbleBarOriginalLocation)
        dragToBubbleController.onDragStarted()

        runOnMainSync {
            dragToBubbleController.onDragUpdate(leftDropRect.centerX(), leftDropRect.centerY())
            dragToBubbleController.onDragEnded()
        }

        verify(bubbleController).animateBubbleBarLocation(BubbleBarLocation.LEFT)
        verify(bubbleController).animateBubbleBarLocation(bubbleBarOriginalLocation)
        assertThat(dropTargetContainer.childCount).isEqualTo(1)

        runOnMainSync { animatorTestRule.advanceTimeBy(250) }
        assertThat(dropTargetContainer.childCount).isEqualTo(0)
    }

    @Test
    fun dragBetweenLeftAndRightDropZones_hasBubblesOnRight_bubbleBarAnimatesCorrectly() {
        val bubbleBarOriginalLocation = BubbleBarLocation.RIGHT
        prepareBubbleController(hasBubbles = true, bubbleBarLocation = bubbleBarOriginalLocation)
        dragToBubbleController.onDragStarted()

        runOnMainSync {
            dragToBubbleController.onDragUpdate(leftDropRect.centerX(), leftDropRect.centerY())
            animatorTestRule.advanceTimeBy(250)
        }
        verify(bubbleController).animateBubbleBarLocation(BubbleBarLocation.LEFT)

        runOnMainSync {
            // drag to no zone
            dragToBubbleController.onDragUpdate(0, 0)
            animatorTestRule.advanceTimeBy(250)
        }
        // should return to original position
        verify(bubbleController).animateBubbleBarLocation(bubbleBarOriginalLocation)
        clearInvocations(bubbleController)

        runOnMainSync {
            // drag to the same zone as bubble bar
            dragToBubbleController.onDragUpdate(rightDropRect.centerX(), rightDropRect.centerY())
            animatorTestRule.advanceTimeBy(250)
        }
        // should not trigger any call to animate bubble bar
        verify(bubbleController, never()).animateBubbleBarLocation(any())
    }

    @Test
    fun dragBetweenLeftAndRightDropZones_noBubblesOnRight_bubbleDropTargetShowRequestedCorrectly() {
        val bubbleBarOriginalLocation = BubbleBarLocation.RIGHT
        prepareBubbleController(hasBubbles = false, bubbleBarLocation = bubbleBarOriginalLocation)
        dragToBubbleController.onDragStarted()

        runOnMainSync {
            dragToBubbleController.onDragUpdate(leftDropRect.centerX(), leftDropRect.centerY())
            animatorTestRule.advanceTimeBy(250)
        }
        // should request displaying pin on left
        verify(bubbleController).showBubbleBarPinAtLocation(BubbleBarLocation.LEFT)

        runOnMainSync {
            // drag to no zone
            dragToBubbleController.onDragUpdate(0, 0)
            animatorTestRule.advanceTimeBy(250)
        }
        // should hide pin view
        verify(bubbleController).showBubbleBarPinAtLocation(null)
        clearInvocations(bubbleController)

        runOnMainSync {
            // drag to the same zone as bubble bar
            dragToBubbleController.onDragUpdate(rightDropRect.centerX(), rightDropRect.centerY())
            animatorTestRule.advanceTimeBy(250)
        }
        // should request displaying pin at right
        verify(bubbleController).showBubbleBarPinAtLocation(BubbleBarLocation.RIGHT)
    }

    @Test
    fun droppedItemWithIntentAtTheLeftDropZone_noBubblesOnTheRight_bubbleCreationRequested() {
        val bubbleBarOriginalLocation = BubbleBarLocation.RIGHT
@@ -273,6 +142,7 @@ class DragToBubbleControllerTest {

        verify(bubbleController)
            .expandStackAndSelectBubble(pendingIntent, userHandle, BubbleBarLocation.LEFT)
        assertThat(dragToBubbleController.isDropHandled).isTrue()
    }

    @Test
@@ -289,6 +159,25 @@ class DragToBubbleControllerTest {
        }

        verify(bubbleController).expandStackAndSelectBubble(shortcutInfo, BubbleBarLocation.LEFT)
        assertThat(dragToBubbleController.isDropHandled).isTrue()
    }

    @Test
    fun droppedItem_afterNewDragStartedOnItemDropCleared() {
        val bubbleBarOriginalLocation = BubbleBarLocation.RIGHT
        prepareBubbleController(hasBubbles = false, bubbleBarLocation = bubbleBarOriginalLocation)
        val shortcutInfo = ShortcutInfo.Builder(context, "id").setLongLabel("Shortcut").build()
        runOnMainSync {
            dragToBubbleController.onDragStarted()
            dragToBubbleController.onDragUpdate(leftDropRect.centerX(), leftDropRect.centerY())
            dragToBubbleController.onItemDropped(shortcutInfo)
            assertThat(dragToBubbleController.isDropHandled).isTrue()
            dragToBubbleController.onDragEnded()
            animatorTestRule.advanceTimeBy(250)

            dragToBubbleController.onDragStarted()
        }
        assertThat(dragToBubbleController.isDropHandled).isFalse()
    }

    @Test
+3 −2
Original line number Diff line number Diff line
@@ -114,8 +114,9 @@ class DragToBubblesZoneChangeListener(
        fun hasBubbles(): Boolean

        /** Called when need to animate the bubble bar location. */
        fun animateBubbleBarLocation(bubbleBarLocation: BubbleBarLocation)
        fun animateBubbleBarLocation(bubbleBarLocation: BubbleBarLocation) {}

        // TODO(b/411505605) remove all related code
        /** Called when the bubble bar pillow view is shown at position. */
        fun bubbleBarPillowShownAtLocation(bubbleBarLocation: BubbleBarLocation?) {}

@@ -125,7 +126,7 @@ class DragToBubblesZoneChangeListener(
         * @param bubbleBarLocation The [BubbleBarLocation] that the drag operation has entered.
         *                          This will be non-null if the drag has entered a valid bubble bar
         *                          location. It will be `null` if the drag operation has exited
         *                          all bubble bar locations.
         *                          all bubble bar locations. Values are guaranteed to be distinct.
         */
        fun onDragEnteredLocation(bubbleBarLocation: BubbleBarLocation?) {}
    }
+8 −2
Original line number Diff line number Diff line
@@ -147,6 +147,8 @@ import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;

import dagger.Lazy;

import kotlin.Unit;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
@@ -161,8 +163,6 @@ import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.IntConsumer;

import kotlin.Unit;

/**
 * Bubbles are a special type of content that can "float" on top of other apps or System UI.
 * Bubbles can be expanded to show more content.
@@ -973,6 +973,7 @@ public class BubbleController implements ConfigurationChangeListener,
        }
    }

    // TODO(b/411505605) remove all related code
    /**
     * Show bubble bar pin view given location.
     */
@@ -982,6 +983,11 @@ public class BubbleController implements ConfigurationChangeListener,
        }
    }

    /** Show bubble bar drop target at provided location or hide it if null. */
    public void showBubbleBarDropTargetAt(@Nullable BubbleBarLocation bubbleBarLocation) {
        // TODO(b/411505605): Implement logic to show/hide drop target on bubble bar.
    }

    private void showBubbleBarExpandedViewDropTarget(BubbleBarLocation bubbleBarLocation) {
        ensureBubbleViewsAndWindowCreated();
        if (mLayerView != null) {
+9 −6
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ class DragToBubbleController(

    @VisibleForTesting
    val dragZoneFactory = createDragZoneFactory()
    @VisibleForTesting
    var isDropHandled = false
    private var lastDragZone: DragZone? = null

    /** Returns the container view in which drop targets are added. */
@@ -73,6 +75,7 @@ class DragToBubbleController(
        if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
            return
        }
        isDropHandled = false
        val draggedObject = LauncherIcon(bubbleBarHasBubbles = true) {}
        val dragZones = dragZoneFactory.createSortedDragZones(draggedObject)
        dropTargetManager.onDragStarted(draggedObject, dragZones)
@@ -91,6 +94,7 @@ class DragToBubbleController(
    /** Called when the item with the [ShortcutInfo] is dropped over the bubble bar drop target. */
    fun onItemDropped(shortcutInfo: ShortcutInfo) {
        val dropLocation = lastDragZone?.getBubbleBarLocation() ?: return
        isDropHandled = true
        bubbleController.expandStackAndSelectBubble(shortcutInfo, dropLocation)
    }

@@ -100,6 +104,7 @@ class DragToBubbleController(
     */
    fun onItemDropped(pendingIntent: PendingIntent, userHandle: UserHandle) {
        val dropLocation = lastDragZone?.getBubbleBarLocation() ?: return
        isDropHandled = true
        bubbleController.expandStackAndSelectBubble(pendingIntent, userHandle, dropLocation)
    }

@@ -135,12 +140,10 @@ class DragToBubbleController(

            override fun hasBubbles(): Boolean = bubbleController.hasBubbles()

            override fun animateBubbleBarLocation(bubbleBarLocation: BubbleBarLocation) {
                bubbleController.animateBubbleBarLocation(bubbleBarLocation)
            }

            override fun bubbleBarPillowShownAtLocation(bubbleBarLocation: BubbleBarLocation?) {
                bubbleController.showBubbleBarPinAtLocation(bubbleBarLocation)
            override fun onDragEnteredLocation(bubbleBarLocation: BubbleBarLocation?) {
                // if drop was handled, do not need to send signal to launcher
                if (isDropHandled) return
                bubbleController.showBubbleBarDropTargetAt(bubbleBarLocation)
            }
        })
}
+271 −273

File changed.

Preview size limit exceeded, changes collapsed.