Merge "Estimate animation duration for AVD and AnimationDrawable" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
172ea326de
@@ -65,6 +65,7 @@ import com.android.internal.util.ContrastColorUtil;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.LongConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>The view which allows an activity to customize its splash screen exit animation.</p>
|
* <p>The view which allows an activity to customize its splash screen exit animation.</p>
|
||||||
@@ -234,7 +235,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
/**
|
/**
|
||||||
* Set the animation duration if icon is animatable.
|
* Set the animation duration if icon is animatable.
|
||||||
*/
|
*/
|
||||||
public Builder setAnimationDurationMillis(int duration) {
|
public Builder setAnimationDurationMillis(long duration) {
|
||||||
mIconAnimationDuration = Duration.ofMillis(duration);
|
mIconAnimationDuration = Duration.ofMillis(duration);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -521,8 +522,11 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animationStartCallback() {
|
private void animationStartCallback(long animDuration) {
|
||||||
mIconAnimationStart = Instant.now();
|
mIconAnimationStart = Instant.now();
|
||||||
|
if (animDuration > 0) {
|
||||||
|
mIconAnimationDuration = Duration.ofMillis(animDuration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -693,9 +697,8 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
* Prepare the animation if this drawable also be animatable.
|
* Prepare the animation if this drawable also be animatable.
|
||||||
* @param duration The animation duration.
|
* @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.
|
||||||
* @return true if this drawable object can also be animated and it can be played now.
|
|
||||||
*/
|
*/
|
||||||
boolean prepareAnimate(long duration, Runnable startListener);
|
void prepareAnimate(long duration, LongConsumer startListener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop animation.
|
* Stop animation.
|
||||||
|
|||||||
@@ -690,6 +690,14 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the total duration of the animation
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public long getTotalDuration() {
|
||||||
|
return mAnimatorSet.getTotalDuration();
|
||||||
|
}
|
||||||
|
|
||||||
private static class AnimatedVectorDrawableState extends ConstantState {
|
private static class AnimatedVectorDrawableState extends ConstantState {
|
||||||
@Config int mChangingConfigurations;
|
@Config int mChangingConfigurations;
|
||||||
VectorDrawable mVectorDrawable;
|
VectorDrawable mVectorDrawable;
|
||||||
@@ -1074,6 +1082,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
boolean isInfinite();
|
boolean isInfinite();
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
|
long getTotalDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class VectorDrawableAnimatorUI implements VectorDrawableAnimator {
|
private static class VectorDrawableAnimatorUI implements VectorDrawableAnimator {
|
||||||
@@ -1085,6 +1094,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
// setup by init().
|
// setup by init().
|
||||||
private ArrayList<AnimatorListener> mListenerArray = null;
|
private ArrayList<AnimatorListener> mListenerArray = null;
|
||||||
private boolean mIsInfinite = false;
|
private boolean mIsInfinite = false;
|
||||||
|
private long mTotalDuration;
|
||||||
|
|
||||||
VectorDrawableAnimatorUI(@NonNull AnimatedVectorDrawable drawable) {
|
VectorDrawableAnimatorUI(@NonNull AnimatedVectorDrawable drawable) {
|
||||||
mDrawable = drawable;
|
mDrawable = drawable;
|
||||||
@@ -1100,7 +1110,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
// Keep a deep copy of the set, such that set can be still be constantly representing
|
// Keep a deep copy of the set, such that set can be still be constantly representing
|
||||||
// the static content from XML file.
|
// the static content from XML file.
|
||||||
mSet = set.clone();
|
mSet = set.clone();
|
||||||
mIsInfinite = mSet.getTotalDuration() == Animator.DURATION_INFINITE;
|
mTotalDuration = mSet.getTotalDuration();
|
||||||
|
mIsInfinite = mTotalDuration == Animator.DURATION_INFINITE;
|
||||||
|
|
||||||
// If there are listeners added before calling init(), now they should be setup.
|
// If there are listeners added before calling init(), now they should be setup.
|
||||||
if (mListenerArray != null && !mListenerArray.isEmpty()) {
|
if (mListenerArray != null && !mListenerArray.isEmpty()) {
|
||||||
@@ -1219,6 +1230,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
private void invalidateOwningView() {
|
private void invalidateOwningView() {
|
||||||
mDrawable.invalidateSelf();
|
mDrawable.invalidateSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTotalDuration() {
|
||||||
|
return mTotalDuration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1249,6 +1265,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
private int mLastListenerId = 0;
|
private int mLastListenerId = 0;
|
||||||
private final IntArray mPendingAnimationActions = new IntArray();
|
private final IntArray mPendingAnimationActions = new IntArray();
|
||||||
private final AnimatedVectorDrawable mDrawable;
|
private final AnimatedVectorDrawable mDrawable;
|
||||||
|
private long mTotalDuration;
|
||||||
|
|
||||||
VectorDrawableAnimatorRT(AnimatedVectorDrawable drawable) {
|
VectorDrawableAnimatorRT(AnimatedVectorDrawable drawable) {
|
||||||
mDrawable = drawable;
|
mDrawable = drawable;
|
||||||
@@ -1270,7 +1287,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
.getNativeTree();
|
.getNativeTree();
|
||||||
nSetVectorDrawableTarget(mSetPtr, vectorDrawableTreePtr);
|
nSetVectorDrawableTarget(mSetPtr, vectorDrawableTreePtr);
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
mIsInfinite = set.getTotalDuration() == Animator.DURATION_INFINITE;
|
mTotalDuration = set.getTotalDuration();
|
||||||
|
mIsInfinite = mTotalDuration == Animator.DURATION_INFINITE;
|
||||||
|
|
||||||
// Check reversible.
|
// Check reversible.
|
||||||
mIsReversible = true;
|
mIsReversible = true;
|
||||||
@@ -1796,6 +1814,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
}
|
}
|
||||||
mPendingAnimationActions.clear();
|
mPendingAnimationActions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTotalDuration() {
|
||||||
|
return mTotalDuration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native long nCreateAnimatorSet();
|
private static native long nCreateAnimatorSet();
|
||||||
|
|||||||
@@ -424,6 +424,17 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
|
|||||||
System.arraycopy(mDurations, 0, newDurations, 0, oldSize);
|
System.arraycopy(mDurations, 0, newDurations, 0, oldSize);
|
||||||
mDurations = newDurations;
|
mDurations = newDurations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getTotalDuration() {
|
||||||
|
if (mDurations != null) {
|
||||||
|
int total = 0;
|
||||||
|
for (int dur : mDurations) {
|
||||||
|
total += dur;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -435,6 +446,14 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the total duration of the animation
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public long getTotalDuration() {
|
||||||
|
return mAnimationState.getTotalDuration();
|
||||||
|
}
|
||||||
|
|
||||||
private AnimationDrawable(AnimationState state, Resources res) {
|
private AnimationDrawable(AnimationState state, Resources res) {
|
||||||
final AnimationState as = new AnimationState(state, this, res);
|
final AnimationState as = new AnimationState(state, this, res);
|
||||||
setConstantState(as);
|
setConstantState(as);
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
|
|||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.launcher3.icons.BaseIconFactory;
|
import com.android.launcher3.icons.BaseIconFactory;
|
||||||
import com.android.launcher3.icons.IconProvider;
|
import com.android.launcher3.icons.IconProvider;
|
||||||
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||||
|
|
||||||
@@ -115,8 +116,10 @@ public class SplashscreenContentDrawer {
|
|||||||
private final Handler mSplashscreenWorkerHandler;
|
private final Handler mSplashscreenWorkerHandler;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final ColorCache mColorCache;
|
final ColorCache mColorCache;
|
||||||
|
private final ShellExecutor mSplashScreenExecutor;
|
||||||
|
|
||||||
SplashscreenContentDrawer(Context context, IconProvider iconProvider, TransactionPool pool) {
|
SplashscreenContentDrawer(Context context, IconProvider iconProvider, TransactionPool pool,
|
||||||
|
ShellExecutor splashScreenExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mIconProvider = iconProvider;
|
mIconProvider = iconProvider;
|
||||||
mTransactionPool = pool;
|
mTransactionPool = pool;
|
||||||
@@ -129,6 +132,7 @@ public class SplashscreenContentDrawer {
|
|||||||
shellSplashscreenWorkerThread.start();
|
shellSplashscreenWorkerThread.start();
|
||||||
mSplashscreenWorkerHandler = shellSplashscreenWorkerThread.getThreadHandler();
|
mSplashscreenWorkerHandler = shellSplashscreenWorkerThread.getThreadHandler();
|
||||||
mColorCache = new ColorCache(mContext, mSplashscreenWorkerHandler);
|
mColorCache = new ColorCache(mContext, mSplashscreenWorkerHandler);
|
||||||
|
mSplashScreenExecutor = splashScreenExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -397,7 +401,7 @@ public class SplashscreenContentDrawer {
|
|||||||
|
|
||||||
SplashScreenView build() {
|
SplashScreenView build() {
|
||||||
Drawable iconDrawable;
|
Drawable iconDrawable;
|
||||||
final int animationDuration;
|
final long animationDuration;
|
||||||
if (mSuggestType == STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
|
if (mSuggestType == STARTING_WINDOW_TYPE_EMPTY_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
|
||||||
@@ -455,8 +459,8 @@ public class SplashscreenContentDrawer {
|
|||||||
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
|
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
|
||||||
} else {
|
} else {
|
||||||
mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
|
mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
|
||||||
mTmpAttrs.mIconBgColor, mThemeColor,
|
mTmpAttrs.mIconBgColor, mThemeColor, iconDrawable, mDefaultIconSize,
|
||||||
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
|
mFinalIconSize, mSplashscreenWorkerHandler, mSplashScreenExecutor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,7 +520,7 @@ public class SplashscreenContentDrawer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
|
private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
|
||||||
int animationDuration, Consumer<Runnable> uiThreadInitTask) {
|
long animationDuration, Consumer<Runnable> uiThreadInitTask) {
|
||||||
Drawable foreground = null;
|
Drawable foreground = null;
|
||||||
Drawable background = null;
|
Drawable background = null;
|
||||||
if (iconDrawable != null) {
|
if (iconDrawable != null) {
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ package com.android.wm.shell.startingsurface;
|
|||||||
|
|
||||||
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.annotation.ColorInt;
|
import android.annotation.ColorInt;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -36,6 +34,8 @@ import android.graphics.PixelFormat;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||||
import android.graphics.drawable.Animatable;
|
import android.graphics.drawable.Animatable;
|
||||||
|
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||||
|
import android.graphics.drawable.AnimationDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
@@ -44,6 +44,9 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creating a lightweight Drawable object used for splash screen.
|
* Creating a lightweight Drawable object used for splash screen.
|
||||||
@@ -60,14 +63,15 @@ 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) {
|
Handler splashscreenWorkerHandler, ShellExecutor splashScreenExecutor) {
|
||||||
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;
|
||||||
@@ -266,14 +270,37 @@ public class SplashscreenIconDrawableFactory {
|
|||||||
*/
|
*/
|
||||||
public static class AnimatableIconAnimateListener extends AdaptiveForegroundDrawable
|
public static class AnimatableIconAnimateListener extends AdaptiveForegroundDrawable
|
||||||
implements SplashScreenView.IconAnimateListener {
|
implements SplashScreenView.IconAnimateListener {
|
||||||
private Animatable mAnimatableIcon;
|
private final Animatable mAnimatableIcon;
|
||||||
private Animator mIconAnimator;
|
|
||||||
private boolean mAnimationTriggered;
|
private boolean mAnimationTriggered;
|
||||||
private AnimatorListenerAdapter mJankMonitoringListener;
|
private AnimatorListenerAdapter mJankMonitoringListener;
|
||||||
|
private boolean mRunning;
|
||||||
|
private long mDuration;
|
||||||
|
private LongConsumer mStartListener;
|
||||||
|
private final ShellExecutor mSplashScreenExecutor;
|
||||||
|
|
||||||
AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) {
|
AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable,
|
||||||
|
ShellExecutor splashScreenExecutor) {
|
||||||
super(foregroundDrawable);
|
super(foregroundDrawable);
|
||||||
mForegroundDrawable.setCallback(mCallback);
|
Callback callback = new Callback() {
|
||||||
|
@Override
|
||||||
|
public void invalidateDrawable(@NonNull Drawable who) {
|
||||||
|
invalidateSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what,
|
||||||
|
long when) {
|
||||||
|
scheduleSelf(what, when);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
|
||||||
|
unscheduleSelf(what);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mForegroundDrawable.setCallback(callback);
|
||||||
|
mSplashScreenExecutor = splashScreenExecutor;
|
||||||
|
mAnimatableIcon = (Animatable) mForegroundDrawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -282,83 +309,68 @@ public class SplashscreenIconDrawableFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean prepareAnimate(long duration, Runnable startListener) {
|
public void prepareAnimate(long duration, LongConsumer startListener) {
|
||||||
mAnimatableIcon = (Animatable) mForegroundDrawable;
|
stopAnimation();
|
||||||
mIconAnimator = ValueAnimator.ofInt(0, 1);
|
mDuration = duration;
|
||||||
mIconAnimator.setDuration(duration);
|
mStartListener = startListener;
|
||||||
mIconAnimator.addListener(new Animator.AnimatorListener() {
|
}
|
||||||
@Override
|
|
||||||
public void onAnimationStart(Animator animation) {
|
|
||||||
if (startListener != null) {
|
|
||||||
startListener.run();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (mJankMonitoringListener != null) {
|
|
||||||
mJankMonitoringListener.onAnimationStart(animation);
|
|
||||||
}
|
|
||||||
mAnimatableIcon.start();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.e(TAG, "Error while running the splash screen animated icon", ex);
|
|
||||||
animation.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private void startAnimation() {
|
||||||
public void onAnimationEnd(Animator animation) {
|
if (mJankMonitoringListener != null) {
|
||||||
mAnimatableIcon.stop();
|
mJankMonitoringListener.onAnimationStart(null);
|
||||||
if (mJankMonitoringListener != null) {
|
}
|
||||||
mJankMonitoringListener.onAnimationEnd(animation);
|
try {
|
||||||
}
|
mAnimatableIcon.start();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(TAG, "Error while running the splash screen animated icon", ex);
|
||||||
|
mRunning = false;
|
||||||
|
if (mJankMonitoringListener != null) {
|
||||||
|
mJankMonitoringListener.onAnimationCancel(null);
|
||||||
}
|
}
|
||||||
|
if (mStartListener != null) {
|
||||||
|
mStartListener.accept(mDuration);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long animDuration = mDuration;
|
||||||
|
if (mAnimatableIcon instanceof AnimatedVectorDrawable
|
||||||
|
&& ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration() > 0) {
|
||||||
|
animDuration = ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration();
|
||||||
|
} else if (mAnimatableIcon instanceof AnimationDrawable
|
||||||
|
&& ((AnimationDrawable) mAnimatableIcon).getTotalDuration() > 0) {
|
||||||
|
animDuration = ((AnimationDrawable) mAnimatableIcon).getTotalDuration();
|
||||||
|
}
|
||||||
|
mRunning = true;
|
||||||
|
mSplashScreenExecutor.executeDelayed(this::stopAnimation, animDuration);
|
||||||
|
if (mStartListener != null) {
|
||||||
|
mStartListener.accept(Math.max(animDuration, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
private void onAnimationEnd() {
|
||||||
public void onAnimationCancel(Animator animation) {
|
mAnimatableIcon.stop();
|
||||||
mAnimatableIcon.stop();
|
if (mJankMonitoringListener != null) {
|
||||||
if (mJankMonitoringListener != null) {
|
mJankMonitoringListener.onAnimationEnd(null);
|
||||||
mJankMonitoringListener.onAnimationCancel(animation);
|
}
|
||||||
}
|
mStartListener = null;
|
||||||
}
|
mRunning = false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationRepeat(Animator animation) {
|
|
||||||
// do not repeat
|
|
||||||
mAnimatableIcon.stop();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopAnimation() {
|
public void stopAnimation() {
|
||||||
if (mIconAnimator != null && mIconAnimator.isRunning()) {
|
if (mRunning) {
|
||||||
mIconAnimator.end();
|
mSplashScreenExecutor.removeCallbacks(this::stopAnimation);
|
||||||
|
onAnimationEnd();
|
||||||
mJankMonitoringListener = null;
|
mJankMonitoringListener = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Callback mCallback = new Callback() {
|
|
||||||
@Override
|
|
||||||
public void invalidateDrawable(@NonNull Drawable who) {
|
|
||||||
invalidateSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
|
|
||||||
scheduleSelf(what, when);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
|
|
||||||
unscheduleSelf(what);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void ensureAnimationStarted() {
|
private void ensureAnimationStarted() {
|
||||||
if (mAnimationTriggered) {
|
if (mAnimationTriggered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mIconAnimator != null && !mIconAnimator.isRunning()) {
|
if (!mRunning) {
|
||||||
mIconAnimator.start();
|
startAnimation();
|
||||||
}
|
}
|
||||||
mAnimationTriggered = true;
|
mAnimationTriggered = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,8 @@ public class StartingSurfaceDrawer {
|
|||||||
mContext = context;
|
mContext = context;
|
||||||
mDisplayManager = mContext.getSystemService(DisplayManager.class);
|
mDisplayManager = mContext.getSystemService(DisplayManager.class);
|
||||||
mSplashScreenExecutor = splashScreenExecutor;
|
mSplashScreenExecutor = splashScreenExecutor;
|
||||||
mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconProvider, pool);
|
mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconProvider, pool,
|
||||||
|
mSplashScreenExecutor);
|
||||||
mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
|
mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
|
||||||
mWindowManagerGlobal = WindowManagerGlobal.getInstance();
|
mWindowManagerGlobal = WindowManagerGlobal.getInstance();
|
||||||
mDisplayManager.getDisplay(DEFAULT_DISPLAY);
|
mDisplayManager.getDisplay(DEFAULT_DISPLAY);
|
||||||
|
|||||||
Reference in New Issue
Block a user