Merge "Fix stashed PiP so it only moves up/down if outside of insets" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
378b9f1156
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user