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

Commit 4748ce9e authored by wilsonshih's avatar wilsonshih
Browse files

Deprecating windowSplashScreenAnimationDuration attr.

In previous CL(5e0c72a2) we provide a
way to read the animation duration from AVD and AnimationDrawable,
which should be enough to deprecate this attribute since the naming
could confusing developers.

The attribute was used to cut off the animation if the icon is
animatable, but since the animation can be stop when removing the
splash screen view from window, the attribute is useless so framework
won't read it anymore.

The attribute was also be the return value from
SplashScreenView#getIconAnimationDuration, however, since this API was
designed to let developer decide when to cut off the animation if the
app want to handle OnExitAnimationListener#onSplashScreenExit,
developer can pre-decide the duration in the app without set this
attribute.

Bug: 211707095
Test: atest SplashscreenTests StartingSurfaceDrawerTests
Change-Id: Ib3a0b4314bd15158c392e56c0e125a33c753e716
parent a56e6c1f
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -1756,7 +1756,7 @@ package android {
    field public static final int windowShowWallpaper = 16843410; // 0x1010292
    field public static final int windowShowWallpaper = 16843410; // 0x1010292
    field public static final int windowSoftInputMode = 16843307; // 0x101022b
    field public static final int windowSoftInputMode = 16843307; // 0x101022b
    field public static final int windowSplashScreenAnimatedIcon = 16844333; // 0x101062d
    field public static final int windowSplashScreenAnimatedIcon = 16844333; // 0x101062d
    field public static final int windowSplashScreenAnimationDuration = 16844334; // 0x101062e
    field @Deprecated public static final int windowSplashScreenAnimationDuration = 16844334; // 0x101062e
    field public static final int windowSplashScreenBackground = 16844332; // 0x101062c
    field public static final int windowSplashScreenBackground = 16844332; // 0x101062c
    field public static final int windowSplashScreenBehavior;
    field public static final int windowSplashScreenBehavior;
    field public static final int windowSplashScreenBrandingImage = 16844335; // 0x101062f
    field public static final int windowSplashScreenBrandingImage = 16844335; // 0x101062f
+10 −15
Original line number Original line Diff line number Diff line
@@ -232,14 +232,6 @@ public final class SplashScreenView extends FrameLayout {
            return this;
            return this;
        }
        }


        /**
         * Set the animation duration if icon is animatable.
         */
        public Builder setAnimationDurationMillis(long duration) {
            mIconAnimationDuration = Duration.ofMillis(duration);
            return this;
        }

        /**
        /**
         * Set the Runnable that can receive the task which should be executed on UI thread.
         * Set the Runnable that can receive the task which should be executed on UI thread.
         * @param uiThreadInitTask
         * @param uiThreadInitTask
@@ -294,8 +286,7 @@ public final class SplashScreenView extends FrameLayout {
                } else {
                } else {
                    view.mIconView = createSurfaceView(view);
                    view.mIconView = createSurfaceView(view);
                }
                }
                view.initIconAnimation(mIconDrawable,
                view.initIconAnimation(mIconDrawable);
                        mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
                view.mIconAnimationStart = mIconAnimationStart;
                view.mIconAnimationStart = mIconAnimationStart;
                view.mIconAnimationDuration = mIconAnimationDuration;
                view.mIconAnimationDuration = mIconAnimationDuration;
            } else if (mIconSize != 0) {
            } else if (mIconSize != 0) {
@@ -463,6 +454,11 @@ public final class SplashScreenView extends FrameLayout {
    /**
    /**
     * Returns the duration of the icon animation if icon is animatable.
     * Returns the duration of the icon animation if icon is animatable.
     *
     *
     * Note the return value can be null or 0 if the
     * {@link android.R.attr#windowSplashScreenAnimatedIcon} is not
     * {@link android.graphics.drawable.AnimationDrawable} or
     * {@link android.graphics.drawable.AnimatedVectorDrawable}.
     *
     * @see android.R.attr#windowSplashScreenAnimatedIcon
     * @see android.R.attr#windowSplashScreenAnimatedIcon
     * @see android.R.attr#windowSplashScreenAnimationDuration
     * @see android.R.attr#windowSplashScreenAnimationDuration
     */
     */
@@ -497,12 +493,12 @@ public final class SplashScreenView extends FrameLayout {
        mSurfaceView.setChildSurfacePackage(mSurfacePackage);
        mSurfaceView.setChildSurfacePackage(mSurfacePackage);
    }
    }


    void initIconAnimation(Drawable iconDrawable, long duration) {
    void initIconAnimation(Drawable iconDrawable) {
        if (!(iconDrawable instanceof IconAnimateListener)) {
        if (!(iconDrawable instanceof IconAnimateListener)) {
            return;
            return;
        }
        }
        IconAnimateListener aniDrawable = (IconAnimateListener) iconDrawable;
        IconAnimateListener aniDrawable = (IconAnimateListener) iconDrawable;
        aniDrawable.prepareAnimate(duration, this::animationStartCallback);
        aniDrawable.prepareAnimate(this::animationStartCallback);
        aniDrawable.setAnimationJankMonitoring(new AnimatorListenerAdapter() {
        aniDrawable.setAnimationJankMonitoring(new AnimatorListenerAdapter() {
            @Override
            @Override
            public void onAnimationCancel(Animator animation) {
            public void onAnimationCancel(Animator animation) {
@@ -524,7 +520,7 @@ public final class SplashScreenView extends FrameLayout {


    private void animationStartCallback(long animDuration) {
    private void animationStartCallback(long animDuration) {
        mIconAnimationStart = Instant.now();
        mIconAnimationStart = Instant.now();
        if (animDuration > 0) {
        if (animDuration >= 0) {
            mIconAnimationDuration = Duration.ofMillis(animDuration);
            mIconAnimationDuration = Duration.ofMillis(animDuration);
        }
        }
    }
    }
@@ -695,10 +691,9 @@ public final class SplashScreenView extends FrameLayout {
    public interface IconAnimateListener {
    public interface IconAnimateListener {
        /**
        /**
         * Prepare the animation if this drawable also be animatable.
         * Prepare the animation if this drawable also be animatable.
         * @param duration The animation duration.
         * @param startListener The callback listener used to receive the start of the animation.
         * @param startListener The callback listener used to receive the start of the animation.
         */
         */
        void prepareAnimate(long duration, LongConsumer startListener);
        void prepareAnimate(LongConsumer startListener);


        /**
        /**
         * Stop animation.
         * Stop animation.
+3 −1
Original line number Original line Diff line number Diff line
@@ -2322,7 +2322,9 @@
        <attr name="windowSplashScreenAnimatedIcon" format="reference"/>
        <attr name="windowSplashScreenAnimatedIcon" format="reference"/>
        <!-- The duration, in milliseconds, of the window splash screen icon animation duration
        <!-- The duration, in milliseconds, of the window splash screen icon animation duration
             when playing the splash screen starting window. The maximum animation duration should
             when playing the splash screen starting window. The maximum animation duration should
             be limited below 1000ms. -->
             be limited below 1000ms.
              @deprecated Not used by framework starting from API level 33. The system estimates the
               duration of the vector animation automatically. -->
        <attr name="windowSplashScreenAnimationDuration" format="integer"/>
        <attr name="windowSplashScreenAnimationDuration" format="integer"/>
        <!-- Place an drawable image in the bottom of the starting window, it can be used to
        <!-- Place an drawable image in the bottom of the starting window, it can be used to
+5 −15
Original line number Original line Diff line number Diff line
@@ -301,8 +301,6 @@ public class SplashscreenContentDrawer {
                Color.TRANSPARENT);
                Color.TRANSPARENT);
        attrs.mSplashScreenIcon = safeReturnAttrDefault((def) -> typedArray.getDrawable(
        attrs.mSplashScreenIcon = safeReturnAttrDefault((def) -> typedArray.getDrawable(
                R.styleable.Window_windowSplashScreenAnimatedIcon), null);
                R.styleable.Window_windowSplashScreenAnimatedIcon), null);
        attrs.mAnimationDuration = safeReturnAttrDefault((def) -> typedArray.getInt(
                R.styleable.Window_windowSplashScreenAnimationDuration, def), 0);
        attrs.mBrandingImage = safeReturnAttrDefault((def) -> typedArray.getDrawable(
        attrs.mBrandingImage = safeReturnAttrDefault((def) -> typedArray.getDrawable(
                R.styleable.Window_windowSplashScreenBrandingImage), null);
                R.styleable.Window_windowSplashScreenBrandingImage), null);
        attrs.mIconBgColor = safeReturnAttrDefault((def) -> typedArray.getColor(
        attrs.mIconBgColor = safeReturnAttrDefault((def) -> typedArray.getColor(
@@ -310,9 +308,8 @@ public class SplashscreenContentDrawer {
                Color.TRANSPARENT);
                Color.TRANSPARENT);
        typedArray.recycle();
        typedArray.recycle();
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                "getWindowAttrs: window attributes color: %s, replace icon: %b, avd duration: %d",
                "getWindowAttrs: window attributes color: %s, replace icon: %b",
                Integer.toHexString(attrs.mWindowBgColor), attrs.mSplashScreenIcon != null,
                Integer.toHexString(attrs.mWindowBgColor), attrs.mSplashScreenIcon != null);
                attrs.mAnimationDuration);
    }
    }


    /** Creates the wrapper with system theme to avoid unexpected styles from app. */
    /** Creates the wrapper with system theme to avoid unexpected styles from app. */
@@ -327,7 +324,6 @@ public class SplashscreenContentDrawer {
        private Drawable mSplashScreenIcon = null;
        private Drawable mSplashScreenIcon = null;
        private Drawable mBrandingImage = null;
        private Drawable mBrandingImage = null;
        private int mIconBgColor = Color.TRANSPARENT;
        private int mIconBgColor = Color.TRANSPARENT;
        private int mAnimationDuration = 0;
    }
    }


    /**
    /**
@@ -401,16 +397,13 @@ public class SplashscreenContentDrawer {


        SplashScreenView build() {
        SplashScreenView build() {
            Drawable iconDrawable;
            Drawable iconDrawable;
            final long animationDuration;
            if (mSuggestType == STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN
            if (mSuggestType == STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN
                    || mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
                    || mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
                // empty or legacy splash screen case
                // empty or legacy splash screen case
                animationDuration = 0;
                mFinalIconSize = 0;
                mFinalIconSize = 0;
            } else if (mTmpAttrs.mSplashScreenIcon != null) {
            } else if (mTmpAttrs.mSplashScreenIcon != null) {
                // Using the windowSplashScreenAnimatedIcon attribute
                // Using the windowSplashScreenAnimatedIcon attribute
                iconDrawable = mTmpAttrs.mSplashScreenIcon;
                iconDrawable = mTmpAttrs.mSplashScreenIcon;
                animationDuration = mTmpAttrs.mAnimationDuration;


                // There is no background below the icon, so scale the icon up
                // There is no background below the icon, so scale the icon up
                if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT
                if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT
@@ -440,11 +433,9 @@ public class SplashscreenContentDrawer {
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                    createIconDrawable(new BitmapDrawable(bitmap), true);
                    createIconDrawable(new BitmapDrawable(bitmap), true);
                }
                }
                animationDuration = 0;
            }
            }


            return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration,
            return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, mUiThreadInitTask);
                    mUiThreadInitTask);
        }
        }


        private class ShapeIconFactory extends BaseIconFactory {
        private class ShapeIconFactory extends BaseIconFactory {
@@ -460,7 +451,7 @@ public class SplashscreenContentDrawer {
            } else {
            } else {
                mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
                mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
                        mTmpAttrs.mIconBgColor, mThemeColor, iconDrawable, mDefaultIconSize,
                        mTmpAttrs.mIconBgColor, mThemeColor, iconDrawable, mDefaultIconSize,
                        mFinalIconSize, mSplashscreenWorkerHandler, mSplashScreenExecutor);
                        mFinalIconSize, mSplashscreenWorkerHandler);
            }
            }
        }
        }


@@ -520,7 +511,7 @@ public class SplashscreenContentDrawer {
        }
        }


        private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
        private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
                long animationDuration, Consumer<Runnable> uiThreadInitTask) {
                Consumer<Runnable> uiThreadInitTask) {
            Drawable foreground = null;
            Drawable foreground = null;
            Drawable background = null;
            Drawable background = null;
            if (iconDrawable != null) {
            if (iconDrawable != null) {
@@ -536,7 +527,6 @@ public class SplashscreenContentDrawer {
                    .setIconSize(iconSize)
                    .setIconSize(iconSize)
                    .setIconBackground(background)
                    .setIconBackground(background)
                    .setCenterViewDrawable(foreground)
                    .setCenterViewDrawable(foreground)
                    .setAnimationDurationMillis(animationDuration)
                    .setUiThreadInitConsumer(uiThreadInitTask)
                    .setUiThreadInitConsumer(uiThreadInitTask)
                    .setAllowHandleSolidColor(mAllowHandleSolidColor);
                    .setAllowHandleSolidColor(mAllowHandleSolidColor);


+7 −16
Original line number Original line Diff line number Diff line
@@ -44,7 +44,6 @@ import android.util.PathParser;
import android.window.SplashScreenView;
import android.window.SplashScreenView;


import com.android.internal.R;
import com.android.internal.R;
import com.android.wm.shell.common.ShellExecutor;


import java.util.function.LongConsumer;
import java.util.function.LongConsumer;


@@ -63,15 +62,14 @@ public class SplashscreenIconDrawableFactory {
     */
     */
    static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor,
    static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor,
            @NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
            @NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
            Handler splashscreenWorkerHandler, ShellExecutor splashScreenExecutor) {
            Handler splashscreenWorkerHandler) {
        Drawable foreground;
        Drawable foreground;
        Drawable background = null;
        Drawable background = null;
        boolean drawBackground =
        boolean drawBackground =
                backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor;
                backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor;


        if (foregroundDrawable instanceof Animatable) {
        if (foregroundDrawable instanceof Animatable) {
            foreground = new AnimatableIconAnimateListener(foregroundDrawable,
            foreground = new AnimatableIconAnimateListener(foregroundDrawable);
                    splashScreenExecutor);
        } else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
        } else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
            // If the icon is Adaptive, we already use the icon background.
            // If the icon is Adaptive, we already use the icon background.
            drawBackground = false;
            drawBackground = false;
@@ -274,12 +272,9 @@ public class SplashscreenIconDrawableFactory {
        private boolean mAnimationTriggered;
        private boolean mAnimationTriggered;
        private AnimatorListenerAdapter mJankMonitoringListener;
        private AnimatorListenerAdapter mJankMonitoringListener;
        private boolean mRunning;
        private boolean mRunning;
        private long mDuration;
        private LongConsumer mStartListener;
        private LongConsumer mStartListener;
        private final ShellExecutor mSplashScreenExecutor;


        AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable,
        AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) {
                ShellExecutor splashScreenExecutor) {
            super(foregroundDrawable);
            super(foregroundDrawable);
            Callback callback = new Callback() {
            Callback callback = new Callback() {
                @Override
                @Override
@@ -299,7 +294,6 @@ public class SplashscreenIconDrawableFactory {
                }
                }
            };
            };
            mForegroundDrawable.setCallback(callback);
            mForegroundDrawable.setCallback(callback);
            mSplashScreenExecutor = splashScreenExecutor;
            mAnimatableIcon = (Animatable) mForegroundDrawable;
            mAnimatableIcon = (Animatable) mForegroundDrawable;
        }
        }


@@ -309,9 +303,8 @@ public class SplashscreenIconDrawableFactory {
        }
        }


        @Override
        @Override
        public void prepareAnimate(long duration, LongConsumer startListener) {
        public void prepareAnimate(LongConsumer startListener) {
            stopAnimation();
            stopAnimation();
            mDuration = duration;
            mStartListener = startListener;
            mStartListener = startListener;
        }
        }


@@ -328,11 +321,11 @@ public class SplashscreenIconDrawableFactory {
                    mJankMonitoringListener.onAnimationCancel(null);
                    mJankMonitoringListener.onAnimationCancel(null);
                }
                }
                if (mStartListener != null) {
                if (mStartListener != null) {
                    mStartListener.accept(mDuration);
                    mStartListener.accept(0);
                }
                }
                return;
                return;
            }
            }
            long animDuration = mDuration;
            long animDuration = 0;
            if (mAnimatableIcon instanceof AnimatedVectorDrawable
            if (mAnimatableIcon instanceof AnimatedVectorDrawable
                    && ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration() > 0) {
                    && ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration() > 0) {
                animDuration = ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration();
                animDuration = ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration();
@@ -341,9 +334,8 @@ public class SplashscreenIconDrawableFactory {
                animDuration = ((AnimationDrawable) mAnimatableIcon).getTotalDuration();
                animDuration = ((AnimationDrawable) mAnimatableIcon).getTotalDuration();
            }
            }
            mRunning = true;
            mRunning = true;
            mSplashScreenExecutor.executeDelayed(this::stopAnimation, animDuration);
            if (mStartListener != null) {
            if (mStartListener != null) {
                mStartListener.accept(Math.max(animDuration, 0));
                mStartListener.accept(animDuration);
            }
            }
        }
        }


@@ -359,7 +351,6 @@ public class SplashscreenIconDrawableFactory {
        @Override
        @Override
        public void stopAnimation() {
        public void stopAnimation() {
            if (mRunning) {
            if (mRunning) {
                mSplashScreenExecutor.removeCallbacks(this::stopAnimation);
                onAnimationEnd();
                onAnimationEnd();
                mJankMonitoringListener = null;
                mJankMonitoringListener = null;
            }
            }