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
This commit is contained in:
Riddle Hsu
2022-07-26 23:17:17 +08:00
parent 619befaa31
commit db7b35a070

View File

@@ -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) {
op.mDrawTransaction = postDrawTransaction;
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);
}