From 604ef951ce5704910c6367a622dcd4a6a0123703 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 15 May 2018 20:13:13 +0200 Subject: [PATCH] PIP: Fix transition to and from PiP when letterboxed When an app is letterboxed, it cannot always take up the full task bounds, and we need to constrain the PIP animations to the constraints imposed by the layout. Change-Id: If238ddfb4462c7e1e5c975f76666ad1d4ec3b076 Fixes: 77802617 Test: Enable cutout emulation, enter landscape, verify transitions both into and out of pip work as intended. Test: atest ActivityManagerPinnedStackTests --- services/core/java/com/android/server/wm/WindowState.java | 13 ++++++++++++- .../java/com/android/server/wm/WindowStateAnimator.java | 7 +++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 91c449ba3832..4e12daf7348c 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -409,7 +409,7 @@ class WindowState extends WindowContainer implements WindowManagerP final Rect mContainingFrame = new Rect(); - private final Rect mParentFrame = new Rect(); + final Rect mParentFrame = new Rect(); /** Whether the parent frame would have been different if there was no display cutout. */ private boolean mParentFrameWasClippedByDisplayCutout; @@ -931,6 +931,17 @@ class WindowState extends WindowContainer implements WindowManagerP mContainingFrame.set(contentFrame); } } + + final TaskStack stack = getStack(); + if (inPinnedWindowingMode() && stack != null + && stack.lastAnimatingBoundsWasToFullscreen()) { + // PIP edge case: When going from pinned to fullscreen, we apply a + // tempInsetFrame for the full task - but we're still at the start of the animation. + // To prevent a jump if there's a letterbox, restrict to the parent frame. + mInsetFrame.intersectUnchecked(parentFrame); + mContainingFrame.intersectUnchecked(parentFrame); + } + mDisplayFrame.set(mContainingFrame); layoutXDiff = !mInsetFrame.isEmpty() ? mInsetFrame.left - mContainingFrame.left : 0; layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0; diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 4a6587bcc8af..c44a5820e92c 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -927,6 +927,13 @@ class WindowStateAnimator { mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets); allowStretching = true; } + + // Make sure that what we're animating to and from is actually the right size in case + // the window cannot take up the full screen. + mTmpStackBounds.intersectUnchecked(w.mParentFrame); + mTmpSourceBounds.intersectUnchecked(w.mParentFrame); + mTmpAnimatingBounds.intersectUnchecked(w.mParentFrame); + if (!mTmpSourceBounds.isEmpty()) { // Get the final target stack bounds, if we are not animating, this is just the // current stack bounds -- 2.11.0