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

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

Lock free app animations (2/n): Use SurfaceAninimator

This is the main CL that switches over from using the legacy
animation system to using the new SurfaceAnimator for app
window animations. Also moves applyAnimationLocked to
AppWindowToken.

AppWindowAnimator still has a bunch of state that needs to be moved
into AppWindowToken in future CL's.

Test: go/wm-smoke
Bug: 64674361
Change-Id: Ifc83cbac281ce0654ecd8a1c2ca9c24a4d87c1d1
parent 94c38c56
Loading
Loading
Loading
Loading
+6 −12
Original line number Diff line number Diff line
@@ -2126,14 +2126,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
            @Override
            public int onAppTransitionStartingLocked(int transit, IBinder openToken,
                    IBinder closeToken,
                    Animation openAnimation, Animation closeAnimation) {
                return handleStartTransitionForKeyguardLw(transit, openAnimation);
                    IBinder closeToken, long duration, long statusBarAnimationStartTime,
                    long statusBarAnimationDuration) {
                return handleStartTransitionForKeyguardLw(transit, duration);
            }

            @Override
            public void onAppTransitionCancelledLocked(int transit) {
                handleStartTransitionForKeyguardLw(transit, null /* transit */);
                handleStartTransitionForKeyguardLw(transit, 0 /* duration */);
            }
        });
        mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
@@ -3989,7 +3989,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
    }

    private int handleStartTransitionForKeyguardLw(int transit, @Nullable Animation anim) {
    private int handleStartTransitionForKeyguardLw(int transit, long duration) {
        if (mKeyguardOccludedChanged) {
            if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded="
                    + mPendingKeyguardOccluded);
@@ -4000,13 +4000,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
        if (AppTransition.isKeyguardGoingAwayTransit(transit)) {
            if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
            final long startTime = anim != null
                    ? SystemClock.uptimeMillis() + anim.getStartOffset()
                    : SystemClock.uptimeMillis();
            final long duration = anim != null
                    ? anim.getDuration()
                    : 0;
            startKeyguardExitAnimation(startTime, duration);
            startKeyguardExitAnimation(SystemClock.uptimeMillis(), duration);
        }
        return 0;
    }
+4 −76
Original line number Diff line number Diff line
@@ -37,8 +37,6 @@ import com.android.server.statusbar.StatusBarManagerInternal;
 */
public class StatusBarController extends BarController {

    private static final long TRANSITION_DURATION = 120L;

    private final AppTransitionListener mAppTransitionListener
            = new AppTransitionListener() {

@@ -57,17 +55,15 @@ public class StatusBarController extends BarController {

        @Override
        public int onAppTransitionStartingLocked(int transit, IBinder openToken,
                IBinder closeToken, final Animation openAnimation, final Animation closeAnimation) {
                IBinder closeToken, long duration, long statusBarAnimationStartTime,
                long statusBarAnimationDuration) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    StatusBarManagerInternal statusbar = getStatusBarInternal();
                    if (statusbar != null) {
                        long startTime = calculateStatusBarTransitionStartTime(openAnimation,
                                closeAnimation);
                        long duration = closeAnimation != null || openAnimation != null
                                ? TRANSITION_DURATION : 0;
                        statusbar.appTransitionStarting(startTime, duration);
                        statusbar.appTransitionStarting(statusBarAnimationStartTime,
                                statusBarAnimationDuration);
                    }
                }
            });
@@ -128,72 +124,4 @@ public class StatusBarController extends BarController {
    public AppTransitionListener getAppTransitionListener() {
        return mAppTransitionListener;
    }

    /**
     * For a given app transition with {@code openAnimation} and {@code closeAnimation}, this
     * calculates the timings for the corresponding status bar transition.
     *
     * @return the desired start time of the status bar transition, in uptime millis
     */
    private static long calculateStatusBarTransitionStartTime(Animation openAnimation,
            Animation closeAnimation) {
        if (openAnimation != null && closeAnimation != null) {
            TranslateAnimation openTranslateAnimation = findTranslateAnimation(openAnimation);
            TranslateAnimation closeTranslateAnimation = findTranslateAnimation(closeAnimation);
            if (openTranslateAnimation != null) {

                // Some interpolators are extremely quickly mostly finished, but not completely. For
                // our purposes, we need to find the fraction for which ther interpolator is mostly
                // there, and use that value for the calculation.
                float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator());
                return SystemClock.uptimeMillis()
                        + openTranslateAnimation.getStartOffset()
                        + (long)(openTranslateAnimation.getDuration()*t) - TRANSITION_DURATION;
            } else if (closeTranslateAnimation != null) {
                return SystemClock.uptimeMillis();
            } else {
                return SystemClock.uptimeMillis();
            }
        } else {
            return SystemClock.uptimeMillis();
        }
    }

    /**
     * Tries to find a {@link TranslateAnimation} inside the {@code animation}.
     *
     * @return the found animation, {@code null} otherwise
     */
    private static TranslateAnimation findTranslateAnimation(Animation animation) {
        if (animation instanceof TranslateAnimation) {
            return (TranslateAnimation) animation;
        } else if (animation instanceof AnimationSet) {
            AnimationSet set = (AnimationSet) animation;
            for (int i = 0; i < set.getAnimations().size(); i++) {
                Animation a = set.getAnimations().get(i);
                if (a instanceof TranslateAnimation) {
                    return (TranslateAnimation) a;
                }
            }
        }
        return null;
    }

    /**
     * Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which
     * {@code interpolator(t + eps) > 0.99}.
     */
    private static float findAlmostThereFraction(Interpolator interpolator) {
        float val = 0.5f;
        float adj = 0.25f;
        while (adj >= 0.01f) {
            if (interpolator.getInterpolation(val) < 0.99f) {
                val += adj;
            } else {
                val -= adj;
            }
            adj /= 2;
        }
        return val;
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 */
interface AnimationAdapter {

    long STATUS_BAR_TRANSITION_DURATION = 120L;

    /**
     * @return Whether we should detach the wallpaper during the animation.
     * @see Animation#setDetachWallpaper
@@ -66,4 +68,13 @@ interface AnimationAdapter {
     * @return The approximate duration of the animation, in milliseconds.
     */
    long getDurationHint();

    /**
     * If this animation is run as an app opening animation, this calculates the start time for all
     * status bar transitions that happen as part of the app opening animation, which will be
     * forwarded to SystemUI.
     *
     * @return the desired start time of the status bar transition, in uptime millis
     */
    long getStatusBarTransitionsStartTime();
}
+18 −14
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpe
import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -63,6 +62,7 @@ import android.os.Debug;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.ArraySet;
@@ -415,17 +415,23 @@ public class AppTransition implements Dump {
     * @return bit-map of WindowManagerPolicy#FINISH_LAYOUT_REDO_* to indicate whether another
     *         layout pass needs to be done
     */
    int goodToGo(int transit, AppWindowAnimator topOpeningAppAnimator,
            AppWindowAnimator topClosingAppAnimator, ArraySet<AppWindowToken> openingApps,
    int goodToGo(int transit, AppWindowToken topOpeningApp,
            AppWindowToken topClosingApp, ArraySet<AppWindowToken> openingApps,
            ArraySet<AppWindowToken> closingApps) {
        mNextAppTransition = TRANSIT_UNSET;
        mNextAppTransitionFlags = 0;
        setAppTransitionState(APP_STATE_RUNNING);
        final AnimationAdapter topOpeningAnim = topOpeningApp != null
                ? topOpeningApp.getAnimation()
                : null;
        int redoLayout = notifyAppTransitionStartingLocked(transit,
                topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null,
                topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null,
                topOpeningAppAnimator != null ? topOpeningAppAnimator.animation : null,
                topClosingAppAnimator != null ? topClosingAppAnimator.animation : null);
                topOpeningApp != null ? topOpeningApp.token : null,
                topClosingApp != null ? topClosingApp.token : null,
                topOpeningAnim != null ? topOpeningAnim.getDurationHint() : 0,
                topOpeningAnim != null
                        ? topOpeningAnim.getStatusBarTransitionsStartTime()
                        : SystemClock.uptimeMillis(),
                AnimationAdapter.STATUS_BAR_TRANSITION_DURATION);
        mService.getDefaultDisplayContentLocked().getDockedDividerController()
                .notifyAppTransitionStarting(openingApps, transit);

@@ -433,8 +439,8 @@ public class AppTransition implements Dump {
        // ended it already then we don't need to wait.
        if (transit == TRANSIT_DOCK_TASK_FROM_RECENTS && !mProlongedAnimationsEnded) {
            for (int i = openingApps.size() - 1; i >= 0; i--) {
                final AppWindowAnimator appAnimator = openingApps.valueAt(i).mAppAnimator;
                appAnimator.startProlongAnimation(PROLONG_ANIMATION_AT_START);
                final AppWindowToken app = openingApps.valueAt(i);
                app.startDelayingAnimationStart();
            }
        }
        return redoLayout;
@@ -504,11 +510,12 @@ public class AppTransition implements Dump {
    }

    private int notifyAppTransitionStartingLocked(int transit, IBinder openToken,
            IBinder closeToken, Animation openAnimation, Animation closeAnimation) {
            IBinder closeToken, long duration, long statusBarAnimationStartTime,
            long statusBarAnimationDuration) {
        int redoLayout = 0;
        for (int i = 0; i < mListeners.size(); i++) {
            redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(transit, openToken,
                    closeToken, openAnimation, closeAnimation);
                    closeToken, duration, statusBarAnimationStartTime, statusBarAnimationDuration);
        }
        return redoLayout;
    }
@@ -1885,9 +1892,6 @@ public class AppTransition implements Dump {
                            mNextAppTransitionFutureCallback, null /* finishedCallback */,
                            mNextAppTransitionScaleUp);
                    mNextAppTransitionFutureCallback = null;
                    if (specs != null) {
                        mService.prolongAnimationsFromSpecs(specs, mNextAppTransitionScaleUp);
                    }
                }
                mService.requestTraversal();
            });
+4 −419

File changed.

Preview size limit exceeded, changes collapsed.

Loading