From 4ef153a7970c64f3cb997c408b41465e3e9ef36f Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Tue, 2 Nov 2021 17:32:44 -0700 Subject: [PATCH] PiP: Recalculate size if too big/small on display change. On display changes, it is possible that the old bounds is now too big or too small for the new display. This is especially like on foldables, such as a min size on a folded state is too big when in an unfolded state. Bug: 198679951 Test: Fold, minimal size, then unfold - see size change, and resizing now doesn't jump to from too small -> small Change-Id: I5de64860f1fbb476ff1a6a8dd9a0c50fd3259a45 --- .../wm/shell/pip/phone/PipController.java | 21 +++++++++++++++---- .../wm/shell/pip/phone/PipMotionHelper.java | 9 ++++++++ .../wm/shell/pip/phone/PipControllerTest.java | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 8e5c5c52cb3fe..685e8851f9f75 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -474,12 +474,25 @@ public class PipController implements PipTransitionController.PipTransitionCallb if (mPipTaskOrganizer.isInPip() && saveRestoreSnapFraction) { // Calculate the snap fraction of the current stack along the old movement bounds final PipSnapAlgorithm pipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm(); - final Rect postChangeStackBounds = new Rect(mPipBoundsState.getBounds()); - final float snapFraction = pipSnapAlgorithm.getSnapFraction(postChangeStackBounds, - mPipBoundsAlgorithm.getMovementBounds(postChangeStackBounds), + final float snapFraction = pipSnapAlgorithm.getSnapFraction(mPipBoundsState.getBounds(), + mPipBoundsAlgorithm.getMovementBounds(mPipBoundsState.getBounds()), mPipBoundsState.getStashedState()); updateDisplayLayout.run(); + final Rect postChangeStackBounds; + if (mPipBoundsState.getBounds() != null + && (mPipBoundsState.getBounds().width() > mPipBoundsState.getMaxSize().x + || mPipBoundsState.getBounds().height() > mPipBoundsState.getMaxSize().y)) { + postChangeStackBounds = new Rect(0, 0, mPipBoundsState.getMaxSize().x, + mPipBoundsState.getMaxSize().y); + } else if (mPipBoundsState.getBounds() != null + && (mPipBoundsState.getBounds().width() < mPipBoundsState.getMinSize().x + || mPipBoundsState.getBounds().height() < mPipBoundsState.getMinSize().y)) { + postChangeStackBounds = new Rect(0, 0, mPipBoundsState.getMinSize().x, + mPipBoundsState.getMinSize().y); + } else { + postChangeStackBounds = new Rect(mPipBoundsState.getBounds()); + } // Calculate the stack bounds in the new orientation based on same fraction along the // rotated movement bounds. @@ -491,7 +504,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb mPipBoundsState.getDisplayBounds(), mPipBoundsState.getDisplayLayout().stableInsets()); - mTouchHandler.getMotionHelper().movePip(postChangeStackBounds); + mTouchHandler.getMotionHelper().animateResizedBounds(postChangeStackBounds); } else { updateDisplayLayout.run(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index c42750d62dd4b..dbd09fd7b2650 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -69,6 +69,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private static final int UNSTASH_DURATION = 250; private static final int LEAVE_PIP_DURATION = 300; private static final int SHIFT_DURATION = 300; + private static final int ANIMATE_PIP_RESIZE_ANIMATION = 250; /** Friction to use for PIP when it moves via physics fling animations. */ private static final float DEFAULT_FRICTION = 1.9f; @@ -540,6 +541,14 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, resizeAndAnimatePipUnchecked(unstashedBounds, UNSTASH_DURATION); } + /** + * Animates the PiP from an old bound to a new bound. This is mostly used when display + * has changed and PiP bounds needs to be changed. + */ + void animateResizedBounds(Rect newBounds) { + resizeAndAnimatePipUnchecked(newBounds, ANIMATE_PIP_RESIZE_ANIMATION); + } + /** * Animates the PiP to offset it from the IME or shelf. */ diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index 935f6695538de..c2f58b8b62662 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -191,7 +191,7 @@ public class PipControllerTest extends ShellTestCase { mPipController.mDisplaysChangedListener.onDisplayConfigurationChanged( displayId, new Configuration()); - verify(mMockPipMotionHelper).movePip(any(Rect.class)); + verify(mMockPipMotionHelper).animateResizedBounds(any(Rect.class)); } @Test