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

Commit bea82678 authored by Jonathan Miranda's avatar Jonathan Miranda Committed by Android (Google) Code Review
Browse files

Merge "Address LAUNCHER_APP_LAUNCH_FROM_ICON jank." into sc-dev

parents 22ed03ee 0750f03c
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -152,16 +152,18 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo

        @UiThread
        public void setAnimation(AnimatorSet animation, Context context) {
            setAnimation(animation, context, null);
            setAnimation(animation, context, null, true);

        }

        /**
         * Sets the animation to play for this app launch
         * @param skipFirstFrame Iff true, we skip the first frame of the animation.
         *                       We set to false when skipping first frame causes jank.
         */
        @UiThread
        public void setAnimation(AnimatorSet animation, Context context,
                @Nullable Runnable onCompleteCallback) {
                @Nullable Runnable onCompleteCallback, boolean skipFirstFrame) {
            if (mInitialized) {
                throw new IllegalStateException("Animation already initialized");
            }
@@ -187,6 +189,7 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
                });
                mAnimator.start();

                if (skipFirstFrame) {
                    // 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(
@@ -195,3 +198,4 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
            }
        }
    }
}
+35 −12
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
@@ -340,12 +341,17 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener

        final int rotationChange = getRotationChange(appTargets);
        // Note: the targetBounds are relative to the launcher
        int startDelay = getSingleFrameMs(mLauncher);
        Rect windowTargetBounds = getWindowTargetBounds(appTargets, rotationChange);
        anim.play(getOpeningWindowAnimators(v, appTargets, wallpaperTargets, nonAppTargets,
                windowTargetBounds, areAllTargetsTranslucent(appTargets), rotationChange));
        Animator windowAnimator = getOpeningWindowAnimators(v, appTargets, wallpaperTargets,
                nonAppTargets, windowTargetBounds, areAllTargetsTranslucent(appTargets),
                rotationChange);
        windowAnimator.setStartDelay(startDelay);
        anim.play(windowAnimator);
        if (launcherClosing) {
            // Delay animation by a frame to avoid jank.
            Pair<AnimatorSet, Runnable> launcherContentAnimator =
                    getLauncherContentAnimator(true /* isAppOpening */);
                    getLauncherContentAnimator(true /* isAppOpening */, startDelay);
            anim.play(launcherContentAnimator.first);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
@@ -436,8 +442,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
     *
     * @param isAppOpening True when this is called when an app is opening.
     *                     False when this is called when an app is closing.
     * @param startDelay Start delay duration.
     */
    private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening) {
    private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening,
            int startDelay) {
        AnimatorSet launcherAnimator = new AnimatorSet();
        Runnable endListener;

@@ -528,6 +536,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
            };
        }

        launcherAnimator.setStartDelay(startDelay);
        return new Pair<>(launcherAnimator, endListener);
    }

@@ -633,7 +643,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                ? 0 : getWindowCornerRadius(mLauncher.getResources());
        final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius;

        appAnimator.addUpdateListener(new MultiValueUpdateListener() {
        MultiValueUpdateListener listener = new MultiValueUpdateListener() {
            FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
            FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);

@@ -662,7 +672,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                    ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);

            @Override
            public void onUpdate(float percent) {
            public void onUpdate(float percent, boolean initOnly) {
                // Calculate the size of the scaled icon.
                float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value;
                float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value;
@@ -707,6 +717,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                floatingIconBounds.right += offsetX;
                floatingIconBounds.bottom += offsetY;

                if (initOnly) {
                    floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f,
                            mWindowRadius.value * scale, true /* isOpening */);
                    return;
                }

                ArrayList<SurfaceParams> params = new ArrayList<>();
                for (int i = appTargets.length - 1; i >= 0; i--) {
                    RemoteAnimationTargetCompat target = appTargets[i];
@@ -779,7 +795,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener

                surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
            }
        });
        };
        appAnimator.addUpdateListener(listener);
        // Since we added a start delay, call update here to init the FloatingIconView properly.
        listener.onUpdate(0, true /* initOnly */);

        animatorSet.playTogether(appAnimator, getBackgroundAnimator(appTargets));
        return animatorSet;
@@ -869,7 +888,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                    ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);

            @Override
            public void onUpdate(float percent) {
            public void onUpdate(float percent, boolean initOnly) {
                widgetBackgroundBounds.set(mDx.value - mWidth.value / 2f,
                        mDy.value - mHeight.value / 2f, mDx.value + mWidth.value / 2f,
                        mDy.value + mHeight.value / 2f);
@@ -1128,7 +1147,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                    DEACCEL_1_7);

            @Override
            public void onUpdate(float percent) {
            public void onUpdate(float percent, boolean initOnly) {
                SurfaceParams[] params = new SurfaceParams[appTargets.length];
                for (int i = appTargets.length - 1; i >= 0; i--) {
                    RemoteAnimationTargetCompat target = appTargets[i];
@@ -1278,8 +1297,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener

                    if (mLauncher.isInState(LauncherState.ALL_APPS)) {
                        Pair<AnimatorSet, Runnable> contentAnimator =
                                getLauncherContentAnimator(false /* isAppOpening */);
                        contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY);
                                getLauncherContentAnimator(false, LAUNCHER_RESUME_START_DELAY);
                        anim.play(contentAnimator.first);
                        anim.addListener(new AnimatorListenerAdapter() {
                            @Override
@@ -1328,27 +1346,32 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener

            final boolean launchingFromWidget = mV instanceof LauncherAppWidgetHostView;
            final boolean launchingFromRecents = isLaunchingFromRecents(mV, appTargets);
            final boolean skipFirstFrame;
            if (launchingFromWidget) {
                composeWidgetLaunchAnimator(anim, (LauncherAppWidgetHostView) mV, appTargets,
                        wallpaperTargets, nonAppTargets);
                addCujInstrumentation(
                        anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_WIDGET);
                skipFirstFrame = true;
            } else if (launchingFromRecents) {
                composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
                        launcherClosing);
                addCujInstrumentation(
                        anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_RECENTS);
                skipFirstFrame = true;
            } else {
                composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
                        launcherClosing);
                addCujInstrumentation(anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON);
                skipFirstFrame = false;
            }

            if (launcherClosing) {
                anim.addListener(mForceInvisibleListener);
            }

            result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy);
            result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy,
                    skipFirstFrame);
        }
    }

+4 −2
Original line number Diff line number Diff line
@@ -214,7 +214,8 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
            AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets,
                    wallpaperTargets, nonAppTargets);
            anim.addListener(resetStateListener());
            result.setAnimation(anim, RecentsActivity.this, onEndCallback::executeAllAndDestroy);
            result.setAnimation(anim, RecentsActivity.this, onEndCallback::executeAllAndDestroy,
                    true /* skipFirstFrame */);
        };

        final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner<>(
@@ -386,7 +387,8 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
        anim.play(controller.getAnimationPlayer());
        anim.setDuration(HOME_APPEAR_DURATION);
        result.setAnimation(anim, this,
                () -> getStateManager().goToState(RecentsState.HOME, false));
                () -> getStateManager().goToState(RecentsState.HOME, false),
                true /* skipFirstFrame */);
    }

    @Override
+1 −1
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ public final class TaskViewUtils {
                            ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);

                    @Override
                    public void onUpdate(float percent) {
                    public void onUpdate(float percent, boolean initOnly) {
                        final SurfaceParams.Builder navBuilder =
                                new SurfaceParams.Builder(navBarTarget.leash);
                        if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
+6 −2
Original line number Diff line number Diff line
@@ -40,10 +40,14 @@ public abstract class MultiValueUpdateListener implements ValueAnimator.Animator
            newPercent = prop.mInterpolator.getInterpolation(newPercent);
            prop.value = prop.mEnd * newPercent + prop.mStart * (1 - newPercent);
        }
        onUpdate(percent);
        onUpdate(percent, false /* initOnly */);
    }

    public abstract void onUpdate(float percent);
    /**
     * @param percent The total animation progress.
     * @param initOnly When true, only does enough work to initialize the animation.
     */
    public abstract void onUpdate(float percent, boolean initOnly);

    public final class FloatProp {

Loading