Skip to content

Commit 9812973

Browse files
author
Dianne Hackborn
committed
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
1 parent 7ab7f53 commit 9812973

File tree

4 files changed

+85
-39
lines changed

4 files changed

+85
-39
lines changed

services/java/com/android/server/wm/WindowAnimator.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS;
1414

1515
import android.content.Context;
16+
import android.os.Debug;
1617
import android.os.SystemClock;
1718
import android.util.Log;
1819
import android.util.Slog;
@@ -203,9 +204,9 @@ private void copyLayoutToAnimParamsLocked() {
203204
if (mWallpaperTarget != layoutToAnim.mWallpaperTarget
204205
|| mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget
205206
|| mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) {
206-
Slog.d(TAG, "Updating anim wallpaper: target=" + mWallpaperTarget
207-
+ " lower=" + mLowerWallpaperTarget + " upper="
208-
+ mUpperWallpaperTarget);
207+
Slog.d(TAG, "Pulling anim wallpaper: target=" + layoutToAnim.mWallpaperTarget
208+
+ " lower=" + layoutToAnim.mLowerWallpaperTarget + " upper="
209+
+ layoutToAnim.mUpperWallpaperTarget);
209210
}
210211
}
211212
mWallpaperTarget = layoutToAnim.mWallpaperTarget;
@@ -259,11 +260,30 @@ private void copyLayoutToAnimParamsLocked() {
259260
}
260261
}
261262

262-
void hideWallpapersLocked(final WindowState w) {
263-
if ((mWallpaperTarget == w && mLowerWallpaperTarget == null) || mWallpaperTarget == null) {
264-
final int numTokens = mWallpaperTokens.size();
263+
void hideWallpapersLocked(final WindowState w, boolean fromAnimator) {
264+
// There is an issue where this function can be called either from
265+
// the animation or the layout side of the window manager. The problem
266+
// is that if it is called from the layout side, we may not yet have
267+
// propagated the current layout wallpaper state over into the animation
268+
// state. If that is the case, we can do bad things like hide the
269+
// wallpaper when we had just made it shown because the animation side
270+
// doesn't yet see that there is now a wallpaper target. As a temporary
271+
// work-around, we tell the function here which side of the window manager
272+
// is calling so it can use the right state.
273+
if (fromAnimator) {
274+
hideWallpapersLocked(w, mWallpaperTarget, mLowerWallpaperTarget, mWallpaperTokens);
275+
} else {
276+
hideWallpapersLocked(w, mService.mWallpaperTarget,
277+
mService.mLowerWallpaperTarget, mService.mWallpaperTokens);
278+
}
279+
}
280+
281+
void hideWallpapersLocked(final WindowState w, final WindowState wallpaperTarget,
282+
final WindowState lowerWallpaperTarget, final ArrayList<WindowToken> wallpaperTokens) {
283+
if ((wallpaperTarget == w && lowerWallpaperTarget == null) || wallpaperTarget == null) {
284+
final int numTokens = wallpaperTokens.size();
265285
for (int i = numTokens - 1; i >= 0; i--) {
266-
final WindowToken token = mWallpaperTokens.get(i);
286+
final WindowToken token = wallpaperTokens.get(i);
267287
final int numWindows = token.windows.size();
268288
for (int j = numWindows - 1; j >= 0; j--) {
269289
final WindowState wallpaper = token.windows.get(j);
@@ -276,7 +296,8 @@ void hideWallpapersLocked(final WindowState w) {
276296
}
277297
}
278298
if (WindowManagerService.DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG,
279-
"Hiding wallpaper " + token + " from " + w);
299+
"Hiding wallpaper " + token + " from " + w + "\n"
300+
+ Debug.getCallers(5, " "));
280301
token.hidden = true;
281302
}
282303
}

services/java/com/android/server/wm/WindowManagerService.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public class WindowManagerService extends IWindowManager.Stub
192192
static final boolean DEBUG_STARTING_WINDOW = false;
193193
static final boolean DEBUG_REORDER = false;
194194
static final boolean DEBUG_WALLPAPER = false;
195-
static final boolean DEBUG_WALLPAPER_LIGHT = true || DEBUG_WALLPAPER;
195+
static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
196196
static final boolean DEBUG_DRAG = false;
197197
static final boolean DEBUG_SCREEN_ON = false;
198198
static final boolean DEBUG_SCREENSHOT = false;
@@ -545,7 +545,7 @@ public void onReceive(Context context, Intent intent) {
545545
WindowState mWallpaperTarget = null;
546546
// If non-null, we are in the middle of animating from one wallpaper target
547547
// to another, and this is the lower one in Z-order.
548-
private WindowState mLowerWallpaperTarget = null;
548+
WindowState mLowerWallpaperTarget = null;
549549
// If non-null, we are in the middle of animating from one wallpaper target
550550
// to another, and this is the higher one in Z-order.
551551
private WindowState mUpperWallpaperTarget = null;
@@ -2847,7 +2847,7 @@ public int relayoutWindow(Session session, IWindow client, int seq,
28472847
}
28482848
if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
28492849
// To change the format, we need to re-build the surface.
2850-
winAnimator.destroySurfaceLocked();
2850+
winAnimator.destroySurfaceLocked(false);
28512851
toBeDisplayed = true;
28522852
surfaceChanged = true;
28532853
}
@@ -2928,7 +2928,7 @@ public int relayoutWindow(Session session, IWindow client, int seq,
29282928
if (mInputMethodWindow == win) {
29292929
mInputMethodWindow = null;
29302930
}
2931-
winAnimator.destroySurfaceLocked();
2931+
winAnimator.destroySurfaceLocked(false);
29322932
}
29332933
scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
29342934
}
@@ -3030,7 +3030,7 @@ public void performDeferredDestroyWindow(Session session, IWindow client) {
30303030
if (win == null) {
30313031
return;
30323032
}
3033-
win.mWinAnimator.destroyDeferredSurfaceLocked();
3033+
win.mWinAnimator.destroyDeferredSurfaceLocked(false);
30343034
}
30353035
} finally {
30363036
Binder.restoreCallingIdentity(origId);
@@ -8136,7 +8136,7 @@ private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
81368136
pw.flush();
81378137
Slog.w(TAG, "This window was lost: " + ws);
81388138
Slog.w(TAG, sw.toString());
8139-
ws.mWinAnimator.destroySurfaceLocked();
8139+
ws.mWinAnimator.destroySurfaceLocked(false);
81408140
}
81418141
}
81428142
Slog.w(TAG, "Current app token list:");
@@ -9443,7 +9443,7 @@ private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMe
94439443
if (win == mWallpaperTarget) {
94449444
wallpaperDestroyed = true;
94459445
}
9446-
win.mWinAnimator.destroySurfaceLocked();
9446+
win.mWinAnimator.destroySurfaceLocked(false);
94479447
} while (i > 0);
94489448
mDestroySurface.clear();
94499449
}
@@ -9692,6 +9692,15 @@ void updateLayoutToAnimationLocked() {
96929692
allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList);
96939693
}
96949694

9695+
if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) {
9696+
if (mWallpaperTarget != layoutToAnim.mWallpaperTarget
9697+
|| mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget
9698+
|| mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) {
9699+
Slog.d(TAG, "Pushing anim wallpaper: target=" + layoutToAnim.mWallpaperTarget
9700+
+ " lower=" + layoutToAnim.mLowerWallpaperTarget + " upper="
9701+
+ layoutToAnim.mUpperWallpaperTarget + "\n" + Debug.getCallers(5, " "));
9702+
}
9703+
}
96959704
layoutToAnim.mWallpaperTarget = mWallpaperTarget;
96969705
layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget;
96979706
layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget;

services/java/com/android/server/wm/WindowState.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -875,8 +875,8 @@ void removeLocked() {
875875
if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
876876
mAttachedWindow.mChildWindows.remove(this);
877877
}
878-
mWinAnimator.destroyDeferredSurfaceLocked();
879-
mWinAnimator.destroySurfaceLocked();
878+
mWinAnimator.destroyDeferredSurfaceLocked(false);
879+
mWinAnimator.destroySurfaceLocked(false);
880880
mSession.windowRemovedLocked();
881881
try {
882882
mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);

services/java/com/android/server/wm/WindowStateAnimator.java

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ void cancelExitAnimationForNextAnimationLocked() {
225225
mAnimation.cancel();
226226
mAnimation = null;
227227
mLocalAnimating = false;
228-
destroySurfaceLocked();
228+
destroySurfaceLocked(true);
229229
}
230230
}
231231

@@ -412,7 +412,7 @@ void finishExit() {
412412
mService.mPendingRemove.add(mWin);
413413
mWin.mRemoveOnExit = false;
414414
}
415-
mAnimator.hideWallpapersLocked(mWin);
415+
mAnimator.hideWallpapersLocked(mWin, true);
416416
}
417417

418418
void hide() {
@@ -500,17 +500,21 @@ public SurfaceTrace(SurfaceSession s,
500500
@Override
501501
public void setAlpha(float alpha) {
502502
super.setAlpha(alpha);
503+
if (alpha != mSurfaceTraceAlpha) {
504+
Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
505+
+ Debug.getCallers(3));
506+
}
503507
mSurfaceTraceAlpha = alpha;
504-
Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
505-
+ Debug.getCallers(3));
506508
}
507509

508510
@Override
509511
public void setLayer(int zorder) {
510512
super.setLayer(zorder);
513+
if (zorder != mLayer) {
514+
Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
515+
+ Debug.getCallers(3));
516+
}
511517
mLayer = zorder;
512-
Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
513-
+ Debug.getCallers(3));
514518

515519
sSurfaces.remove(this);
516520
int i;
@@ -526,49 +530,61 @@ public void setLayer(int zorder) {
526530
@Override
527531
public void setPosition(float x, float y) {
528532
super.setPosition(x, y);
533+
if (x != mPosition.x || y != mPosition.y) {
534+
Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
535+
+ Debug.getCallers(3));
536+
}
529537
mPosition.set(x, y);
530-
Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
531-
+ Debug.getCallers(3));
532538
}
533539

534540
@Override
535541
public void setSize(int w, int h) {
536542
super.setSize(w, h);
543+
if (w != mSize.x || h != mSize.y) {
544+
Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
545+
+ Debug.getCallers(3));
546+
}
537547
mSize.set(w, h);
538-
Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
539-
+ Debug.getCallers(3));
540548
}
541549

542550
@Override
543551
public void setWindowCrop(Rect crop) {
544552
super.setWindowCrop(crop);
545553
if (crop != null) {
554+
if (!crop.equals(mWindowCrop)) {
555+
Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
556+
+ Debug.getCallers(3));
557+
}
546558
mWindowCrop.set(crop);
547559
}
548-
Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
549-
+ Debug.getCallers(3));
550560
}
551561

552562
@Override
553563
public void setLayerStack(int layerStack) {
554564
super.setLayerStack(layerStack);
565+
if (layerStack != mLayerStack) {
566+
Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3));
567+
}
555568
mLayerStack = layerStack;
556-
Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3));
557569
}
558570

559571
@Override
560572
public void hide() {
561573
super.hide();
574+
if (mShown) {
575+
Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
576+
+ Debug.getCallers(3));
577+
}
562578
mShown = false;
563-
Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
564-
+ Debug.getCallers(3));
565579
}
566580
@Override
567581
public void show() {
568582
super.show();
583+
if (!mShown) {
584+
Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
585+
+ Debug.getCallers(3));
586+
}
569587
mShown = true;
570-
Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
571-
+ Debug.getCallers(3));
572588
}
573589

574590
@Override
@@ -728,7 +744,7 @@ Surface createSurfaceLocked() {
728744
return mSurface;
729745
}
730746

731-
void destroySurfaceLocked() {
747+
void destroySurfaceLocked(boolean fromAnimator) {
732748
if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
733749
mWin.mAppToken.startingDisplayed = false;
734750
}
@@ -778,7 +794,7 @@ void destroySurfaceLocked() {
778794
}
779795
mSurface.destroy();
780796
}
781-
mAnimator.hideWallpapersLocked(mWin);
797+
mAnimator.hideWallpapersLocked(mWin, fromAnimator);
782798
} catch (RuntimeException e) {
783799
Slog.w(TAG, "Exception thrown when destroying Window " + this
784800
+ " surface " + mSurface + " session " + mSession
@@ -792,7 +808,7 @@ void destroySurfaceLocked() {
792808
}
793809
}
794810

795-
void destroyDeferredSurfaceLocked() {
811+
void destroyDeferredSurfaceLocked(boolean fromAnimator) {
796812
try {
797813
if (mPendingDestroySurface != null) {
798814
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
@@ -804,7 +820,7 @@ void destroyDeferredSurfaceLocked() {
804820
WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
805821
}
806822
mPendingDestroySurface.destroy();
807-
mAnimator.hideWallpapersLocked(mWin);
823+
mAnimator.hideWallpapersLocked(mWin, fromAnimator);
808824
}
809825
} catch (RuntimeException e) {
810826
Slog.w(TAG, "Exception thrown when destroying Window "
@@ -1192,7 +1208,7 @@ public void prepareSurfaceLocked(final boolean recoveringMemory) {
11921208
hide();
11931209
} else if (w.mAttachedHidden || !w.isReadyForDisplay()) {
11941210
hide();
1195-
mAnimator.hideWallpapersLocked(w);
1211+
mAnimator.hideWallpapersLocked(w, true);
11961212

11971213
// If we are waiting for this window to handle an
11981214
// orientation change, well, it is hidden, so

0 commit comments

Comments
 (0)