diff options
3 files changed, 31 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 16b4449bbbb2..be5f141b3762 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -3993,6 +3993,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } // Otherwise this is the "root" of a synced subtree, so continue on to preparation. } + if (oldParent != null && newParent != null && !shouldUpdateSyncOnReparent()) { + return; + } // This container's situation has changed so we need to restart its sync. // We cannot reset the sync without a chance of a deadlock since it will request a new @@ -4007,6 +4010,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< prepareSync(); } + /** Returns {@code true} if {@link #mSyncState} needs to be updated when reparenting. */ + protected boolean shouldUpdateSyncOnReparent() { + return true; + } + void registerWindowContainerListener(WindowContainerListener listener) { registerWindowContainerListener(listener, true /* shouldPropConfig */); } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 032f08a92abb..bab7a78a7286 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5635,6 +5635,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } @Override + protected boolean shouldUpdateSyncOnReparent() { + // Keep the sync state in case the client is drawing for the latest conifguration or the + // configuration is not changed after reparenting. This avoids a redundant redraw request. + return mSyncState != SYNC_STATE_NONE && !mLastConfigReportedToClient; + } + + @Override boolean prepareSync() { if (!mDrawHandlers.isEmpty()) { Slog.w(TAG, "prepareSync with mDrawHandlers, " + this + ", " + Debug.getCallers(8)); 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 a3a36841d807..5eebe746d64b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java @@ -26,6 +26,7 @@ import static com.android.server.wm.BLASTSyncEngine.METHOD_NONE; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.WindowContainer.SYNC_STATE_NONE; +import static com.android.server.wm.WindowContainer.SYNC_STATE_READY; import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION; import static org.junit.Assert.assertEquals; @@ -38,7 +39,9 @@ import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Mockito.spy; import android.platform.test.annotations.Presubmit; +import android.util.MergedConfiguration; import android.view.SurfaceControl; +import android.window.ClientWindowFrames; import androidx.test.filters.SmallTest; @@ -306,6 +309,19 @@ public class SyncEngineTests extends WindowTestsBase { assertEquals(SYNC_STATE_NONE, parentWC.mSyncState); assertEquals(SYNC_STATE_NONE, topChildWC.mSyncState); assertEquals(SYNC_STATE_NONE, botChildWC.mSyncState); + + // If the appearance of window won't change after reparenting, its sync state can be kept. + final WindowState w = createWindow(null, TYPE_BASE_APPLICATION, "win"); + parentWC.onRequestedOverrideConfigurationChanged(w.getConfiguration()); + w.reparent(botChildWC, POSITION_TOP); + parentWC.prepareSync(); + // Assume the window has drawn with the latest configuration. + w.fillClientWindowFramesAndConfiguration(new ClientWindowFrames(), + new MergedConfiguration(), true /* useLatestConfig */, true /* relayoutVisible */); + assertTrue(w.onSyncFinishedDrawing()); + assertEquals(SYNC_STATE_READY, w.mSyncState); + w.reparent(topChildWC, POSITION_TOP); + assertEquals(SYNC_STATE_READY, w.mSyncState); } @Test |