Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt +22 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.Rect import android.graphics.Region import android.os.Binder import android.view.LayoutInflater import android.view.RoundedCorner import android.view.SurfaceControl import android.view.SurfaceControlViewHost import android.view.View Loading Loading @@ -53,12 +54,14 @@ class DesktopTilingDividerWindowManager( private val transitionHandler: DesktopTilingWindowDecoration, private val transactionSupplier: Supplier<SurfaceControl.Transaction>, private var dividerBounds: Rect, private val displayContext: Context, ) : WindowlessWindowManager(config, leash, null), DividerMoveCallback, View.OnLayoutChangeListener { private lateinit var viewHost: SurfaceControlViewHost private var tilingDividerView: TilingDividerView? = null private var dividerShown = false private var handleRegionWidth: Int = -1 private var setTouchRegion = true private val maxRoundedCornerRadius = getMaxRoundedCornerRadius() /** * Gets bounds of divider window with screen based coordinate on the param Rect. Loading Loading @@ -93,7 +96,11 @@ class DesktopTilingDividerWindowManager( getDividerBounds(tmpDividerBounds) dividerView.setup(this, tmpDividerBounds) t.setRelativeLayer(leash, relativeLeash, 1) .setPosition(leash, dividerBounds.left.toFloat(), dividerBounds.top.toFloat()) .setPosition( leash, dividerBounds.left.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat(), ) .show(leash) syncQueue.runInSync { transaction -> transaction.merge(t) Loading Loading @@ -144,7 +151,7 @@ class DesktopTilingDividerWindowManager( */ override fun onDividerMove(pos: Int): Boolean { val t = transactionSupplier.get() t.setPosition(leash, pos.toFloat(), dividerBounds.top.toFloat()) t.setPosition(leash, pos.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat()) val dividerWidth = dividerBounds.width() dividerBounds.set(pos, dividerBounds.top, pos + dividerWidth, dividerBounds.bottom) return transitionHandler.onDividerHandleMoved(dividerBounds, t) Loading @@ -157,7 +164,7 @@ class DesktopTilingDividerWindowManager( override fun onDividerMovedEnd(pos: Int) { setSlippery(true) val t = transactionSupplier.get() t.setPosition(leash, pos.toFloat(), dividerBounds.top.toFloat()) t.setPosition(leash, pos.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat()) val dividerWidth = dividerBounds.width() dividerBounds.set(pos, dividerBounds.top, pos + dividerWidth, dividerBounds.bottom) transitionHandler.onDividerHandleDragEnd(dividerBounds, t) Loading @@ -166,7 +173,7 @@ class DesktopTilingDividerWindowManager( private fun getWindowManagerParams(): WindowManager.LayoutParams { val lp = WindowManager.LayoutParams( dividerBounds.width(), dividerBounds.width() + 2 * maxRoundedCornerRadius, dividerBounds.height(), TYPE_DOCK_DIVIDER, FLAG_NOT_FOCUSABLE or Loading Loading @@ -225,4 +232,15 @@ class DesktopTilingDividerWindowManager( } viewHost.relayout(lp) } private fun getMaxRoundedCornerRadius(): Int { val display = displayContext.display return listOf( RoundedCorner.POSITION_TOP_LEFT, RoundedCorner.POSITION_TOP_RIGHT, RoundedCorner.POSITION_BOTTOM_RIGHT, RoundedCorner.POSITION_BOTTOM_LEFT, ) .maxOf { position -> display.getRoundedCorner(position)?.getRadius() ?: 0 } } } libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt +2 −0 Original line number Diff line number Diff line Loading @@ -195,6 +195,7 @@ class DesktopTilingWindowDecoration( val builder = SurfaceControl.Builder() rootTdaOrganizer.attachToDisplayArea(displayId, builder) val leash = builder.setName(TILING_DIVIDER_TAG).setContainerLayer().build() val displayContext = displayController.getDisplayContext(displayId) ?: return null val tilingManager = displayLayout?.let { dividerBounds = inflateDividerBounds(it) Loading @@ -207,6 +208,7 @@ class DesktopTilingWindowDecoration( this, transactionSupplier, dividerBounds, displayContext, ) } // a leash to present the divider on top of, without re-parenting. Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt +1 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion val dividerSize = resources.getDimensionPixelSize(R.dimen.split_divider_bar_width) val backgroundLeft = (width - dividerSize) / 2 val backgroundTop = 0 val backgroundRight = left + dividerSize val backgroundRight = backgroundLeft + dividerSize val backgroundBottom = height backgroundRect.set(backgroundLeft, backgroundTop, backgroundRight, backgroundBottom) } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt +29 −1 Original line number Diff line number Diff line Loading @@ -16,9 +16,12 @@ package com.android.wm.shell.windowdecor.tiling import android.content.Context import android.content.res.Configuration import android.graphics.Rect import android.testing.AndroidTestingRunner import android.view.Display import android.view.RoundedCorner import android.view.SurfaceControl import androidx.test.annotation.UiThreadTest import androidx.test.filters.SmallTest Loading @@ -29,6 +32,7 @@ import kotlin.test.Test import org.junit.Before import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify Loading @@ -55,10 +59,17 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { private lateinit var desktopTilingWindowManager: DesktopTilingDividerWindowManager private val context = mock<Context>() private val display = mock<Display>() private val roundedCorner = mock<RoundedCorner>() @Before fun setup() { config = Configuration() config.setToDefaults() whenever(context.display).thenReturn(display) whenever(display.getRoundedCorner(any())).thenReturn(roundedCorner) whenever(roundedCorner.radius).thenReturn(CORNER_RADIUS) desktopTilingWindowManager = DesktopTilingDividerWindowManager( config, Loading @@ -69,6 +80,7 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { transitionHandlerMock, transactionSupplierMock, BOUNDS, context, ) } Loading @@ -85,7 +97,6 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { // Ensure a surfaceControl transaction runs to show the divider. verify(transactionSupplierMock, times(1)).get() verify(syncQueueMock, times(1)).runInSync(any()) desktopTilingWindowManager.release() verify(transaction, times(1)).hide(any()) Loading @@ -93,7 +104,24 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { verify(transaction, times(1)).apply() } @Test @UiThreadTest fun testWindowManager_accountsForRoundedCornerDimensions() { whenever(transactionSupplierMock.get()).thenReturn(transaction) whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction) whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction) whenever(transaction.setPosition(any(), any(), any())).thenReturn(transaction) whenever(transaction.show(any())).thenReturn(transaction) desktopTilingWindowManager.generateViewHost(surfaceControl) // Ensure a surfaceControl transaction runs to show the divider. verify(transaction, times(1)) .setPosition(any(), eq(BOUNDS.left.toFloat() - CORNER_RADIUS), any()) } companion object { private val BOUNDS = Rect(1, 2, 3, 4) private val CORNER_RADIUS = 28 } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt +22 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.Rect import android.graphics.Region import android.os.Binder import android.view.LayoutInflater import android.view.RoundedCorner import android.view.SurfaceControl import android.view.SurfaceControlViewHost import android.view.View Loading Loading @@ -53,12 +54,14 @@ class DesktopTilingDividerWindowManager( private val transitionHandler: DesktopTilingWindowDecoration, private val transactionSupplier: Supplier<SurfaceControl.Transaction>, private var dividerBounds: Rect, private val displayContext: Context, ) : WindowlessWindowManager(config, leash, null), DividerMoveCallback, View.OnLayoutChangeListener { private lateinit var viewHost: SurfaceControlViewHost private var tilingDividerView: TilingDividerView? = null private var dividerShown = false private var handleRegionWidth: Int = -1 private var setTouchRegion = true private val maxRoundedCornerRadius = getMaxRoundedCornerRadius() /** * Gets bounds of divider window with screen based coordinate on the param Rect. Loading Loading @@ -93,7 +96,11 @@ class DesktopTilingDividerWindowManager( getDividerBounds(tmpDividerBounds) dividerView.setup(this, tmpDividerBounds) t.setRelativeLayer(leash, relativeLeash, 1) .setPosition(leash, dividerBounds.left.toFloat(), dividerBounds.top.toFloat()) .setPosition( leash, dividerBounds.left.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat(), ) .show(leash) syncQueue.runInSync { transaction -> transaction.merge(t) Loading Loading @@ -144,7 +151,7 @@ class DesktopTilingDividerWindowManager( */ override fun onDividerMove(pos: Int): Boolean { val t = transactionSupplier.get() t.setPosition(leash, pos.toFloat(), dividerBounds.top.toFloat()) t.setPosition(leash, pos.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat()) val dividerWidth = dividerBounds.width() dividerBounds.set(pos, dividerBounds.top, pos + dividerWidth, dividerBounds.bottom) return transitionHandler.onDividerHandleMoved(dividerBounds, t) Loading @@ -157,7 +164,7 @@ class DesktopTilingDividerWindowManager( override fun onDividerMovedEnd(pos: Int) { setSlippery(true) val t = transactionSupplier.get() t.setPosition(leash, pos.toFloat(), dividerBounds.top.toFloat()) t.setPosition(leash, pos.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat()) val dividerWidth = dividerBounds.width() dividerBounds.set(pos, dividerBounds.top, pos + dividerWidth, dividerBounds.bottom) transitionHandler.onDividerHandleDragEnd(dividerBounds, t) Loading @@ -166,7 +173,7 @@ class DesktopTilingDividerWindowManager( private fun getWindowManagerParams(): WindowManager.LayoutParams { val lp = WindowManager.LayoutParams( dividerBounds.width(), dividerBounds.width() + 2 * maxRoundedCornerRadius, dividerBounds.height(), TYPE_DOCK_DIVIDER, FLAG_NOT_FOCUSABLE or Loading Loading @@ -225,4 +232,15 @@ class DesktopTilingDividerWindowManager( } viewHost.relayout(lp) } private fun getMaxRoundedCornerRadius(): Int { val display = displayContext.display return listOf( RoundedCorner.POSITION_TOP_LEFT, RoundedCorner.POSITION_TOP_RIGHT, RoundedCorner.POSITION_BOTTOM_RIGHT, RoundedCorner.POSITION_BOTTOM_LEFT, ) .maxOf { position -> display.getRoundedCorner(position)?.getRadius() ?: 0 } } }
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt +2 −0 Original line number Diff line number Diff line Loading @@ -195,6 +195,7 @@ class DesktopTilingWindowDecoration( val builder = SurfaceControl.Builder() rootTdaOrganizer.attachToDisplayArea(displayId, builder) val leash = builder.setName(TILING_DIVIDER_TAG).setContainerLayer().build() val displayContext = displayController.getDisplayContext(displayId) ?: return null val tilingManager = displayLayout?.let { dividerBounds = inflateDividerBounds(it) Loading @@ -207,6 +208,7 @@ class DesktopTilingWindowDecoration( this, transactionSupplier, dividerBounds, displayContext, ) } // a leash to present the divider on top of, without re-parenting. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt +1 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion val dividerSize = resources.getDimensionPixelSize(R.dimen.split_divider_bar_width) val backgroundLeft = (width - dividerSize) / 2 val backgroundTop = 0 val backgroundRight = left + dividerSize val backgroundRight = backgroundLeft + dividerSize val backgroundBottom = height backgroundRect.set(backgroundLeft, backgroundTop, backgroundRight, backgroundBottom) } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt +29 −1 Original line number Diff line number Diff line Loading @@ -16,9 +16,12 @@ package com.android.wm.shell.windowdecor.tiling import android.content.Context import android.content.res.Configuration import android.graphics.Rect import android.testing.AndroidTestingRunner import android.view.Display import android.view.RoundedCorner import android.view.SurfaceControl import androidx.test.annotation.UiThreadTest import androidx.test.filters.SmallTest Loading @@ -29,6 +32,7 @@ import kotlin.test.Test import org.junit.Before import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify Loading @@ -55,10 +59,17 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { private lateinit var desktopTilingWindowManager: DesktopTilingDividerWindowManager private val context = mock<Context>() private val display = mock<Display>() private val roundedCorner = mock<RoundedCorner>() @Before fun setup() { config = Configuration() config.setToDefaults() whenever(context.display).thenReturn(display) whenever(display.getRoundedCorner(any())).thenReturn(roundedCorner) whenever(roundedCorner.radius).thenReturn(CORNER_RADIUS) desktopTilingWindowManager = DesktopTilingDividerWindowManager( config, Loading @@ -69,6 +80,7 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { transitionHandlerMock, transactionSupplierMock, BOUNDS, context, ) } Loading @@ -85,7 +97,6 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { // Ensure a surfaceControl transaction runs to show the divider. verify(transactionSupplierMock, times(1)).get() verify(syncQueueMock, times(1)).runInSync(any()) desktopTilingWindowManager.release() verify(transaction, times(1)).hide(any()) Loading @@ -93,7 +104,24 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() { verify(transaction, times(1)).apply() } @Test @UiThreadTest fun testWindowManager_accountsForRoundedCornerDimensions() { whenever(transactionSupplierMock.get()).thenReturn(transaction) whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction) whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction) whenever(transaction.setPosition(any(), any(), any())).thenReturn(transaction) whenever(transaction.show(any())).thenReturn(transaction) desktopTilingWindowManager.generateViewHost(surfaceControl) // Ensure a surfaceControl transaction runs to show the divider. verify(transaction, times(1)) .setPosition(any(), eq(BOUNDS.left.toFloat() - CORNER_RADIUS), any()) } companion object { private val BOUNDS = Rect(1, 2, 3, 4) private val CORNER_RADIUS = 28 } }