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

Commit 09dd5edb authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Automerger Merge Worker
Browse files

Merge "Refine splash screen APIs" into sc-dev am: 5719f05c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14048545

Change-Id: Ibc0d8cad36ef7985655e08202890173cc226e119
parents a13681b2 5719f05c
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -56740,18 +56740,19 @@ package android.widget.inline {
package android.window {
  public interface SplashScreen {
    method public void setOnExitAnimationListener(@Nullable android.window.SplashScreen.OnExitAnimationListener);
    method public void clearOnExitAnimationListener();
    method public void setOnExitAnimationListener(@NonNull android.window.SplashScreen.OnExitAnimationListener);
  }
  public static interface SplashScreen.OnExitAnimationListener {
    method public void onSplashScreenExit(@NonNull android.window.SplashScreenView);
    method @UiThread public void onSplashScreenExit(@NonNull android.window.SplashScreenView);
  }
  public final class SplashScreenView extends android.widget.FrameLayout {
    method public long getIconAnimationDurationMillis();
    method public long getIconAnimationStartMillis();
    method @Nullable public java.time.Duration getIconAnimationDuration();
    method @Nullable public java.time.Instant getIconAnimationStart();
    method @Nullable public android.view.View getIconView();
    method public void remove();
    method @UiThread public void remove();
  }
}
+26 −11
Original line number Diff line number Diff line
@@ -17,8 +17,8 @@
package android.window;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.UiThread;
import android.app.Activity;
import android.app.ActivityThread;
import android.content.Context;
@@ -52,7 +52,13 @@ public interface SplashScreen {
     * @see OnExitAnimationListener#onSplashScreenExit(SplashScreenView)
     */
    @SuppressLint("ExecutorRegistration")
    void setOnExitAnimationListener(@Nullable SplashScreen.OnExitAnimationListener listener);
    void setOnExitAnimationListener(@NonNull SplashScreen.OnExitAnimationListener listener);

    /**
     * Clear exist listener
     * @see #setOnExitAnimationListener
     */
    void clearOnExitAnimationListener();

    /**
     * Listens for the splash screen exit event.
@@ -63,15 +69,14 @@ public interface SplashScreen {
         * of the activity. The {@link SplashScreenView} represents the splash screen view
         * object, developer can make an exit animation based on this view.</p>
         *
         * <p>If {@link SplashScreenView#remove} is not called after 5000ms, the method will be
         * automatically called and the splash screen removed.</p>
         *
         * <p>This method is never invoked if your activity sets
         * {@link #setOnExitAnimationListener} to <code>null</code>..
         * <p>This method is never invoked if your activity clear the listener by
         * {@link #clearOnExitAnimationListener}.
         *
         * @param view The view object which on top of this Activity.
         * @see #setOnExitAnimationListener
         * @see #clearOnExitAnimationListener
         */
        @UiThread
        void onSplashScreenExit(@NonNull SplashScreenView view);
    }

@@ -90,20 +95,30 @@ public interface SplashScreen {

        @Override
        public void setOnExitAnimationListener(
                @Nullable SplashScreen.OnExitAnimationListener listener) {
                @NonNull SplashScreen.OnExitAnimationListener listener) {
            if (mActivityToken == null) {
                // This is not an activity.
                return;
            }
            synchronized (mGlobal.mGlobalLock) {
                mExitAnimationListener = listener;
                if (listener != null) {
                    mExitAnimationListener = listener;
                    mGlobal.addImpl(this);
                } else {
                    mGlobal.removeImpl(this);
                }
            }
        }

        @Override
        public void clearOnExitAnimationListener() {
            if (mActivityToken == null) {
                // This is not an activity.
                return;
            }
            synchronized (mGlobal.mGlobalLock) {
                mExitAnimationListener = null;
                mGlobal.removeImpl(this);
            }
        }
    }

    /**
+39 −26
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UiThread;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
@@ -32,7 +33,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.Trace;
import android.util.AttributeSet;
import android.util.Log;
@@ -46,7 +46,8 @@ import android.widget.FrameLayout;
import com.android.internal.R;
import com.android.internal.policy.DecorView;

import java.util.function.Consumer;
import java.time.Duration;
import java.time.Instant;

/**
 * <p>The view which allows an activity to customize its splash screen exit animation.</p>
@@ -75,8 +76,8 @@ public final class SplashScreenView extends FrameLayout {
    private Bitmap mParceledIconBitmap;
    private View mBrandingImageView;
    private Bitmap mParceledBrandingBitmap;
    private long mIconAnimationDuration;
    private long mIconAnimationStart;
    private Duration mIconAnimationDuration;
    private Instant mIconAnimationStart;

    // The host activity when transfer view to it.
    private Activity mHostActivity;
@@ -85,6 +86,7 @@ public final class SplashScreenView extends FrameLayout {
    private boolean mDrawBarBackground;
    private int mStatusBarColor;
    private int mNavigationBarColor;
    private boolean mHasRemoved;

    /**
     * Internal builder to create a SplashScreenView object.
@@ -101,8 +103,8 @@ public final class SplashScreenView extends FrameLayout {
        private int mBrandingImageHeight;
        private Drawable mBrandingDrawable;
        private Bitmap mParceledBrandingBitmap;
        private long mIconAnimationStart;
        private long mIconAnimationDuration;
        private Instant mIconAnimationStart;
        private Duration mIconAnimationDuration;

        public Builder(@NonNull Context context) {
            mContext = context;
@@ -126,8 +128,8 @@ public final class SplashScreenView extends FrameLayout {
                        parcelable.mBrandingHeight);
                mParceledBrandingBitmap = parcelable.mBrandingBitmap;
            }
            mIconAnimationStart = parcelable.mIconAnimationStart;
            mIconAnimationDuration = parcelable.mIconAnimationDuration;
            mIconAnimationStart = Instant.ofEpochMilli(parcelable.mIconAnimationStartMillis);
            mIconAnimationDuration = Duration.ofMillis(parcelable.mIconAnimationDurationMillis);
            return this;
        }

@@ -166,8 +168,8 @@ public final class SplashScreenView extends FrameLayout {
        /**
         * Set the animation duration if icon is animatable.
         */
        public Builder setAnimationDuration(int duration) {
            mIconAnimationDuration = duration;
        public Builder setAnimationDurationMillis(int duration) {
            mIconAnimationDuration = Duration.ofMillis(duration);
            return this;
        }

@@ -203,7 +205,8 @@ public final class SplashScreenView extends FrameLayout {
            }
            if (mIconDrawable != null) {
                view.mIconView.setBackground(mIconDrawable);
                view.initIconAnimation(mIconDrawable, mIconAnimationDuration);
                view.initIconAnimation(mIconDrawable,
                        mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
            }
            view.mIconAnimationStart = mIconAnimationStart;
            view.mIconAnimationDuration = mIconAnimationDuration;
@@ -266,15 +269,16 @@ public final class SplashScreenView extends FrameLayout {
     * @see android.R.attr#windowSplashScreenAnimatedIcon
     * @see android.R.attr#windowSplashScreenAnimationDuration
     */
    public long getIconAnimationDurationMillis() {
    @Nullable
    public Duration getIconAnimationDuration() {
        return mIconAnimationDuration;
    }

    /**
     * If the replaced icon is animatable, return the animation start time in millisecond based on
     * system. The start time is set using {@link SystemClock#uptimeMillis()}.
     * If the replaced icon is animatable, return the animation start time based on system clock.
     */
    public long getIconAnimationStartMillis() {
    @Nullable
    public Instant getIconAnimationStart() {
        return mIconAnimationStart;
    }

@@ -286,8 +290,8 @@ public final class SplashScreenView extends FrameLayout {
        aniDrawable.prepareAnimate(duration, this::animationStartCallback);
    }

    private void animationStartCallback(long startAt) {
        mIconAnimationStart = startAt;
    private void animationStartCallback() {
        mIconAnimationStart = Instant.now();
    }

    /**
@@ -295,7 +299,11 @@ public final class SplashScreenView extends FrameLayout {
     * <p><strong>Do not</strong> invoke this method from a drawing method
     * ({@link #onDraw(android.graphics.Canvas)} for instance).</p>
     */
    @UiThread
    public void remove() {
        if (mHasRemoved) {
            return;
        }
        setVisibility(GONE);
        if (mParceledIconBitmap != null) {
            mIconView.setBackground(null);
@@ -321,6 +329,7 @@ public final class SplashScreenView extends FrameLayout {
        if (mHostActivity != null) {
            mHostActivity.detachSplashScreenView();
        }
        mHasRemoved = true;
    }

    /**
@@ -414,7 +423,7 @@ public final class SplashScreenView extends FrameLayout {
         * @param startListener The callback listener used to receive the start of the animation.
         * @return true if this drawable object can also be animated and it can be played now.
         */
        protected boolean prepareAnimate(long duration, Consumer<Long> startListener) {
        protected boolean prepareAnimate(long duration, Runnable startListener) {
            return false;
        }
    }
@@ -433,8 +442,8 @@ public final class SplashScreenView extends FrameLayout {
        private int mBrandingHeight;
        private Bitmap mBrandingBitmap;

        private long mIconAnimationStart;
        private long mIconAnimationDuration;
        private long mIconAnimationStartMillis;
        private long mIconAnimationDurationMillis;

        public SplashScreenViewParcelable(SplashScreenView view) {
            ViewGroup.LayoutParams params = view.getIconView().getLayoutParams();
@@ -447,8 +456,12 @@ public final class SplashScreenView extends FrameLayout {
            mBrandingWidth = params.width;
            mBrandingHeight = params.height;

            mIconAnimationStart = view.getIconAnimationStartMillis();
            mIconAnimationDuration = view.getIconAnimationDurationMillis();
            if (view.getIconAnimationStart() != null) {
                mIconAnimationStartMillis = view.getIconAnimationStart().toEpochMilli();
            }
            if (view.getIconAnimationDuration() != null) {
                mIconAnimationDurationMillis = view.getIconAnimationDuration().toMillis();
            }
        }

        private Bitmap copyDrawable(Drawable drawable) {
@@ -479,8 +492,8 @@ public final class SplashScreenView extends FrameLayout {
            mBrandingWidth = source.readInt();
            mBrandingHeight = source.readInt();
            mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR);
            mIconAnimationStart = source.readLong();
            mIconAnimationDuration = source.readLong();
            mIconAnimationStartMillis = source.readLong();
            mIconAnimationDurationMillis = source.readLong();
            mIconBackground = source.readInt();
        }

@@ -497,8 +510,8 @@ public final class SplashScreenView extends FrameLayout {
            dest.writeInt(mBrandingWidth);
            dest.writeInt(mBrandingHeight);
            dest.writeTypedObject(mBrandingBitmap, flags);
            dest.writeLong(mIconAnimationStart);
            dest.writeLong(mIconAnimationDuration);
            dest.writeLong(mIconAnimationStartMillis);
            dest.writeLong(mIconAnimationDurationMillis);
            dest.writeInt(mIconBackground);
        }

+1 −1
Original line number Diff line number Diff line
@@ -357,7 +357,7 @@ public class SplashscreenContentDrawer {
            if (iconDrawable != null) {
                builder.setCenterViewDrawable(iconDrawable);
            }
            builder.setAnimationDuration(mIconAnimationDuration);
            builder.setAnimationDurationMillis(mIconAnimationDuration);
            if (mBrandingDrawable != null) {
                builder.setBrandingDrawable(mBrandingDrawable, mBrandingImageWidth,
                        mBrandingImageHeight);
+2 −7
Original line number Diff line number Diff line
@@ -37,15 +37,12 @@ import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.os.Trace;
import android.util.PathParser;
import android.window.SplashScreenView;

import com.android.internal.R;

import java.util.function.Consumer;

/**
 * Creating a lightweight Drawable object used for splash screen.
 * @hide
@@ -133,7 +130,6 @@ public class SplashscreenIconDrawableFactory {
        private Animatable mAnimatableIcon;
        private Animator mIconAnimator;
        private boolean mAnimationTriggered;
        private long mIconAnimationStart;

        AnimatableIconDrawable(@ColorInt int backgroundColor, Drawable foregroundDrawable) {
            mForegroundDrawable = foregroundDrawable;
@@ -150,16 +146,15 @@ public class SplashscreenIconDrawableFactory {
        }

        @Override
        protected boolean prepareAnimate(long duration, Consumer<Long> startListener) {
        protected boolean prepareAnimate(long duration, Runnable startListener) {
            mAnimatableIcon = (Animatable) mForegroundDrawable;
            mIconAnimator = ValueAnimator.ofInt(0, 1);
            mIconAnimator.setDuration(duration);
            mIconAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                    mIconAnimationStart = SystemClock.uptimeMillis();
                    if (startListener != null) {
                        startListener.accept(mIconAnimationStart);
                        startListener.run();
                    }
                    mAnimatableIcon.start();
                }