Loading services/core/java/com/android/server/wm/BLASTSyncEngine.java +13 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Handler; import android.os.Trace; import android.util.ArraySet; import android.util.Slog; Loading Loading @@ -172,7 +173,7 @@ class BLASTSyncEngine { if (ran) { return; } mWm.mH.removeCallbacks(this); mHandler.removeCallbacks(this); ran = true; SurfaceControl.Transaction t = new SurfaceControl.Transaction(); for (WindowContainer wc : wcAwaitingCommit) { Loading @@ -199,13 +200,13 @@ class BLASTSyncEngine { }; CommitCallback callback = new CommitCallback(); merged.addTransactionCommittedListener((r) -> { r.run(); }, callback::onCommitted); mWm.mH.postDelayed(callback, BLAST_TIMEOUT_DURATION); mHandler.postDelayed(callback, BLAST_TIMEOUT_DURATION); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady"); mListener.onTransactionReady(mSyncId, merged); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); mActiveSyncs.remove(mSyncId); mWm.mH.removeCallbacks(mOnTimeout); mHandler.removeCallbacks(mOnTimeout); // Immediately start the next pending sync-transaction if there is one. if (mActiveSyncs.size() == 0 && !mPendingSyncSets.isEmpty()) { Loading @@ -216,7 +217,7 @@ class BLASTSyncEngine { throw new IllegalStateException("Pending Sync Set didn't start a sync."); } // Post this so that the now-playing transition setup isn't interrupted. mWm.mH.post(() -> { mHandler.post(() -> { synchronized (mWm.mGlobalLock) { pt.mApplySync.run(); } Loading Loading @@ -269,6 +270,7 @@ class BLASTSyncEngine { } private final WindowManagerService mWm; private final Handler mHandler; private int mNextSyncId = 0; private final SparseArray<SyncGroup> mActiveSyncs = new SparseArray<>(); Loading @@ -280,7 +282,13 @@ class BLASTSyncEngine { private final ArrayList<PendingSyncSet> mPendingSyncSets = new ArrayList<>(); BLASTSyncEngine(WindowManagerService wms) { this(wms, wms.mH); } @VisibleForTesting BLASTSyncEngine(WindowManagerService wms, Handler mainHandler) { mWm = wms; mHandler = mainHandler; } /** Loading Loading @@ -325,7 +333,7 @@ class BLASTSyncEngine { @VisibleForTesting void scheduleTimeout(SyncGroup s, long timeoutMs) { mWm.mH.postDelayed(s.mOnTimeout, timeoutMs); mHandler.postDelayed(s.mOnTimeout, timeoutMs); } void addToSyncSet(int id, WindowContainer wc) { Loading services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java +45 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ import android.view.SurfaceControl; import androidx.test.filters.SmallTest; import com.android.server.testutils.TestHandler; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -371,6 +373,49 @@ public class SyncEngineTests extends WindowTestsBase { mAppWindow.removeImmediately(); } @Test public void testQueueSyncSet() { final TestHandler testHandler = new TestHandler(null); TestWindowContainer mockWC = new TestWindowContainer(mWm, true /* waiter */); TestWindowContainer mockWC2 = new TestWindowContainer(mWm, true /* waiter */); final BLASTSyncEngine bse = createTestBLASTSyncEngine(testHandler); BLASTSyncEngine.TransactionReadyListener listener = mock( BLASTSyncEngine.TransactionReadyListener.class); int id = startSyncSet(bse, listener); bse.addToSyncSet(id, mockWC); bse.setReady(id); bse.onSurfacePlacement(); verify(listener, times(0)).onTransactionReady(eq(id), notNull()); final int[] nextId = new int[]{-1}; bse.queueSyncSet( () -> nextId[0] = startSyncSet(bse, listener), () -> { bse.setReady(nextId[0]); bse.addToSyncSet(nextId[0], mockWC2); }); // Make sure it is queued assertEquals(-1, nextId[0]); // Finish the original sync and see that we've started a new sync-set immediately but // that the readiness was posted. mockWC.onSyncFinishedDrawing(); verify(mWm.mWindowPlacerLocked).requestTraversal(); bse.onSurfacePlacement(); verify(listener, times(1)).onTransactionReady(eq(id), notNull()); assertTrue(nextId[0] != -1); assertFalse(bse.isReady(nextId[0])); // now make sure the applySync callback was posted. testHandler.flush(); assertTrue(bse.isReady(nextId[0])); } static int startSyncSet(BLASTSyncEngine engine, BLASTSyncEngine.TransactionReadyListener listener) { return engine.startSyncSet(listener, BLAST_TIMEOUT_DURATION, "Test"); Loading services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +6 −1 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import android.hardware.display.DisplayManager; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; Loading Loading @@ -886,7 +887,11 @@ class WindowTestsBase extends SystemServiceTestsBase { } BLASTSyncEngine createTestBLASTSyncEngine() { return new BLASTSyncEngine(mWm) { return createTestBLASTSyncEngine(mWm.mH); } BLASTSyncEngine createTestBLASTSyncEngine(Handler handler) { return new BLASTSyncEngine(mWm, handler) { @Override void scheduleTimeout(SyncGroup s, long timeoutMs) { // Disable timeout. Loading Loading
services/core/java/com/android/server/wm/BLASTSyncEngine.java +13 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Handler; import android.os.Trace; import android.util.ArraySet; import android.util.Slog; Loading Loading @@ -172,7 +173,7 @@ class BLASTSyncEngine { if (ran) { return; } mWm.mH.removeCallbacks(this); mHandler.removeCallbacks(this); ran = true; SurfaceControl.Transaction t = new SurfaceControl.Transaction(); for (WindowContainer wc : wcAwaitingCommit) { Loading @@ -199,13 +200,13 @@ class BLASTSyncEngine { }; CommitCallback callback = new CommitCallback(); merged.addTransactionCommittedListener((r) -> { r.run(); }, callback::onCommitted); mWm.mH.postDelayed(callback, BLAST_TIMEOUT_DURATION); mHandler.postDelayed(callback, BLAST_TIMEOUT_DURATION); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady"); mListener.onTransactionReady(mSyncId, merged); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); mActiveSyncs.remove(mSyncId); mWm.mH.removeCallbacks(mOnTimeout); mHandler.removeCallbacks(mOnTimeout); // Immediately start the next pending sync-transaction if there is one. if (mActiveSyncs.size() == 0 && !mPendingSyncSets.isEmpty()) { Loading @@ -216,7 +217,7 @@ class BLASTSyncEngine { throw new IllegalStateException("Pending Sync Set didn't start a sync."); } // Post this so that the now-playing transition setup isn't interrupted. mWm.mH.post(() -> { mHandler.post(() -> { synchronized (mWm.mGlobalLock) { pt.mApplySync.run(); } Loading Loading @@ -269,6 +270,7 @@ class BLASTSyncEngine { } private final WindowManagerService mWm; private final Handler mHandler; private int mNextSyncId = 0; private final SparseArray<SyncGroup> mActiveSyncs = new SparseArray<>(); Loading @@ -280,7 +282,13 @@ class BLASTSyncEngine { private final ArrayList<PendingSyncSet> mPendingSyncSets = new ArrayList<>(); BLASTSyncEngine(WindowManagerService wms) { this(wms, wms.mH); } @VisibleForTesting BLASTSyncEngine(WindowManagerService wms, Handler mainHandler) { mWm = wms; mHandler = mainHandler; } /** Loading Loading @@ -325,7 +333,7 @@ class BLASTSyncEngine { @VisibleForTesting void scheduleTimeout(SyncGroup s, long timeoutMs) { mWm.mH.postDelayed(s.mOnTimeout, timeoutMs); mHandler.postDelayed(s.mOnTimeout, timeoutMs); } void addToSyncSet(int id, WindowContainer wc) { Loading
services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java +45 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ import android.view.SurfaceControl; import androidx.test.filters.SmallTest; import com.android.server.testutils.TestHandler; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -371,6 +373,49 @@ public class SyncEngineTests extends WindowTestsBase { mAppWindow.removeImmediately(); } @Test public void testQueueSyncSet() { final TestHandler testHandler = new TestHandler(null); TestWindowContainer mockWC = new TestWindowContainer(mWm, true /* waiter */); TestWindowContainer mockWC2 = new TestWindowContainer(mWm, true /* waiter */); final BLASTSyncEngine bse = createTestBLASTSyncEngine(testHandler); BLASTSyncEngine.TransactionReadyListener listener = mock( BLASTSyncEngine.TransactionReadyListener.class); int id = startSyncSet(bse, listener); bse.addToSyncSet(id, mockWC); bse.setReady(id); bse.onSurfacePlacement(); verify(listener, times(0)).onTransactionReady(eq(id), notNull()); final int[] nextId = new int[]{-1}; bse.queueSyncSet( () -> nextId[0] = startSyncSet(bse, listener), () -> { bse.setReady(nextId[0]); bse.addToSyncSet(nextId[0], mockWC2); }); // Make sure it is queued assertEquals(-1, nextId[0]); // Finish the original sync and see that we've started a new sync-set immediately but // that the readiness was posted. mockWC.onSyncFinishedDrawing(); verify(mWm.mWindowPlacerLocked).requestTraversal(); bse.onSurfacePlacement(); verify(listener, times(1)).onTransactionReady(eq(id), notNull()); assertTrue(nextId[0] != -1); assertFalse(bse.isReady(nextId[0])); // now make sure the applySync callback was posted. testHandler.flush(); assertTrue(bse.isReady(nextId[0])); } static int startSyncSet(BLASTSyncEngine engine, BLASTSyncEngine.TransactionReadyListener listener) { return engine.startSyncSet(listener, BLAST_TIMEOUT_DURATION, "Test"); Loading
services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +6 −1 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import android.hardware.display.DisplayManager; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; Loading Loading @@ -886,7 +887,11 @@ class WindowTestsBase extends SystemServiceTestsBase { } BLASTSyncEngine createTestBLASTSyncEngine() { return new BLASTSyncEngine(mWm) { return createTestBLASTSyncEngine(mWm.mH); } BLASTSyncEngine createTestBLASTSyncEngine(Handler handler) { return new BLASTSyncEngine(mWm, handler) { @Override void scheduleTimeout(SyncGroup s, long timeoutMs) { // Disable timeout. Loading