Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithm.java +6 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,12 @@ public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithmInterfac Rect startingBounds = pipBoundsState.getBounds().isEmpty() ? pipBoundsAlgorithm.getEntryDestinationBoundsIgnoringKeepClearAreas() : pipBoundsState.getBounds(); // If IME is not showing and restore bounds (pre-IME bounds) is not empty, we should set PiP // bounds to the restore bounds. if (!pipBoundsState.isImeShowing() && !pipBoundsState.getRestoreBounds().isEmpty()) { startingBounds.set(pipBoundsState.getRestoreBounds()); pipBoundsState.clearRestoreBounds(); } Rect insets = new Rect(); pipBoundsAlgorithm.getInsetBounds(insets); if (pipBoundsState.isImeShowing()) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java +23 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ public class PipBoundsState { @NonNull private final Rect mExpandedBounds = new Rect(); @NonNull private final Rect mNormalMovementBounds = new Rect(); @NonNull private final Rect mExpandedMovementBounds = new Rect(); @NonNull private final Rect mRestoreBounds = new Rect(); @NonNull private final PipDisplayLayoutState mPipDisplayLayoutState; private final Point mMaxSize = new Point(); private final Point mMinSize = new Point(); Loading Loading @@ -404,6 +405,10 @@ public class PipBoundsState { public void setImeVisibility(boolean imeShowing, int imeHeight) { mIsImeShowing = imeShowing; mImeHeight = imeHeight; // If IME is showing, save the current PiP bounds in case we need to restore it later. if (mIsImeShowing) { mRestoreBounds.set(getBounds()); } } /** Returns whether the IME is currently showing. */ Loading @@ -411,6 +416,16 @@ public class PipBoundsState { return mIsImeShowing; } /** Returns the bounds to restore PiP to (bounds before IME was expanded). */ public Rect getRestoreBounds() { return mRestoreBounds; } /** Sets mRestoreBounds to (0,0,0,0). */ public void clearRestoreBounds() { mRestoreBounds.setEmpty(); } /** Returns the IME height. */ public int getImeHeight() { return mImeHeight; Loading Loading @@ -521,6 +536,10 @@ public class PipBoundsState { /** Set whether the user has resized the PIP. */ public void setHasUserResizedPip(boolean hasUserResizedPip) { mHasUserResizedPip = hasUserResizedPip; // If user resized PiP while IME is showing, clear the pre-IME restore bounds. if (hasUserResizedPip && isImeShowing()) { clearRestoreBounds(); } } /** Returns whether the user has moved the PIP. */ Loading @@ -531,6 +550,10 @@ public class PipBoundsState { /** Set whether the user has moved the PIP. */ public void setHasUserMovedPip(boolean hasUserMovedPip) { mHasUserMovedPip = hasUserMovedPip; // If user moved PiP while IME is showing, clear the pre-IME restore bounds. if (hasUserMovedPip && isImeShowing()) { clearRestoreBounds(); } } /** Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java +46 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -127,6 +128,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -145,6 +147,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Loading @@ -164,6 +167,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Loading @@ -185,6 +189,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -205,6 +210,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -227,6 +233,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.bottom - 100, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -249,6 +256,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.bottom - 100, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -269,6 +277,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -289,6 +298,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -301,4 +311,40 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { assertEquals(expected, outBounds); } @Test public void adjust_restoreBoundsPresent_appliesRestoreBounds() { final Rect pipBounds = new Rect(0, 0, 100, 100); final Rect restoreBounds = new Rect(50, 50, 150, 150); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(restoreBounds); when(mMockPipBoundsState.hasUserMovedPip()).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(restoreBounds, outBounds); } @Test public void adjust_restoreBoundsCleared_boundsUnchanged() { final Rect pipBounds = new Rect(0, 0, 100, 100); final Rect restoreBounds = new Rect(0, 0, 0, 0); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(restoreBounds); when(mMockPipBoundsState.hasUserMovedPip()).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(pipBounds, outBounds); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithm.java +6 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,12 @@ public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithmInterfac Rect startingBounds = pipBoundsState.getBounds().isEmpty() ? pipBoundsAlgorithm.getEntryDestinationBoundsIgnoringKeepClearAreas() : pipBoundsState.getBounds(); // If IME is not showing and restore bounds (pre-IME bounds) is not empty, we should set PiP // bounds to the restore bounds. if (!pipBoundsState.isImeShowing() && !pipBoundsState.getRestoreBounds().isEmpty()) { startingBounds.set(pipBoundsState.getRestoreBounds()); pipBoundsState.clearRestoreBounds(); } Rect insets = new Rect(); pipBoundsAlgorithm.getInsetBounds(insets); if (pipBoundsState.isImeShowing()) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java +23 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ public class PipBoundsState { @NonNull private final Rect mExpandedBounds = new Rect(); @NonNull private final Rect mNormalMovementBounds = new Rect(); @NonNull private final Rect mExpandedMovementBounds = new Rect(); @NonNull private final Rect mRestoreBounds = new Rect(); @NonNull private final PipDisplayLayoutState mPipDisplayLayoutState; private final Point mMaxSize = new Point(); private final Point mMinSize = new Point(); Loading Loading @@ -404,6 +405,10 @@ public class PipBoundsState { public void setImeVisibility(boolean imeShowing, int imeHeight) { mIsImeShowing = imeShowing; mImeHeight = imeHeight; // If IME is showing, save the current PiP bounds in case we need to restore it later. if (mIsImeShowing) { mRestoreBounds.set(getBounds()); } } /** Returns whether the IME is currently showing. */ Loading @@ -411,6 +416,16 @@ public class PipBoundsState { return mIsImeShowing; } /** Returns the bounds to restore PiP to (bounds before IME was expanded). */ public Rect getRestoreBounds() { return mRestoreBounds; } /** Sets mRestoreBounds to (0,0,0,0). */ public void clearRestoreBounds() { mRestoreBounds.setEmpty(); } /** Returns the IME height. */ public int getImeHeight() { return mImeHeight; Loading Loading @@ -521,6 +536,10 @@ public class PipBoundsState { /** Set whether the user has resized the PIP. */ public void setHasUserResizedPip(boolean hasUserResizedPip) { mHasUserResizedPip = hasUserResizedPip; // If user resized PiP while IME is showing, clear the pre-IME restore bounds. if (hasUserResizedPip && isImeShowing()) { clearRestoreBounds(); } } /** Returns whether the user has moved the PIP. */ Loading @@ -531,6 +550,10 @@ public class PipBoundsState { /** Set whether the user has moved the PIP. */ public void setHasUserMovedPip(boolean hasUserMovedPip) { mHasUserMovedPip = hasUserMovedPip; // If user moved PiP while IME is showing, clear the pre-IME restore bounds. if (hasUserMovedPip && isImeShowing()) { clearRestoreBounds(); } } /** Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java +46 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -127,6 +128,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -145,6 +147,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Loading @@ -164,6 +167,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { 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.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); when(mMockPipBoundsState.getRestrictedKeepClearAreas()).thenReturn(Set.of(keepClearRect)); doAnswer(invocation -> { Loading @@ -185,6 +189,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -205,6 +210,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -227,6 +233,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.bottom - 100, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -249,6 +256,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { DISPLAY_BOUNDS.right - 100, DISPLAY_BOUNDS.bottom - 100, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); arg0.set(DISPLAY_BOUNDS); Loading @@ -269,6 +277,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -289,6 +298,7 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { final Rect expected = new Rect( 0, DISPLAY_BOUNDS.bottom - 100, 100, DISPLAY_BOUNDS.bottom); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(new Rect(0, 0, 0, 0)); when(mMockPipBoundsState.isStashed()).thenReturn(true); doAnswer(invocation -> { Rect arg0 = invocation.getArgument(0); Loading @@ -301,4 +311,40 @@ public class PhonePipKeepClearAlgorithmTest extends ShellTestCase { assertEquals(expected, outBounds); } @Test public void adjust_restoreBoundsPresent_appliesRestoreBounds() { final Rect pipBounds = new Rect(0, 0, 100, 100); final Rect restoreBounds = new Rect(50, 50, 150, 150); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(restoreBounds); when(mMockPipBoundsState.hasUserMovedPip()).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(restoreBounds, outBounds); } @Test public void adjust_restoreBoundsCleared_boundsUnchanged() { final Rect pipBounds = new Rect(0, 0, 100, 100); final Rect restoreBounds = new Rect(0, 0, 0, 0); when(mMockPipBoundsState.getBounds()).thenReturn(pipBounds); when(mMockPipBoundsState.getRestoreBounds()).thenReturn(restoreBounds); when(mMockPipBoundsState.hasUserMovedPip()).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(pipBounds, outBounds); } }