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

Commit c58e1df6 authored by Yunfan Chen's avatar Yunfan Chen
Browse files

Use the layout frame to decide whether to do a server sync

When the shell side resize/reposition happens, the relayout won't happen
until the next traversal happens. However, the mWinFrame will be updated
directly before the relayout happens. When that's happening, the
relayout may miss the actual resize/reposition from the shell.

Test: See b/266582561. Check the unfold compat mode.
Bug: 266582561
Change-Id: I059db87e0bb61ddc4efcc8e1f67e4fa532c4e5a9
parent 0e4f1e13
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -78,7 +78,6 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
@@ -712,6 +711,7 @@ public final class ViewRootImpl implements ViewParent,

    // These are accessed by multiple threads.
    final Rect mWinFrame; // frame given by window manager.
    private final Rect mLastLayoutFrame;
    Rect mOverrideInsetsFrame;

    final Rect mPendingBackDropFrame = new Rect();
@@ -932,6 +932,7 @@ public final class ViewRootImpl implements ViewParent,
        mHeight = -1;
        mDirty = new Rect();
        mWinFrame = new Rect();
        mLastLayoutFrame = new Rect();
        mWindow = new W(this);
        mLeashToken = new Binder();
        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
@@ -1303,7 +1304,7 @@ public final class ViewRootImpl implements ViewParent,
                        UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH,
                        mInsetsController.getRequestedVisibilities(), 1f /* compactScale */,
                        mTmpFrames);
                setFrame(mTmpFrames.frame);
                setFrame(mTmpFrames.frame, true /* withinRelayout */);
                registerBackCallbackOnWindow();
                if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
                    // For apps requesting legacy back behavior, we add a compat callback that
@@ -1824,7 +1825,7 @@ public final class ViewRootImpl implements ViewParent,
            onMovedToDisplay(displayId, mLastConfigurationFromResources);
        }

        setFrame(frame);
        setFrame(frame, false /* withinRelayout */);
        mTmpFrames.displayFrame.set(displayFrame);
        if (mTmpFrames.attachedFrame != null && attachedFrame != null) {
            mTmpFrames.attachedFrame.set(attachedFrame);
@@ -5740,7 +5741,7 @@ public final class ViewRootImpl implements ViewParent,
                        mTmpFrames.frame.right = l + w;
                        mTmpFrames.frame.top = t;
                        mTmpFrames.frame.bottom = t + h;
                        setFrame(mTmpFrames.frame);
                        setFrame(mTmpFrames.frame, false /* withinRelayout */);
                        maybeHandleWindowMove(mWinFrame);
                    }
                    break;
@@ -8210,7 +8211,7 @@ public final class ViewRootImpl implements ViewParent,
            // If the position and the size of the frame are both changed, it will trigger a BLAST
            // sync, and we still need to call relayout to obtain the syncSeqId. Otherwise, we just
            // need to send attributes via relayoutAsync.
            final Rect oldFrame = mWinFrame;
            final Rect oldFrame = mLastLayoutFrame;
            final Rect newFrame = mTmpFrames.frame;
            final boolean positionChanged =
                    newFrame.top != oldFrame.top || newFrame.left != oldFrame.left;
@@ -8340,7 +8341,7 @@ public final class ViewRootImpl implements ViewParent,
            params.restore();
        }

        setFrame(mTmpFrames.frame);
        setFrame(mTmpFrames.frame, true /* withinRelayout */);
        return relayoutResult;
    }

@@ -8375,8 +8376,18 @@ public final class ViewRootImpl implements ViewParent,
        mIsSurfaceOpaque = opaque;
    }

    private void setFrame(Rect frame) {
    /**
     * Set the mWinFrame of this window.
     * @param frame the new frame of this window.
     * @param withinRelayout {@code true} if this setting is within the relayout, or is the initial
     *                       setting. That will make sure in the relayout process, we always compare
     *                       the window frame with the last processed window frame.
     */
    private void setFrame(Rect frame, boolean withinRelayout) {
        mWinFrame.set(frame);
        if (withinRelayout) {
            mLastLayoutFrame.set(frame);
        }

        final WindowConfiguration winConfig = getCompatWindowConfiguration();
        mPendingBackDropFrame.set(mPendingDragResizing && !winConfig.useWindowFrameForBackdrop()