OSDN Git Service

PIP: Fix transition to and from PiP when letterboxed
authorAdrian Roos <roosa@google.com>
Tue, 15 May 2018 18:13:13 +0000 (20:13 +0200)
committerAdrian Roos <roosa@google.com>
Fri, 18 May 2018 12:38:07 +0000 (12:38 +0000)
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
services/core/java/com/android/server/wm/WindowStateAnimator.java

index 91c449b..4e12daf 100644 (file)
@@ -409,7 +409,7 @@ class WindowState extends WindowContainer<WindowState> 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<WindowState> 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;
index 4a6587b..c44a582 100644 (file)
@@ -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