From 7b3c8ddea7d6e725d0a1b64fdeae35f940836974 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Thu, 17 Aug 2023 09:02:16 -0700 Subject: [PATCH] Only set SYNC flag if >1 track While technically it's true that a transition is sync if another is running in the same track, tracks already imply sync between their constituents, so it's redundant. The player also interprets SYNC as "stop everything immediately" which isn't actually useful unless there are multiple active tracks. So, only set the sync flag when there are >1 tracks. Bug: 296242449 Test: atest TransitionTests#testNoSyncFlagIfOneTrack Change-Id: I61d97542825627beba4dbfa77f1cff0cf1e86ab8 --- .../server/wm/TransitionController.java | 9 +++--- .../android/server/wm/TransitionTests.java | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 48cca3291650a..5b466a017cac0 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -1124,14 +1124,15 @@ class TransitionController { + "track #%d", transition.getSyncId(), track); } } - if (sync) { + transition.mAnimationTrack = track; + info.setTrack(track); + mTrackCount = Math.max(mTrackCount, track + 1); + if (sync && mTrackCount > 1) { + // If there are >1 tracks, mark as sync so that all tracks finish. info.setFlags(info.getFlags() | TransitionInfo.FLAG_SYNC); ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Marking #%d animation as SYNC.", transition.getSyncId()); } - transition.mAnimationTrack = track; - info.setTrack(track); - mTrackCount = Math.max(mTrackCount, track + 1); } void updateAnimatingState(SurfaceControl.Transaction t) { diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index b4f1176f71e1d..d7cd9f256387b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -39,6 +39,7 @@ import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER; +import static android.window.TransitionInfo.FLAG_SYNC; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; import static android.window.TransitionInfo.isIndependent; @@ -2384,6 +2385,37 @@ public class TransitionTests extends WindowTestsBase { assertFalse(controller.isCollecting()); } + @Test + public void testNoSyncFlagIfOneTrack() { + final TransitionController controller = mAtm.getTransitionController(); + final TestTransitionPlayer player = registerTestTransitionPlayer(); + + mSyncEngine = createTestBLASTSyncEngine(); + controller.setSyncEngine(mSyncEngine); + + final Transition transitA = createTestTransition(TRANSIT_OPEN, controller); + final Transition transitB = createTestTransition(TRANSIT_OPEN, controller); + final Transition transitC = createTestTransition(TRANSIT_OPEN, controller); + + controller.startCollectOrQueue(transitA, (deferred) -> {}); + controller.startCollectOrQueue(transitB, (deferred) -> {}); + controller.startCollectOrQueue(transitC, (deferred) -> {}); + + // Verify that, as-long as there is <= 1 track, we won't get a SYNC flag + transitA.start(); + transitA.setAllReady(); + mSyncEngine.tryFinishForTest(transitA.getSyncId()); + assertTrue((player.mLastReady.getFlags() & FLAG_SYNC) == 0); + transitB.start(); + transitB.setAllReady(); + mSyncEngine.tryFinishForTest(transitB.getSyncId()); + assertTrue((player.mLastReady.getFlags() & FLAG_SYNC) == 0); + transitC.start(); + transitC.setAllReady(); + mSyncEngine.tryFinishForTest(transitC.getSyncId()); + assertTrue((player.mLastReady.getFlags() & FLAG_SYNC) == 0); + } + private static void makeTaskOrganized(Task... tasks) { final ITaskOrganizer organizer = mock(ITaskOrganizer.class); for (Task t : tasks) {