OSDN Git Service

Handle surfaceInset changes with deferred transactions.
authorRobert Carr <racarr@google.com>
Tue, 27 Feb 2018 01:46:00 +0000 (17:46 -0800)
committerRobert Carr <racarr@google.com>
Wed, 28 Feb 2018 19:44:14 +0000 (11:44 -0800)
First we have the client pass up the next frameNumber from relayoutWindow
and then we simply deferTransactions at the WindowState level until
this frame number is reached. This was always a little terrifying
because deferring transaction effecftively meant we gave up
control of the surface until the frame number was reached. However now
we can still control the surface from the stack and other SurfaceControl
nodes and so the window can still be moved around and animated even if
the client is unresponsive.

Bug: 70666541
Test: Manual. go/wm-smoke
Change-Id: I2fecbeaa30fc0eb9cc8f08e1ea734dcc65da0aa0

core/java/android/view/ViewRootImpl.java
core/java/android/view/WindowManager.java
services/core/java/com/android/server/wm/WindowState.java

index 01d9265..098583c 100644 (file)
@@ -6440,18 +6440,24 @@ public final class ViewRootImpl implements ViewParent,
             params.backup();
             mTranslator.translateWindowLayout(params);
         }
+
         if (params != null) {
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
-        }
 
-        if (params != null && mOrigWindowType != params.type) {
-            // For compatibility with old apps, don't crash here.
-            if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-                Slog.w(mTag, "Window type can not be changed after "
-                        + "the window is added; ignoring change of " + mView);
-                params.type = mOrigWindowType;
+            if (mOrigWindowType != params.type) {
+                // For compatibility with old apps, don't crash here.
+                if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+                    Slog.w(mTag, "Window type can not be changed after "
+                            + "the window is added; ignoring change of " + mView);
+                    params.type = mOrigWindowType;
+                }
+            }
+
+            if (mSurface.isValid()) {
+                params.frameNumber = mSurface.getNextFrameNumber();
             }
         }
+
         int relayoutResult = mWindowSession.relayout(
                 mWindow, mSeq, params,
                 (int) (mView.getMeasuredWidth() * appScale + 0.5f),
index c0a9666..e271701 100644 (file)
@@ -2371,6 +2371,13 @@ public interface WindowManager extends ViewManager {
         public long hideTimeoutMilliseconds = -1;
 
         /**
+         * A frame number in which changes requested in this layout will be rendered.
+         *
+         * @hide
+         */
+        public long frameNumber = -1;
+
+        /**
          * The color mode requested by this window. The target display may
          * not be able to honor the request. When the color mode is not set
          * to {@link ActivityInfo#COLOR_MODE_DEFAULT}, it might override the
@@ -2543,6 +2550,7 @@ public interface WindowManager extends ViewManager {
             TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
             out.writeInt(mColorMode);
             out.writeLong(hideTimeoutMilliseconds);
+            out.writeLong(frameNumber);
         }
 
         public static final Parcelable.Creator<LayoutParams> CREATOR
@@ -2599,6 +2607,7 @@ public interface WindowManager extends ViewManager {
             accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
             mColorMode = in.readInt();
             hideTimeoutMilliseconds = in.readLong();
+            frameNumber = in.readLong();
         }
 
         @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -2799,6 +2808,10 @@ public interface WindowManager extends ViewManager {
                 changes |= SURFACE_INSETS_CHANGED;
             }
 
+            // The frame number changing is only relevant in the context of other
+            // changes, and so we don't need to track it with a flag.
+            frameNumber = o.frameNumber;
+
             if (hasManualSurfaceInsets != o.hasManualSurfaceInsets) {
                 hasManualSurfaceInsets = o.hasManualSurfaceInsets;
                 changes |= SURFACE_INSETS_CHANGED;
index c0ab3f9..e1aa4fc 100644 (file)
@@ -4274,14 +4274,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
         // When we change the Surface size, in scenarios which may require changing
         // the surface position in sync with the resize, we use a preserved surface
         // so we can freeze it while waiting for the client to report draw on the newly
-        // sized surface.  Don't preserve surfaces if the insets change while animating the pinned
-        // stack since it can lead to issues if a new surface is created while calculating the
-        // scale for the animation using the source hint rect
-        // (see WindowStateAnimator#setSurfaceBoundariesLocked()).
-        if (isDragResizeChanged()
-                || (surfaceInsetsChanging() && !inPinnedWindowingMode())) {
-            mLastSurfaceInsets.set(mAttrs.surfaceInsets);
-
+        // sized surface. At the moment this logic is only in place for switching
+        // in and out of the big surface for split screen resize.
+        if (isDragResizeChanged()) {
             setDragResizing();
             // We can only change top level windows to the full-screen surface when
             // resizing (as we only have one full-screen surface). So there is no need
@@ -4529,9 +4524,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
         }
 
         transformFrameToSurfacePosition(mFrame.left, mFrame.top, mSurfacePosition);
+
         if (!mSurfaceAnimator.hasLeash() && !mLastSurfacePosition.equals(mSurfacePosition)) {
             t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y);
             mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
+            if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) {
+                mLastSurfaceInsets.set(mAttrs.surfaceInsets);
+                t.deferTransactionUntil(mSurfaceControl,
+                        mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
+                        mAttrs.frameNumber);
+            }
         }
     }