diff options
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"); |