From 812d2ca475e88d4e52870a4eeeb096a411f0f077 Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Thu, 27 Sep 2012 15:35:34 -0700 Subject: [PATCH] Fix layout state issues. - Restore test of hidden to isGoneForLayoutLw(), without that we return false when setAppVisibility(true) is called which leads to early layout of windows. Particulary on return from full screen to non-full we lay out once before recognizing that the status bar should be back and then again once the status bar appears causing a jump. Fixes bug 6470541. - Add a new test for configuration size changes to gone or hidden windows. This forces a layout call to these windows which informs them of the new size even though they are not shown until later. In particular this keeps windows that were in the background during a rotation from using their old boundaries on return. Fixes bug 6615859. - Consolidate WindowState.mConfiguration tests into WindowState. Change-Id: I7a82ce747a3fcf7d74104dc23f1532efe64bd767 --- .../server/wm/WindowManagerService.java | 21 ++++++++----------- .../com/android/server/wm/WindowState.java | 17 ++++++++++++++- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 5a6e0107de6f3..7616117830b7f 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -74,7 +74,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.hardware.display.DisplayManager; -import android.hardware.input.InputManager; import android.os.Binder; import android.os.Bundle; import android.os.Debug; @@ -2749,7 +2748,8 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs); + if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility + + " " + requestedWidth + "x" + requestedHeight + " " + win.mAttrs); win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0; @@ -4036,7 +4036,8 @@ public class WindowManagerService extends IWindowManager.Stub } changed = mFocusedApp != newFocus; mFocusedApp = newFocus; - if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp); + if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp + + " moveFocusNow=" + moveFocusNow); if (changed) { mInputMonitor.setFocusedAppLw(newFocus); } @@ -8296,7 +8297,8 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_LAYOUT && !win.mLayoutAttached) { Slog.v(TAG, "1ST PASS " + win + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame - + " mLayoutAttached=" + win.mLayoutAttached); + + " mLayoutAttached=" + win.mLayoutAttached + + " screen changed=" + win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE)); final AppWindowToken atoken = win.mAppToken; if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + win.mViewVisibility + " mRelayoutCalled=" @@ -8318,6 +8320,7 @@ public class WindowManagerService extends IWindowManager.Stub // windows, since that means "perform layout as normal, // just don't display"). if (!gone || !win.mHaveFrame || win.mLayoutNeeded + || win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE) || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) { if (!win.mLayoutAttached) { if (initial) { @@ -8753,10 +8756,7 @@ public class WindowManagerService extends IWindowManager.Stub !w.mLastContentInsets.equals(w.mContentInsets); w.mVisibleInsetsChanged |= !w.mLastVisibleInsets.equals(w.mVisibleInsets); - boolean configChanged = - w.mConfiguration != mCurConfiguration - && (w.mConfiguration == null - || mCurConfiguration.diff(w.mConfiguration) != 0); + boolean configChanged = w.isConfigChanged(); if (DEBUG_CONFIGURATION && configChanged) { Slog.v(TAG, "Win " + w + " config changed: " + mCurConfiguration); @@ -9254,10 +9254,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + win + ": " + win.mCompatFrame); int diff = 0; - boolean configChanged = - win.mConfiguration != mCurConfiguration - && (win.mConfiguration == null - || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0); + boolean configChanged = win.isConfigChanged(); if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) { Slog.i(TAG, "Sending new config to window " + win + ": " diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index ac958b82e78c0..9963d14b18f0c 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -574,6 +574,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mAttrs; } + @Override public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) { int index = -1; WindowState ws = this; @@ -612,6 +613,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mLayer; } + @Override public IApplicationToken getAppToken() { return mAppToken != null ? mAppToken.appToken : null; } @@ -801,12 +803,13 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mWinAnimator.mAnimation != null; } + @Override public boolean isGoneForLayoutLw() { final AppWindowToken atoken = mAppToken; return mViewVisibility == View.GONE || !mRelayoutCalled || (atoken == null && mRootToken.hidden) - || (atoken != null && atoken.hiddenRequested) + || (atoken != null && (atoken.hiddenRequested || atoken.hidden)) || mAttachedHidden || mExiting || mDestroying; } @@ -849,6 +852,18 @@ final class WindowState implements WindowManagerPolicy.WindowState { mFrame.right >= screenWidth && mFrame.bottom >= screenHeight; } + boolean isConfigChanged() { + return mConfiguration != mService.mCurConfiguration + && (mConfiguration == null + || (mConfiguration.diff(mService.mCurConfiguration) != 0)); + } + + boolean isConfigDiff(int mask) { + return mConfiguration != mService.mCurConfiguration + && mConfiguration != null + && (mConfiguration.diff(mService.mCurConfiguration) & mask) != 0; + } + void removeLocked() { disposeInputChannel();