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

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

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

am: 7e7449f1

* commit '7e7449f1':
  Fixes for restoring more than one child surfaces

Change-Id: I12388334b28a51d1f964634cd17cd8f738cca6c8
parents 57977c14 7e7449f1
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;