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

Commit 5061843a authored by Todd Lee's avatar Todd Lee Committed by Android (Google) Code Review
Browse files

Merge "Enable two-part fade out for splash screen reveal anim" into main

parents 29efa2a2 98c83944
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -44,6 +44,12 @@
    if a custom action is present before closing it. -->
    <integer name="config_pipForceCloseDelay">5000</integer>

    <!-- Animation duration when exit starting window: fade out icon -->
    <integer name="starting_window_app_reveal_icon_fade_out_duration">500</integer>

    <!-- Animation delay when exit starting window: reveal app -->
    <integer name="starting_window_app_reveal_anim_delay">0</integer>

    <!-- Animation duration when exit starting window: reveal app -->
    <integer name="starting_window_app_reveal_anim_duration">500</integer>

+35 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2022 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.
  -->

<!-- These resources are around just to allow their values to be customized
     for watch products.  Do not translate. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">

    <!-- Animation duration when exit starting window: fade out icon -->
    <integer name="starting_window_app_reveal_icon_fade_out_duration">50</integer>

    <!-- Animation delay when exit starting window: reveal app -->
    <integer name="starting_window_app_reveal_anim_delay">50</integer>

    <!-- Animation duration when exit starting window: reveal app -->
    <integer name="starting_window_app_reveal_anim_duration">200</integer>

    <!-- Default animation type when hiding the starting window. The possible values are:
          - 0 for radial vanish + slide up
          - 1 for fade out -->
    <integer name="starting_window_exit_animation_type">1</integer>
</resources>
+5 −29
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import static android.view.View.GONE;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLASHSCREEN_EXIT_ANIM;

import android.animation.Animator;
import android.annotation.IntDef;
import android.content.Context;
import android.graphics.Rect;
import android.util.Slog;
@@ -47,7 +46,7 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
    private final int mIconFadeOutDuration;
    private final int mAppRevealDelay;
    private final int mAppRevealDuration;
    @ExitAnimationType
    @SplashScreenExitAnimationUtils.ExitAnimationType
    private final int mAnimationType;
    private final int mAnimationDuration;
    private final float mIconStartAlpha;
@@ -58,24 +57,6 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {

    private Runnable mFinishCallback;

    /**
    * This splash screen exit animation type uses a radial vanish to hide
    * the starting window and slides up the main window content.
    */
    private static final int TYPE_RADIAL_VANISH_SLIDE_UP = 0;

    /**
    * This splash screen exit animation type fades out the starting window
    * to reveal the main window content.
    */
    private static final int TYPE_FADE_OUT = 1;

    @IntDef(prefix = { "TYPE_" }, value = {
        TYPE_RADIAL_VANISH_SLIDE_UP,
        TYPE_FADE_OUT,
    })
    private @interface ExitAnimationType {}

    SplashScreenExitAnimation(Context context, SplashScreenView view, SurfaceControl leash,
            Rect frame, int mainWindowShiftLength, TransactionPool pool, Runnable handleFinish,
            float roundedCornerRadius) {
@@ -121,15 +102,10 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
    }

    void startAnimations() {
        if (mAnimationType == TYPE_FADE_OUT) {
            SplashScreenExitAnimationUtils.startFadeOutAnimation(mSplashScreenView,
                    mAnimationDuration, this);
        } else {
            SplashScreenExitAnimationUtils.startAnimations(mSplashScreenView, mFirstWindowSurface,
                    mMainWindowShiftLength, mTransactionPool, mFirstWindowFrame, mAnimationDuration,
                    mIconFadeOutDuration, mIconStartAlpha, mBrandingStartAlpha, mAppRevealDelay,
                    mAppRevealDuration, this, mRoundedCornerRadius);
        }
        SplashScreenExitAnimationUtils.startAnimations(mAnimationType, mSplashScreenView,
                mFirstWindowSurface, mMainWindowShiftLength, mTransactionPool, mFirstWindowFrame,
                mAnimationDuration, mIconFadeOutDuration, mIconStartAlpha, mBrandingStartAlpha,
                mAppRevealDelay, mAppRevealDuration, this, mRoundedCornerRadius);
    }

    private void reset() {
+89 −19
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.view.Choreographer.CALLBACK_COMMIT;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
@@ -54,6 +55,7 @@ import com.android.wm.shell.common.TransactionPool;
public class SplashScreenExitAnimationUtils {
    private static final boolean DEBUG_EXIT_ANIMATION = false;
    private static final boolean DEBUG_EXIT_ANIMATION_BLEND = false;
    private static final boolean DEBUG_EXIT_FADE_ANIMATION = false;
    private static final String TAG = "SplashScreenExitAnimationUtils";

    private static final Interpolator ICON_INTERPOLATOR = new PathInterpolator(0.15f, 0f, 1f, 1f);
@@ -61,20 +63,48 @@ public class SplashScreenExitAnimationUtils {
            new PathInterpolator(0f, 0f, 0.4f, 1f);
    private static final Interpolator SHIFT_UP_INTERPOLATOR = new PathInterpolator(0f, 0f, 0f, 1f);

    /**
     * This splash screen exit animation type uses a radial vanish to hide
     * the starting window and slides up the main window content.
     * @hide
     */
    public static final int TYPE_RADIAL_VANISH_SLIDE_UP = 0;

    /**
     * This splash screen exit animation type fades out the starting window
     * to reveal the main window content.
     * @hide
     */
    public static final int TYPE_FADE_OUT = 1;

    /** @hide */
    @IntDef(prefix = { "TYPE_" }, value = {
            TYPE_RADIAL_VANISH_SLIDE_UP,
            TYPE_FADE_OUT,
    })
    public @interface ExitAnimationType {}

    /**
     * Creates and starts the animator to fade out the icon, reveal the app, and shift up main
     * window with rounded corner radius.
     */
    static void startAnimations(ViewGroup splashScreenView,
            SurfaceControl firstWindowSurface, int mainWindowShiftLength,
            TransactionPool transactionPool, Rect firstWindowFrame, int animationDuration,
            int iconFadeOutDuration, float iconStartAlpha, float brandingStartAlpha,
            int appRevealDelay, int appRevealDuration, Animator.AnimatorListener animatorListener,
            float roundedCornerRadius) {
        ValueAnimator animator = createRadialVanishSlideUpAnimator(splashScreenView,
    static void startAnimations(@ExitAnimationType int animationType,
            ViewGroup splashScreenView, SurfaceControl firstWindowSurface,
            int mainWindowShiftLength, TransactionPool transactionPool, Rect firstWindowFrame,
            int animationDuration, int iconFadeOutDuration, float iconStartAlpha,
            float brandingStartAlpha, int appRevealDelay, int appRevealDuration,
            Animator.AnimatorListener animatorListener, float roundedCornerRadius) {
        ValueAnimator animator;
        if (animationType == TYPE_FADE_OUT) {
            animator = createFadeOutAnimation(splashScreenView, animationDuration,
                    iconFadeOutDuration, iconStartAlpha, brandingStartAlpha, appRevealDelay,
                    appRevealDuration, animatorListener);
        } else {
            animator = createRadialVanishSlideUpAnimator(splashScreenView,
                    firstWindowSurface, mainWindowShiftLength, transactionPool, firstWindowFrame,
                    animationDuration, iconFadeOutDuration, iconStartAlpha, brandingStartAlpha,
                    appRevealDelay, appRevealDuration, animatorListener, roundedCornerRadius);
        }
        animator.start();
    }

@@ -88,10 +118,11 @@ public class SplashScreenExitAnimationUtils {
            TransactionPool transactionPool, Rect firstWindowFrame, int animationDuration,
            int iconFadeOutDuration, float iconStartAlpha, float brandingStartAlpha,
            int appRevealDelay, int appRevealDuration, Animator.AnimatorListener animatorListener) {
        startAnimations(splashScreenView, firstWindowSurface, mainWindowShiftLength,
                transactionPool, firstWindowFrame, animationDuration, iconFadeOutDuration,
                iconStartAlpha, brandingStartAlpha, appRevealDelay, appRevealDuration,
                animatorListener, 0f /* roundedCornerRadius */);
        // Start the default 'reveal' animation.
        startAnimations(TYPE_RADIAL_VANISH_SLIDE_UP, splashScreenView,
                firstWindowSurface, mainWindowShiftLength, transactionPool, firstWindowFrame,
                animationDuration, iconFadeOutDuration, iconStartAlpha, brandingStartAlpha,
                appRevealDelay, appRevealDuration, animatorListener, 0f /* roundedCornerRadius */);
    }

    /**
@@ -209,18 +240,57 @@ public class SplashScreenExitAnimationUtils {
        return nightMode == Configuration.UI_MODE_NIGHT_YES;
    }

    static void startFadeOutAnimation(ViewGroup splashScreenView,
            int animationDuration, Animator.AnimatorListener animatorListener) {
        final ValueAnimator animator = ValueAnimator.ofFloat(1f, 0f);
    private static ValueAnimator createFadeOutAnimation(ViewGroup splashScreenView,
            int animationDuration, int iconFadeOutDuration, float iconStartAlpha,
            float brandingStartAlpha, int appRevealDelay, int appRevealDuration,
            Animator.AnimatorListener animatorListener) {

        if (DEBUG_EXIT_FADE_ANIMATION) {
            splashScreenView.setBackgroundColor(Color.BLUE);
        }

        final ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
        animator.setDuration(animationDuration);
        animator.setInterpolator(Interpolators.LINEAR);
        animator.addUpdateListener(animation -> {
            splashScreenView.setAlpha((float) animation.getAnimatedValue());

            float linearProgress = (float) animation.getAnimatedValue();

            // Icon fade out progress (always starts immediately)
            final float iconFadeProgress = ICON_INTERPOLATOR.getInterpolation(getProgress(
                            linearProgress, 0 /* delay */, iconFadeOutDuration, animationDuration));
            View iconView = null;
            View brandingView = null;

            if (splashScreenView instanceof SplashScreenView) {
                iconView = ((SplashScreenView) splashScreenView).getIconView();
                brandingView = ((SplashScreenView) splashScreenView).getBrandingView();
            }
            if (iconView != null) {
                iconView.setAlpha(iconStartAlpha * (1f - iconFadeProgress));
            }
            if (brandingView != null) {
                brandingView.setAlpha(brandingStartAlpha * (1f - iconFadeProgress));
            }

            // Splash screen fade out progress (possibly delayed)
            final float splashFadeProgress = Interpolators.ALPHA_OUT.getInterpolation(
                    getProgress(linearProgress, appRevealDelay,
                    appRevealDuration, animationDuration));

            splashScreenView.setAlpha(1f - splashFadeProgress);

            if (DEBUG_EXIT_FADE_ANIMATION) {
                Slog.d(TAG, "progress -> animation: " + linearProgress
                        + "\t icon alpha: " + ((iconView != null) ? iconView.getAlpha() : "n/a")
                        + "\t splash alpha: " + splashScreenView.getAlpha()
                );
            }
        });
        if (animatorListener != null) {
            animator.addListener(animatorListener);
        }
        animator.start();
        return animator;
    }

    /**