summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java50
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java163
4 files changed, 80 insertions, 143 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java
index 4cbb78f2dae2..d36201a4ac9e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java
@@ -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;
}
@@ -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;
}
@@ -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);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index f81f330e50c4..a02a51f92b1b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -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);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 6fdfecaf15d5..d1bc450c3c4d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -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());
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
index 1756aad8fc9b..cc23d9a75fcd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
@@ -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;
@@ -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;
-
- // represents the most recent manually resized bounds
- // i.e. dimensions from the most recent pinch in/out
- @Mock private Rect mUserResizeBoundsMock;
-
- // 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.
- */
+ @Mock private PipBoundsState mMockPipBoundsState;
+
+ // 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;
+
@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);
+ }
+
+ @Test
+ 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 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_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 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_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);
}
- /**
- * 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_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);
}
}