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

Commit 9ecf7cfe authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Android (Google) Code Review
Browse files

Merge "Clean-up WindowState if exit animation is done before app finishes" into nyc-dev

parents 7503d06e c48a3547
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -254,7 +254,7 @@ class AppWindowToken extends WindowToken {
                // In cases where there are multiple windows, we prefer the non-exiting window. This
                // happens for example when replacing windows during an activity relaunch. When
                // constructing the animation, we want the new window, not the exiting one.
                if (win.mExiting) {
                if (win.mAnimatingExit) {
                    candidate = win;
                } else {
                    return win;
@@ -307,11 +307,11 @@ class AppWindowToken extends WindowToken {
            // If the app already requested to remove its window, we don't modify
            // its exiting state. Otherwise the stale window won't get removed on
            // exit and could cause focus to be given to the wrong window.
            if (!(win.mRemoveOnExit && win.mExiting)) {
                win.mExiting = exiting;
            if (!(win.mRemoveOnExit && win.mAnimatingExit)) {
                win.mAnimatingExit = exiting;
            }
            // If we're no longer exiting, remove the window from destroying list
            if (!win.mExiting && win.mDestroying) {
            if (!win.mAnimatingExit && win.mDestroying) {
                win.mDestroying = false;
                service.mDestroySurface.remove(win);
            }
@@ -330,13 +330,13 @@ class AppWindowToken extends WindowToken {
                continue;
            }

            if (!mAppStopped && !win.mClientRemoveRequested) {
            if (!(mAppStopped || win.mWindowRemovalAllowed)) {
                continue;
            }

            win.destroyOrSaveSurface();
            if (win.mRemoveOnExit) {
                win.mExiting = false;
                win.mAnimatingExit = false;
                service.removeWindowInnerLocked(win);
            }
            final DisplayContent displayContent = win.getDisplayContent();
+1 −1
Original line number Diff line number Diff line
@@ -383,7 +383,7 @@ public class TaskStack implements DimLayer.DimLayerUser,
                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                    final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
                    if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) {
                    if (winAnimator.isAnimating() || winAnimator.mWin.mAnimatingExit) {
                        return true;
                    }
                }
+54 −49
Original line number Diff line number Diff line
@@ -192,6 +192,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
@@ -1354,7 +1356,7 @@ public class WindowManagerService extends IWindowManager.Stub
                            + " policyVis=" + w.mPolicyVisibility
                            + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
                            + " attachHid=" + w.mAttachedHidden
                            + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
                            + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
                    if (w.mAppToken != null) {
                        Slog.i(TAG_WM, "  mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
                    }
@@ -2057,7 +2059,7 @@ public class WindowManagerService extends IWindowManager.Stub
        WindowState replacedWindow = null;
        for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) {
            WindowState candidate = atoken.windows.get(i);
            if (candidate.mExiting && candidate.mWillReplaceWindow
            if (candidate.mAnimatingExit && candidate.mWillReplaceWindow
                    && candidate.mAnimateReplacingWindow) {
                replacedWindow = candidate;
            }
@@ -2131,19 +2133,12 @@ public class WindowManagerService extends IWindowManager.Stub
            if (win == null) {
                return;
            }
            // We set this here instead of removeWindowLocked because we only want it to be
            // true when the client has requested we remove the window. In other remove
            // cases, we have to wait for activity stop to safely remove the window (as the
            // client may still be using the surface). In this case though, the client has
            // just dismissed a window (for example a Dialog) and activity stop isn't
            // necessarily imminent, so we need to know not to wait for it after our
            // hanimation (if applicable) finishes.
            win.mClientRemoveRequested = true;
            removeWindowLocked(win);
        }
    }

    void removeWindowLocked(WindowState win) {
        win.mWindowRemovalAllowed = true;
        final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING;
        if (startingWindow) {
            if (DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, "Starting window removed " + win);
@@ -2159,23 +2154,25 @@ public class WindowManagerService extends IWindowManager.Stub

        win.disposeInputChannel();

        if (DEBUG_APP_TRANSITIONS) Slog.v(
                TAG_WM, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
                + " mExiting=" + win.mExiting
        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
                + " mAnimatingExit=" + win.mAnimatingExit
                + " mRemoveOnExit=" + win.mRemoveOnExit
                + " mHasSurface=" + win.mHasSurface
                + " surfaceShowing=" + win.mWinAnimator.getShown()
                + " isAnimating=" + win.mWinAnimator.isAnimating()
                + " app-animation="
                + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
                + " mWillReplaceWindow="
                + win.mWillReplaceWindow
                + " mWillReplaceWindow=" + win.mWillReplaceWindow
                + " inPendingTransaction="
                + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
                + " mDisplayFrozen=" + mDisplayFrozen);
                + " mDisplayFrozen=" + mDisplayFrozen
                + " callers=" + Debug.getCallers(6));
        // Visibility of the removed window. Will be used later to update orientation later on.
        boolean wasVisible = false;
        // First, see if we need to run an animation.  If we do, we have
        // to hold off on removing the window until the animation is done.
        // If the display is frozen, just remove immediately, since the
        // animation wouldn't be seen.
        // First, see if we need to run an animation. If we do, we have to hold off on removing the
        // window until the animation is done. If the display is frozen, just remove immediately,
        // since the animation wouldn't be seen.
        if (win.mHasSurface && okToDisplay()) {
            final AppWindowToken appToken = win.mAppToken;
            if (win.mWillReplaceWindow) {
@@ -2183,13 +2180,16 @@ public class WindowManagerService extends IWindowManager.Stub
                // gets added, then we will get rid of this one.
                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is "
                        + "added");
                win.mExiting = true;
                // TODO: We are overloading mAnimatingExit flag to prevent the window state from
                // been removed. We probably need another falg to indicate that window removal
                // should be deffered vs. overloading the flag that says we are playing an exit
                // animation.
                win.mAnimatingExit = true;
                win.mReplacingRemoveRequested = true;
                Binder.restoreCallingIdentity(origId);
                return;
            }
            // If we are not currently running the exit animation, we
            // need to see about starting one.
            // If we are not currently running the exit animation, we need to see about starting one
            wasVisible = win.isWinVisibleLw();

            if (win.shouldKeepVisibleDeadAppWindow()) {
@@ -2209,14 +2209,13 @@ public class WindowManagerService extends IWindowManager.Stub
                return;
            }

            final WindowStateAnimator winAnimator = win.mWinAnimator;
            if (wasVisible) {
                final int transit = (!startingWindow)
                        ? WindowManagerPolicy.TRANSIT_EXIT
                        : WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
                final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;

                // Try starting an animation.
                if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
                    win.mExiting = true;
                if (winAnimator.applyAnimationLocked(transit, false)) {
                    win.mAnimatingExit = true;
                }
                //TODO (multidisplay): Magnification is supported only for the default display.
                if (mAccessibilityController != null
@@ -2224,15 +2223,20 @@ public class WindowManagerService extends IWindowManager.Stub
                    mAccessibilityController.onWindowTransitionLocked(win, transit);
                }
            }
            final boolean isAnimating = win.mWinAnimator.isAnimating()
                    && !win.mWinAnimator.isDummyAnimation();
            // The starting window is the last window in this app token and it isn't animating.
            // Allow it to be removed now as there is no additional window or animation that will
            // trigger its removal.
            final boolean lastWinStartingNotAnimating = startingWindow && appToken!= null
                    && appToken.allAppWindows.size() == 1 && !isAnimating;
            if (!lastWinStartingNotAnimating && win.mExiting) {
                // The exit animation is running... wait for it!
            final boolean isAnimating =
                    winAnimator.isAnimating() && !winAnimator.isDummyAnimation();
            final boolean lastWindowIsStartingWindow = startingWindow && appToken != null
                    && appToken.allAppWindows.size() == 1;
            // We delay the removal of a window if it has a showing surface that can be used to run
            // exit animation and it is marked as exiting.
            // Also, If isn't the an animating starting window that is the last window in the app.
            // We allow the removal of the non-animating starting window now as there is no
            // additional window or animation that will trigger its removal.
            if (winAnimator.getShown() && win.mAnimatingExit
                    && (!lastWindowIsStartingWindow || isAnimating)) {
                // The exit animation is running or should run... wait for it!
                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                        "Not removing " + win + " due to exit animation ");
                win.mRemoveOnExit = true;
                win.setDisplayLayoutNeeded();
                final boolean focusChanged = updateFocusedWindowLocked(
@@ -2262,13 +2266,14 @@ public class WindowManagerService extends IWindowManager.Stub
    void removeWindowInnerLocked(WindowState win) {
        if (win.mRemoved) {
            // Nothing to do.
            if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                    "removeWindowInnerLocked: " + win + " Already removed...");
            return;
        }

        for (int i = win.mChildWindows.size() - 1; i >= 0; i--) {
            WindowState cwin = win.mChildWindows.get(i);
            Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container "
                    + win);
            Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container " + win);
            removeWindowInnerLocked(cwin);
        }

@@ -2681,16 +2686,16 @@ public class WindowManagerService extends IWindowManager.Stub
                final boolean usingSavedSurfaceBeforeVisible =
                        oldVisibility != View.VISIBLE && win.isAnimatingWithSavedSurface();
                if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
                    if (winAnimator.hasSurface() && !win.mExiting
                    if (winAnimator.hasSurface() && !win.mAnimatingExit
                            && usingSavedSurfaceBeforeVisible) {
                        Slog.d(TAG, "Ignoring layout to invisible when using saved surface " + win);
                    }
                }

                if (winAnimator.hasSurface() && !win.mExiting
                if (winAnimator.hasSurface() && !win.mAnimatingExit
                        && !usingSavedSurfaceBeforeVisible) {
                    if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win
                            + ": mExiting=" + win.mExiting);
                            + ": mAnimatingExit=" + win.mAnimatingExit);
                    // If we are not currently running the exit animation, we
                    // need to see about starting one.
                    // We don't want to animate visibility of windows which are pending
@@ -2797,16 +2802,16 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
            focusMayChange = isDefaultDisplay;
            win.mExiting = true;
            win.mAnimatingExit = true;
        } else if (win.mWinAnimator.isAnimating()) {
            // Currently in a hide animation... turn this into
            // an exit.
            win.mExiting = true;
            win.mAnimatingExit = true;
        } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
            // If the wallpaper is currently behind this
            // window, we need to change both of them inside
            // of a transaction to avoid artifacts.
            win.mExiting = true;
            win.mAnimatingExit = true;
            win.mWinAnimator.mAnimating = true;
        } else {
            if (mInputMethodWindow == win) {
@@ -2842,12 +2847,12 @@ public class WindowManagerService extends IWindowManager.Stub
    private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win,
            WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) {
        result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0;
        if (win.mExiting) {
            Slog.d(TAG, "relayoutVisibleWindow: " + win + " mExiting=true, mRemoveOnExit="
        if (win.mAnimatingExit) {
            Slog.d(TAG, "relayoutVisibleWindow: " + win + " mAnimatingExit=true, mRemoveOnExit="
                    + win.mRemoveOnExit + ", mDestroying=" + win.mDestroying);

            winAnimator.cancelExitAnimationForNextAnimationLocked();
            win.mExiting = false;
            win.mAnimatingExit = false;
        }
        if (win.mDestroying) {
            win.mDestroying = false;
+20 −20
Original line number Diff line number Diff line
@@ -358,7 +358,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    boolean mLayoutNeeded;

    /** Currently running an exit animation? */
    boolean mExiting;
    boolean mAnimatingExit;

    /** Currently on the mDestroySurface list? */
    boolean mDestroying;
@@ -387,11 +387,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    boolean mRemoved;

    /**
     * Has the client requested we remove the window? In this case we know
     * that we can dispose of it when we wish without further synchronization
     * with the client
     * It is save to remove the window and destroy the surface because the client requested removal
     * or some other higher level component said so (e.g. activity manager).
     * TODO: We should either have different booleans for the removal reason or use a bit-field.
     */
    boolean mClientRemoveRequested;
    boolean mWindowRemovalAllowed;

    /**
     * Temp for keeping track of windows that have been removed when
@@ -614,7 +614,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    @Override
    public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
            Rect osf) {
        if (mWillReplaceWindow && (mExiting || !mReplacingRemoveRequested)) {
        if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
            // This window is being replaced and either already got information that it's being
            // removed or we are still waiting for some information. Because of this we don't
            // want to apply any more changes to it, so it remains in this state until new window
@@ -1075,7 +1075,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
     */
    private boolean isVisibleUnchecked() {
        return mHasSurface && mPolicyVisibility && !mAttachedHidden
                && !mExiting && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
                && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
    }

    /**
@@ -1100,7 +1100,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        }
        final AppWindowToken atoken = mAppToken;
        final boolean animating = atoken != null && atoken.mAppAnimator.animation != null;
        return mHasSurface && !mDestroying && !mExiting
        return mHasSurface && !mDestroying && !mAnimatingExit
                && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
                        || mWinAnimator.mAnimation != null || animating);
@@ -1143,7 +1143,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
                && mPolicyVisibility && !mAttachedHidden
                && (atoken == null || !atoken.hiddenRequested)
                && !mExiting && !mDestroying;
                && !mAnimatingExit && !mDestroying;
    }

    /**
@@ -1237,7 +1237,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
                || (atoken == null && mRootToken.hidden)
                || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
                || mAttachedHidden
                || (mExiting && !isAnimatingLw())
                || (mAnimatingExit && !isAnimatingLw())
                || mDestroying;
    }

@@ -1283,7 +1283,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
     */
    boolean hasMoved() {
        return mHasSurface && (mContentChanged || mMovedByResize)
                && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay()
                && !mAnimatingExit && !mWinAnimator.mLastHidden && mService.okToDisplay()
                && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left)
                && (mAttachedWindow == null || !mAttachedWindow.hasMoved());
    }
@@ -1438,11 +1438,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
            return;
        }

        if (!mExiting && mAppDied) {
        if (!mAnimatingExit && mAppDied) {
            // If app died visible, apply a dim over the window to indicate that it's inactive
            mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator);
        } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0
                && mDisplayContent != null && !mExiting && isDisplayedLw()) {
                && mDisplayContent != null && !mAnimatingExit && isDisplayedLw()) {
            mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator);
        }
    }
@@ -1467,7 +1467,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
                win.mAnimateReplacingWindow = false;
                win.mReplacingRemoveRequested = false;
                win.mReplacingWindow = null;
                if (win.mExiting) {
                if (win.mAnimatingExit) {
                    mService.removeWindowInnerLocked(win);
                }
            }
@@ -1810,7 +1810,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    }

    boolean isClosing() {
        return mExiting || (mService.mClosingApps.contains(mAppToken));
        return mAnimatingExit || (mService.mClosingApps.contains(mAppToken));
    }

    boolean isAnimatingWithSavedSurface() {
@@ -2341,8 +2341,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        }
        pw.print(prefix); pw.print(mWinAnimator); pw.println(":");
        mWinAnimator.dump(pw, prefix + "  ", dumpAll);
        if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
            pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
        if (mAnimatingExit || mRemoveOnExit || mDestroying || mRemoved) {
            pw.print(prefix); pw.print("mAnimatingExit="); pw.print(mAnimatingExit);
                    pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
                    pw.print(" mDestroying="); pw.print(mDestroying);
                    pw.print(" mRemoved="); pw.println(mRemoved);
@@ -2403,12 +2403,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    @Override
    public String toString() {
        final CharSequence title = getWindowTag();
        if (mStringNameCache == null || mLastTitle != title || mWasExiting != mExiting) {
        if (mStringNameCache == null || mLastTitle != title || mWasExiting != mAnimatingExit) {
            mLastTitle = title;
            mWasExiting = mExiting;
            mWasExiting = mAnimatingExit;
            mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
                    + " u" + UserHandle.getUserId(mSession.mUid)
                    + " " + mLastTitle + (mExiting ? " EXITING}" : "}");
                    + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}");
        }
        return mStringNameCache;
    }
+10 −11
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -375,7 +374,7 @@ class WindowStateAnimator {

        // Done animating, clean up.
        if (DEBUG_ANIM) Slog.v(
            TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
            TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit
            + ", reportedVisible="
            + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));

@@ -430,7 +429,7 @@ class WindowStateAnimator {
    void finishExit() {
        if (DEBUG_ANIM) Slog.v(
                TAG, "finishExit in " + this
                + ": exiting=" + mWin.mExiting
                + ": exiting=" + mWin.mAnimatingExit
                + " remove=" + mWin.mRemoveOnExit
                + " windowAnimating=" + isWindowAnimating());

@@ -460,7 +459,7 @@ class WindowStateAnimator {
            }
        }

        if (!mWin.mExiting) {
        if (!mWin.mAnimatingExit) {
            return;
        }

@@ -475,27 +474,27 @@ class WindowStateAnimator {

        mWin.mDestroying = true;

        final boolean hasSurface = hasSurface();
        if (hasSurface) {
            hide("finishExit");
        }

        // If we have an app token, we ask it to destroy the surface for us,
        // so that it can take care to ensure the activity has actually stopped
        // and the surface is not still in use. Otherwise we add the service to
        // mDestroySurface and allow it to be processed in our next transaction.
        if (mWin.mAppToken != null) {
            if (hasSurface()) {
                hide("finishExit");
            }
            mWin.mAppToken.destroySurfaces();
        } else {
            if (hasSurface()) {
            if (hasSurface) {
                mService.mDestroySurface.add(mWin);
                hide("finishExit");
            }
            mWin.mExiting = false;
            if (mWin.mRemoveOnExit) {
                mService.mPendingRemove.add(mWin);
                mWin.mRemoveOnExit = false;
            }
        }

        mWin.mAnimatingExit = false;
        mWallpaperControllerLocked.hideWallpapers(mWin);
    }

Loading