summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java16
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