Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6d5af55 authored by Robert Carr's avatar Robert Carr
Browse files

Handle surfaceInset changes with deferred transactions.

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
parent 74a66a2c
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -6440,11 +6440,11 @@ 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) {
            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 "
@@ -6452,6 +6452,12 @@ public final class ViewRootImpl implements ViewParent,
                    params.type = mOrigWindowType;
                }
            }

            if (mSurface.isValid()) {
                params.frameNumber = mSurface.getNextFrameNumber();
            }
        }

        int relayoutResult = mWindowSession.relayout(
                mWindow, mSeq, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
+13 −0
Original line number Diff line number Diff line
@@ -2370,6 +2370,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
@@ -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;
+10 −8
Original line number Diff line number Diff line
@@ -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);
            }
        }
    }