diff options
| author | 2020-11-19 20:20:53 -0800 | |
|---|---|---|
| committer | 2020-11-23 11:02:08 -0800 | |
| commit | 2da185d516d4441f0ea6aab4e42ea77845607fc9 (patch) | |
| tree | 90e7be8f1be2b6b2e0d46a59d3e08f962d7d4256 | |
| parent | 961f737505c854b783de6e08b1c5d49e64f143e3 (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.java | 6 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java | 2 |
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); |