Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98129739 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

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
parent 7ab7f538
Loading
Loading
Loading
Loading
+29 −8
Original line number Diff line number Diff line
@@ -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;
            }
        }
+16 −7
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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);
+38 −22
Original line number Diff line number Diff line
@@ -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);
            mSurfaceTraceAlpha = alpha;
            if (alpha != mSurfaceTraceAlpha) {
                Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
                        + Debug.getCallers(3));
            }
            mSurfaceTraceAlpha = alpha;
        }

        @Override
        public void setLayer(int zorder) {
            super.setLayer(zorder);
            mLayer = zorder;
            if (zorder != mLayer) {
                Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
                        + Debug.getCallers(3));
            }
            mLayer = zorder;

            sSurfaces.remove(this);
            int i;
@@ -526,50 +530,62 @@ class WindowStateAnimator {
        @Override
        public void setPosition(float x, float y) {
            super.setPosition(x, y);
            mPosition.set(x, y);
            if (x != mPosition.x || y != mPosition.y) {
                Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
                        + Debug.getCallers(3));
            }
            mPosition.set(x, y);
        }

        @Override
        public void setSize(int w, int h) {
            super.setSize(w, h);
            mSize.set(w, h);
            if (w != mSize.x || h != mSize.y) {
                Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
                        + Debug.getCallers(3));
            }
            mSize.set(w, h);
        }

        @Override
        public void setWindowCrop(Rect crop) {
            super.setWindowCrop(crop);
            if (crop != null) {
                mWindowCrop.set(crop);
            }
                if (!crop.equals(mWindowCrop)) {
                    Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
                            + Debug.getCallers(3));
                }
                mWindowCrop.set(crop);
            }
        }

        @Override
        public void setLayerStack(int layerStack) {
            super.setLayerStack(layerStack);
            mLayerStack = layerStack;
            if (layerStack != mLayerStack) {
                Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3));
            }
            mLayerStack = layerStack;
        }

        @Override
        public void hide() {
            super.hide();
            mShown = false;
            if (mShown) {
                Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
                        + Debug.getCallers(3));
            }
            mShown = false;
        }
        @Override
        public void show() {
            super.show();
            mShown = true;
            if (!mShown) {
                Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
                        + Debug.getCallers(3));
            }
            mShown = true;
        }

        @Override
        public void destroy() {
@@ -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