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

Commit b6e66624 authored by Filip Gruszczynski's avatar Filip Gruszczynski
Browse files

Improve infrastructure for replacing windows.

We need to be more precise when removing the window that is being
replaced. We used to depend on the fact that we can remove it after
the first draw of the new added window. However, due to resizing the
old window might reset its draw state and that will trigger a removal
of that window.

We need to add an information about the window that is replacing the
old one and only when this new window draws itself, we remove the old
one.

This improves the transition after maximizing docked window. This is
a situation where first resize operation finishes and immediately
after we have a replacement operation.

Bug: 24914011
Change-Id: Ia8e5bb7872787e663ba23f26588f9c4db1a5e574
parent 20070371
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ public class Point implements Parcelable {

    /** @hide */
    public void printShortString(PrintWriter pw) {
        pw.println("["); pw.print(x); pw.print(","); pw.print(y); pw.print("]");
        pw.print("["); pw.print(x); pw.print(","); pw.print(y); pw.print("]");
    }

    /**
+4 −1
Original line number Diff line number Diff line
@@ -114,11 +114,14 @@ class AppWindowToken extends WindowToken {
    // This application will have its window replaced due to relaunch. This allows window manager
    // to differentiate between simple removal of a window and replacement. In the latter case it
    // will preserve the old window until the new one is drawn.
    boolean mReplacingWindow;
    boolean mWillReplaceWindow;
    // If true, the replaced window was already requested to be removed.
    boolean mReplacingRemoveRequested;
    // Whether the replacement of the window should trigger app transition animation.
    boolean mAnimateReplacingWindow;
    // If not null, the window that will be used to replace the old one. This is being set when
    // the window is added and unset when this window reports its first draw.
    WindowState mReplacingWindow;

    AppWindowToken(WindowManagerService _service, IApplicationToken _token,
            boolean _voiceInteraction) {
+22 −10
Original line number Diff line number Diff line
@@ -1327,8 +1327,14 @@ public class WindowManagerService extends IWindowManager.Stub
            addAttachedWindowToListLocked(win, addToToken);
        }

        if (win.mAppToken != null && addToToken) {
            win.mAppToken.allAppWindows.add(win);
        final AppWindowToken appToken = win.mAppToken;
        if (appToken != null) {
            if (addToToken) {
                appToken.allAppWindows.add(win);
            }
            if (appToken.mWillReplaceWindow) {
                appToken.mReplacingWindow = win;
            }
        }
    }

@@ -2053,7 +2059,7 @@ public class WindowManagerService extends IWindowManager.Stub
    }

    private void prepareWindowReplacementTransition(AppWindowToken atoken) {
        if (atoken == null || !atoken.mReplacingWindow || !atoken.mAnimateReplacingWindow) {
        if (atoken == null || !atoken.mWillReplaceWindow || !atoken.mAnimateReplacingWindow) {
            return;
        }
        atoken.allDrawn = false;
@@ -2157,6 +2163,8 @@ public class WindowManagerService extends IWindowManager.Stub
                + " isAnimating=" + win.mWinAnimator.isAnimating()
                + " app-animation="
                + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
                + " mWillReplaceWindow="
                + (win.mAppToken != null ? win.mAppToken.mWillReplaceWindow : false)
                + " inPendingTransaction="
                + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
                + " mDisplayFrozen=" + mDisplayFrozen);
@@ -2168,8 +2176,8 @@ public class WindowManagerService extends IWindowManager.Stub
        // animation wouldn't be seen.
        if (win.mHasSurface && okToDisplay()) {
            final AppWindowToken appToken = win.mAppToken;
            if (appToken != null && appToken.mReplacingWindow) {
                // This window is going to be replaced. We need to kepp it around until the new one
            if (appToken != null && appToken.mWillReplaceWindow) {
                // This window is going to be replaced. We need to keep it around until the new one
                // gets added, then we will get rid of this one.
                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Preserving " + win + " until the new one is "
                        + "added");
@@ -2833,7 +2841,8 @@ public class WindowManagerService extends IWindowManager.Stub
        try {
            synchronized (mWindowMap) {
                WindowState win = windowForClientLocked(session, client, false);
                if (DEBUG_ADD_REMOVE) Slog.d(TAG, "finishDrawingWindow: " + win);
                if (DEBUG_ADD_REMOVE) Slog.d(TAG, "finishDrawingWindow: " + win + " mDrawState="
                        + (win != null ? win.mWinAnimator.drawStateToString() : "null"));
                if (win != null && win.mWinAnimator.finishDrawingLocked()) {
                    if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
                        getDefaultDisplayContentLocked().pendingLayoutChanges |=
@@ -3920,7 +3929,7 @@ public class WindowManagerService extends IWindowManager.Stub
        // transition animation
        // * or this is an opening app and windows are being replaced.
        if (wtoken.hidden == visible || (wtoken.hidden && wtoken.mIsExiting) ||
                (visible && wtoken.mReplacingWindow)) {
                (visible && wtoken.mWillReplaceWindow)) {
            boolean changed = false;
            if (DEBUG_APP_TRANSITIONS) Slog.v(
                TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
@@ -8358,7 +8367,7 @@ public class WindowManagerService extends IWindowManager.Stub
                final int numTokens = tokens.size();
                for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
                    final AppWindowToken wtoken = tokens.get(tokenNdx);
                    if (wtoken.mIsExiting && !wtoken.mReplacingWindow) {
                    if (wtoken.mIsExiting && !wtoken.mWillReplaceWindow) {
                        continue;
                    }
                    i = reAddAppWindowsLocked(displayContent, i, wtoken);
@@ -8428,7 +8437,8 @@ public class WindowManagerService extends IWindowManager.Stub
            } else if (wtoken != null) {
                winAnimator.mAnimLayer =
                        w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
                if (wtoken.mReplacingWindow && wtoken.mAnimateReplacingWindow) {
                if (wtoken.mWillReplaceWindow && wtoken.mAnimateReplacingWindow &&
                        wtoken.mReplacingWindow != w) {
                    // We know that we will be animating a relaunching window in the near future,
                    // which will receive a z-order increase. We want the replaced window to
                    // immediately receive the same treatment, e.g. to be above the dock divider.
@@ -9974,7 +9984,9 @@ public class WindowManagerService extends IWindowManager.Stub
                Slog.w(TAG, "Attempted to set replacing window on non-existing app token " + token);
                return;
            }
            appWindowToken.mReplacingWindow = true;
            if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Marking app token " + appWindowToken
                    + " as replacing window.");
            appWindowToken.mWillReplaceWindow = true;
            appWindowToken.mAnimateReplacingWindow = animate;
        }
    }
+8 −5
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
@@ -55,7 +56,6 @@ import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.IBinder;
import android.os.RemoteException;
@@ -446,7 +446,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
                    + WindowManagerService.TYPE_LAYER_OFFSET;
            mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
            mAttachedWindow = attachedWindow;
            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to "
                    + mAttachedWindow);

            final WindowList childWindows = mAttachedWindow.mChildWindows;
            final int numChildWindows = childWindows.size();
@@ -552,7 +553,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 (mAppToken != null && mAppToken.mReplacingWindow
        if (mAppToken != null && mAppToken.mWillReplaceWindow
                && (mExiting || !mAppToken.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
@@ -1307,10 +1308,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {

    void maybeRemoveReplacedWindow() {
        AppWindowToken token = mAppToken;
        if (token != null && token.mReplacingWindow) {
            token.mReplacingWindow = false;
        if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == this) {
            if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replacing window: " + this);
            token.mWillReplaceWindow = false;
            token.mAnimateReplacingWindow = false;
            token.mReplacingRemoveRequested = false;
            token.mReplacingWindow = null;
            for (int i = token.allAppWindows.size() - 1; i >= 0; i--) {
                WindowState win = token.allAppWindows.get(i);
                if (win.mExiting) {
+2 −4
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Debug;
import android.os.RemoteException;
@@ -1428,7 +1427,7 @@ class WindowStateAnimator {
        // living in a different stack. If we suddenly crop it to the new stack bounds, it might
        // get cut off. We don't want it to happen, so we let it ignore the stack bounds until it
        // gets removed. The window that will replace it will abide them.
        if (appToken != null && appToken.mCropWindowsToStack && !appToken.mReplacingWindow) {
        if (appToken != null && appToken.mCropWindowsToStack && !appToken.mWillReplaceWindow) {
            TaskStack stack = w.getTask().mStack;
            stack.getBounds(mTmpStackBounds);
            // When we resize we use the big surface approach, which means we can't trust the
@@ -1854,8 +1853,7 @@ class WindowStateAnimator {
                }
            }

            if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
                    && mWin.mAppToken != null) {
            if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING && mWin.mAppToken != null) {
                mWin.mAppToken.firstWindowDrawn = true;

                if (mWin.mAppToken.startingData != null) {