summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evan Rosky <erosky@google.com> 2020-11-19 20:20:53 -0800
committer Evan Rosky <erosky@google.com> 2020-11-23 11:02:08 -0800
commit2da185d516d4441f0ea6aab4e42ea77845607fc9 (patch)
tree90e7be8f1be2b6b2e0d46a59d3e08f962d7d4256
parent961f737505c854b783de6e08b1c5d49e64f143e3 (diff)
Don't updateSurfacePosition with invalid window frames
updateSurfacePosition runs pretty frequently (during configuration update). However, the WindowState override relies on mWindowFrames which is calculated during layout. This means that surface positions are frequently calculated with out-of-date mWindowFrames (most commonly when the onConfigurationChange cascade is called). This can easily cause visible glitching based on the timings of SFTransaction applications -- particularly when mixed with syncTransactions since those aren't serialized with layout. This CL prevents WindowState's updateSurfacePosition from running when layout is deferred or when the window is goneForLayout. Bug: 169035082 Test: With new split-screen transitions, launch a non-resizable task while in split-screen and observe that home surface doesn't get repositioned incorrectly. Change-Id: If35fb3560eed83fe1c944a1cb7cbb685f58a3b90
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java2
2 files changed, 8 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b5509f62f92a..008a7a68ab33 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -5262,6 +5262,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mSurfaceControl == null) {
return;
}
+ if (mWmService.mWindowPlacerLocked.isLayoutDeferred() || isGoneForLayout()) {
+ // Since this relies on mWindowFrames, changes made while layout is deferred are
+ // likely to be invalid. Similarly, if it's goneForLayout, mWindowFrames may not be
+ // up-to-date and thus can't be relied on.
+ return;
+ }
transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
mSurfacePosition);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 75d2c5159187..12746b1bd4c3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -647,6 +647,8 @@ public class WindowStateTests extends WindowTestsBase {
win1.mSurfaceControl = mock(SurfaceControl.class);
win1.mAttrs.surfaceInsets.set(1, 2, 3, 4);
win1.getFrame().offsetTo(WINDOW_OFFSET, 0);
+ // Simulate layout
+ win1.mRelayoutCalled = true;
win1.updateSurfacePosition(t);
win1.getTransformationMatrix(values, matrix);