diff options
5 files changed, 49 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9bc4389282fc..d1c703e101dd 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -11157,8 +11157,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean cancel) { // This override is just for getting metrics. allFinished needs to be checked before // finish because finish resets all the states. - final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup(); - if (syncGroup != null && group != getSyncGroup()) return; + if (isDifferentSyncGroup(group)) return; mLastAllReadyAtSync = allSyncFinished(); super.finishSync(outMergedTransaction, group, cancel); } diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java index e8faff621165..a8cc2ae161cf 100644 --- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java +++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java @@ -348,6 +348,11 @@ class BLASTSyncEngine { wc.setSyncGroup(this); } wc.prepareSync(); + if (wc.mSyncState == WindowContainer.SYNC_STATE_NONE && wc.mSyncGroup != null) { + Slog.w(TAG, "addToSync: unset SyncGroup " + wc.mSyncGroup.mSyncId + + " for non-sync " + wc); + wc.mSyncGroup = null; + } if (mReady) { mWm.mWindowPlacerLocked.requestTraversal(); } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 6dbd259b67c0..1f31af68c693 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -3986,6 +3986,19 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } /** + * Returns {@code true} if this window container belongs to a different sync group than the + * given group. + */ + boolean isDifferentSyncGroup(@Nullable BLASTSyncEngine.SyncGroup group) { + if (group == null) return false; + final BLASTSyncEngine.SyncGroup thisGroup = getSyncGroup(); + if (thisGroup == null || group == thisGroup) return false; + Slog.d(TAG, this + " uses a different SyncGroup, current=" + thisGroup.mSyncId + + " given=" + group.mSyncId); + return true; + } + + /** * Recursively finishes/cleans-up sync state of this subtree and collects all the sync * transactions into `outMergedTransaction`. * @param outMergedTransaction A transaction to merge all the recorded sync operations into. @@ -3994,10 +4007,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< */ void finishSync(Transaction outMergedTransaction, @Nullable BLASTSyncEngine.SyncGroup group, boolean cancel) { - if (mSyncState == SYNC_STATE_NONE) return; - final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup(); - // If it's null, then we need to clean-up anyways. - if (syncGroup != null && group != syncGroup) return; + if (mSyncState == SYNC_STATE_NONE) { + if (mSyncGroup != null) { + Slog.e(TAG, "finishSync: stale group " + mSyncGroup.mSyncId + " of " + this); + mSyncGroup = null; + } + return; + } + if (isDifferentSyncGroup(group)) return; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "finishSync cancel=%b for %s", cancel, this); outMergedTransaction.merge(mSyncTransaction); for (int i = mChildren.size() - 1; i >= 0; --i) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index dcd4bd68c3fc..a24ed6fb7932 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5791,8 +5791,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override void finishSync(Transaction outMergedTransaction, BLASTSyncEngine.SyncGroup group, boolean cancel) { - final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup(); - if (syncGroup != null && group != syncGroup) return; + if (isDifferentSyncGroup(group)) return; mPrepareSyncSeqId = 0; if (cancel) { // This is leaving sync so any buffers left in the sync have a chance of diff --git a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java index 6c5f9752b6fc..1c32980aac91 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java @@ -33,6 +33,7 @@ import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -417,6 +418,22 @@ public class SyncEngineTests extends WindowTestsBase { } @Test + public void testSkipPrepareSync() { + final TestWindowContainer wc = new TestWindowContainer(mWm, true /* waiter */); + wc.mSkipPrepareSync = true; + final BLASTSyncEngine bse = createTestBLASTSyncEngine(); + final BLASTSyncEngine.SyncGroup syncGroup = bse.prepareSyncSet( + mock(BLASTSyncEngine.TransactionReadyListener.class), "test"); + bse.startSyncSet(syncGroup); + bse.addToSyncSet(syncGroup.mSyncId, wc); + assertEquals(SYNC_STATE_NONE, wc.mSyncState); + // If the implementation of prepareSync doesn't set sync state, the sync group should also + // be empty. + assertNull(wc.mSyncGroup); + assertTrue(wc.isSyncFinished(syncGroup)); + } + + @Test public void testNonBlastMethod() { mAppWindow = createWindow(null, TYPE_BASE_APPLICATION, "mAppWindow"); @@ -694,6 +711,7 @@ public class SyncEngineTests extends WindowTestsBase { final boolean mWaiter; boolean mVisibleRequested = true; boolean mFillsParent = false; + boolean mSkipPrepareSync = false; TestWindowContainer(WindowManagerService wms, boolean waiter) { super(wms); @@ -703,6 +721,9 @@ public class SyncEngineTests extends WindowTestsBase { @Override boolean prepareSync() { + if (mSkipPrepareSync) { + return false; + } if (!super.prepareSync()) { return false; } |