summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/res/values/config.xml8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java188
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java5
4 files changed, 133 insertions, 77 deletions
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index edf000b5e68a..bbbbe6987adf 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -52,6 +52,12 @@
when the PIP menu is shown in center. -->
<string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string>
+ <!-- Animation duration when exit starting window: fade out icon -->
+ <integer name="starting_window_app_reveal_icon_fade_out_duration">133</integer>
+
+ <!-- Animation duration when exit starting window: reveal app -->
+ <integer name="starting_window_app_reveal_anim_delay">83</integer>
+
<!-- Animation duration when exit starting window: reveal app -->
- <integer name="starting_window_app_reveal_anim_duration">333</integer>
+ <integer name="starting_window_app_reveal_anim_duration">266</integer>
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
index 3fe57c61c0bb..c303a33afc78 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
@@ -20,6 +20,7 @@ import static android.view.View.GONE;
import android.animation.Animator;
import android.animation.ValueAnimator;
+import android.content.Context;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -29,6 +30,7 @@ import android.graphics.Point;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Shader;
+import android.util.MathUtils;
import android.util.Slog;
import android.view.Choreographer;
import android.view.SurfaceControl;
@@ -38,10 +40,10 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
-import android.view.animation.Transformation;
-import android.view.animation.TranslateYAnimation;
import android.window.SplashScreenView;
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.TransactionPool;
/**
@@ -53,52 +55,64 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
private static final boolean DEBUG_EXIT_ANIMATION_BLEND = false;
private static final String TAG = StartingSurfaceDrawer.TAG;
- private static final Interpolator APP_EXIT_INTERPOLATOR = new PathInterpolator(0f, 0f, 0f, 1f);
+ private static final Interpolator ICON_INTERPOLATOR = new PathInterpolator(0.15f, 0f, 1f, 1f);
+ private static final Interpolator MASK_RADIUS_INTERPOLATOR =
+ new PathInterpolator(0f, 0f, 0.4f, 1f);
+ private static final Interpolator SHIFT_UP_INTERPOLATOR = new PathInterpolator(0f, 0f, 0f, 1f);
- private final Matrix mTmpTransform = new Matrix();
private final SurfaceControl mFirstWindowSurface;
private final Rect mFirstWindowFrame = new Rect();
private final SplashScreenView mSplashScreenView;
private final int mMainWindowShiftLength;
- private final int mAppDuration;
+ private final int mIconFadeOutDuration;
+ private final int mAppRevealDelay;
+ private final int mAppRevealDuration;
+ private final int mAnimationDuration;
+ private final float mIconStartAlpha;
private final TransactionPool mTransactionPool;
private ValueAnimator mMainAnimator;
private ShiftUpAnimation mShiftUpAnimation;
+ private RadialVanishAnimation mRadialVanishAnimation;
private Runnable mFinishCallback;
- SplashScreenExitAnimation(SplashScreenView view, SurfaceControl leash, Rect frame,
- int appDuration, int mainWindowShiftLength, TransactionPool pool,
- Runnable handleFinish) {
+ SplashScreenExitAnimation(Context context, SplashScreenView view, SurfaceControl leash,
+ Rect frame, int mainWindowShiftLength, TransactionPool pool, Runnable handleFinish) {
mSplashScreenView = view;
mFirstWindowSurface = leash;
if (frame != null) {
mFirstWindowFrame.set(frame);
}
- mAppDuration = appDuration;
+
+ View iconView = view.getIconView();
+ if (iconView == null) {
+ mIconFadeOutDuration = 0;
+ mIconStartAlpha = 0;
+ mAppRevealDelay = 0;
+ } else {
+ iconView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mIconFadeOutDuration = context.getResources().getInteger(
+ R.integer.starting_window_app_reveal_icon_fade_out_duration);
+ mAppRevealDelay = context.getResources().getInteger(
+ R.integer.starting_window_app_reveal_anim_delay);
+ mIconStartAlpha = iconView.getAlpha();
+ }
+ mAppRevealDuration = context.getResources().getInteger(
+ R.integer.starting_window_app_reveal_anim_duration);
+ mAnimationDuration = Math.max(mIconFadeOutDuration, mAppRevealDelay + mAppRevealDuration);
mMainWindowShiftLength = mainWindowShiftLength;
mFinishCallback = handleFinish;
mTransactionPool = pool;
}
void startAnimations() {
- prepareRevealAnimation();
- if (mMainAnimator != null) {
- mMainAnimator.start();
- }
- if (mShiftUpAnimation != null) {
- mShiftUpAnimation.start();
- }
+ mMainAnimator = createAnimator();
+ mMainAnimator.start();
}
- // reveal splash screen, shift up main window
- private void prepareRevealAnimation() {
- // splash screen
- mMainAnimator = ValueAnimator.ofFloat(0f, 1f);
- mMainAnimator.setDuration(mAppDuration);
- mMainAnimator.setInterpolator(APP_EXIT_INTERPOLATOR);
- mMainAnimator.addListener(this);
-
+ // fade out icon, reveal app, shift up main window
+ private ValueAnimator createAnimator() {
+ // reveal app
final float transparentRatio = 0.8f;
final int globalHeight = mSplashScreenView.getHeight();
final int verticalCircleCenter = 0;
@@ -106,14 +120,13 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
final int halfWidth = mSplashScreenView.getWidth() / 2;
final int endRadius = (int) (0.5 + (1f / transparentRatio * (int)
Math.sqrt(finalVerticalLength * finalVerticalLength + halfWidth * halfWidth)));
- final RadialVanishAnimation radialVanishAnimation = new RadialVanishAnimation(
- mSplashScreenView, mMainAnimator);
- radialVanishAnimation.setCircleCenter(halfWidth, verticalCircleCenter);
- radialVanishAnimation.setRadius(0/* initRadius */, endRadius);
- final int[] colors = {Color.TRANSPARENT, Color.TRANSPARENT, Color.WHITE};
+ final int[] colors = {Color.WHITE, Color.WHITE, Color.TRANSPARENT};
final float[] stops = {0f, transparentRatio, 1f};
- radialVanishAnimation.setRadialPaintParam(colors, stops);
- radialVanishAnimation.setReady();
+
+ mRadialVanishAnimation = new RadialVanishAnimation(mSplashScreenView);
+ mRadialVanishAnimation.setCircleCenter(halfWidth, verticalCircleCenter);
+ mRadialVanishAnimation.setRadius(0 /* initRadius */, endRadius);
+ mRadialVanishAnimation.setRadialPaintParam(colors, stops);
if (mFirstWindowSurface != null && mFirstWindowSurface.isValid()) {
// shift up main window
@@ -128,38 +141,47 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
mSplashScreenView.addView(occludeHoleView, params);
mShiftUpAnimation = new ShiftUpAnimation(0, -mMainWindowShiftLength, occludeHoleView);
- mShiftUpAnimation.setDuration(mAppDuration);
- mShiftUpAnimation.setInterpolator(APP_EXIT_INTERPOLATOR);
-
- occludeHoleView.setAnimation(mShiftUpAnimation);
}
+
+ ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
+ animator.setDuration(mAnimationDuration);
+ animator.setInterpolator(Interpolators.LINEAR);
+ animator.addListener(this);
+ animator.addUpdateListener(a -> onAnimationProgress((float) a.getAnimatedValue()));
+ return animator;
}
private static class RadialVanishAnimation extends View {
private final SplashScreenView mView;
private int mInitRadius;
private int mFinishRadius;
- private boolean mReady;
private final Point mCircleCenter = new Point();
private final Matrix mVanishMatrix = new Matrix();
private final Paint mVanishPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- RadialVanishAnimation(SplashScreenView target, ValueAnimator animator) {
+ RadialVanishAnimation(SplashScreenView target) {
super(target.getContext());
mView = target;
- animator.addUpdateListener((animation) -> {
- if (mVanishPaint.getShader() == null) {
- return;
- }
- final float value = (float) animation.getAnimatedValue();
- final float scale = (mFinishRadius - mInitRadius) * value + mInitRadius;
- mVanishMatrix.setScale(scale, scale);
- mVanishMatrix.postTranslate(mCircleCenter.x, mCircleCenter.y);
- mVanishPaint.getShader().setLocalMatrix(mVanishMatrix);
- postInvalidate();
- });
mView.addView(this);
+ mVanishPaint.setAlpha(0);
+ }
+
+ void onAnimationProgress(float linearProgress) {
+ if (mVanishPaint.getShader() == null) {
+ return;
+ }
+
+ final float radiusProgress = MASK_RADIUS_INTERPOLATOR.getInterpolation(linearProgress);
+ final float alphaProgress = Interpolators.ALPHA_OUT.getInterpolation(linearProgress);
+ final float scale = mInitRadius + (mFinishRadius - mInitRadius) * radiusProgress;
+
+ mVanishMatrix.setScale(scale, scale);
+ mVanishMatrix.postTranslate(mCircleCenter.x, mCircleCenter.y);
+ mVanishPaint.getShader().setLocalMatrix(mVanishMatrix);
+ mVanishPaint.setAlpha(Math.round(0xFF * alphaProgress));
+
+ postInvalidate();
}
void setRadius(int initRadius, int finishRadius) {
@@ -184,38 +206,44 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
new RadialGradient(0, 0, 1, colors, stops, Shader.TileMode.CLAMP);
mVanishPaint.setShader(rShader);
if (!DEBUG_EXIT_ANIMATION_BLEND) {
- mVanishPaint.setBlendMode(BlendMode.MODULATE);
+ // We blend the reveal gradient with the splash screen using DST_OUT so that the
+ // splash screen is fully visible when radius = 0 (or gradient opacity is 0) and
+ // fully invisible when radius = finishRadius AND gradient opacity is 1.
+ mVanishPaint.setBlendMode(BlendMode.DST_OUT);
}
}
- void setReady() {
- mReady = true;
- }
-
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
- if (mReady) {
- canvas.drawRect(0, 0, mView.getWidth(), mView.getHeight(), mVanishPaint);
- }
+ canvas.drawRect(0, 0, mView.getWidth(), mView.getHeight(), mVanishPaint);
}
}
- private final class ShiftUpAnimation extends TranslateYAnimation {
- final SyncRtSurfaceTransactionApplier mApplier;
- ShiftUpAnimation(float fromYDelta, float toYDelta, View targetView) {
- super(fromYDelta, toYDelta);
- mApplier = new SyncRtSurfaceTransactionApplier(targetView);
+ private final class ShiftUpAnimation {
+ private final float mFromYDelta;
+ private final float mToYDelta;
+ private final View mOccludeHoleView;
+ private final SyncRtSurfaceTransactionApplier mApplier;
+ private final Matrix mTmpTransform = new Matrix();
+
+ ShiftUpAnimation(float fromYDelta, float toYDelta, View occludeHoleView) {
+ mFromYDelta = fromYDelta;
+ mToYDelta = toYDelta;
+ mOccludeHoleView = occludeHoleView;
+ mApplier = new SyncRtSurfaceTransactionApplier(occludeHoleView);
}
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- super.applyTransformation(interpolatedTime, t);
-
+ void onAnimationProgress(float linearProgress) {
if (mFirstWindowSurface == null || !mFirstWindowSurface.isValid()) {
return;
}
- mTmpTransform.set(t.getMatrix());
+
+ final float progress = SHIFT_UP_INTERPOLATOR.getInterpolation(linearProgress);
+ final float dy = mFromYDelta + (mToYDelta - mFromYDelta) * progress;
+
+ mOccludeHoleView.setTranslationY(dy);
+ mTmpTransform.setTranslate(0 /* dx */, dy);
// set the vsyncId to ensure the transaction doesn't get applied too early.
final SurfaceControl.Transaction tx = mTransactionPool.acquire();
@@ -290,4 +318,32 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
public void onAnimationRepeat(Animator animation) {
// ignore
}
+
+ private void onAnimationProgress(float linearProgress) {
+ View iconView = mSplashScreenView.getIconView();
+ if (iconView != null) {
+ final float iconProgress = ICON_INTERPOLATOR.getInterpolation(
+ getProgress(linearProgress, 0 /* delay */, mIconFadeOutDuration));
+ iconView.setAlpha(mIconStartAlpha * (1 - iconProgress));
+ }
+
+ final float revealLinearProgress = getProgress(linearProgress, mAppRevealDelay,
+ mAppRevealDuration);
+
+ if (mRadialVanishAnimation != null) {
+ mRadialVanishAnimation.onAnimationProgress(revealLinearProgress);
+ }
+
+ if (mShiftUpAnimation != null) {
+ mShiftUpAnimation.onAnimationProgress(revealLinearProgress);
+ }
+ }
+
+ private float getProgress(float linearProgress, long delay, long duration) {
+ return MathUtils.constrain(
+ (linearProgress * (mAnimationDuration) - delay) / duration,
+ 0.0f,
+ 1.0f
+ );
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index e656f43cfe35..fd6f0ad99e66 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -74,16 +74,14 @@ public class SplashscreenContentDrawer {
private int mDefaultIconSize;
private int mBrandingImageWidth;
private int mBrandingImageHeight;
- private final int mAppRevealDuration;
private int mMainWindowShiftLength;
private final TransactionPool mTransactionPool;
private final SplashScreenWindowAttrs mTmpAttrs = new SplashScreenWindowAttrs();
private final Handler mSplashscreenWorkerHandler;
- SplashscreenContentDrawer(Context context, int appRevealAnimDuration, TransactionPool pool) {
+ SplashscreenContentDrawer(Context context, TransactionPool pool) {
mContext = context;
mIconProvider = new IconProvider(context);
- mAppRevealDuration = appRevealAnimDuration;
mTransactionPool = pool;
// Initialize Splashscreen worker thread
@@ -671,9 +669,8 @@ public class SplashscreenContentDrawer {
*/
void applyExitAnimation(SplashScreenView view, SurfaceControl leash,
Rect frame, Runnable finishCallback) {
- final SplashScreenExitAnimation animation = new SplashScreenExitAnimation(view, leash,
- frame, mAppRevealDuration, mMainWindowShiftLength, mTransactionPool,
- finishCallback);
+ final SplashScreenExitAnimation animation = new SplashScreenExitAnimation(mContext, view,
+ leash, frame, mMainWindowShiftLength, mTransactionPool, finishCallback);
animation.startAnimations();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index b7a0339aa93d..8fa2236f7fa1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -116,10 +116,7 @@ public class StartingSurfaceDrawer {
mContext = context;
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mSplashScreenExecutor = splashScreenExecutor;
- final int appRevealAnimDuration = context.getResources().getInteger(
- com.android.wm.shell.R.integer.starting_window_app_reveal_anim_duration);
- mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, appRevealAnimDuration,
- pool);
+ mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, pool);
mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
}