ViewRootImpl: Ensure seqId only increases

We could process an earlier scheduled MSG_RESIZED after
a later executed relayoutWindow. In this case we might
accidentally move the seqId backwards, which could mess
up our logic. While we are touching this area, we
take the opportunity to ensure SyncHandlers execute
in the order they were added.

Bug: 161810301
Bug: 227561299
Test: Existing tests pass
Change-Id: I8e5ceea1ef34e4da94807582c89a33df95772c04
This commit is contained in:
Robert Carr
2022-04-04 12:19:50 -07:00
committed by Rob Carr
parent a7b858cd2d
commit 25bdf74a0b
2 changed files with 15 additions and 5 deletions

View File

@@ -1742,7 +1742,7 @@ public final class ViewRootImpl implements ViewParent,
mForceNextWindowRelayout = forceNextWindowRelayout; mForceNextWindowRelayout = forceNextWindowRelayout;
mPendingAlwaysConsumeSystemBars = args.argi2 != 0; mPendingAlwaysConsumeSystemBars = args.argi2 != 0;
mSyncSeqId = args.argi4; mSyncSeqId = args.argi4 > mSyncSeqId ? args.argi4 : mSyncSeqId;
if (msg == MSG_RESIZED_REPORT) { if (msg == MSG_RESIZED_REPORT) {
reportNextDraw(); reportNextDraw();
@@ -7986,7 +7986,10 @@ public final class ViewRootImpl implements ViewParent,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mRelayoutBundle); mTempControls, mRelayoutBundle);
mSyncSeqId = mRelayoutBundle.getInt("seqid"); final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid");
if (maybeSyncSeqId > 0) {
mSyncSeqId = maybeSyncSeqId;
}
if (mTranslator != null) { if (mTranslator != null) {
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);

View File

@@ -6125,14 +6125,21 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
applyHere = true; applyHere = true;
} }
for (int i = mDrawHandlers.size() - 1; i >= 0; i--) { final List<DrawHandler> handlersToRemove = new ArrayList<>();
DrawHandler h = mDrawHandlers.get(i); // Iterate forwards to ensure we process in the same order
// we added.
for (int i = 0; i < mDrawHandlers.size(); i++) {
final DrawHandler h = mDrawHandlers.get(i);
if (h.mSeqId <= seqId) { if (h.mSeqId <= seqId) {
h.mConsumer.accept(t); h.mConsumer.accept(t);
mDrawHandlers.remove(h); handlersToRemove.add(h);
hadHandlers = true; hadHandlers = true;
} }
} }
for (int i = 0; i < handlersToRemove.size(); i++) {
final DrawHandler h = handlersToRemove.get(i);
mDrawHandlers.remove(h);
}
if (hadHandlers) { if (hadHandlers) {
mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this); mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);