From 8ccc4fcf76025d649b0795f94167a67cc0ae6f23 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Fri, 13 Mar 2020 10:48:49 -0700 Subject: [PATCH] BLASTSyncEngine: Disable overlapping calls to a single container Currently we only keep one copy of mWaitingListener and mBLASTSyncTransaction per level of the hierarchy and so we are unable to support multiple sync operations at the same level. For now skip overlapping syncs (making them unsynced). It's relatively easy for the client to avoid overlapping calls, so this should be good enough for now. In the future we'd like to keep a map of mWaitingListener per SyncID, but there is a little additional complexity about keeping multiple mBLASTSyncTransactions which we will probably wait for S to tackle. Bug: 151389300 Test: TaskOrganizerTests Change-Id: I09efb6bc33468b1e060b8c21bab8cefba65a340e --- .../android/server/wm/WindowContainer.java | 9 ++++-- .../android/server/wm/TaskOrganizerTests.java | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 9a9283257b032..a1902bbd6764c 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2476,9 +2476,12 @@ class WindowContainer extends ConfigurationContainer< boolean prepareForSync(BLASTSyncEngine.TransactionReadyListener waitingListener, int waitingId) { - boolean willSync = false; - if (!isVisible()) { - return willSync; + boolean willSync = true; + + // If we are invisible, no need to sync, likewise if we are already engaged in a sync, + // we can't support overlapping syncs on a single container yet. + if (!isVisible() || mWaitingListener != null) { + return false; } mUsingBLASTSyncTransaction = true; diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java index bc81d5e7c807d..dea5ee25d91e9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java @@ -532,6 +532,9 @@ public class TaskOrganizerTests extends WindowTestsBase { final Task task = createTaskInStack(stackController1, 0 /* userId */); final ITaskOrganizer organizer = registerMockOrganizer(); + spyOn(task); + doReturn(true).when(task).isVisible(); + BLASTSyncEngine bse = new BLASTSyncEngine(); BLASTSyncEngine.TransactionReadyListener transactionListener = @@ -545,6 +548,35 @@ public class TaskOrganizerTests extends WindowTestsBase { .transactionReady(anyInt(), any()); } + @Test + public void testOverlappingBLASTCallback() throws RemoteException { + final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent); + final Task task = createTaskInStack(stackController1, 0 /* userId */); + final ITaskOrganizer organizer = registerMockOrganizer(); + + spyOn(task); + doReturn(true).when(task).isVisible(); + final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window"); + makeWindowVisible(w); + + BLASTSyncEngine bse = new BLASTSyncEngine(); + + BLASTSyncEngine.TransactionReadyListener transactionListener = + mock(BLASTSyncEngine.TransactionReadyListener.class); + + int id = bse.startSyncSet(transactionListener); + assertEquals(true, bse.addToSyncSet(id, task)); + bse.setReady(id); + + int id2 = bse.startSyncSet(transactionListener); + // We should be rejected from the second sync since we are already + // in one. + assertEquals(false, bse.addToSyncSet(id2, task)); + w.finishDrawing(null); + assertEquals(true, bse.addToSyncSet(id2, task)); + bse.setReady(id2); + } + @Test public void testBLASTCallbackWithWindow() { final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);