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 Diff line number Diff line
@@ -1756,7 +1756,7 @@ package android {
    field public static final int windowShowWallpaper = 16843410; // 0x1010292
    field public static final int windowSoftInputMode = 16843307; // 0x101022b
    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 windowSplashScreenBehavior;
    field public static final int windowSplashScreenBrandingImage = 16844335; // 0x101062f
+10 −15
Original line number Diff line number Diff line
@@ -232,14 +232,6 @@ public final class SplashScreenView extends FrameLayout {
            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.
         * @param uiThreadInitTask
@@ -294,8 +286,7 @@ public final class SplashScreenView extends FrameLayout {
                } else {
                    view.mIconView = createSurfaceView(view);
                }
                view.initIconAnimation(mIconDrawable,
                        mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
                view.initIconAnimation(mIconDrawable);
                view.mIconAnimationStart = mIconAnimationStart;
                view.mIconAnimationDuration = mIconAnimationDuration;
            } 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.
     *
     * 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#windowSplashScreenAnimationDuration
     */
@@ -497,12 +493,12 @@ public final class SplashScreenView extends FrameLayout {
        mSurfaceView.setChildSurfacePackage(mSurfacePackage);
    }

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

    private void animationStartCallback(long animDuration) {
        mIconAnimationStart = Instant.now();
        if (animDuration > 0) {
        if (animDuration >= 0) {
            mIconAnimationDuration = Duration.ofMillis(animDuration);
        }
    }
@@ -695,10 +691,9 @@ public final class SplashScreenView extends FrameLayout {
    public interface IconAnimateListener {
        /**
         * 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.
         */
        void prepareAnimate(long duration, LongConsumer startListener);
        void prepareAnimate(LongConsumer startListener);

        /**
         * Stop animation.
+3 −1
Original line number Diff line number Diff line
@@ -2322,7 +2322,9 @@
        <attr name="windowSplashScreenAnimatedIcon" format="reference"/>
        <!-- The duration, in milliseconds, of the window splash screen icon animation duration
             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"/>
        <!-- Place an drawable image in the bottom of the starting window, it can be used to
+5 −15
Original line number Diff line number Diff line
@@ -301,8 +301,6 @@ public class SplashscreenContentDrawer {
                Color.TRANSPARENT);
        attrs.mSplashScreenIcon = safeReturnAttrDefault((def) -> typedArray.getDrawable(
                R.styleable.Window_windowSplashScreenAnimatedIcon), null);
        attrs.mAnimationDuration = safeReturnAttrDefault((def) -> typedArray.getInt(
                R.styleable.Window_windowSplashScreenAnimationDuration, def), 0);
        attrs.mBrandingImage = safeReturnAttrDefault((def) -> typedArray.getDrawable(
                R.styleable.Window_windowSplashScreenBrandingImage), null);
        attrs.mIconBgColor = safeReturnAttrDefault((def) -> typedArray.getColor(
@@ -310,9 +308,8 @@ public class SplashscreenContentDrawer {
                Color.TRANSPARENT);
        typedArray.recycle();
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                "getWindowAttrs: window attributes color: %s, replace icon: %b, avd duration: %d",
                Integer.toHexString(attrs.mWindowBgColor), attrs.mSplashScreenIcon != null,
                attrs.mAnimationDuration);
                "getWindowAttrs: window attributes color: %s, replace icon: %b",
                Integer.toHexString(attrs.mWindowBgColor), attrs.mSplashScreenIcon != null);
    }

    /** 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 mBrandingImage = null;
        private int mIconBgColor = Color.TRANSPARENT;
        private int mAnimationDuration = 0;
    }

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

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

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

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

        private class ShapeIconFactory extends BaseIconFactory {
@@ -460,7 +451,7 @@ public class SplashscreenContentDrawer {
            } else {
                mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
                        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,
                long animationDuration, Consumer<Runnable> uiThreadInitTask) {
                Consumer<Runnable> uiThreadInitTask) {
            Drawable foreground = null;
            Drawable background = null;
            if (iconDrawable != null) {
@@ -536,7 +527,6 @@ public class SplashscreenContentDrawer {
                    .setIconSize(iconSize)
                    .setIconBackground(background)
                    .setCenterViewDrawable(foreground)
                    .setAnimationDurationMillis(animationDuration)
                    .setUiThreadInitConsumer(uiThreadInitTask)
                    .setAllowHandleSolidColor(mAllowHandleSolidColor);

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

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

import java.util.function.LongConsumer;

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

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

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

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

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

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

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