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

Commit 8926e452 authored by Chong Zhang's avatar Chong Zhang Committed by android-build-merger
Browse files

Merge "Fix a flicker when window is removed during entering animation" into nyc-dev am: a285fdeb

am: 8f6a9ca5

* commit '8f6a9ca5':
  Fix a flicker when window is removed during entering animation

Change-Id: I716bfdd02375389667bd2b20dc6dcc6d60e6f2e3
parents 1ee1d948 8f6a9ca5
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -88,6 +88,11 @@ class AppWindowToken extends WindowToken {
    // case do not clear allDrawn until the animation completes.
    boolean deferClearAllDrawn;

    // These are to track the app's real drawing status if there were no saved surfaces.
    boolean allDrawnExcludingSaved;
    int numInterestingWindowsExcludingSaved;
    int numDrawnWindowsExclusingSaved;

    // Is this window's surface needed?  This is almost like hidden, except
    // it will sometimes be true a little earlier: when the token has
    // been shown, but is still waiting for its app transition to execute
@@ -411,6 +416,39 @@ class AppWindowToken extends WindowToken {
        }
    }

    /**
     * Whether the app has some window that is invisible in layout, but
     * animating with saved surface.
     */
    boolean isAnimatingInvisibleWithSavedSurface() {
        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
            final WindowState w = allAppWindows.get(i);
            if (w.isAnimatingInvisibleWithSavedSurface()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Hide all window surfaces that's still invisible in layout but animating
     * with a saved surface, and mark them destroying.
     */
    void stopUsingSavedSurfaceLocked() {
        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
            final WindowState w = allAppWindows.get(i);
            if (w.isAnimatingInvisibleWithSavedSurface()) {
                if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
                        "stopUsingSavedSurfaceLocked: " + w);
                w.clearAnimatingWithSavedSurface();
                w.mDestroying = true;
                w.mWinAnimator.hide("stopUsingSavedSurfaceLocked");
                w.mWinAnimator.mWallpaperControllerLocked.hideWallpapers(w);
            }
        }
        destroySurfaces();
    }

    void restoreSavedSurfaces() {
        if (!canRestoreSurfaces()) {
            clearVisibleBeforeClientHidden();
@@ -456,6 +494,7 @@ class AppWindowToken extends WindowToken {
    void clearAllDrawn() {
        allDrawn = false;
        deferClearAllDrawn = false;
        allDrawnExcludingSaved = false;
    }

    @Override
+1 −0
Original line number Diff line number Diff line
@@ -788,6 +788,7 @@ public class WindowAnimator {
            removeReplacedWindowsLocked();
        }

        mService.stopUsingSavedSurfaceLocked();
        mService.destroyPreservedSurfaceLocked();
        mService.mWindowPlacerLocked.destroyPendingSurfaces();

+33 −0
Original line number Diff line number Diff line
@@ -414,6 +414,13 @@ public class WindowManagerService extends IWindowManager.Stub
     */
    final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<>();

    /**
     * List of window tokens that have finished drawing their own windows and
     * no longer need to show any saved surfaces. Windows that's still showing
     * saved surfaces will be cleaned up after next animation pass.
     */
    final ArrayList<AppWindowToken> mFinishedEarlyAnim = new ArrayList<>();

    /**
     * List of app window tokens that are waiting for replacing windows. If the
     * replacement doesn't come in time the stale windows needs to be disposed of.
@@ -2330,6 +2337,23 @@ public class WindowManagerService extends IWindowManager.Stub
                Binder.restoreCallingIdentity(origId);
                return;
            }

            if (win.isAnimatingWithSavedSurface() && !appToken.allDrawnExcludingSaved) {
                // We started enter animation early with a saved surface, now the app asks to remove
                // this window. If we remove it now and the app is not yet drawn, we'll show a
                // flicker. Delay the removal now until it's really drawn.
                if (DEBUG_ADD_REMOVE) {
                    Slog.d(TAG_WM, "removeWindowLocked: delay removal of " + win
                            + " due to early animation");
                }
                // Do not set mAnimatingExit to true here, it will cause the surface to be hidden
                // immediately after the enter animation is done. If the app is not yet drawn then
                // it will show up as a flicker.
                win.mRemoveOnExit = true;
                win.mWindowRemovalAllowed = true;
                Binder.restoreCallingIdentity(origId);
                return;
            }
            // If we are not currently running the exit animation, we need to see about starting one
            wasVisible = win.isWinVisibleLw();

@@ -8560,6 +8584,15 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        mDestroyPreservedSurface.clear();
    }

    void stopUsingSavedSurfaceLocked() {
        for (int i = mFinishedEarlyAnim.size() - 1; i >= 0 ; i--) {
            final AppWindowToken wtoken = mFinishedEarlyAnim.get(i);
            wtoken.stopUsingSavedSurfaceLocked();
        }
        mFinishedEarlyAnim.clear();
    }

    // -------------------------------------------------------------
    // IWindowManager API
    // -------------------------------------------------------------
+35 −1
Original line number Diff line number Diff line
@@ -437,7 +437,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    // used to start an entering animation earlier.
    private boolean mSurfaceSaved = false;

    // Whether we're performing an entering animation with a saved surface.
    // Whether we're performing an entering animation with a saved surface. This flag is
    // true during the time we're showing a window with a previously saved surface. It's
    // cleared when surface is destroyed, saved, or re-drawn by the app.
    private boolean mAnimatingWithSavedSurface;

    // Whether the window was visible when we set the app to invisible last time. WM uses
@@ -1255,6 +1257,32 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        return !mAttachedHidden || mWinAnimator.mAnimation != null;
    }

    /**
     * Whether this window's drawn state might affect the drawn states of the app token.
     *
     * @param visibleOnly Whether we should consider only the windows that's currently
     *                    visible in layout. If true, windows that has not relayout to VISIBLE
     *                    would always return false.
     *
     * @return true if the window should be considered while evaluating allDrawn flags.
     */
    boolean mightAffectAllDrawn(boolean visibleOnly) {
        final boolean isViewVisible = (mViewVisibility == View.VISIBLE)
                && (mAppToken == null || !mAppToken.clientHidden);
        return (isOnScreenIgnoringKeyguard() && (!visibleOnly || isViewVisible)
                || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION)
                && !mAnimatingExit && !mDestroying;
    }

    /**
     * Whether this window is "interesting" when evaluating allDrawn. If it's interesting,
     * it must be drawn before allDrawn can become true.
     */
    boolean isInteresting() {
        return mAppToken != null && !mAppDied
                && (!mAppToken.mAppAnimator.freezingScreen || !mAppFreezing);
    }

    /**
     * Like isOnScreen(), but we don't return true if the window is part
     * of a transition that has not yet been started.
@@ -1960,6 +1988,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        return mAnimatingWithSavedSurface;
    }

    boolean isAnimatingInvisibleWithSavedSurface() {
        return mAnimatingWithSavedSurface
                && (mViewVisibility != View.VISIBLE || mWindowRemovalAllowed);
    }

    public void setVisibleBeforeClientHidden() {
        mWasVisibleBeforeClientHidden |=
                (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface);
@@ -2042,6 +2075,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
            if (mWinAnimator.mSurfaceController != null) {
                mWinAnimator.mSurfaceController.disconnectInTransaction();
            }
            mAnimatingWithSavedSurface = false;
        } else {
            mWinAnimator.destroySurfaceLocked();
        }
+41 −6
Original line number Diff line number Diff line
@@ -792,15 +792,16 @@ class WindowSurfacePlacer {
                            + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
                            + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
                }
                if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
                if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
                        || atoken.mAppAnimator.freezingScreen)) {
                    if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
                        atoken.lastTransactionSequence = mService.mTransactionSequence;
                        atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
                        atoken.numInterestingWindowsExcludingSaved = 0;
                        atoken.numDrawnWindowsExclusingSaved = 0;
                        atoken.startingDisplayed = false;
                    }
                    if ((w.isOnScreenIgnoringKeyguard()
                            || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
                            && !w.mAnimatingExit && !w.mDestroying) {
                    if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
                        if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
                            Slog.v(TAG, "Eval win " + w + ": isDrawn="
                                    + w.isDrawnLw()
@@ -816,13 +817,14 @@ class WindowSurfacePlacer {
                            }
                        }
                        if (w != atoken.startingWindow) {
                            if (!w.mAppDied &&
                                    (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing)) {
                            if (w.isInteresting()) {
                                atoken.numInterestingWindows++;
                                if (w.isDrawnLw()) {
                                    atoken.numDrawnWindows++;
                                    if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
                                        Slog.v(TAG, "tokenMayBeDrawn: " + atoken
                                                + " w=" + w + " numInteresting="
                                                + atoken.numInterestingWindows
                                                + " freezingScreen="
                                                + atoken.mAppAnimator.freezingScreen
                                                + " mAppFreezing=" + w.mAppFreezing);
@@ -834,6 +836,23 @@ class WindowSurfacePlacer {
                            atoken.startingDisplayed = true;
                        }
                    }
                    if (!atoken.allDrawnExcludingSaved
                            && w.mightAffectAllDrawn(true /* visibleOnly */)) {
                        if (w != atoken.startingWindow && w.isInteresting()) {
                            atoken.numInterestingWindowsExcludingSaved++;
                            if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
                                atoken.numDrawnWindowsExclusingSaved++;
                                if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
                                    Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
                                            + " w=" + w + " numInteresting="
                                            + atoken.numInterestingWindowsExcludingSaved
                                            + " freezingScreen="
                                            + atoken.mAppAnimator.freezingScreen
                                            + " mAppFreezing=" + w.mAppFreezing);
                                updateAllDrawn = true;
                            }
                        }
                    }
                }

                if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
@@ -1539,6 +1558,22 @@ class WindowSurfacePlacer {
                                    wtoken.token).sendToTarget();
                        }
                    }
                    if (!wtoken.allDrawnExcludingSaved) {
                        int numInteresting = wtoken.numInterestingWindowsExcludingSaved;
                        if (numInteresting > 0
                                && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) {
                            if (DEBUG_VISIBILITY)
                                Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken
                                    + " interesting=" + numInteresting
                                    + " drawn=" + wtoken.numDrawnWindowsExclusingSaved);
                            wtoken.allDrawnExcludingSaved = true;
                            displayContent.layoutNeeded = true;
                            if (wtoken.isAnimatingInvisibleWithSavedSurface()
                                    && !mService.mFinishedEarlyAnim.contains(wtoken)) {
                                mService.mFinishedEarlyAnim.add(wtoken);
                            }
                        }
                    }
                }
            }
        }