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: I782ccbbc44cf2b29df5afaa636ff3078371e360b Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -63,6 +63,15 @@ public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithmInterfac
|
|||||||
if (pipBoundsState.isImeShowing()) {
|
if (pipBoundsState.isImeShowing()) {
|
||||||
insets.bottom -= pipBoundsState.getImeHeight();
|
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);
|
Rect pipBounds = new Rect(startingBounds);
|
||||||
|
|
||||||
boolean shouldApplyGravity = false;
|
boolean shouldApplyGravity = false;
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ package com.android.wm.shell.pip.phone;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
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.graphics.Rect;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
@@ -26,10 +29,13 @@ import android.testing.TestableLooper;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.wm.shell.ShellTestCase;
|
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.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -42,6 +48,10 @@ import java.util.Set;
|
|||||||
public class PhonePipKeepClearAlgorithmTest extends ShellTestCase {
|
public class PhonePipKeepClearAlgorithmTest extends ShellTestCase {
|
||||||
|
|
||||||
private PhonePipKeepClearAlgorithm mPipKeepClearAlgorithm;
|
private PhonePipKeepClearAlgorithm mPipKeepClearAlgorithm;
|
||||||
|
|
||||||
|
@Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
|
||||||
|
@Mock private PipBoundsState mMockPipBoundsState;
|
||||||
|
|
||||||
private static final Rect DISPLAY_BOUNDS = new Rect(0, 0, 1000, 1000);
|
private static final Rect DISPLAY_BOUNDS = new Rect(0, 0, 1000, 1000);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -73,7 +83,6 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findUnoccludedPosition_withCollidingUnrestrictedKeepClearArea_moveBounds() {
|
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 inBounds = new Rect(0, 0, 100, 100);
|
||||||
final Rect keepClearRect = new Rect(50, 50, 150, 150);
|
final Rect keepClearRect = new Rect(50, 50, 150, 150);
|
||||||
|
|
||||||
@@ -93,4 +102,202 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase {
|
|||||||
|
|
||||||
assertEquals(inBounds, outBounds);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user