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

Commit db7b35a0 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Make a copy for draw transaction of local window

Because local window means that ViewRootImpl lives in the same
process. The transaction sent from ViewRootImpl#reportDrawFinished
is the same instance as WindowState#finishDrawing receives.

Then if the transaction is cleared before applying, the blast sync
will be broken and block render thread.

Bug: 234585256
Test: adb shell setprop persist.wm.debug.shell_transit 1; reboot
      Enable "Pointer location" in developer options.
      Rotate display many times and no any timeout.

Change-Id: I111c44b9100771b38fe60f07735e93778458c502
parent 619befaa
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -204,11 +204,8 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
            final WindowToken token = mTargetWindowTokens.keyAt(i);
            for (int j = token.getChildCount() - 1; j >= 0; j--) {
                // TODO(b/234585256): The consumer should be handleFinishDrawing(). And check why
                //  the local window might easily time out.
                final WindowState w = token.getChildAt(j);
                if (w.isClientLocal()) continue;
                w.applyWithNextDraw(t -> {});
                // TODO(b/234585256): The consumer should be handleFinishDrawing().
                token.getChildAt(j).applyWithNextDraw(t -> {});
            }
        }
        mIsSyncDrawRequested = true;
@@ -484,7 +481,16 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        if (op == null) return false;
        if (DEBUG) Slog.d(TAG, "handleFinishDrawing " + w);
        if (op.mDrawTransaction == null) {
            if (w.isClientLocal()) {
                // Use a new transaction to merge the draw transaction of local window because the
                // same instance will be cleared (Transaction#clear()) after reporting draw.
                op.mDrawTransaction = mService.mTransactionFactory.get();
                op.mDrawTransaction.merge(postDrawTransaction);
            } else {
                // The transaction read from parcel (the client is in a different process) is
                // already a copy, so just reference it directly.
                op.mDrawTransaction = postDrawTransaction;
            }
        } else {
            op.mDrawTransaction.merge(postDrawTransaction);
        }