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

Commit b0fc817f authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Lock free app animations (7/n): Cleanup

- Make sure persister pausing is working
- Make sure Surface animation thread is being boosted
- Move all remaining fields from AppWindowAnimator and NUKE it,
also remove getAnimLayerAdjustment and do the z-boosting
directly on the AppWindowToken.

Bug: 64674361
Test: go/wm-smoke
Test: Inspect thread priorities before/during/after animations
Change-Id: Ie64c8231bcebd8536eab476ee9f2c51abf85480c
parent 32fd84ac
Loading
Loading
Loading
Loading
+0 −45
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.wm;

import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.view.SurfaceControl;
import android.view.animation.Animation;
import android.view.animation.Transformation;

// TODO: Move all remaining fields to AppWindowToken and remove this class.
public class AppWindowAnimator {

    // Have we been asked to have this token keep the screen frozen?
    // Protect with mAnimator.
    boolean freezingScreen;

    /**
     * How long we last kept the screen frozen.
     */
    int lastFreezeDuration;

    // Offset to the window of all layers in the token, for use by
    // AppWindowToken animations.
    int animLayerAdjustment;

    // Propagated from AppWindowToken.allDrawn, to determine when
    // the state changes.
    boolean allDrawn;
}
+1 −1
Original line number Diff line number Diff line
@@ -690,7 +690,7 @@ public class AppWindowContainerController
                return;
            }
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + mToken + ": hidden="
                    + mContainer.isHidden() + " freezing=" + mContainer.mAppAnimator.freezingScreen);
                    + mContainer.isHidden() + " freezing=" + mContainer.isFreezingScreen());
            mContainer.stopFreezingScreen(true, force);
        }
    }
+32 −27
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@ import android.os.Binder;
import android.os.Debug;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -96,8 +95,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    // Non-null only for application tokens.
    final IApplicationToken appToken;

    @NonNull final AppWindowAnimator mAppAnimator;

    final boolean mVoiceInteraction;

    /** @see WindowContainer#fillsParent() */
@@ -125,6 +122,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    private int mNumDrawnWindows;
    boolean inPendingTransaction;
    boolean allDrawn;
    private boolean mLastAllDrawn;

    // Set to true when this app creates a surface while in the middle of an animation. In that
    // case do not clear allDrawn until the animation completes.
    boolean deferClearAllDrawn;
@@ -211,6 +210,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

    private AppWindowThumbnail mThumbnail;

    /** Have we been asked to have this token keep the screen frozen? */
    private boolean mFreezingScreen;

    /** Whether this token should be boosted at the top of all app window tokens. */
    private boolean mNeedsZBoost;

    AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
            DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
            boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -240,7 +245,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
        mVoiceInteraction = voiceInteraction;
        mFillsParent = fillsParent;
        mInputApplicationHandle = new InputApplicationHandle(this);
        mAppAnimator = new AppWindowAnimator();
    }

    void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
@@ -1018,13 +1022,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

    void startFreezingScreen() {
        if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
                + isHidden() + " freezing=" + mAppAnimator.freezingScreen + " hiddenRequested="
                + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
                + hiddenRequested);
        if (!hiddenRequested) {
            if (!mAppAnimator.freezingScreen) {
                mAppAnimator.freezingScreen = true;
            if (!mFreezingScreen) {
                mFreezingScreen = true;
                mService.registerAppFreezeListener(this);
                mAppAnimator.lastFreezeDuration = 0;
                mService.mAppsFreezingScreen++;
                if (mService.mAppsFreezingScreen == 1) {
                    mService.startFreezingDisplayLocked(false, 0, 0, getDisplayContent());
@@ -1041,7 +1044,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    }

    void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
        if (!mAppAnimator.freezingScreen) {
        if (!mFreezingScreen) {
            return;
        }
        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
@@ -1053,10 +1056,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
        }
        if (force || unfrozeWindows) {
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
            mAppAnimator.freezingScreen = false;
            mFreezingScreen = false;
            mService.unregisterAppFreezeListener(this);
            mAppAnimator.lastFreezeDuration =
                    (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime);
            mService.mAppsFreezingScreen--;
            mService.mLastFinishedFreezeSource = this;
        }
@@ -1203,17 +1204,17 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

    @Override
    void checkAppWindowsReadyToShow() {
        if (allDrawn == mAppAnimator.allDrawn) {
        if (allDrawn == mLastAllDrawn) {
            return;
        }

        mAppAnimator.allDrawn = allDrawn;
        mLastAllDrawn = allDrawn;
        if (!allDrawn) {
            return;
        }

        // The token has now changed state to having all windows shown...  what to do, what to do?
        if (mAppAnimator.freezingScreen) {
        if (mFreezingScreen) {
            showAllWindowsLocked();
            stopFreezingScreen(false, true);
            if (DEBUG_ORIENTATION) Slog.i(TAG,
@@ -1297,10 +1298,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

        if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
            Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
                    + " allDrawn=" + allDrawn + " freezingScreen=" + mAppAnimator.freezingScreen);
                    + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
        }

        if (allDrawn && !mAppAnimator.freezingScreen) {
        if (allDrawn && !mFreezingScreen) {
            return false;
        }

@@ -1335,7 +1336,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

                        if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
                                + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
                                + " freezingScreen=" + mAppAnimator.freezingScreen
                                + " freezingScreen=" + mFreezingScreen
                                + " mAppFreezing=" + w.mAppFreezing);

                        isInterestingAndDrawn = true;
@@ -1502,11 +1503,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
                true /* topToBottom */);
    }

    @Override
    int getAnimLayerAdjustment() {
        return mAppAnimator.animLayerAdjustment;
    }

    boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
            boolean isVoiceInteraction) {

@@ -1531,7 +1527,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
                        mService.mSurfaceAnimationRunner);
                startAnimation(getPendingTransaction(), adapter, !isVisible());
                if (a.getZAdjustment() == Animation.ZORDER_TOP) {
                    mAppAnimator.animLayerAdjustment = 1;
                    mNeedsZBoost = true;
                    getDisplayContent().assignWindowLayers(false /* setLayoutNeeded */);
                }
                mTransit = transit;
@@ -1618,7 +1614,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

        mTransit = TRANSIT_UNSET;
        mTransitFlags = 0;
        mAppAnimator.animLayerAdjustment = 0;
        mNeedsZBoost = false;

        setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
                "AppWindowToken");
@@ -1742,13 +1738,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
            pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
        }
        if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
                || allDrawn || mAppAnimator.allDrawn) {
                || allDrawn || mLastAllDrawn) {
            pw.print(prefix); pw.print("mNumInterestingWindows=");
                    pw.print(mNumInterestingWindows);
                    pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
                    pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
                    pw.print(" allDrawn="); pw.print(allDrawn);
                    pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
                    pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
                    pw.println(")");
        }
        if (inPendingTransaction) {
@@ -1809,6 +1805,15 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
        super.prepareSurfaces();
    }

    boolean isFreezingScreen() {
        return mFreezingScreen;
    }

    @Override
    boolean needsZBoost() {
        return mNeedsZBoost || super.needsZBoost();
    }

    @CallSuper
    @Override
    public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+7 −22
Original line number Diff line number Diff line
@@ -351,7 +351,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    private boolean mDisplayReady = false;

    WallpaperController mWallpaperController;
    int mInputMethodAnimLayerAdjustment;

    private final SurfaceSession mSession = new SurfaceSession();

@@ -2048,12 +2047,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
    }

    void setInputMethodAnimLayerAdjustment(int adj) {
        if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
        mInputMethodAnimLayerAdjustment = adj;
        assignWindowLayers(false /* relayoutNeeded */);
    }

    /**
     * If a window that has an animation specifying a colored background and the current wallpaper
     * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
@@ -2233,11 +2226,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        pw.println();
        mPinnedStackControllerLocked.dump(prefix, pw);

        if (mInputMethodAnimLayerAdjustment != 0) {
            pw.println(subPrefix
                    + "mInputMethodAnimLayerAdjustment=" + mInputMethodAnimLayerAdjustment);
        }

        pw.println();
        mDisplayFrames.dump(prefix, pw);
    }
@@ -2397,7 +2385,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            if (updateImeTarget) {
                if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from "
                        + mService.mInputMethodTarget + " to null since mInputMethodWindow is null");
                setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim, 0);
                setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim);
            }
            return null;
        }
@@ -2446,7 +2434,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
                        + " to null." + (SHOW_STACK_CRAWLS ? " Callers="
                        + Debug.getCallers(4) : ""));
                setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim, 0);
                setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim);
            }

            return null;
@@ -2474,14 +2462,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                    if (appTransition.isTransitionSet()) {
                        // If we are currently setting up for an animation, hold everything until we
                        // can find out what will happen.
                        setInputMethodTarget(highestTarget, true, mInputMethodAnimLayerAdjustment);
                        setInputMethodTarget(highestTarget, true);
                        return highestTarget;
                    } else if (highestTarget.mWinAnimator.isAnimationSet() &&
                            highestTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer) {
                        // If the window we are currently targeting is involved with an animation,
                        // and it is on top of the next target we will be over, then hold off on
                        // moving until that is done.
                        setInputMethodTarget(highestTarget, true, mInputMethodAnimLayerAdjustment);
                        setInputMethodTarget(highestTarget, true);
                        return highestTarget;
                    }
                }
@@ -2489,23 +2477,20 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

            if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
                    + target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
            setInputMethodTarget(target, false, target.mAppToken != null
                    ? target.mAppToken.getAnimLayerAdjustment() : 0);
            setInputMethodTarget(target, false);
        }

        return target;
    }

    private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim, int layerAdj) {
    private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) {
        if (target == mService.mInputMethodTarget
                && mService.mInputMethodTargetWaitingAnim == targetWaitingAnim
                && mInputMethodAnimLayerAdjustment == layerAdj) {
                && mService.mInputMethodTargetWaitingAnim == targetWaitingAnim) {
            return;
        }

        mService.mInputMethodTarget = target;
        mService.mInputMethodTargetWaitingAnim = targetWaitingAnim;
        setInputMethodAnimLayerAdjustment(layerAdj);
        assignWindowLayers(false /* setLayoutNeeded */);
    }

+1 −17
Original line number Diff line number Diff line
@@ -64,8 +64,6 @@ class WallpaperController {
    // to another, and this is the previous wallpaper target.
    private WindowState mPrevWallpaperTarget = null;

    private int mWallpaperAnimLayerAdjustment;

    private float mLastWallpaperX = -1;
    private float mLastWallpaperY = -1;
    private float mLastWallpaperXStep = -1;
@@ -442,10 +440,6 @@ class WallpaperController {
        }
    }

    int getAnimLayerAdjustment() {
        return mWallpaperAnimLayerAdjustment;
    }

    private void findWallpaperTarget(DisplayContent dc) {
        mFindResults.reset();
        if (dc.isStackVisible(WINDOWING_MODE_FREEFORM)) {
@@ -547,7 +541,7 @@ class WallpaperController {
    private void updateWallpaperTokens(boolean visible) {
        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
            final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
            token.updateWallpaperWindows(visible, mWallpaperAnimLayerAdjustment);
            token.updateWallpaperWindows(visible);
            token.getDisplayContent().assignWindowLayers(false);
        }
    }
@@ -566,12 +560,6 @@ class WallpaperController {
        if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);

        if (visible) {
            // If the wallpaper target is animating, we may need to copy its layer adjustment.
            // Only do this if we are not transferring between two wallpaper targets.
            mWallpaperAnimLayerAdjustment =
                    (mPrevWallpaperTarget == null && mWallpaperTarget.mAppToken != null)
                            ? mWallpaperTarget.mAppToken.getAnimLayerAdjustment() : 0;

            if (mWallpaperTarget.mWallpaperX >= 0) {
                mLastWallpaperX = mWallpaperTarget.mWallpaperX;
                mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
@@ -682,10 +670,6 @@ class WallpaperController {
            pw.print("mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
            pw.print(" mLastWallpaperDisplayOffsetY="); pw.println(mLastWallpaperDisplayOffsetY);
        }

        if (mWallpaperAnimLayerAdjustment != 0) {
            pw.println(prefix + "mWallpaperAnimLayerAdjustment=" + mWallpaperAnimLayerAdjustment);
        }
    }

    /** Helper class for storing the results of a wallpaper target find operation. */
Loading