From 13626d09e8243a0af5ff694a7c38d4199b1bfad4 Mon Sep 17 00:00:00 2001 From: Robert Horvath Date: Fri, 14 Oct 2022 15:31:39 +0200 Subject: [PATCH] Only unrestricted KCA can move expanded PiP off the edge Moving expanded PiP windows away from the edge of the screen can be disruptive due to the large size of expanded PiPs. Allow expanded PiPs to be moved away from the edge only by unrestricted keep clear areas, otherwise prefer movement along the edge or stashing. Bug: 253014898 Test: atest TvPipKeepClearAlgorithmTest Test: Manual, with expanded PiP and dashboard Change-Id: I3c934e8a8a7a58d4fd78d968b4ec3eb4b2a02c78 --- .../shell/pip/tv/TvPipKeepClearAlgorithm.kt | 8 ++-- .../pip/tv/TvPipKeepClearAlgorithmTest.kt | 43 ++++++++++++++++--- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt index 1e54436ebce92..a94bd6ec10406 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt @@ -284,8 +284,10 @@ class TvPipKeepClearAlgorithm() { ): Rect? { val movementBounds = transformedMovementBounds val candidateEdgeRects = mutableListOf() + val maxRestrictedXDistanceFraction = + if (isPipAnchoredToCorner()) maxRestrictedDistanceFraction else 0.0 val minRestrictedLeft = - pipAnchorBounds.right - screenSize.width * maxRestrictedDistanceFraction + pipAnchorBounds.right - screenSize.width * maxRestrictedXDistanceFraction candidateEdgeRects.add( movementBounds.offsetCopy(movementBounds.width() + pipAreaPadding, 0) @@ -296,7 +298,6 @@ class TvPipKeepClearAlgorithm() { // throw out edges that are too close to the left screen edge to fit the PiP val minLeft = movementBounds.left + pipAnchorBounds.width() candidateEdgeRects.retainAll { it.left - pipAreaPadding > minLeft } - candidateEdgeRects.sortBy { -it.left } val maxRestrictedDY = (screenSize.height * maxRestrictedDistanceFraction).roundToInt() @@ -335,8 +336,7 @@ class TvPipKeepClearAlgorithm() { } } - candidateBounds.sortBy { candidateCost(it, pipAnchorBounds) } - return candidateBounds.firstOrNull() + return candidateBounds.minByOrNull { candidateCost(it, pipAnchorBounds) } } private fun getNearbyStashedPosition(bounds: Rect, keepClearAreas: Set): Rect { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt index 0fcc5cf384c94..9effaa47b377a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt @@ -21,23 +21,24 @@ import android.graphics.Rect import android.testing.AndroidTestingRunner import android.util.Size import android.view.Gravity -import org.junit.runner.RunWith -import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_BOTTOM +import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_TOP import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement -import org.junit.Before -import org.junit.Test import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertNull import junit.framework.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith @RunWith(AndroidTestingRunner::class) class TvPipKeepClearAlgorithmTest { private val DEFAULT_PIP_SIZE = Size(384, 216) - private val EXPANDED_WIDE_PIP_SIZE = Size(384*2, 216) + private val EXPANDED_WIDE_PIP_SIZE = Size(384 * 2, 216) + private val EXPANDED_TALL_PIP_SIZE = Size(384, 216 * 4) private val DASHBOARD_WIDTH = 484 private val BOTTOM_SHEET_HEIGHT = 524 private val STASH_OFFSET = 64 @@ -485,6 +486,38 @@ class TvPipKeepClearAlgorithmTest { testAnchorPositionWithInsets(insets) } + @Test + fun test_AnchorRightExpandedPiP_UnrestrictedRightSidebar_PushedLeft() { + pipSize = EXPANDED_TALL_PIP_SIZE + gravity = Gravity.RIGHT + + val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.RIGHT) + unrestrictedAreas.add(sidebar) + + val expectedBounds = anchorBoundsOffsetBy(SCREEN_EDGE_INSET - sidebar.width() - PADDING, 0) + + val placement = getActualPlacement() + assertEquals(expectedBounds, placement.bounds) + assertNotStashed(placement) + } + + @Test + fun test_AnchorRightExpandedPiP_RestrictedRightSidebar_StashedRight() { + pipSize = EXPANDED_TALL_PIP_SIZE + gravity = Gravity.RIGHT + + val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.RIGHT) + restrictedAreas.add(sidebar) + + val expectedBounds = getExpectedAnchorBounds() + expectedBounds.offsetTo(SCREEN_SIZE.width - STASH_OFFSET, expectedBounds.top) + + val placement = getActualPlacement() + assertEquals(expectedBounds, placement.bounds) + assertEquals(STASH_TYPE_RIGHT, placement.stashType) + assertEquals(getExpectedAnchorBounds(), placement.unstashDestinationBounds) + } + private fun testAnchorPositionWithInsets(insets: Insets) { var pipRect = Rect(0, 0, pipSize.width, pipSize.height) pipRect.inset(insets)