Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java +18 −32 Original line number Diff line number Diff line Loading @@ -52,24 +52,15 @@ public class PipDoubleTapHelper { public static final int SIZE_SPEC_MAX = 1; public static final int SIZE_SPEC_CUSTOM = 2; /** * Returns MAX or DEFAULT {@link PipSizeSpec} to toggle to/from. * * <p>Each double tap toggles back and forth between {@code PipSizeSpec.CUSTOM} and * either {@code PipSizeSpec.MAX} or {@code PipSizeSpec.DEFAULT}. The choice between * the latter two sizes is determined based on the current state of the pip screen.</p> * * @param mPipBoundsState current state of the pip screen */ @PipSizeSpec private static int getMaxOrDefaultPipSizeSpec(@NonNull PipBoundsState mPipBoundsState) { private static int getMaxOrDefaultPipSizeSpec(@NonNull PipBoundsState pipBoundsState) { // determine the average pip screen width int averageWidth = (mPipBoundsState.getMaxSize().x + mPipBoundsState.getMinSize().x) / 2; int averageWidth = (pipBoundsState.getMaxSize().x + pipBoundsState.getMinSize().x) / 2; // If pip screen width is above average, DEFAULT is the size spec we need to // toggle to. Otherwise, we choose MAX. return (mPipBoundsState.getBounds().width() > averageWidth) return (pipBoundsState.getBounds().width() > averageWidth) ? SIZE_SPEC_DEFAULT : SIZE_SPEC_MAX; } Loading @@ -77,35 +68,33 @@ public class PipDoubleTapHelper { /** * Determines the {@link PipSizeSpec} to toggle to on double tap. * * @param mPipBoundsState current state of the pip screen * @param pipBoundsState current state of the pip bounds * @param userResizeBounds latest user resized bounds (by pinching in/out) * @return pip screen size to switch to */ @PipSizeSpec public static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, public static int nextSizeSpec(@NonNull PipBoundsState pipBoundsState, @NonNull Rect userResizeBounds) { // is pip screen at its maximum boolean isScreenMax = mPipBoundsState.getBounds().width() == mPipBoundsState.getMaxSize().x; // is pip screen at its normal default size boolean isScreenDefault = (mPipBoundsState.getBounds().width() == mPipBoundsState.getNormalBounds().width()) && (mPipBoundsState.getBounds().height() == mPipBoundsState.getNormalBounds().height()); boolean isScreenMax = pipBoundsState.getBounds().width() == pipBoundsState.getMaxSize().x && pipBoundsState.getBounds().height() == pipBoundsState.getMaxSize().y; boolean isScreenDefault = (pipBoundsState.getBounds().width() == pipBoundsState.getNormalBounds().width()) && (pipBoundsState.getBounds().height() == pipBoundsState.getNormalBounds().height()); // edge case 1 // if user hasn't resized screen yet, i.e. CUSTOM size does not exist yet // or if user has resized exactly to DEFAULT, then we just want to maximize if (isScreenDefault && userResizeBounds.width() == mPipBoundsState.getNormalBounds().width()) { && userResizeBounds.width() == pipBoundsState.getNormalBounds().width() && userResizeBounds.height() == pipBoundsState.getNormalBounds().height()) { return SIZE_SPEC_MAX; } // edge case 2 // if user has maximized, then we want to toggle to DEFAULT // if user has resized to max, then we want to toggle to DEFAULT if (isScreenMax && userResizeBounds.width() == mPipBoundsState.getMaxSize().x) { && userResizeBounds.width() == pipBoundsState.getMaxSize().x && userResizeBounds.height() == pipBoundsState.getMaxSize().y) { return SIZE_SPEC_DEFAULT; } Loading @@ -113,9 +102,6 @@ public class PipDoubleTapHelper { if (isScreenDefault || isScreenMax) { return SIZE_SPEC_CUSTOM; } // if we are currently in user resized CUSTOM size state // then we toggle either to MAX or DEFAULT depending on the current pip screen state return getMaxOrDefaultPipSizeSpec(mPipBoundsState); return getMaxOrDefaultPipSizeSpec(pipBoundsState); } } libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +8 −1 Original line number Diff line number Diff line Loading @@ -180,10 +180,17 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange return; } WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setBounds(pipTaskToken, toBounds); if (configAtEnd) { wct.deferConfigToTransitionEnd(pipTaskToken); if (mPipBoundsState.getBounds().width() == toBounds.width() && mPipBoundsState.getBounds().height() == toBounds.height()) { // TODO (b/393159816): Config-at-End causes a flicker without size change. // If PiP size isn't changing enforce a minimal one-pixel change as a workaround. --toBounds.bottom; } } wct.setBounds(pipTaskToken, toBounds); mPipTransitionController.startResizeTransition(wct, duration); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java +1 −0 Original line number Diff line number Diff line Loading @@ -934,6 +934,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha } // the size to toggle to after a double tap mPipBoundsState.setNormalBounds(getAdjustedNormalBounds()); int nextSize = PipDoubleTapHelper .nextSizeSpec(mPipBoundsState, getUserResizeBounds()); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java +53 −110 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_DEFAU import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_MAX; import static com.android.wm.shell.common.pip.PipDoubleTapHelper.nextSizeSpec; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.graphics.Point; Loading @@ -41,131 +40,75 @@ import org.mockito.Mock; */ @RunWith(AndroidTestingRunner.class) public class PipDoubleTapHelperTest extends ShellTestCase { // represents the current pip window state and has information on current // max, min, and normal sizes @Mock private PipBoundsState mBoundStateMock; // tied to boundsStateMock.getBounds() in setUp() @Mock private Rect mBoundsMock; @Mock private PipBoundsState mMockPipBoundsState; // represents the most recent manually resized bounds // i.e. dimensions from the most recent pinch in/out @Mock private Rect mUserResizeBoundsMock; // Actual dimension guidelines of the PiP bounds. private static final int MAX_EDGE_SIZE = 100; private static final int DEFAULT_EDGE_SIZE = 60; private static final int MIN_EDGE_SIZE = 50; private static final int AVERAGE_EDGE_SIZE = (MAX_EDGE_SIZE + MIN_EDGE_SIZE) / 2; // actual dimensions of the pip screen bounds private static final int MAX_WIDTH = 100; private static final int DEFAULT_WIDTH = 40; private static final int MIN_WIDTH = 10; private static final int AVERAGE_WIDTH = (MAX_WIDTH + MIN_WIDTH) / 2; /** * Initializes mocks and assigns values for different pip screen bounds. */ @Before public void setUp() { // define pip bounds when(mBoundStateMock.getMaxSize()).thenReturn(new Point(MAX_WIDTH, 20)); when(mBoundStateMock.getMinSize()).thenReturn(new Point(MIN_WIDTH, 2)); when(mMockPipBoundsState.getMaxSize()).thenReturn(new Point(MAX_EDGE_SIZE, MAX_EDGE_SIZE)); when(mMockPipBoundsState.getMinSize()).thenReturn(new Point(MIN_EDGE_SIZE, MIN_EDGE_SIZE)); Rect rectMock = mock(Rect.class); when(rectMock.width()).thenReturn(DEFAULT_WIDTH); when(mBoundStateMock.getNormalBounds()).thenReturn(rectMock); final Rect normalBounds = new Rect(0, 0, DEFAULT_EDGE_SIZE, DEFAULT_EDGE_SIZE); when(mMockPipBoundsState.getNormalBounds()).thenReturn(normalBounds); } when(mBoundsMock.width()).thenReturn(DEFAULT_WIDTH); when(mBoundStateMock.getBounds()).thenReturn(mBoundsMock); @Test public void nextSizeSpec_resizedWiderThanAverage_returnDefaultThenCustom() { final int resizeEdgeSize = (MAX_EDGE_SIZE + AVERAGE_EDGE_SIZE) / 2; final Rect userResizeBounds = new Rect(0, 0, resizeEdgeSize, resizeEdgeSize); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_DEFAULT); // once we toggle to DEFAULT only PiP bounds state gets updated - not the user resize bounds when(mMockPipBoundsState.getBounds()).thenReturn( new Rect(0, 0, DEFAULT_EDGE_SIZE, DEFAULT_EDGE_SIZE)); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_CUSTOM); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to a larger than the average but not the maximum width, * then we toggle between {@code PipSizeSpec.CUSTOM} and {@code PipSizeSpec.DEFAULT} */ @Test public void testNextScreenSize_resizedWiderThanAverage_returnDefaultThenCustom() { // make the user resize width in between MAX and average when(mUserResizeBoundsMock.width()).thenReturn((MAX_WIDTH + AVERAGE_WIDTH) / 2); // make current bounds same as resized bound since no double tap yet when(mBoundsMock.width()).thenReturn((MAX_WIDTH + AVERAGE_WIDTH) / 2); // then nextScreenSize() i.e. double tapping should // toggle to DEFAULT state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_DEFAULT); // once we toggle to DEFAULT our screen size gets updated // but not the user resize bounds when(mBoundsMock.width()).thenReturn(DEFAULT_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to CUSTOM state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_CUSTOM); public void nextSizeSpec_resizedSmallerThanAverage_returnMaxThenCustom() { final int resizeEdgeSize = (AVERAGE_EDGE_SIZE + MIN_EDGE_SIZE) / 2; final Rect userResizeBounds = new Rect(0, 0, resizeEdgeSize, resizeEdgeSize); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_MAX); // Once we toggle to MAX our screen size gets updated but not the user resize bounds when(mMockPipBoundsState.getBounds()).thenReturn( new Rect(0, 0, MAX_EDGE_SIZE, MAX_EDGE_SIZE)); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_CUSTOM); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to a smaller than the average but not the default width, * then we toggle between {@code PipSizeSpec.CUSTOM} and {@code PipSizeSpec.MAX} */ @Test public void testNextScreenSize_resizedNarrowerThanAverage_returnMaxThenCustom() { // make the user resize width in between MIN and average when(mUserResizeBoundsMock.width()).thenReturn((MIN_WIDTH + AVERAGE_WIDTH) / 2); // make current bounds same as resized bound since no double tap yet when(mBoundsMock.width()).thenReturn((MIN_WIDTH + AVERAGE_WIDTH) / 2); // then nextScreenSize() i.e. double tapping should // toggle to MAX state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_MAX); // once we toggle to MAX our screen size gets updated // but not the user resize bounds when(mBoundsMock.width()).thenReturn(MAX_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to CUSTOM state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_CUSTOM); public void nextSizeSpec_resizedToMax_returnDefault() { final Rect userResizeBounds = new Rect(0, 0, MAX_EDGE_SIZE, MAX_EDGE_SIZE); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_DEFAULT); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to exactly the maximum width * then we toggle to {@code PipSizeSpec.DEFAULT} */ @Test public void testNextScreenSize_resizedToMax_returnDefault() { // the resized width is the same as MAX_WIDTH when(mUserResizeBoundsMock.width()).thenReturn(MAX_WIDTH); // the current bounds are also at MAX_WIDTH when(mBoundsMock.width()).thenReturn(MAX_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to DEFAULT state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_DEFAULT); public void nextSizeSpec_resizedToDefault_returnMax() { final Rect userResizeBounds = new Rect(0, 0, DEFAULT_EDGE_SIZE, DEFAULT_EDGE_SIZE); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_MAX); } @Test public void nextSizeSpec_resizedToAlmostMax_returnDefault() { final Rect userResizeBounds = new Rect(0, 0, MAX_EDGE_SIZE, MAX_EDGE_SIZE - 1); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_DEFAULT); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to exactly the default width * then we toggle to {@code PipSizeSpec.MAX} */ @Test public void testNextScreenSize_resizedToDefault_returnMax() { // the resized width is the same as DEFAULT_WIDTH when(mUserResizeBoundsMock.width()).thenReturn(DEFAULT_WIDTH); // the current bounds are also at DEFAULT_WIDTH when(mBoundsMock.width()).thenReturn(DEFAULT_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to MAX state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_MAX); public void nextSizeSpec_resizedToAlmostMin_returnMax() { final Rect userResizeBounds = new Rect(0, 0, MIN_EDGE_SIZE, MIN_EDGE_SIZE + 1); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_MAX); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java +18 −32 Original line number Diff line number Diff line Loading @@ -52,24 +52,15 @@ public class PipDoubleTapHelper { public static final int SIZE_SPEC_MAX = 1; public static final int SIZE_SPEC_CUSTOM = 2; /** * Returns MAX or DEFAULT {@link PipSizeSpec} to toggle to/from. * * <p>Each double tap toggles back and forth between {@code PipSizeSpec.CUSTOM} and * either {@code PipSizeSpec.MAX} or {@code PipSizeSpec.DEFAULT}. The choice between * the latter two sizes is determined based on the current state of the pip screen.</p> * * @param mPipBoundsState current state of the pip screen */ @PipSizeSpec private static int getMaxOrDefaultPipSizeSpec(@NonNull PipBoundsState mPipBoundsState) { private static int getMaxOrDefaultPipSizeSpec(@NonNull PipBoundsState pipBoundsState) { // determine the average pip screen width int averageWidth = (mPipBoundsState.getMaxSize().x + mPipBoundsState.getMinSize().x) / 2; int averageWidth = (pipBoundsState.getMaxSize().x + pipBoundsState.getMinSize().x) / 2; // If pip screen width is above average, DEFAULT is the size spec we need to // toggle to. Otherwise, we choose MAX. return (mPipBoundsState.getBounds().width() > averageWidth) return (pipBoundsState.getBounds().width() > averageWidth) ? SIZE_SPEC_DEFAULT : SIZE_SPEC_MAX; } Loading @@ -77,35 +68,33 @@ public class PipDoubleTapHelper { /** * Determines the {@link PipSizeSpec} to toggle to on double tap. * * @param mPipBoundsState current state of the pip screen * @param pipBoundsState current state of the pip bounds * @param userResizeBounds latest user resized bounds (by pinching in/out) * @return pip screen size to switch to */ @PipSizeSpec public static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, public static int nextSizeSpec(@NonNull PipBoundsState pipBoundsState, @NonNull Rect userResizeBounds) { // is pip screen at its maximum boolean isScreenMax = mPipBoundsState.getBounds().width() == mPipBoundsState.getMaxSize().x; // is pip screen at its normal default size boolean isScreenDefault = (mPipBoundsState.getBounds().width() == mPipBoundsState.getNormalBounds().width()) && (mPipBoundsState.getBounds().height() == mPipBoundsState.getNormalBounds().height()); boolean isScreenMax = pipBoundsState.getBounds().width() == pipBoundsState.getMaxSize().x && pipBoundsState.getBounds().height() == pipBoundsState.getMaxSize().y; boolean isScreenDefault = (pipBoundsState.getBounds().width() == pipBoundsState.getNormalBounds().width()) && (pipBoundsState.getBounds().height() == pipBoundsState.getNormalBounds().height()); // edge case 1 // if user hasn't resized screen yet, i.e. CUSTOM size does not exist yet // or if user has resized exactly to DEFAULT, then we just want to maximize if (isScreenDefault && userResizeBounds.width() == mPipBoundsState.getNormalBounds().width()) { && userResizeBounds.width() == pipBoundsState.getNormalBounds().width() && userResizeBounds.height() == pipBoundsState.getNormalBounds().height()) { return SIZE_SPEC_MAX; } // edge case 2 // if user has maximized, then we want to toggle to DEFAULT // if user has resized to max, then we want to toggle to DEFAULT if (isScreenMax && userResizeBounds.width() == mPipBoundsState.getMaxSize().x) { && userResizeBounds.width() == pipBoundsState.getMaxSize().x && userResizeBounds.height() == pipBoundsState.getMaxSize().y) { return SIZE_SPEC_DEFAULT; } Loading @@ -113,9 +102,6 @@ public class PipDoubleTapHelper { if (isScreenDefault || isScreenMax) { return SIZE_SPEC_CUSTOM; } // if we are currently in user resized CUSTOM size state // then we toggle either to MAX or DEFAULT depending on the current pip screen state return getMaxOrDefaultPipSizeSpec(mPipBoundsState); return getMaxOrDefaultPipSizeSpec(pipBoundsState); } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +8 −1 Original line number Diff line number Diff line Loading @@ -180,10 +180,17 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange return; } WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setBounds(pipTaskToken, toBounds); if (configAtEnd) { wct.deferConfigToTransitionEnd(pipTaskToken); if (mPipBoundsState.getBounds().width() == toBounds.width() && mPipBoundsState.getBounds().height() == toBounds.height()) { // TODO (b/393159816): Config-at-End causes a flicker without size change. // If PiP size isn't changing enforce a minimal one-pixel change as a workaround. --toBounds.bottom; } } wct.setBounds(pipTaskToken, toBounds); mPipTransitionController.startResizeTransition(wct, duration); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java +1 −0 Original line number Diff line number Diff line Loading @@ -934,6 +934,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha } // the size to toggle to after a double tap mPipBoundsState.setNormalBounds(getAdjustedNormalBounds()); int nextSize = PipDoubleTapHelper .nextSizeSpec(mPipBoundsState, getUserResizeBounds()); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java +53 −110 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_DEFAU import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_MAX; import static com.android.wm.shell.common.pip.PipDoubleTapHelper.nextSizeSpec; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.graphics.Point; Loading @@ -41,131 +40,75 @@ import org.mockito.Mock; */ @RunWith(AndroidTestingRunner.class) public class PipDoubleTapHelperTest extends ShellTestCase { // represents the current pip window state and has information on current // max, min, and normal sizes @Mock private PipBoundsState mBoundStateMock; // tied to boundsStateMock.getBounds() in setUp() @Mock private Rect mBoundsMock; @Mock private PipBoundsState mMockPipBoundsState; // represents the most recent manually resized bounds // i.e. dimensions from the most recent pinch in/out @Mock private Rect mUserResizeBoundsMock; // Actual dimension guidelines of the PiP bounds. private static final int MAX_EDGE_SIZE = 100; private static final int DEFAULT_EDGE_SIZE = 60; private static final int MIN_EDGE_SIZE = 50; private static final int AVERAGE_EDGE_SIZE = (MAX_EDGE_SIZE + MIN_EDGE_SIZE) / 2; // actual dimensions of the pip screen bounds private static final int MAX_WIDTH = 100; private static final int DEFAULT_WIDTH = 40; private static final int MIN_WIDTH = 10; private static final int AVERAGE_WIDTH = (MAX_WIDTH + MIN_WIDTH) / 2; /** * Initializes mocks and assigns values for different pip screen bounds. */ @Before public void setUp() { // define pip bounds when(mBoundStateMock.getMaxSize()).thenReturn(new Point(MAX_WIDTH, 20)); when(mBoundStateMock.getMinSize()).thenReturn(new Point(MIN_WIDTH, 2)); when(mMockPipBoundsState.getMaxSize()).thenReturn(new Point(MAX_EDGE_SIZE, MAX_EDGE_SIZE)); when(mMockPipBoundsState.getMinSize()).thenReturn(new Point(MIN_EDGE_SIZE, MIN_EDGE_SIZE)); Rect rectMock = mock(Rect.class); when(rectMock.width()).thenReturn(DEFAULT_WIDTH); when(mBoundStateMock.getNormalBounds()).thenReturn(rectMock); final Rect normalBounds = new Rect(0, 0, DEFAULT_EDGE_SIZE, DEFAULT_EDGE_SIZE); when(mMockPipBoundsState.getNormalBounds()).thenReturn(normalBounds); } when(mBoundsMock.width()).thenReturn(DEFAULT_WIDTH); when(mBoundStateMock.getBounds()).thenReturn(mBoundsMock); @Test public void nextSizeSpec_resizedWiderThanAverage_returnDefaultThenCustom() { final int resizeEdgeSize = (MAX_EDGE_SIZE + AVERAGE_EDGE_SIZE) / 2; final Rect userResizeBounds = new Rect(0, 0, resizeEdgeSize, resizeEdgeSize); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_DEFAULT); // once we toggle to DEFAULT only PiP bounds state gets updated - not the user resize bounds when(mMockPipBoundsState.getBounds()).thenReturn( new Rect(0, 0, DEFAULT_EDGE_SIZE, DEFAULT_EDGE_SIZE)); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_CUSTOM); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to a larger than the average but not the maximum width, * then we toggle between {@code PipSizeSpec.CUSTOM} and {@code PipSizeSpec.DEFAULT} */ @Test public void testNextScreenSize_resizedWiderThanAverage_returnDefaultThenCustom() { // make the user resize width in between MAX and average when(mUserResizeBoundsMock.width()).thenReturn((MAX_WIDTH + AVERAGE_WIDTH) / 2); // make current bounds same as resized bound since no double tap yet when(mBoundsMock.width()).thenReturn((MAX_WIDTH + AVERAGE_WIDTH) / 2); // then nextScreenSize() i.e. double tapping should // toggle to DEFAULT state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_DEFAULT); // once we toggle to DEFAULT our screen size gets updated // but not the user resize bounds when(mBoundsMock.width()).thenReturn(DEFAULT_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to CUSTOM state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_CUSTOM); public void nextSizeSpec_resizedSmallerThanAverage_returnMaxThenCustom() { final int resizeEdgeSize = (AVERAGE_EDGE_SIZE + MIN_EDGE_SIZE) / 2; final Rect userResizeBounds = new Rect(0, 0, resizeEdgeSize, resizeEdgeSize); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_MAX); // Once we toggle to MAX our screen size gets updated but not the user resize bounds when(mMockPipBoundsState.getBounds()).thenReturn( new Rect(0, 0, MAX_EDGE_SIZE, MAX_EDGE_SIZE)); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_CUSTOM); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to a smaller than the average but not the default width, * then we toggle between {@code PipSizeSpec.CUSTOM} and {@code PipSizeSpec.MAX} */ @Test public void testNextScreenSize_resizedNarrowerThanAverage_returnMaxThenCustom() { // make the user resize width in between MIN and average when(mUserResizeBoundsMock.width()).thenReturn((MIN_WIDTH + AVERAGE_WIDTH) / 2); // make current bounds same as resized bound since no double tap yet when(mBoundsMock.width()).thenReturn((MIN_WIDTH + AVERAGE_WIDTH) / 2); // then nextScreenSize() i.e. double tapping should // toggle to MAX state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_MAX); // once we toggle to MAX our screen size gets updated // but not the user resize bounds when(mBoundsMock.width()).thenReturn(MAX_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to CUSTOM state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_CUSTOM); public void nextSizeSpec_resizedToMax_returnDefault() { final Rect userResizeBounds = new Rect(0, 0, MAX_EDGE_SIZE, MAX_EDGE_SIZE); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_DEFAULT); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to exactly the maximum width * then we toggle to {@code PipSizeSpec.DEFAULT} */ @Test public void testNextScreenSize_resizedToMax_returnDefault() { // the resized width is the same as MAX_WIDTH when(mUserResizeBoundsMock.width()).thenReturn(MAX_WIDTH); // the current bounds are also at MAX_WIDTH when(mBoundsMock.width()).thenReturn(MAX_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to DEFAULT state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_DEFAULT); public void nextSizeSpec_resizedToDefault_returnMax() { final Rect userResizeBounds = new Rect(0, 0, DEFAULT_EDGE_SIZE, DEFAULT_EDGE_SIZE); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_MAX); } @Test public void nextSizeSpec_resizedToAlmostMax_returnDefault() { final Rect userResizeBounds = new Rect(0, 0, MAX_EDGE_SIZE, MAX_EDGE_SIZE - 1); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_DEFAULT); } /** * Tests {@link PipDoubleTapHelper#nextSizeSpec(PipBoundsState, Rect)}. * * <p>when the user resizes the screen to exactly the default width * then we toggle to {@code PipSizeSpec.MAX} */ @Test public void testNextScreenSize_resizedToDefault_returnMax() { // the resized width is the same as DEFAULT_WIDTH when(mUserResizeBoundsMock.width()).thenReturn(DEFAULT_WIDTH); // the current bounds are also at DEFAULT_WIDTH when(mBoundsMock.width()).thenReturn(DEFAULT_WIDTH); // then nextScreenSize() i.e. double tapping should // toggle to MAX state Assert.assertSame(nextSizeSpec(mBoundStateMock, mUserResizeBoundsMock), SIZE_SPEC_MAX); public void nextSizeSpec_resizedToAlmostMin_returnMax() { final Rect userResizeBounds = new Rect(0, 0, MIN_EDGE_SIZE, MIN_EDGE_SIZE + 1); when(mMockPipBoundsState.getBounds()).thenReturn(userResizeBounds); Assert.assertEquals(nextSizeSpec(mMockPipBoundsState, userResizeBounds), SIZE_SPEC_MAX); } }