diff options
author | Dianne Hackborn <hackbod@google.com> | 2012-11-01 16:28:16 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2012-11-02 14:19:59 -0700 |
commit | 98129739afcb3786a6ec9f3efe774d8e01f6d632 (patch) | |
tree | 7e38ec6db6862e3b1f0e4557361fec2e09ac6d8c /services | |
parent | 7ab7f538924371a9dd4be7a27a6ae3b4c04b301c (diff) | |
download | frameworks_base-98129739afcb3786a6ec9f3efe774d8e01f6d632.zip frameworks_base-98129739afcb3786a6ec9f3efe774d8e01f6d632.tar.gz frameworks_base-98129739afcb3786a6ec9f3efe774d8e01f6d632.tar.bz2 |
Fix issue #7343200: Fails to show wallpaper in the background for...
...lockscreen sometimes and remains black / blank
The problem was that we were using the animation-side wallpaper state
in cases where it was not updated yet.
The mWallpaperTarget variable is propagated over to the animation
side when the main window manager state updates. On the animation
side, this is used by hideWallpapersLocked() to determine if the
current wallpaper should be hidden.
The problem is that various paths to hideWallpapersLocked() can
come from the layout side of the window manager instead of the
animation side. This causes the problem here because in this case
the wallpaper state may not have yet been propagated to the
animation side, so it could incorrectly decide to hide the wallpaper
because it thinks there is not a target when in fact a target is
set in the layout side. This won't get fixed until some time way
later that the layout side decides that a new window is being shown
that may need to have the wallpaper shown.
The fix here is pretty gross, but as safe as possible -- the
hideWallpapersLocked() function now uses either the animation or
layout wallpaper state depending on where the call to it is coming
from.
Change-Id: I9250bfeae6e11c1761760bcc696fdb33fb5c8a5f
Diffstat (limited to 'services')
4 files changed, 85 insertions, 39 deletions
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index c8d9cc3..eecc74e 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -13,6 +13,7 @@ import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENT import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS; import android.content.Context; +import android.os.Debug; import android.os.SystemClock; import android.util.Log; import android.util.Slog; @@ -203,9 +204,9 @@ public class WindowAnimator { if (mWallpaperTarget != layoutToAnim.mWallpaperTarget || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) { - Slog.d(TAG, "Updating anim wallpaper: target=" + mWallpaperTarget - + " lower=" + mLowerWallpaperTarget + " upper=" - + mUpperWallpaperTarget); + Slog.d(TAG, "Pulling anim wallpaper: target=" + layoutToAnim.mWallpaperTarget + + " lower=" + layoutToAnim.mLowerWallpaperTarget + " upper=" + + layoutToAnim.mUpperWallpaperTarget); } } mWallpaperTarget = layoutToAnim.mWallpaperTarget; @@ -259,11 +260,30 @@ public class WindowAnimator { } } - void hideWallpapersLocked(final WindowState w) { - if ((mWallpaperTarget == w && mLowerWallpaperTarget == null) || mWallpaperTarget == null) { - final int numTokens = mWallpaperTokens.size(); + void hideWallpapersLocked(final WindowState w, boolean fromAnimator) { + // There is an issue where this function can be called either from + // the animation or the layout side of the window manager. The problem + // is that if it is called from the layout side, we may not yet have + // propagated the current layout wallpaper state over into the animation + // state. If that is the case, we can do bad things like hide the + // wallpaper when we had just made it shown because the animation side + // doesn't yet see that there is now a wallpaper target. As a temporary + // work-around, we tell the function here which side of the window manager + // is calling so it can use the right state. + if (fromAnimator) { + hideWallpapersLocked(w, mWallpaperTarget, mLowerWallpaperTarget, mWallpaperTokens); + } else { + hideWallpapersLocked(w, mService.mWallpaperTarget, + mService.mLowerWallpaperTarget, mService.mWallpaperTokens); + } + } + + void hideWallpapersLocked(final WindowState w, final WindowState wallpaperTarget, + final WindowState lowerWallpaperTarget, final ArrayList<WindowToken> wallpaperTokens) { + if ((wallpaperTarget == w && lowerWallpaperTarget == null) || wallpaperTarget == null) { + final int numTokens = wallpaperTokens.size(); for (int i = numTokens - 1; i >= 0; i--) { - final WindowToken token = mWallpaperTokens.get(i); + final WindowToken token = wallpaperTokens.get(i); final int numWindows = token.windows.size(); for (int j = numWindows - 1; j >= 0; j--) { final WindowState wallpaper = token.windows.get(j); @@ -276,7 +296,8 @@ public class WindowAnimator { } } if (WindowManagerService.DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, - "Hiding wallpaper " + token + " from " + w); + "Hiding wallpaper " + token + " from " + w + "\n" + + Debug.getCallers(5, " ")); token.hidden = true; } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 137c8ee..d2034fe 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -192,7 +192,7 @@ public class WindowManagerService extends IWindowManager.Stub static final boolean DEBUG_STARTING_WINDOW = false; static final boolean DEBUG_REORDER = false; static final boolean DEBUG_WALLPAPER = false; - static final boolean DEBUG_WALLPAPER_LIGHT = true || DEBUG_WALLPAPER; + static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER; static final boolean DEBUG_DRAG = false; static final boolean DEBUG_SCREEN_ON = false; static final boolean DEBUG_SCREENSHOT = false; @@ -545,7 +545,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState mWallpaperTarget = null; // If non-null, we are in the middle of animating from one wallpaper target // to another, and this is the lower one in Z-order. - private WindowState mLowerWallpaperTarget = null; + WindowState mLowerWallpaperTarget = null; // If non-null, we are in the middle of animating from one wallpaper target // to another, and this is the higher one in Z-order. private WindowState mUpperWallpaperTarget = null; @@ -2847,7 +2847,7 @@ public class WindowManagerService extends IWindowManager.Stub } if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) { // To change the format, we need to re-build the surface. - winAnimator.destroySurfaceLocked(); + winAnimator.destroySurfaceLocked(false); toBeDisplayed = true; surfaceChanged = true; } @@ -2928,7 +2928,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mInputMethodWindow == win) { mInputMethodWindow = null; } - winAnimator.destroySurfaceLocked(); + winAnimator.destroySurfaceLocked(false); } scheduleNotifyWindowTranstionIfNeededLocked(win, transit); } @@ -3030,7 +3030,7 @@ public class WindowManagerService extends IWindowManager.Stub if (win == null) { return; } - win.mWinAnimator.destroyDeferredSurfaceLocked(); + win.mWinAnimator.destroyDeferredSurfaceLocked(false); } } finally { Binder.restoreCallingIdentity(origId); @@ -8136,7 +8136,7 @@ public class WindowManagerService extends IWindowManager.Stub pw.flush(); Slog.w(TAG, "This window was lost: " + ws); Slog.w(TAG, sw.toString()); - ws.mWinAnimator.destroySurfaceLocked(); + ws.mWinAnimator.destroySurfaceLocked(false); } } Slog.w(TAG, "Current app token list:"); @@ -9443,7 +9443,7 @@ public class WindowManagerService extends IWindowManager.Stub if (win == mWallpaperTarget) { wallpaperDestroyed = true; } - win.mWinAnimator.destroySurfaceLocked(); + win.mWinAnimator.destroySurfaceLocked(false); } while (i > 0); mDestroySurface.clear(); } @@ -9692,6 +9692,15 @@ public class WindowManagerService extends IWindowManager.Stub allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList); } + if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) { + if (mWallpaperTarget != layoutToAnim.mWallpaperTarget + || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget + || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) { + Slog.d(TAG, "Pushing anim wallpaper: target=" + layoutToAnim.mWallpaperTarget + + " lower=" + layoutToAnim.mLowerWallpaperTarget + " upper=" + + layoutToAnim.mUpperWallpaperTarget + "\n" + Debug.getCallers(5, " ")); + } + } layoutToAnim.mWallpaperTarget = mWallpaperTarget; layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget; layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget; diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index e1cc58f..35bebbe 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -875,8 +875,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow); mAttachedWindow.mChildWindows.remove(this); } - mWinAnimator.destroyDeferredSurfaceLocked(); - mWinAnimator.destroySurfaceLocked(); + mWinAnimator.destroyDeferredSurfaceLocked(false); + mWinAnimator.destroySurfaceLocked(false); mSession.windowRemovedLocked(); try { mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 85f087f..7b30c89 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -225,7 +225,7 @@ class WindowStateAnimator { mAnimation.cancel(); mAnimation = null; mLocalAnimating = false; - destroySurfaceLocked(); + destroySurfaceLocked(true); } } @@ -412,7 +412,7 @@ class WindowStateAnimator { mService.mPendingRemove.add(mWin); mWin.mRemoveOnExit = false; } - mAnimator.hideWallpapersLocked(mWin); + mAnimator.hideWallpapersLocked(mWin, true); } void hide() { @@ -500,17 +500,21 @@ class WindowStateAnimator { @Override public void setAlpha(float alpha) { super.setAlpha(alpha); + if (alpha != mSurfaceTraceAlpha) { + Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by " + + Debug.getCallers(3)); + } mSurfaceTraceAlpha = alpha; - Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by " - + Debug.getCallers(3)); } @Override public void setLayer(int zorder) { super.setLayer(zorder); + if (zorder != mLayer) { + Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by " + + Debug.getCallers(3)); + } mLayer = zorder; - Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by " - + Debug.getCallers(3)); sSurfaces.remove(this); int i; @@ -526,49 +530,61 @@ class WindowStateAnimator { @Override public void setPosition(float x, float y) { super.setPosition(x, y); + if (x != mPosition.x || y != mPosition.y) { + Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by " + + Debug.getCallers(3)); + } mPosition.set(x, y); - Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by " - + Debug.getCallers(3)); } @Override public void setSize(int w, int h) { super.setSize(w, h); + if (w != mSize.x || h != mSize.y) { + Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by " + + Debug.getCallers(3)); + } mSize.set(w, h); - Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by " - + Debug.getCallers(3)); } @Override public void setWindowCrop(Rect crop) { super.setWindowCrop(crop); if (crop != null) { + if (!crop.equals(mWindowCrop)) { + Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by " + + Debug.getCallers(3)); + } mWindowCrop.set(crop); } - Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by " - + Debug.getCallers(3)); } @Override public void setLayerStack(int layerStack) { super.setLayerStack(layerStack); + if (layerStack != mLayerStack) { + Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3)); + } mLayerStack = layerStack; - Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3)); } @Override public void hide() { super.hide(); + if (mShown) { + Slog.v(SURFACE_TAG, "hide: " + this + ". Called by " + + Debug.getCallers(3)); + } mShown = false; - Slog.v(SURFACE_TAG, "hide: " + this + ". Called by " - + Debug.getCallers(3)); } @Override public void show() { super.show(); + if (!mShown) { + Slog.v(SURFACE_TAG, "show: " + this + ". Called by " + + Debug.getCallers(3)); + } mShown = true; - Slog.v(SURFACE_TAG, "show: " + this + ". Called by " - + Debug.getCallers(3)); } @Override @@ -728,7 +744,7 @@ class WindowStateAnimator { return mSurface; } - void destroySurfaceLocked() { + void destroySurfaceLocked(boolean fromAnimator) { if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) { mWin.mAppToken.startingDisplayed = false; } @@ -778,7 +794,7 @@ class WindowStateAnimator { } mSurface.destroy(); } - mAnimator.hideWallpapersLocked(mWin); + mAnimator.hideWallpapersLocked(mWin, fromAnimator); } catch (RuntimeException e) { Slog.w(TAG, "Exception thrown when destroying Window " + this + " surface " + mSurface + " session " + mSession @@ -792,7 +808,7 @@ class WindowStateAnimator { } } - void destroyDeferredSurfaceLocked() { + void destroyDeferredSurfaceLocked(boolean fromAnimator) { try { if (mPendingDestroySurface != null) { if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { @@ -804,7 +820,7 @@ class WindowStateAnimator { WindowManagerService.logSurface(mWin, "DESTROY PENDING", e); } mPendingDestroySurface.destroy(); - mAnimator.hideWallpapersLocked(mWin); + mAnimator.hideWallpapersLocked(mWin, fromAnimator); } } catch (RuntimeException e) { Slog.w(TAG, "Exception thrown when destroying Window " @@ -1192,7 +1208,7 @@ class WindowStateAnimator { hide(); } else if (w.mAttachedHidden || !w.isReadyForDisplay()) { hide(); - mAnimator.hideWallpapersLocked(w); + mAnimator.hideWallpapersLocked(w, true); // If we are waiting for this window to handle an // orientation change, well, it is hidden, so |