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

Commit 1cea2e09 authored by Liran Binyamin's avatar Liran Binyamin
Browse files

Updates to bubble drag zones

1. Update the bubble bar drop target to be pill shaped. The drop
   target uses the current size and position of the bubble bar.
2. Update the dismiss drag zone to a circle shape rather than rectangle.
   Also update the position of the X dismiss icon, aligning it with the
   dismiss drag zone.
3. Updates the positioning logic for the DismissView to support bubble bar.

Flag: com.android.wm.shell.enable_bubble_to_fullscreen
Fixes: 404920503
Fixes: 404916611
Test: atest DragZoneFactoryScreenshotTest
Test: atest DragZoneFactoryTest
Test: atest DropTargetManagerTest
Test: manual
       - turn enable_bubble_to_fullscreen flag on
       - drag the bubble bar and an individual bubble through the dismiss zone
       - observe behavior
       - repeat with flag off to verify existing behavior
Change-Id: Ia3d0e680aa55bd96b094d7e4ca523cdb21ae3694
parent d3e40abc
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import androidx.core.graphics.green
import androidx.core.graphics.red
import androidx.core.graphics.toColorInt
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import com.android.wm.shell.shared.bubbles.DragZoneFactory.BubbleBarPropertiesProvider
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.DragZoneFactory.SplitScreenModeChecker.SplitScreenMode
@@ -133,26 +134,44 @@ class DragZoneFactoryScreenshotTest(private val param: Param) {
            DeviceConfig.create(context, context.getSystemService(WindowManager::class.java)!!)
        val splitScreenModeChecker = SplitScreenModeChecker { param.splitScreenMode }
        val desktopWindowModeChecker = DesktopWindowModeChecker { true }
        val bubbleBarPropertiesProvider = object : BubbleBarPropertiesProvider {
            override fun getHeight() = 80
            override fun getWidth() = 100
            override fun getBottomPadding() = 40
        }
        return DragZoneFactory(
            context,
            deviceConfig,
            splitScreenModeChecker,
            desktopWindowModeChecker
            desktopWindowModeChecker,
            bubbleBarPropertiesProvider,
        )
    }

    private fun FrameLayout.addZoneView(zone: DragZone) {
        val view = View(context)
        this.addView(view, 0)
        view.layoutParams = FrameLayout.LayoutParams(zone.bounds.width(), zone.bounds.height())
        view.background = createZoneDrawable(zone.color)
        view.x = zone.bounds.left.toFloat()
        view.y = zone.bounds.top.toFloat()
        when (val bounds = zone.bounds) {
            is DragZone.Bounds.RectZone -> {
                view.layoutParams =
                    FrameLayout.LayoutParams(bounds.rect.width(), bounds.rect.height())
                view.background = createZoneDrawable(zone.color, GradientDrawable.RECTANGLE)
                view.x = bounds.rect.left.toFloat()
                view.y = bounds.rect.top.toFloat()
            }
            is DragZone.Bounds.CircleZone -> {
                view.layoutParams =
                    FrameLayout.LayoutParams(bounds.radius * 2, bounds.radius * 2)
                view.background = createZoneDrawable(zone.color, GradientDrawable.OVAL)
                view.x = (bounds.x - bounds.radius).toFloat()
                view.y = (bounds.y - bounds.radius).toFloat()
            }
        }
    }

    private fun createZoneDrawable(@ColorInt color: Int): Drawable {
    private fun createZoneDrawable(@ColorInt color: Int, zoneShape: Int): Drawable {
        val shape = GradientDrawable()
        shape.shape = GradientDrawable.RECTANGLE
        shape.shape = zoneShape
        shape.setColor(Color.argb(128, color.red, color.green, color.blue))
        shape.setStroke(2, color)
        return shape
+22 −12
Original line number Diff line number Diff line
@@ -144,11 +144,21 @@ class BubbleBarLayerViewTest {
        testBubblesList = mutableListOf()
        val bubbleData = mock<BubbleData>()
        whenever(bubbleData.bubbles).thenReturn(testBubblesList)
        whenever(bubbleData.hasBubbles()).thenReturn(!testBubblesList.isEmpty())
        whenever(bubbleData.hasBubbles()).thenReturn(testBubblesList.isNotEmpty())

        dragZoneFactory = DragZoneFactory(context, deviceConfig,
        val bubbleBarPropertiesProvider = object : DragZoneFactory.BubbleBarPropertiesProvider {
            override fun getHeight() = 60
            override fun getWidth() = 90
            override fun getBottomPadding() = 20
        }
        dragZoneFactory =
            DragZoneFactory(
                context,
                deviceConfig,
                { SplitScreenMode.UNSUPPORTED },
            { false })
                { false },
                bubbleBarPropertiesProvider
            )

        bubbleController =
            createBubbleController(
@@ -368,11 +378,11 @@ class BubbleBarLayerViewTest {
        val dragZones = dragZoneFactory.createSortedDragZones(
            DraggedObject.ExpandedView(BubbleBarLocation.RIGHT))
        val rightDragZone = dragZones.filterIsInstance<DragZone.Bubble.Right>().first()
        val rightPoint = PointF(rightDragZone.bounds.centerX().toFloat(),
            rightDragZone.bounds.centerY().toFloat())
        val rightPoint = PointF(rightDragZone.bounds.rect.centerX().toFloat(),
            rightDragZone.bounds.rect.centerY().toFloat())
        val leftDragZone = dragZones.filterIsInstance<DragZone.Bubble.Left>().first()
        val leftPoint = PointF(leftDragZone.bounds.centerX().toFloat(),
            leftDragZone.bounds.centerY().toFloat())
        val leftPoint = PointF(leftDragZone.bounds.rect.centerX().toFloat(),
            leftDragZone.bounds.rect.centerY().toFloat())

        // Drag from right to left
        handleView.dispatchTouchEvent(0L, MotionEvent.ACTION_DOWN, rightPoint)
@@ -403,11 +413,11 @@ class BubbleBarLayerViewTest {
        val dragZones = dragZoneFactory.createSortedDragZones(
            DraggedObject.ExpandedView(BubbleBarLocation.LEFT))
        val rightDragZone = dragZones.filterIsInstance<DragZone.Bubble.Right>().first()
        val rightPoint = PointF(rightDragZone.bounds.centerX().toFloat(),
            rightDragZone.bounds.centerY().toFloat())
        val rightPoint = PointF(rightDragZone.bounds.rect.centerX().toFloat(),
            rightDragZone.bounds.rect.centerY().toFloat())
        val leftDragZone = dragZones.filterIsInstance<DragZone.Bubble.Left>().first()
        val leftPoint = PointF(leftDragZone.bounds.centerX().toFloat(),
            leftDragZone.bounds.centerY().toFloat())
        val leftPoint = PointF(leftDragZone.bounds.rect.centerX().toFloat(),
            leftDragZone.bounds.rect.centerY().toFloat())

        // Drag from left to right
        handleView.dispatchTouchEvent(0L, MotionEvent.ACTION_DOWN, leftPoint)
+2 −0
Original line number Diff line number Diff line
@@ -303,6 +303,8 @@
    <dimen name="bubble_transform_area_height">140dp</dimen>
    <!-- How much elevation a bubble ui needs when dragged, must be above drop target & dismiss. -->
    <dimen name="dragged_bubble_elevation">3dp</dimen>
    <!-- Space between the bottom dismiss view and the bottom edge of the screen -->
    <dimen name="bubble_bar_dismiss_view_bottom_margin">60dp</dimen>

    <!-- Bottom and end margin for compat buttons. -->
    <dimen name="compat_button_margin">24dp</dimen>
+2 −2
Original line number Diff line number Diff line
@@ -19,8 +19,7 @@
    <dimen name="floating_dismiss_background_size">96dp</dimen>

    <!-- Bubble drag zone dimensions -->
    <dimen name="drag_zone_dismiss_fold">140dp</dimen>
    <dimen name="drag_zone_dismiss_tablet">200dp</dimen>
    <dimen name="drag_zone_dismiss_radius">96dp</dimen>
    <dimen name="drag_zone_bubble_fold">140dp</dimen>
    <dimen name="drag_zone_bubble_tablet">200dp</dimen>
    <dimen name="drag_zone_full_screen_width">512dp</dimen>
@@ -49,6 +48,7 @@
    <dimen name="drop_target_expanded_view_height">578dp</dimen>
    <dimen name="drop_target_expanded_view_padding_bottom">108dp</dimen>
    <dimen name="drop_target_expanded_view_padding_horizontal">24dp</dimen>
    <dimen name="drop_target_bubble_bar_padding_horizontal">24dp</dimen>

    <!-- The corner radius of freeform tasks in desktop windowing. -->
    <dimen name="desktop_windowing_freeform_rounded_corner_radius">16dp</dimen>
+27 −10
Original line number Diff line number Diff line
@@ -55,7 +55,13 @@ class DismissView(context: Context) : FrameLayout(context) {
            @DimenRes val targetSizeResId: Int,
            /** dimen resource id of the icon size in the dismiss target */
            @DimenRes val iconSizeResId: Int,
            /** dimen resource id of the bottom margin for the dismiss target */
            /**
             * dimen resource id of the bottom margin for the dismiss target
             *
             * By default the margin is applied on top of the bottom navigation bar inset. To ignore
             * the bottom navigation inset, and apply a margin relative to the bottom edge of the
             * screen set [applyMarginOverNavBarInset] to `false`.
             */
            @DimenRes var bottomMarginResId: Int,
            /** dimen resource id of the height for dismiss area gradient */
            @DimenRes val floatingGradientHeightResId: Int,
@@ -64,7 +70,13 @@ class DismissView(context: Context) : FrameLayout(context) {
            /** drawable resource id of the dismiss target background */
            @DrawableRes val backgroundResId: Int,
            /** drawable resource id of the icon for the dismiss target */
            @DrawableRes val iconResId: Int
            @DrawableRes val iconResId: Int,
            /**
             * Whether the value provided in [bottomMarginResId] should be applied on top of the
             * bottom navigation bar inset. If this is `false` the margin is relative to the bottom
             * edge of the screen.
             */
            val applyMarginOverNavBarInset: Boolean = true,
    )

    companion object {
@@ -95,9 +107,9 @@ class DismissView(context: Context) : FrameLayout(context) {
    }

    init {
        setClipToPadding(false)
        setClipChildren(false)
        setVisibility(View.INVISIBLE)
        clipToPadding = false
        clipChildren = false
        visibility = View.INVISIBLE
        addView(circle)
    }

@@ -209,11 +221,16 @@ class DismissView(context: Context) : FrameLayout(context) {

    private fun updatePadding() {
        val config = checkExists(config) ?: return
        val insets: WindowInsets = wm.getCurrentWindowMetrics().getWindowInsets()
        val bottomMargin = resources.getDimensionPixelSize(config.bottomMarginResId)
        if (config.applyMarginOverNavBarInset) {
            val insets: WindowInsets = wm.currentWindowMetrics.windowInsets
            val navInset = insets.getInsetsIgnoringVisibility(
                WindowInsets.Type.navigationBars())
        setPadding(0, 0, 0, navInset.bottom +
                resources.getDimensionPixelSize(config.bottomMarginResId))
                WindowInsets.Type.navigationBars()
            )
            setPadding(0, 0, 0, navInset.bottom + bottomMargin)
        } else {
            setPadding(0, 0, 0, bottomMargin)
        }
    }

    /**
Loading