diff options
| author | 2023-06-13 18:04:43 +0000 | |
|---|---|---|
| committer | 2023-06-13 18:04:43 +0000 | |
| commit | eeb0ec7dd9d9de06f4eef2650bf1c676935b8cd4 (patch) | |
| tree | feb4fe628fb24cd882037cae622dab7daa9ec4f2 | |
| parent | 7055f7c4d4f575075b072de73cbc57b736016bf1 (diff) | |
| parent | 378b9f11563c52d340e75d335a4c330df13dc4c4 (diff) | |
Merge "Fix stashed PiP so it only moves up/down if outside of insets" into udc-dev am: 378b9f1156
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23647404
Change-Id: I31120a385a6aa83421c0d1e2e605a6dff8215afe
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
2 files changed, 217 insertions, 1 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java index fc674a8aa59b..f9332e4bdb2e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java @@ -63,6 +63,15 @@ public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithmInterfac if (pipBoundsState.isImeShowing()) { insets.bottom -= pipBoundsState.getImeHeight(); } + // if PiP is stashed we only adjust the vertical position if it's outside of insets and + // ignore all keep clear areas, since it's already on the side + if (pipBoundsState.isStashed()) { + if (startingBounds.bottom > insets.bottom || startingBounds.top < insets.top) { + // bring PiP back to be aligned by bottom inset + startingBounds.offset(0, insets.bottom - startingBounds.bottom); + } + return startingBounds; + } Rect pipBounds = new Rect(startingBounds); boolean shouldApplyGravity = false; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java index 4d7e9e450ceb..cc9e26b2c4f1 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java @@ -18,6 +18,9 @@ package com.android.wm.shell.pip.phone; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; import android.graphics.Rect; import android.testing.AndroidTestingRunner; @@ -26,10 +29,13 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.wm.shell.ShellTestCase; +import com.android.wm.shell.pip.PipBoundsAlgorithm; +import com.android.wm.shell.pip.PipBoundsState; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import java.util.Set; @@ -42,6 +48,10 @@ import java.util.Set; public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { private PhonePipKeepClearAlgorithm mPipKeepClearAlgorithm; + + @Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm; + @Mock private PipBoundsState mMockPipBoundsState; + private static final Rect DISPLAY_BOUNDS = new Rect(0, 0, 1000, 1000); @Before @@ -73,7 +83,6 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { @Test public void findUnoccludedPosition_withCollidingUnrestrictedKeepClearArea_moveBounds() { - // TODO(b/183746978): update this test to accommodate for the updated algorithm final Rect inBounds = new Rect(0, 0, 100, 100); final Rect keepClearRect = new Rect(50, 50, 150, 150); @@ -93,4 +102,202 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { assertEquals(inBounds, outBounds); } + + @Test + public void adjust_withCollidingRestrictedKeepClearArea_moveBounds() { + final Rect pipBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(50, 50, 150, 150); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertFalse(outBounds.contains(keepClearRect)); + } + + @Test + public void adjust_withNonCollidingRestrictedKeepClearArea_boundsUnchanged() { + final Rect pipBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(100, 100, 150, 150); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertFalse(outBounds.contains(keepClearRect)); + } + + @Test + public void adjust_withCollidingRestrictedKeepClearArea_whileStashed_boundsUnchanged() { + final Rect pipBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(50, 50, 150, 150); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + when(mMockPipBoundsState.isStashed()).thenReturn(true); + when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(pipBounds, outBounds); + } + + @Test + public void adjust_withNonCollidingRestrictedKeepClearArea_whileStashed_boundsUnchanged() { + final Rect pipBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(100, 100, 150, 150); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + when(mMockPipBoundsState.isStashed()).thenReturn(true); + when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(pipBounds, outBounds); + } + + @Test + public void adjust_aboveDisplayBounds_onLeftEdge_appliesBottomLeftGravity() { + final Rect pipBounds = new Rect( + 0, DISPLAY_BOUNDS.top - 50, 100, DISPLAY_BOUNDS.top + 50); + final Rect expected = new Rect( + 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + when(mMockPipBoundsAlgorithm.getSnapFraction(any(Rect.class))).thenReturn(0f); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(expected, outBounds); + } + + @Test + public void adjust_belowDisplayBounds_onLeftEdge_appliesBottomLeftGravity() { + final Rect pipBounds = new Rect( + 0, DISPLAY_BOUNDS.bottom - 50, 100, DISPLAY_BOUNDS.bottom + 50); + final Rect expected = new Rect( + 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + when(mMockPipBoundsAlgorithm.getSnapFraction(any(Rect.class))).thenReturn(3f); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(expected, outBounds); + } + + @Test + public void adjust_aboveDisplayBounds_onRightEdge_appliesBottomRightGravity() { + final Rect pipBounds = new Rect( + DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.top - 50, + DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.top + 50); + final Rect expected = new Rect( + DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.bottom - 100, + DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + when(mMockPipBoundsAlgorithm.getSnapFraction(any(Rect.class))).thenReturn(1f); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(expected, outBounds); + } + + @Test + public void adjust_belowDisplayBounds_onRightEdge_appliesBottomRightGravity() { + final Rect pipBounds = new Rect( + DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.bottom - 50, + DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom + 50); + final Rect expected = new Rect( + DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.bottom - 100, + DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + when(mMockPipBoundsAlgorithm.getSnapFraction(any(Rect.class))).thenReturn(2f); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(expected, outBounds); + } + + @Test + public void adjust_whileStashed_aboveDisplayBounds_alignsToBottomInset() { + final Rect pipBounds = new Rect( + 0, DISPLAY_BOUNDS.top - 50, 100, DISPLAY_BOUNDS.top + 50); + final Rect expected = new Rect( + 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + when(mMockPipBoundsState.isStashed()).thenReturn(true); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(expected, outBounds); + } + + @Test + public void adjust_whileStashed_belowDisplayBounds_alignsToBottomInset() { + final Rect pipBounds = new Rect( + 0, DISPLAY_BOUNDS.bottom - 50, 100, DISPLAY_BOUNDS.bottom + 50); + final Rect expected = new Rect( + 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); + when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); + when(mMockPipBoundsState.isStashed()).thenReturn(true); + doAnswer(invocation -> { + Rect arg0 = invocation.getArgument(0); + arg0.set(DISPLAY_BOUNDS); + return null; + }).when(mMockPipBoundsAlgorithm).getInsetBounds(any(Rect.class)); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust( + mMockPipBoundsState, mMockPipBoundsAlgorithm); + + assertEquals(expected, outBounds); + } } |