Apply rounded corners to startWindow

This removes the corner animation flickering happening when
starting a letterboxed app after a configuration change
(eg. Dark/Light mode)

Test: Manual
Fixes: 234107097

Change-Id: Iad9f4aaeb8edeeb56b0c88d7d0239843cd66a8f9
This commit is contained in:
Massimo Carli
2022-10-19 11:49:08 +00:00
parent 86d092aa7e
commit f4976b84a3
6 changed files with 48 additions and 15 deletions

View File

@@ -61,6 +61,12 @@ public final class StartingWindowRemovalInfo implements Parcelable {
*/
public boolean deferRemoveForIme;
/**
* The rounded corner radius
* @hide
*/
public float roundedCornerRadius;
public StartingWindowRemovalInfo() {
}
@@ -80,6 +86,7 @@ public final class StartingWindowRemovalInfo implements Parcelable {
mainFrame = source.readTypedObject(Rect.CREATOR);
playRevealAnimation = source.readBoolean();
deferRemoveForIme = source.readBoolean();
roundedCornerRadius = source.readFloat();
}
@Override
@@ -89,6 +96,7 @@ public final class StartingWindowRemovalInfo implements Parcelable {
dest.writeTypedObject(mainFrame, flags);
dest.writeBoolean(playRevealAnimation);
dest.writeBoolean(deferRemoveForIme);
dest.writeFloat(roundedCornerRadius);
}
@Override
@@ -96,6 +104,7 @@ public final class StartingWindowRemovalInfo implements Parcelable {
return "StartingWindowRemovalInfo{taskId=" + taskId
+ " frame=" + mainFrame
+ " playRevealAnimation=" + playRevealAnimation
+ " roundedCornerRadius=" + roundedCornerRadius
+ " deferRemoveForIme=" + deferRemoveForIme + "}";
}

View File

@@ -50,13 +50,17 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
private final float mIconStartAlpha;
private final float mBrandingStartAlpha;
private final TransactionPool mTransactionPool;
// TODO(b/261167708): Clean enter animation code after moving Letterbox code to Shell
private final float mRoundedCornerRadius;
private Runnable mFinishCallback;
SplashScreenExitAnimation(Context context, SplashScreenView view, SurfaceControl leash,
Rect frame, int mainWindowShiftLength, TransactionPool pool, Runnable handleFinish) {
Rect frame, int mainWindowShiftLength, TransactionPool pool, Runnable handleFinish,
float roundedCornerRadius) {
mSplashScreenView = view;
mFirstWindowSurface = leash;
mRoundedCornerRadius = roundedCornerRadius;
if (frame != null) {
mFirstWindowFrame.set(frame);
}
@@ -97,7 +101,7 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
SplashScreenExitAnimationUtils.startAnimations(mSplashScreenView, mFirstWindowSurface,
mMainWindowShiftLength, mTransactionPool, mFirstWindowFrame, mAnimationDuration,
mIconFadeOutDuration, mIconStartAlpha, mBrandingStartAlpha, mAppRevealDelay,
mAppRevealDuration, this);
mAppRevealDuration, this, mRoundedCornerRadius);
}
private void reset() {

View File

@@ -61,6 +61,24 @@ public class SplashScreenExitAnimationUtils {
new PathInterpolator(0f, 0f, 0.4f, 1f);
private static final Interpolator SHIFT_UP_INTERPOLATOR = new PathInterpolator(0f, 0f, 0f, 1f);
/**
* Creates and starts the animator to fade out the icon, reveal the app, and shift up main
* window with rounded corner radius.
*/
static void startAnimations(ViewGroup splashScreenView,
SurfaceControl firstWindowSurface, int mainWindowShiftLength,
TransactionPool transactionPool, Rect firstWindowFrame, int animationDuration,
int iconFadeOutDuration, float iconStartAlpha, float brandingStartAlpha,
int appRevealDelay, int appRevealDuration, Animator.AnimatorListener animatorListener,
float roundedCornerRadius) {
ValueAnimator animator =
createAnimator(splashScreenView, firstWindowSurface, mainWindowShiftLength,
transactionPool, firstWindowFrame, animationDuration, iconFadeOutDuration,
iconStartAlpha, brandingStartAlpha, appRevealDelay, appRevealDuration,
animatorListener, roundedCornerRadius);
animator.start();
}
/**
* Creates and starts the animator to fade out the icon, reveal the app, and shift up main
* window.
@@ -71,12 +89,10 @@ public class SplashScreenExitAnimationUtils {
TransactionPool transactionPool, Rect firstWindowFrame, int animationDuration,
int iconFadeOutDuration, float iconStartAlpha, float brandingStartAlpha,
int appRevealDelay, int appRevealDuration, Animator.AnimatorListener animatorListener) {
ValueAnimator animator =
createAnimator(splashScreenView, firstWindowSurface, mainWindowShiftLength,
transactionPool, firstWindowFrame, animationDuration, iconFadeOutDuration,
iconStartAlpha, brandingStartAlpha, appRevealDelay, appRevealDuration,
animatorListener);
animator.start();
startAnimations(splashScreenView, firstWindowSurface, mainWindowShiftLength,
transactionPool, firstWindowFrame, animationDuration, iconFadeOutDuration,
iconStartAlpha, brandingStartAlpha, appRevealDelay, appRevealDuration,
animatorListener, 0f /* roundedCornerRadius */);
}
/**
@@ -87,7 +103,8 @@ public class SplashScreenExitAnimationUtils {
SurfaceControl firstWindowSurface, int mMainWindowShiftLength,
TransactionPool transactionPool, Rect firstWindowFrame, int animationDuration,
int iconFadeOutDuration, float iconStartAlpha, float brandingStartAlpha,
int appRevealDelay, int appRevealDuration, Animator.AnimatorListener animatorListener) {
int appRevealDelay, int appRevealDuration, Animator.AnimatorListener animatorListener,
float roundedCornerRadius) {
// reveal app
final float transparentRatio = 0.8f;
final int globalHeight = splashScreenView.getHeight();
@@ -124,7 +141,7 @@ public class SplashScreenExitAnimationUtils {
shiftUpAnimation = new ShiftUpAnimation(0, -mMainWindowShiftLength, occludeHoleView,
firstWindowSurface, splashScreenView, transactionPool, firstWindowFrame,
mMainWindowShiftLength);
mMainWindowShiftLength, roundedCornerRadius);
}
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
@@ -289,8 +306,8 @@ public class SplashScreenExitAnimationUtils {
public ShiftUpAnimation(float fromYDelta, float toYDelta, View occludeHoleView,
SurfaceControl firstWindowSurface, ViewGroup splashScreenView,
TransactionPool transactionPool, Rect firstWindowFrame,
int mainWindowShiftLength) {
mFromYDelta = fromYDelta;
int mainWindowShiftLength, float roundedCornerRadius) {
mFromYDelta = fromYDelta - roundedCornerRadius;
mToYDelta = toYDelta;
mOccludeHoleView = occludeHoleView;
mApplier = new SyncRtSurfaceTransactionApplier(occludeHoleView);

View File

@@ -993,10 +993,11 @@ public class SplashscreenContentDrawer {
* Create and play the default exit animation for splash screen view.
*/
void applyExitAnimation(SplashScreenView view, SurfaceControl leash,
Rect frame, Runnable finishCallback, long createTime) {
Rect frame, Runnable finishCallback, long createTime, float roundedCornerRadius) {
final Runnable playAnimation = () -> {
final SplashScreenExitAnimation animation = new SplashScreenExitAnimation(mContext,
view, leash, frame, mMainWindowShiftLength, mTransactionPool, finishCallback);
view, leash, frame, mMainWindowShiftLength, mTransactionPool, finishCallback,
roundedCornerRadius);
animation.startAnimations();
};
if (view.getIconView() == null) {

View File

@@ -645,7 +645,7 @@ public class StartingSurfaceDrawer {
mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
removalInfo.windowAnimationLeash, removalInfo.mainFrame,
() -> removeWindowInner(record.mDecorView, true),
record.mCreateTime);
record.mCreateTime, removalInfo.roundedCornerRadius);
} else {
// the SplashScreenView has been copied to client, hide the view to skip
// default exit animation

View File

@@ -691,6 +691,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
if (mainWindow == null || mainWindow.mRemoved) {
removalInfo.playRevealAnimation = false;
} else if (removalInfo.playRevealAnimation && playShiftUpAnimation) {
removalInfo.roundedCornerRadius =
topActivity.mLetterboxUiController.getRoundedCornersRadius(mainWindow);
removalInfo.windowAnimationLeash = applyStartingWindowAnimation(mainWindow);
removalInfo.mainFrame = mainWindow.getRelativeFrame();
}