mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 03:08:19 +00:00
Merge "Notify taskbar and nav bar of bubble bar location updates." into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
bd997ba791
@@ -565,6 +565,7 @@ public class BubbleBarViewController {
|
||||
mBarView.showDropTarget(showingDropTarget);
|
||||
}
|
||||
|
||||
//TODO(b/411505605) remove unused IPC calls and code
|
||||
/**
|
||||
* Notifies the controller that a drag event is over the Bubble Bar drop zone. The controller
|
||||
* will display the appropriate drop target and enter drop target mode. The controller will also
|
||||
|
||||
@@ -140,6 +140,7 @@ public class BubbleControllers {
|
||||
return -(int) bubbleStashController.getBubbleBarTranslationY();
|
||||
}
|
||||
},
|
||||
bubbleBarLocationListeners,
|
||||
SystemUiProxy.INSTANCE.get(taskbarControllers.taskbarActivityContext));
|
||||
mPostInitRunnables.executeAllAndDestroy();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.android.launcher3.dragndrop.DragController
|
||||
import com.android.launcher3.dragndrop.DragOptions
|
||||
import com.android.launcher3.model.data.ItemInfo
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo
|
||||
import com.android.launcher3.taskbar.bubbles.BubbleBarController.BubbleBarLocationListener
|
||||
import com.android.launcher3.taskbar.bubbles.BubbleBarLocationDropTarget.BubbleBarDropTargetController
|
||||
import com.android.quickstep.SystemUiProxy
|
||||
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
|
||||
@@ -47,10 +48,12 @@ class DragToBubbleController(private val context: Context, bubbleBarContainer: F
|
||||
DragController.DragListener {
|
||||
|
||||
@VisibleForTesting val dropTargetManager: DropTargetManager
|
||||
|
||||
@VisibleForTesting lateinit var bubbleBarLeftDropTarget: BubbleBarLocationDropTarget
|
||||
@VisibleForTesting lateinit var bubbleBarRightDropTarget: BubbleBarLocationDropTarget
|
||||
@VisibleForTesting lateinit var dragZoneFactory: DragZoneFactory
|
||||
// If item drop is handled the next sysui update will set the bubble bar location
|
||||
@VisibleForTesting var isItemDropHandled = false
|
||||
private lateinit var bubbleBarLocationListener: BubbleBarLocationListener
|
||||
private lateinit var systemUiProxy: SystemUiProxy
|
||||
private lateinit var bubbleBarViewController: BubbleBarViewController
|
||||
|
||||
@@ -61,10 +64,12 @@ class DragToBubbleController(private val context: Context, bubbleBarContainer: F
|
||||
fun init(
|
||||
bubbleBarViewController: BubbleBarViewController,
|
||||
bubbleBarPropertiesProvider: BubbleBarPropertiesProvider,
|
||||
bubbleBarLocationListener: BubbleBarLocationListener,
|
||||
systemUiProxy: SystemUiProxy,
|
||||
) {
|
||||
this.bubbleBarViewController = bubbleBarViewController
|
||||
this.systemUiProxy = systemUiProxy
|
||||
this.bubbleBarLocationListener = bubbleBarLocationListener
|
||||
val dropController: BubbleBarDropTargetController = createDropController()
|
||||
dragZoneFactory = createDragZoneFactory(bubbleBarPropertiesProvider)
|
||||
bubbleBarLeftDropTarget = createDropTarget(dropController, isLeftDropTarget = true)
|
||||
@@ -95,6 +100,7 @@ class DragToBubbleController(private val context: Context, bubbleBarContainer: F
|
||||
}
|
||||
|
||||
override fun onDragStart(dragObject: DragObject, options: DragOptions) {
|
||||
isItemDropHandled = false
|
||||
val launcherIcon: DraggedObject = LauncherIcon(bubbleBarViewController.hasBubbles()) {}
|
||||
val dragZones: List<DragZone> = dragZoneFactory.createSortedDragZones(launcherIcon)
|
||||
dropTargetManager.onDragStarted(launcherIcon, dragZones)
|
||||
@@ -110,8 +116,17 @@ class DragToBubbleController(private val context: Context, bubbleBarContainer: F
|
||||
context.isRtl,
|
||||
object : DragToBubblesZoneChangeListener.Callback {
|
||||
|
||||
private var currentBarLocation: BubbleBarLocation? = null
|
||||
|
||||
override fun onDragEnteredLocation(bubbleBarLocation: BubbleBarLocation?) {
|
||||
bubbleBarViewController.isShowingDropTarget = bubbleBarLocation != null
|
||||
if (isItemDropHandled) return
|
||||
val updatedLocation = bubbleBarLocation ?: getStartingBubbleBarLocation()
|
||||
currentBarLocation = currentBarLocation ?: getStartingBubbleBarLocation()
|
||||
if (updatedLocation != currentBarLocation) {
|
||||
currentBarLocation = updatedLocation
|
||||
bubbleBarLocationListener.onBubbleBarLocationAnimated(updatedLocation)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getStartingBubbleBarLocation(): BubbleBarLocation {
|
||||
@@ -122,14 +137,9 @@ class DragToBubbleController(private val context: Context, bubbleBarContainer: F
|
||||
override fun hasBubbles(): Boolean = bubbleBarViewController.hasBubbles()
|
||||
|
||||
override fun animateBubbleBarLocation(bubbleBarLocation: BubbleBarLocation) {
|
||||
if (isItemDropHandled) return
|
||||
bubbleBarViewController.animateBubbleBarLocation(bubbleBarLocation)
|
||||
}
|
||||
|
||||
override fun bubbleBarPillowShownAtLocation(
|
||||
bubbleBarLocation: BubbleBarLocation?
|
||||
) {
|
||||
// TODO(b/411506181) adjust taskbar
|
||||
}
|
||||
},
|
||||
)
|
||||
return DropTargetManager(context, bubbleBarContainer, listener)
|
||||
@@ -154,6 +164,18 @@ class DragToBubbleController(private val context: Context, bubbleBarContainer: F
|
||||
private fun createDropController(): BubbleBarDropTargetController {
|
||||
return object : BubbleBarDropTargetController {
|
||||
override fun onDrop(itemInfo: ItemInfo, isLeftDropTarget: Boolean) {
|
||||
isItemDropHandled = handleDrop(itemInfo, isLeftDropTarget)
|
||||
}
|
||||
|
||||
override fun acceptDrop(itemInfo: ItemInfo): Boolean {
|
||||
return hasShortcutInfo(itemInfo) || itemInfo.intent?.component != null
|
||||
}
|
||||
|
||||
fun hasShortcutInfo(itemInfo: ItemInfo): Boolean {
|
||||
return itemInfo is WorkspaceItemInfo && itemInfo.deepShortcutInfo != null
|
||||
}
|
||||
|
||||
private fun handleDrop(itemInfo: ItemInfo, isLeftDropTarget: Boolean): Boolean {
|
||||
val location =
|
||||
if (isLeftDropTarget) {
|
||||
BubbleBarLocation.LEFT
|
||||
@@ -163,20 +185,13 @@ class DragToBubbleController(private val context: Context, bubbleBarContainer: F
|
||||
if (hasShortcutInfo(itemInfo)) {
|
||||
val si = (itemInfo as WorkspaceItemInfo).deepShortcutInfo
|
||||
systemUiProxy.showShortcutBubble(si, location)
|
||||
return
|
||||
return true
|
||||
}
|
||||
val itemIntent: Intent = itemInfo.intent ?: return
|
||||
val packageName = itemIntent.component?.packageName ?: return
|
||||
val itemIntent: Intent = itemInfo.intent ?: return false
|
||||
val packageName = itemIntent.component?.packageName ?: return false
|
||||
itemIntent.setPackage(packageName)
|
||||
systemUiProxy.showAppBubble(itemIntent, itemInfo.user, location)
|
||||
}
|
||||
|
||||
override fun acceptDrop(itemInfo: ItemInfo): Boolean {
|
||||
return hasShortcutInfo(itemInfo) || itemInfo.intent?.component != null
|
||||
}
|
||||
|
||||
fun hasShortcutInfo(itemInfo: ItemInfo): Boolean {
|
||||
return itemInfo is WorkspaceItemInfo && itemInfo.deepShortcutInfo != null
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.launcher3.DropTarget
|
||||
import com.android.launcher3.DropTarget.DragObject
|
||||
import com.android.launcher3.dragndrop.DragOptions
|
||||
import com.android.launcher3.model.data.AppInfo
|
||||
import com.android.launcher3.taskbar.bubbles.BubbleBarController.BubbleBarLocationListener
|
||||
import com.android.quickstep.SystemUiProxy
|
||||
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
|
||||
import com.android.wm.shell.shared.bubbles.DeviceConfig
|
||||
@@ -44,7 +45,9 @@ 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.inOrder
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.never
|
||||
import org.mockito.kotlin.stub
|
||||
@@ -61,6 +64,7 @@ class DragToBubbleControllerTest {
|
||||
private val container = FrameLayout(context)
|
||||
private val bubbleBarViewController: BubbleBarViewController = mock()
|
||||
private val systemUiProxy: SystemUiProxy = mock()
|
||||
private val bubbleBarLocationListener: BubbleBarLocationListener = mock()
|
||||
private val bubbleBarPropertiesProvider = FakeBubbleBarPropertiesProvider()
|
||||
private val testDragZonesFactory = createTestDragZoneFactory()
|
||||
private val dragObject = DragObject(context)
|
||||
@@ -86,10 +90,12 @@ class DragToBubbleControllerTest {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
prepareBubbleBarViewController()
|
||||
dragToBubbleController = DragToBubbleController(context, container)
|
||||
dragToBubbleController.init(
|
||||
bubbleBarViewController,
|
||||
bubbleBarPropertiesProvider,
|
||||
bubbleBarLocationListener,
|
||||
systemUiProxy,
|
||||
)
|
||||
dragToBubbleController.dragZoneFactory = testDragZonesFactory
|
||||
@@ -104,6 +110,7 @@ class DragToBubbleControllerTest {
|
||||
assertThat(secondDropTargetView!!.parent).isEqualTo(container)
|
||||
assertThat(dropTargetView.alpha).isEqualTo(0f)
|
||||
assertThat(secondDropTargetView!!.alpha).isEqualTo(0f)
|
||||
assertThat(dragToBubbleController.isItemDropHandled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -235,13 +242,168 @@ class DragToBubbleControllerTest {
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXYToCenterOf(leftDropTargetRect)
|
||||
bubbleBarLeftDropTarget.onDragEnter(dragObject)
|
||||
bubbleBarLeftDropTarget.onDragExit(dragObject)
|
||||
bubbleBarLeftDropTarget.onDrop(dragObject, DragOptions())
|
||||
assertThat(dragToBubbleController.isItemDropHandled).isTrue()
|
||||
bubbleBarLeftDropTarget.onDragExit(dragObject)
|
||||
}
|
||||
|
||||
verify(systemUiProxy).showAppBubble(itemIntent, appInfo.user, BubbleBarLocation.LEFT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragExitRightZone_noBubbles_listenerNotNotified() {
|
||||
// Scenario: No bubbles. Drag enters RIGHT, then exits to no particular zone.
|
||||
// This is distinct as it starts on the default side.
|
||||
prepareBubbleBarViewController(
|
||||
hasBubbles = false,
|
||||
bubbleBarLocation = BubbleBarLocation.RIGHT,
|
||||
)
|
||||
dragToBubbleController.onDragStart(dragObject, DragOptions())
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXYToCenterOf(rightDropTargetRect)
|
||||
bubbleBarRightDropTarget.onDragEnter(dragObject) // Location is the same
|
||||
}
|
||||
verify(bubbleBarLocationListener, never())
|
||||
.onBubbleBarLocationAnimated(BubbleBarLocation.RIGHT)
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXY(0, 0) // Move out of all zones
|
||||
bubbleBarRightDropTarget.onDragExit(dragObject)
|
||||
}
|
||||
|
||||
// Exiting the RIGHT zone (which is the default) should not re-notify of RIGHT
|
||||
verify(bubbleBarLocationListener, never())
|
||||
.onBubbleBarLocationAnimated(BubbleBarLocation.RIGHT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onDragEnd_noBubbles_wasDraggingLeft_listenerNotifiedWithDefaultRightLocationAnimated() {
|
||||
val startingLocation = BubbleBarLocation.RIGHT
|
||||
// Scenario: No bubbles. Drag was over LEFT zone. Drag ends.
|
||||
prepareBubbleBarViewController(hasBubbles = false, bubbleBarLocation = startingLocation)
|
||||
dragToBubbleController.onDragStart(dragObject, DragOptions())
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXYToCenterOf(leftDropTargetRect)
|
||||
bubbleBarLeftDropTarget.onDragEnter(dragObject)
|
||||
}
|
||||
// Notifies onBubbleBarLocationAnimated(LEFT)
|
||||
verify(bubbleBarLocationListener).onBubbleBarLocationAnimated(BubbleBarLocation.LEFT)
|
||||
clearInvocations(bubbleBarLocationListener)
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragToBubbleController.onDragEnd()
|
||||
}
|
||||
assertThat(dragToBubbleController.isItemDropHandled).isFalse()
|
||||
|
||||
// After drag ends (and no bubbles), the listener should be notified of the default location
|
||||
verify(bubbleBarLocationListener).onBubbleBarLocationAnimated(startingLocation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onDragEnd_noBubbles_wasDraggingRight_listenerNotifiedWithDefaultRightLocationAnimated() {
|
||||
// Scenario: No bubbles. Drag was over RIGHT zone (default side). Drag ends.
|
||||
prepareBubbleBarViewController(hasBubbles = false)
|
||||
dragToBubbleController.onDragStart(dragObject, DragOptions())
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXYToCenterOf(rightDropTargetRect)
|
||||
}
|
||||
verify(bubbleBarLocationListener, never())
|
||||
.onBubbleBarLocationAnimated(BubbleBarLocation.RIGHT)
|
||||
clearInvocations(bubbleBarLocationListener)
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXY(0, 0)
|
||||
bubbleBarLeftDropTarget.onDragExit(dragObject)
|
||||
dragToBubbleController.onDragEnd()
|
||||
}
|
||||
|
||||
// After drag ends (and no bubbles), listener should not be notified of the default
|
||||
// location.
|
||||
verify(bubbleBarLocationListener, never())
|
||||
.onBubbleBarLocationAnimated(BubbleBarLocation.RIGHT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragEnterLeftZone_bubblesOnLeft_listenerNotNotified() {
|
||||
// Scenario: Bubbles on LEFT. Drag enters LEFT zone.
|
||||
prepareBubbleBarViewController(
|
||||
hasBubbles = true,
|
||||
bubbleBarLocation = BubbleBarLocation.LEFT,
|
||||
)
|
||||
dragToBubbleController.onDragStart(dragObject, DragOptions())
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXYToCenterOf(leftDropTargetRect)
|
||||
bubbleBarLeftDropTarget.onDragEnter(dragObject)
|
||||
}
|
||||
|
||||
// Bubbles are already on the LEFT, and drag enters LEFT.
|
||||
// No new animation to LEFT should be triggered by the zone entry itself.
|
||||
verify(bubbleBarLocationListener, never())
|
||||
.onBubbleBarLocationAnimated(BubbleBarLocation.LEFT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onDragEnd_bubblesOnLeft_defaultIsLeft_wasDraggingRight_listenerNotifiedLeftAnimated() {
|
||||
// Scenario: Bubbles on LEFT. Drag was over RIGHT zone. Drag ends.
|
||||
prepareBubbleBarViewController(
|
||||
hasBubbles = true,
|
||||
bubbleBarLocation = BubbleBarLocation.LEFT,
|
||||
)
|
||||
dragToBubbleController.onDragStart(dragObject, DragOptions())
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXYToCenterOf(rightDropTargetRect)
|
||||
bubbleBarRightDropTarget.onDragEnter(dragObject) // Notifies Animated(RIGHT)
|
||||
}
|
||||
verify(bubbleBarLocationListener).onBubbleBarLocationAnimated(BubbleBarLocation.RIGHT)
|
||||
clearInvocations(bubbleBarLocationListener) // Clear the Animated(RIGHT)
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
dragObject.updateXY(0, 0)
|
||||
bubbleBarLeftDropTarget.onDragExit(dragObject)
|
||||
dragToBubbleController.onDragEnd()
|
||||
}
|
||||
|
||||
// Bubble bar's final animated location should be LEFT.
|
||||
verify(bubbleBarLocationListener).onBubbleBarLocationAnimated(BubbleBarLocation.LEFT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragEnterLeftThenExitToNoZoneThenEnterRight_noBubbles_listenerSequenceCorrectAnimated() {
|
||||
// Scenario: No bubbles. Complex drag path: Left -> None -> Right
|
||||
prepareBubbleBarViewController(hasBubbles = false)
|
||||
dragToBubbleController.onDragStart(dragObject, DragOptions())
|
||||
clearInvocations(bubbleBarLocationListener)
|
||||
|
||||
val inOrder = inOrder(bubbleBarLocationListener)
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
// 1. Enter Left
|
||||
dragObject.updateXYToCenterOf(leftDropTargetRect)
|
||||
bubbleBarLeftDropTarget.onDragEnter(dragObject)
|
||||
|
||||
// 2. Exit Left to no zone
|
||||
dragObject.updateXY(0, 0)
|
||||
bubbleBarLeftDropTarget.onDragExit(dragObject)
|
||||
|
||||
// 3. Enter Right
|
||||
dragObject.updateXYToCenterOf(rightDropTargetRect)
|
||||
bubbleBarRightDropTarget.onDragEnter(dragObject)
|
||||
}
|
||||
|
||||
inOrder
|
||||
.verify(bubbleBarLocationListener)
|
||||
.onBubbleBarLocationAnimated(BubbleBarLocation.LEFT)
|
||||
// Revert to default, following enter of the same zone should not trigger updated
|
||||
inOrder
|
||||
.verify(bubbleBarLocationListener)
|
||||
.onBubbleBarLocationAnimated(BubbleBarLocation.RIGHT)
|
||||
}
|
||||
|
||||
private fun prepareBubbleBarViewController(
|
||||
hasBubbles: Boolean = false,
|
||||
bubbleBarLocation: BubbleBarLocation = BubbleBarLocation.RIGHT,
|
||||
|
||||
Reference in New Issue
Block a user