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

Commit 2ff244d1 authored by Evan Rosky's avatar Evan Rosky
Browse files

Always apply postDrawTransaction started during sync

ViewRootImpl tracks the full lifetime of all sync buffers.
This means its important to apply all transactions which have
a sync buffer or ViewRootImpl will not draw new frames.

This CL makes it so that even if a window is no-longer in a
sync-set, the post-draw transaction will be applied as long
as it was in a sync transaction at the time it was requested.

Bug: 183993924
Test: atest WindowUntrustedTouchTest
Change-Id: Id89d039328bd9b091d4ed78a1616bc78d1bd83fa
parent e7b68347
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -371,6 +371,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    private int mResizeMode;
    private boolean mRedrawForSyncReported;

    /**
     * {@code true} when the client was still drawing for sync when the sync-set was finished or
     * cancelled. This can happen if the window goes away during a sync. In this situation we need
     * to make sure to still apply the postDrawTransaction when it finishes to prevent the client
     * from getting stuck in a bad state.
     */
    boolean mClientWasDrawingForSync = false;

    /**
     * Special mode that is intended only for the rounded corner overlay: during rotation
     * transition, we un-rotate the window token such that the window appears as it did before the
@@ -6009,6 +6017,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return super.isSyncFinished();
    }

    @Override
    void finishSync(Transaction outMergedTransaction, boolean cancel) {
        if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW && mRedrawForSyncReported) {
            mClientWasDrawingForSync = true;
        }
        super.finishSync(outMergedTransaction, cancel);
    }

    boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction) {
        if (mOrientationChangeRedrawRequestTime > 0) {
            final long duration =
@@ -6024,8 +6040,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        }

        executeDrawHandlers(postDrawTransaction);

        final boolean applyPostDrawNow = mClientWasDrawingForSync && postDrawTransaction != null;
        mClientWasDrawingForSync = false;
        if (!onSyncFinishedDrawing()) {
            return mWinAnimator.finishDrawingLocked(postDrawTransaction);
            return mWinAnimator.finishDrawingLocked(postDrawTransaction, applyPostDrawNow);
        }

        if (mActivityRecord != null
@@ -6039,7 +6058,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            mSyncTransaction.merge(postDrawTransaction);
        }

        mWinAnimator.finishDrawingLocked(null);
        mWinAnimator.finishDrawingLocked(null, false /* forceApplyNow */);
        // We always want to force a traversal after a finish draw for blast sync.
        return true;
    }
+4 −3
Original line number Diff line number Diff line
@@ -228,7 +228,8 @@ class WindowStateAnimator {
        }
    }

    boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
    boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction,
            boolean forceApplyNow) {
        final boolean startingWindow =
                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
        if (startingWindow) {
@@ -253,11 +254,11 @@ class WindowStateAnimator {
            // If there is no surface, the last draw was for the previous surface. We don't want to
            // wait until the new surface is shown and instead just apply the transaction right
            // away.
            if (mLastHidden && mDrawState != NO_SURFACE) {
            if (mLastHidden && mDrawState != NO_SURFACE && !forceApplyNow) {
                mPostDrawTransaction.merge(postDrawTransaction);
                layoutNeeded = true;
            } else {
                postDrawTransaction.apply();
                mWin.getSyncTransaction().merge(postDrawTransaction);
            }
        }