Loading libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryScreenshotTest.kt +26 −7 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +22 −12 Original line number Diff line number Diff line Loading @@ -145,11 +145,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( Loading Loading @@ -370,11 +380,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) Loading Loading @@ -405,11 +415,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) Loading libs/WindowManager/Shell/res/values/dimen.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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> Loading libs/WindowManager/Shell/shared/res/values/dimen.xml +2 −2 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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> Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissView.kt +27 −10 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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 { Loading Loading @@ -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) } Loading Loading @@ -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 Loading
libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryScreenshotTest.kt +26 −7 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +22 −12 Original line number Diff line number Diff line Loading @@ -145,11 +145,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( Loading Loading @@ -370,11 +380,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) Loading Loading @@ -405,11 +415,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) Loading
libs/WindowManager/Shell/res/values/dimen.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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> Loading
libs/WindowManager/Shell/shared/res/values/dimen.xml +2 −2 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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> Loading
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissView.kt +27 −10 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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 { Loading Loading @@ -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) } Loading Loading @@ -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