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

Commit e22006d9 authored by Chong Zhang's avatar Chong Zhang
Browse files

Fix a flicker when opening app again quickly while it's exiting

If the app is waiting for an opening animation with a dummy placeholder,
we need to skip the surface placement (in addition to the animateLocked).

Also, when animating is changing from exiting to entering, the mAnimating
flag needs to be cleared until the new animation starts. This prevents the
surface placement to place it wrong before the new animaition starts.

bug: 28599295
bug: 27742244
Change-Id: I26f0ead80ee9993a6c766ae8686ab11d1729519c
parent 3a3fb73c
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -322,6 +322,14 @@ class WindowStateAnimator {
        return mAnimation != null;
    }

    /**
     * Is this window currently waiting to run an opening animation?
     */
    boolean isWaitingForOpening() {
        return mService.mAppTransition.isTransitionSet() && isDummyAnimation()
                && mService.mOpeningApps.contains(mWin.mAppToken);
    }

    void cancelExitAnimationForNextAnimationLocked() {
        if (DEBUG_ANIM) Slog.d(TAG,
                "cancelExitAnimationForNextAnimationLocked: " + mWin);
@@ -1448,8 +1456,7 @@ class WindowStateAnimator {
        // the same app again before the app's surface is destroyed or saved, the surface
        // is always ready in the whole process.) If we go ahead here, the opening app
        // will be shown with the full size before the correct animation spec arrives.
        if (mService.mAppTransition.isTransitionSet() && isDummyAnimation() &&
                mService.mOpeningApps.contains(w.mAppToken)) {
        if (isWaitingForOpening()) {
            return;
        }

+11 −3
Original line number Diff line number Diff line
@@ -772,7 +772,7 @@ class WindowSurfacePlacer {
                            }
                        }
                    }
                    if (!winAnimator.isAnimationStarting()) {
                    if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
                        // Updates the shown frame before we set up the surface. This is needed
                        // because the resizing could change the top-left position (in addition to
                        // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
@@ -1236,8 +1236,8 @@ class WindowSurfacePlacer {
            int topOpeningLayer = 0;
            if (animLp != null) {
                int layer = -1;
                for (int j = 0; j < wtoken.windows.size(); j++) {
                    final WindowState win = wtoken.windows.get(j);
                for (int j = 0; j < wtoken.allAppWindows.size(); j++) {
                    final WindowState win = wtoken.allAppWindows.get(j);
                    // Clearing the mAnimatingExit flag before entering animation. It will be set to true
                    // if app window is removed, or window relayout to invisible. We don't want to
                    // clear it out for windows that get replaced, because the animation depends on
@@ -1249,6 +1249,14 @@ class WindowSurfacePlacer {
                    // they won't eventually be removed by WindowStateAnimator#finishExit.
                    if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
                        win.mAnimatingExit = false;
                        // Clear mAnimating flag together with mAnimatingExit. When animation
                        // changes from exiting to entering, we need to clear this flag until the
                        // new animation gets applied, so that isAnimationStarting() becomes true
                        // until then.
                        // Otherwise applySurfaceChangesTransaction will faill to skip surface
                        // placement for this window during this period, one or more frame will
                        // show up with wrong position or scale.
                        win.mWinAnimator.mAnimating = false;
                    }
                    if (win.mWinAnimator.mAnimLayer > layer) {
                        layer = win.mWinAnimator.mAnimLayer;