diff options
| author | 2018-03-23 18:57:43 +0100 | |
|---|---|---|
| committer | 2018-03-26 14:49:37 +0200 | |
| commit | 5251b1df577d99cd6b39ca21b1e2887c16462063 (patch) | |
| tree | 07ab4bbcc93fc3afe404ed7571165a34197c4c00 | |
| parent | d21b33d8cadeb3d618e31031939f9d26ab1f6c17 (diff) | |
WM: Move mLayoutSeq to DisplayContent
Fixes an issue where the mLayoutSeq could advance due to laying
out a secondary display, but that would not advance the mLayoutSeq
of the WindowStates on the primary display.
Because the mLayoutSeq no longer matched the global value, the
windows on the primary display would then not get the resized
notification.
Fixed by making mLayoutSeq a property of the DisplayContent, such
that for different displays, mLayoutSeq is independent.
Change-Id: I9d6b95117e8428b0f2f5e88a9260ea6514074fe5
Fixes: 36781810
Test: atest WindowStateTests DisplayContentTests
5 files changed, 53 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 3e47ea641123..a7eac5556221 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -385,6 +385,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ private int mSurfaceSize; + /** + * Sequence number for the current layout pass. + */ + int mLayoutSeq = 0; + /** Temporary float array to retrieve 3x3 matrix values. */ private final float[] mTmpFloats = new float[9]; @@ -554,7 +559,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo w.prelayout(); final boolean firstLayout = !w.isLaidOut(); mService.mPolicy.layoutWindowLw(w, null, mDisplayFrames); - w.mLayoutSeq = mService.mLayoutSeq; + w.mLayoutSeq = mLayoutSeq; // If this is the first layout, we need to initialize the last inset values as // otherwise we'd immediately cause an unnecessary resize. @@ -593,7 +598,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo w.mLayoutNeeded = false; w.prelayout(); mService.mPolicy.layoutWindowLw(w, w.getParentWindow(), mDisplayFrames); - w.mLayoutSeq = mService.mLayoutSeq; + w.mLayoutSeq = mLayoutSeq; if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.mFrame + " mContainingFrame=" + w.mContainingFrame + " mDisplayFrame=" + w.mDisplayFrame); @@ -2219,6 +2224,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo pw.println(" mTouchExcludeRegion=" + mTouchExcludeRegion); pw.println(); + pw.print(prefix); pw.print("mLayoutSeq="); pw.println(mLayoutSeq); + + pw.println(); pw.println(prefix + "Application tokens in top down Z order:"); for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx); @@ -2927,9 +2935,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mService.mScreenRect.set(0, 0, dw, dh); } - int seq = mService.mLayoutSeq + 1; + int seq = mLayoutSeq + 1; if (seq < 0) seq = 0; - mService.mLayoutSeq = seq; + mLayoutSeq = seq; // Used to indicate that we have processed the dream window and all additional windows are // behind it. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 56b314f18e79..449aa2c113ae 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -596,8 +596,6 @@ public class WindowManagerService extends IWindowManager.Stub boolean mClientFreezingScreen = false; int mAppsFreezingScreen = 0; - int mLayoutSeq = 0; - // Last systemUiVisibility we received from status bar. int mLastStatusBarVisibility = 0; // Last systemUiVisibility we dispatched to windows. @@ -6344,8 +6342,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mInputMethodTarget != null) { pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget); } - pw.print(" mInTouchMode="); pw.print(mInTouchMode); - pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); + pw.print(" mInTouchMode="); pw.println(mInTouchMode); pw.print(" mLastDisplayFreezeDuration="); TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw); if ( mLastFinishedFreezeSource != null) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 993556faee7d..30bbfe0b83c4 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1236,7 +1236,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP */ void updateResizingWindowIfNeeded() { final WindowStateAnimator winAnimator = mWinAnimator; - if (!mHasSurface || mService.mLayoutSeq != mLayoutSeq || isGoneForLayoutLw()) { + if (!mHasSurface || getDisplayContent().mLayoutSeq != mLayoutSeq || isGoneForLayoutLw()) { return; } @@ -1360,6 +1360,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mToken.getDisplayContent(); } + @Override + void onDisplayChanged(DisplayContent dc) { + super.onDisplayChanged(dc); + // Window was not laid out for this display yet, so make sure mLayoutSeq does not match. + if (dc != null) { + mLayoutSeq = dc.mLayoutSeq - 1; + } + } + DisplayInfo getDisplayInfo() { final DisplayContent displayContent = getDisplayContent(); return displayContent != null ? displayContent.getDisplayInfo() : null; diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java index b645700abb79..7f1bcac05ffe 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java @@ -30,8 +30,10 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static com.android.server.wm.WindowContainer.POSITION_TOP; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -436,6 +438,20 @@ public class DisplayContentTests extends WindowTestsBase { } @Test + public void testLayoutSeq_assignedDuringLayout() throws Exception { + synchronized (sWm.getWindowManagerLock()) { + + final DisplayContent dc = createNewDisplay(); + final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); + + dc.setLayoutNeeded(); + dc.performLayout(true /* initial */, false /* updateImeWindows */); + + assertThat(win.mLayoutSeq, is(dc.mLayoutSeq)); + } + } + + @Test @SuppressLint("InlinedApi") public void testOrientationDefinedByKeyguard() { final DisplayContent dc = createNewDisplay(); diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java index 56b7d9f40ec0..1248eaea7ae7 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java @@ -40,9 +40,12 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVE import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; @@ -312,6 +315,17 @@ public class WindowStateTests extends WindowTestsBase { assertTrue(child2.isSelfOrAncestorWindowAnimatingExit()); } + @Test + public void testLayoutSeqResetOnReparent() throws Exception { + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + app.mLayoutSeq = 1; + mDisplayContent.mLayoutSeq = 1; + + app.onDisplayChanged(mDisplayContent); + + assertThat(app.mLayoutSeq, not(is(mDisplayContent.mLayoutSeq))); + } + private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) { reset(mPowerManagerWrapper); final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); |