From 6a776fc55a916a9a789bfd0ee25cbfea50c773c0 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 17 May 2023 23:18:12 +0800 Subject: Wait for relaunching activity to finish sync Otherwise the sync group may be finished too early and then the animation will start too early. E.g. when changing wallpaper (theme color), sometimes it may triggers multiple CONFIG_ASSETS_PATHS changes. The sequence could be config_change_1 -> drawn_1 (finish sync) -> config_change_2 -> animation starts by 1 -> drawn_2. Then if the activity is relaunching without preserving window and the animation finishes before "drawn_2" happens, it will show black screen. Bug: 282200672 Test: atest SyncEngineTests#testWaitingSyncCallback Change-Id: I044f194150dee563f9df5e93f19a47bd8f384c6a --- .../core/java/com/android/server/wm/ActivityRecord.java | 1 + .../src/com/android/server/wm/SyncEngineTests.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 0b7618da4d34..a3b6f92e1e23 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -10608,6 +10608,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } if (!isVisibleRequested()) return true; + if (mPendingRelaunchCount > 0) return false; // Wait for attach. That is the earliest time where we know if there will be an associated // display rotation. If we don't wait, the starting-window can finishDrawing first and // cause the display rotation to end-up in a following transition. 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 5eebe746d64b..fc5e9cab5447 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; @@ -119,6 +120,22 @@ public class SyncEngineTests extends WindowTestsBase { assertTrue(mockWC.onSyncFinishedDrawing()); bse.onSurfacePlacement(); verify(listener, times(1)).onTransactionReady(eq(id), notNull()); + + // The sync is not finished for a relaunching activity. + id = startSyncSet(bse, listener); + final ActivityRecord r = new ActivityBuilder(mAtm).setCreateTask(true).build(); + final WindowState w = mock(WindowState.class); + doReturn(true).when(w).isVisibleRequested(); + doReturn(true).when(w).fillsParent(); + doReturn(true).when(w).isSyncFinished(any()); + r.mChildren.add(w); + bse.addToSyncSet(id, r); + r.onSyncFinishedDrawing(); + assertTrue(r.isSyncFinished(r.getSyncGroup())); + r.startRelaunching(); + assertFalse(r.isSyncFinished(r.getSyncGroup())); + r.finishRelaunching(); + assertTrue(r.isSyncFinished(r.getSyncGroup())); } @Test -- cgit v1.2.3-59-g8ed1b