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

Commit 7e7449f1 authored by Chong Zhang's avatar Chong Zhang Committed by Android (Google) Code Review
Browse files

Merge "Fixes for restoring more than one child surfaces" into nyc-dev

parents 79e28a53 9214704e
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -185,8 +185,7 @@ public class AppWindowAnimator {
        clearThumbnail();
        setNullAnimation();
        if (mAppToken.deferClearAllDrawn) {
            mAppToken.allDrawn = false;
            mAppToken.deferClearAllDrawn = false;
            mAppToken.clearAllDrawn();
        }
        mStackClip = STACK_CLIP_BEFORE_ANIM;
    }
+39 −19
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEME
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.WINDOW_REPLACEMENT_TIMEOUT_DURATION;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;

import com.android.server.input.InputApplicationHandle;
import com.android.server.wm.WindowManagerService.H;
@@ -65,10 +66,6 @@ class AppWindowToken extends WindowToken {

    final boolean voiceInteraction;

    // Whether we're performing an entering animation with a saved surface.
    boolean mAnimatingWithSavedSurface;


    Task mTask;
    boolean appFullscreen;
    int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -160,6 +157,13 @@ class AppWindowToken extends WindowToken {
        }
    }

    void setVisibleBeforeClientHidden() {
        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
            final WindowState w = allAppWindows.get(i);
            w.setVisibleBeforeClientHidden();
        }
    }

    void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
        firstWindowDrawn = true;

@@ -295,7 +299,7 @@ class AppWindowToken extends WindowToken {
            // If we're animating with a saved surface, we're already visible.
            // Return true so that the alpha doesn't get cleared.
            if (!win.mAppFreezing
                    && (win.mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface
                    && (win.mViewVisibility == View.VISIBLE || win.isAnimatingWithSavedSurface()
                            || (win.mWinAnimator.isAnimationSet()
                                    && !service.mAppTransition.isTransitionSet()))
                    && !win.mDestroying
@@ -347,7 +351,6 @@ class AppWindowToken extends WindowToken {

            win.destroyOrSaveSurface();
            if (win.mRemoveOnExit) {
                win.mAnimatingExit = false;
                service.removeWindowInnerLocked(win);
            }
            final DisplayContent displayContent = win.getDisplayContent();
@@ -391,43 +394,56 @@ class AppWindowToken extends WindowToken {
        return allDrawn;
    }

    boolean hasSavedSurface() {
    boolean canRestoreSurfaces() {
        for (int i = allAppWindows.size() -1; i >= 0; i--) {
            final WindowState ws = allAppWindows.get(i);
            if (ws.hasSavedSurface()) {
            final WindowState w = allAppWindows.get(i);
            if (w.canRestoreSurface()) {
                return true;
            }
        }
        return false;
    }

    void clearVisibleBeforeClientHidden() {
        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
            final WindowState w = allAppWindows.get(i);
            w.clearVisibleBeforeClientHidden();
        }
    }

    void restoreSavedSurfaces() {
        if (!hasSavedSurface()) {
        if (!canRestoreSurfaces()) {
            clearVisibleBeforeClientHidden();
            return;
        }
        mAnimatingWithSavedSurface = true;

        // Check if we have enough drawn windows to mark allDrawn= true.
        int numInteresting = 0;
        int numDrawn = 0;
        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
            WindowState w = allAppWindows.get(i);
            if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
                    && (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
                numInteresting++;
                if (w.hasSavedSurface()) {
                    w.restoreSavedSurface();
                }
            if (w != startingWindow && !w.mAppDied
                    && (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
                numInteresting++;
                if (w.isDrawnLw()) {
                    numDrawn++;
                }
            }
        }

        allDrawn |= (numInteresting > 0) && (numInteresting == numDrawn);
        if (!allDrawn) {
            allDrawn = (numInteresting > 0) && (numInteresting == numDrawn);
            if (allDrawn) {
                service.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
            }
        }
        clearVisibleBeforeClientHidden();

        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
                "restoreSavedSurfaces: " + appWindowToken + " allDrawn=" + allDrawn);
                "restoreSavedSurfaces: " + appWindowToken + " allDrawn=" + allDrawn
                + " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
    }

    void destroySavedSurfaces() {
@@ -435,7 +451,11 @@ class AppWindowToken extends WindowToken {
            WindowState win = allAppWindows.get(i);
            win.destroySavedSurface();
        }
        mAnimatingWithSavedSurface = false;
    }

    void clearAllDrawn() {
        allDrawn = false;
        deferClearAllDrawn = false;
    }

    @Override
+7 −8
Original line number Diff line number Diff line
@@ -2170,7 +2170,7 @@ public class WindowManagerService extends IWindowManager.Stub
     * Returns true if we're done setting up any transitions.
     */
    private boolean prepareWindowReplacementTransition(AppWindowToken atoken) {
        atoken.allDrawn = false;
        atoken.clearAllDrawn();
        WindowState replacedWindow = null;
        for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) {
            WindowState candidate = atoken.windows.get(i);
@@ -2316,7 +2316,7 @@ public class WindowManagerService extends IWindowManager.Stub
                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is "
                        + "added");
                // TODO: We are overloading mAnimatingExit flag to prevent the window state from
                // been removed. We probably need another falg to indicate that window removal
                // been removed. We probably need another flag to indicate that window removal
                // should be deffered vs. overloading the flag that says we are playing an exit
                // animation.
                win.mAnimatingExit = true;
@@ -2464,7 +2464,7 @@ public class WindowManagerService extends IWindowManager.Stub
                mTokenMap.remove(token.token);
            } else if (atoken != null) {
                atoken.firstWindowDrawn = false;
                atoken.allDrawn = false;
                atoken.clearAllDrawn();
            }
        }

@@ -4423,6 +4423,7 @@ public class WindowManagerService extends IWindowManager.Stub
                // Now that the app is going invisible, we can remove it. It will be restarted
                // if made visible again.
                wtoken.removeAllDeadWindows();
                wtoken.setVisibleBeforeClientHidden();
            } else if (visible) {
                if (!mAppTransition.isTransitionSet() && mAppTransition.isReady()) {
                    // Add the app mOpeningApps if transition is unset but ready. This means
@@ -4434,8 +4435,7 @@ public class WindowManagerService extends IWindowManager.Stub
                // If the token is currently hidden (should be the common case), or has been
                // stopped, then we need to set up to wait for its windows to be ready.
                if (wtoken.hidden || wtoken.mAppStopped) {
                    wtoken.allDrawn = false;
                    wtoken.deferClearAllDrawn = false;
                    wtoken.clearAllDrawn();

                    // If the app was already visible, don't reset the waitingToShow state.
                    if (wtoken.hidden) {
@@ -9234,8 +9234,7 @@ public class WindowManagerService extends IWindowManager.Stub
                    }
                    winAnimator.mDrawState = DRAW_PENDING;
                    if (w.mAppToken != null) {
                        w.mAppToken.allDrawn = false;
                        w.mAppToken.deferClearAllDrawn = false;
                        w.mAppToken.clearAllDrawn();
                    }
                }
                if (!mResizingWindows.contains(w)) {
@@ -9392,7 +9391,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
                                + ws + " surface=" + wsa.mSurfaceController
                                + " token=" + ws.mAppToken
                                + " saved=" + ws.mAppToken.hasSavedSurface());
                                + " saved=" + ws.hasSavedSurface());
                        if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
                        wsa.destroySurface();
                        leakedSurface = true;
+55 −5
Original line number Diff line number Diff line
@@ -435,7 +435,15 @@ final class WindowState implements WindowManagerPolicy.WindowState {

    // Whether the window has a saved surface from last pause, which can be
    // used to start an entering animation earlier.
    public boolean mSurfaceSaved = false;
    private boolean mSurfaceSaved = false;

    // Whether we're performing an entering animation with a saved surface.
    private boolean mAnimatingWithSavedSurface;

    // Whether the window was visible when we set the app to invisible last time. WM uses
    // this as a hint to restore the surface (if available) for early animation next time
    // the app is brought visible.
    boolean mWasVisibleBeforeClientHidden;

    // This window will be replaced due to relaunch. This allows window manager
    // to differentiate between simple removal of a window and replacement. In the latter case it
@@ -1949,7 +1957,20 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    }

    boolean isAnimatingWithSavedSurface() {
        return mAppToken != null && mAppToken.mAnimatingWithSavedSurface;
        return mAnimatingWithSavedSurface;
    }

    public void setVisibleBeforeClientHidden() {
        mWasVisibleBeforeClientHidden |=
                (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface);
    }

    public void clearVisibleBeforeClientHidden() {
        mWasVisibleBeforeClientHidden = false;
    }

    public boolean wasVisibleBeforeClientHidden() {
        return mWasVisibleBeforeClientHidden;
    }

    private boolean shouldSaveSurface() {
@@ -1958,6 +1979,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
            return false;
        }

        if (!mWasVisibleBeforeClientHidden) {
            return false;
        }

        if ((mAttrs.flags & FLAG_SECURE) != 0) {
            // We don't save secure surfaces since their content shouldn't be shown while the app
            // isn't on screen and content might leak through during the transition animation with
@@ -2020,18 +2045,22 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        } else {
            mWinAnimator.destroySurfaceLocked();
        }
        // Clear animating flags now, since the surface is now gone. (Note this is true even
        // if the surface is saved, to outside world the surface is still NO_SURFACE.)
        mAnimatingExit = false;
    }

    public void destroySavedSurface() {
    void destroySavedSurface() {
        if (mSurfaceSaved) {
            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
                Slog.v(TAG, "Destroying saved surface: " + this);
            }
            mWinAnimator.destroySurfaceLocked();
        }
        mWasVisibleBeforeClientHidden = false;
    }

    public void restoreSavedSurface() {
    void restoreSavedSurface() {
        if (!mSurfaceSaved) {
            return;
        }
@@ -2039,6 +2068,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        if (mWinAnimator.mSurfaceController != null) {
            setHasSurface(true);
            mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
            mAnimatingWithSavedSurface = true;

            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
                Slog.v(TAG, "Restoring saved surface: " + this);
@@ -2051,10 +2081,30 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        }
    }

    public boolean hasSavedSurface() {
    boolean canRestoreSurface() {
        return mWasVisibleBeforeClientHidden && mSurfaceSaved;
    }

    boolean hasSavedSurface() {
        return mSurfaceSaved;
    }

    void clearHasSavedSurface() {
        mSurfaceSaved = false;
        mAnimatingWithSavedSurface = false;
        mWasVisibleBeforeClientHidden = false;
    }

    void clearAnimatingWithSavedSurface() {
        if (mAnimatingWithSavedSurface) {
            // App has drawn something to its windows, we're no longer animating with
            // the saved surfaces.
            if (DEBUG_ANIM) Slog.d(TAG,
                    "clearAnimatingWithSavedSurface(): win=" + this);
            mAnimatingWithSavedSurface = false;
        }
    }

    @Override
    public boolean isDefaultDisplay() {
        final DisplayContent displayContent = getDisplayContent();
+5 −13
Original line number Diff line number Diff line
@@ -584,14 +584,8 @@ class WindowStateAnimator {
                    + drawStateToString());
        }

        if (mWin.mAppToken != null && mWin.mAppToken.mAnimatingWithSavedSurface) {
            // App has drawn something to its windows, we're no longer animating with
            // the saved surfaces. If the user exits now, we only want to save again
            // if allDrawn is true.
            if (DEBUG_ANIM) Slog.d(TAG,
                    "finishDrawingLocked: mAnimatingWithSavedSurface=false " + mWin);
            mWin.mAppToken.mAnimatingWithSavedSurface = false;
        }
        mWin.clearAnimatingWithSavedSurface();

        if (mDrawState == DRAW_PENDING) {
            if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
                Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
@@ -687,8 +681,7 @@ class WindowStateAnimator {
        mDrawState = DRAW_PENDING;
        if (w.mAppToken != null) {
            if (w.mAppToken.mAppAnimator.animation == null) {
                w.mAppToken.allDrawn = false;
                w.mAppToken.deferClearAllDrawn = false;
                w.mAppToken.clearAllDrawn();
            } else {
                // Currently animating, persist current state of allDrawn until animation
                // is complete.
@@ -840,20 +833,19 @@ class WindowStateAnimator {
    }

    boolean hasSurface() {
        return !mWin.mSurfaceSaved
        return !mWin.hasSavedSurface()
                && mSurfaceController != null && mSurfaceController.hasSurface();
    }

    void destroySurfaceLocked() {
        final AppWindowToken wtoken = mWin.mAppToken;
        if (wtoken != null) {
            wtoken.mAnimatingWithSavedSurface = false;
            if (mWin == wtoken.startingWindow) {
                wtoken.startingDisplayed = false;
            }
        }

        mWin.mSurfaceSaved = false;
        mWin.clearHasSavedSurface();

        if (mSurfaceController == null) {
            return;