summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2012-11-01 16:28:16 -0700
committerDianne Hackborn <hackbod@google.com>2012-11-02 14:19:59 -0700
commit98129739afcb3786a6ec9f3efe774d8e01f6d632 (patch)
tree7e38ec6db6862e3b1f0e4557361fec2e09ac6d8c /services
parent7ab7f538924371a9dd4be7a27a6ae3b4c04b301c (diff)
downloadframeworks_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')
-rw-r--r--services/java/com/android/server/wm/WindowAnimator.java37
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java23
-rw-r--r--services/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java60
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