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

Commit 3483c52e authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Waiting until onResume before creating the wallpaper-open animation.

Bug: 77853906
Change-Id: I5126855492da59c9dbfef0ce2a97f94662a6522b
parent 9162f818
Loading
Loading
Loading
Loading
+65 −40
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.launcher3;

import static com.android.launcher3.Utilities.postAsyncCallback;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -28,16 +30,12 @@ import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;

@TargetApi(Build.VERSION_CODES.P)
public abstract class LauncherAnimationRunner extends AnimatorListenerAdapter
        implements RemoteAnimationRunnerCompat {
public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {

    private static final int REFRESH_RATE_MS = 16;

    private final Handler mHandler;

    private Runnable mSysFinishRunnable;

    private AnimatorSet mAnimator;
    private AnimationResult mAnimationResult;

    public LauncherAnimationRunner(Handler handler) {
        mHandler = handler;
@@ -46,34 +44,26 @@ public abstract class LauncherAnimationRunner extends AnimatorListenerAdapter
    @BinderThread
    @Override
    public void onAnimationStart(RemoteAnimationTargetCompat[] targetCompats, Runnable runnable) {
        mHandler.post(() -> {
            // Finish any previous animation
            finishSystemAnimation();

            mSysFinishRunnable = runnable;
            mAnimator = getAnimator(targetCompats);
            if (mAnimator == null) {
                finishSystemAnimation();
                return;
            }
            mAnimator.addListener(this);
            mAnimator.start();
            // Because t=0 has the app icon in its original spot, we can skip the
            // first frame and have the same movement one frame earlier.
            mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);

        postAsyncCallback(mHandler, () -> {
            finishExistingAnimation();
            mAnimationResult = new AnimationResult(runnable);
            onCreateAnimation(targetCompats, mAnimationResult);
        });
    }

    /**
     * Called on the UI thread when the animation targets are received. The implementation must
     * call {@link AnimationResult#setAnimation(AnimatorSet)} with the target animation to be run.
     */
    @UiThread
    public abstract AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats);
    public abstract void onCreateAnimation(
            RemoteAnimationTargetCompat[] targetCompats, AnimationResult result);

    @UiThread
    @Override
    public void onAnimationEnd(Animator animation) {
        if (animation == mAnimator) {
            mAnimator = null;
            finishSystemAnimation();
    private void finishExistingAnimation() {
        if (mAnimationResult != null) {
            mAnimationResult.finish();
            mAnimationResult = null;
        }
    }

@@ -83,20 +73,55 @@ public abstract class LauncherAnimationRunner extends AnimatorListenerAdapter
    @BinderThread
    @Override
    public void onAnimationCancelled() {
        mHandler.post(() -> {
            if (mAnimator != null) {
                mAnimator.removeListener(this);
                mAnimator.end();
                mAnimator = null;
        postAsyncCallback(mHandler, this::finishExistingAnimation);
    }

    public static final class AnimationResult {

        private final Runnable mFinishRunnable;

        private AnimatorSet mAnimator;
        private boolean mFinished = false;
        private boolean mInitialized = false;

        private AnimationResult(Runnable finishRunnable) {
            mFinishRunnable = finishRunnable;
        }

        @UiThread
        private void finish() {
            if (!mFinished) {
                mFinishRunnable.run();
                mFinished = true;
            }
        });
        }

        @UiThread
    private void finishSystemAnimation() {
        if (mSysFinishRunnable != null) {
            mSysFinishRunnable.run();
            mSysFinishRunnable = null;
        public void setAnimation(AnimatorSet animation) {
            if (mInitialized) {
                throw new IllegalStateException("Animation already initialized");
            }
            mInitialized = true;
            mAnimator = animation;
            if (mAnimator == null) {
                finish();
            } else if (mFinished) {
                // Animation callback was already finished, skip the animation.
                mAnimator.end();
            } else {
                // Start the animation
                mAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        finish();
                    }
                });
                mAnimator.start();

                // Because t=0 has the app icon in its original spot, we can skip the
                // first frame and have the same movement one frame earlier.
                mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
            }
        }
    }
}
 No newline at end of file
+15 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.android.launcher3.BaseActivity.INVISIBLE_ALL;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
@@ -163,7 +164,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
            RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mHandler) {

                @Override
                public AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats) {
                public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
                        AnimationResult result) {
                    AnimatorSet anim = new AnimatorSet();

                    boolean launcherClosing =
@@ -185,7 +187,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
                        anim.addListener(mForceInvisibleListener);
                    }

                    return anim;
                    result.setAnimation(anim);
                }
            };

@@ -558,7 +560,16 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
    private RemoteAnimationRunnerCompat getWallpaperOpenRunner() {
        return new LauncherAnimationRunner(mHandler) {
            @Override
            public AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats) {
            public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
                    AnimationResult result) {
                if (!mLauncher.hasBeenResumed()) {
                    // If launcher is not resumed, wait until new async-frame after resume
                    mLauncher.setOnResumeCallback(() ->
                            postAsyncCallback(mHandler, () ->
                                    onCreateAnimation(targetCompats, result)));
                    return;
                }

                AnimatorSet anim = null;
                RemoteAnimationProvider provider = mRemoteAnimationProvider;
                if (provider != null) {
@@ -586,7 +597,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
                }

                mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
                return anim;
                result.setAnimation(anim);
            }
        };
    }
+3 −2
Original line number Diff line number Diff line
@@ -168,8 +168,9 @@ public class RecentsActivity extends BaseDraggingActivity {
        RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mUiHandler) {

            @Override
            public AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats) {
                return composeRecentsLaunchAnimator(taskView, targetCompats);
            public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
                    AnimationResult result) {
                result.setAnimation(composeRecentsLaunchAnimator(taskView, targetCompats));
            }
        };
        return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
+2 −3
Original line number Diff line number Diff line
@@ -16,13 +16,12 @@
package com.android.quickstep;

import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_DURATION;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
import static com.android.systemui.shared.recents.utilities.Utilities
        .postAtFrontOfQueueAsynchronously;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;

import android.animation.Animator;
@@ -248,7 +247,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
        if (Looper.myLooper() == handler.getLooper()) {
            mStateCallback.setState(stateFlag);
        } else {
            postAtFrontOfQueueAsynchronously(handler, () -> mStateCallback.setState(stateFlag));
            postAsyncCallback(handler, () -> mStateCallback.setState(stateFlag));
        }
    }

+4 −2
Original line number Diff line number Diff line
@@ -32,9 +32,11 @@ public interface RemoteAnimationProvider {

    default ActivityOptions toActivityOptions(Handler handler, long duration) {
        LauncherAnimationRunner runner = new LauncherAnimationRunner(handler) {

            @Override
            public AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats) {
                return createWindowAnimation(targetCompats);
            public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
                    AnimationResult result) {
                result.setAnimation(createWindowAnimation(targetCompats));
            }
        };
        return ActivityOptionsCompat.makeRemoteAnimation(
Loading