Merge "Support enable default splash screen reveal aninatmion" into sc-dev

This commit is contained in:
Vadim Caen
2021-05-06 10:03:56 +00:00
committed by Android (Google) Code Review
8 changed files with 184 additions and 149 deletions

View File

@@ -70,6 +70,7 @@ public final class SplashScreenView extends FrameLayout {
private static final boolean DEBUG = false;
private boolean mNotCopyable;
private boolean mRevealAnimationSupported = true;
private int mInitBackgroundColor;
private int mInitIconBackgroundColor;
private View mIconView;
@@ -263,6 +264,25 @@ public final class SplashScreenView extends FrameLayout {
return !mNotCopyable;
}
/**
* If set to true, indicates to the system that this view can be dismissed by playing the
* Reveal animation.
* <p>
* If the exit animation is handled by the client, the animation won't be played anyway.
* @hide
*/
public void setRevealAnimationSupported(boolean support) {
mRevealAnimationSupported = support;
}
/**
* Whether this view support reveal animation.
* @hide
*/
public boolean isRevealAnimationSupported() {
return mRevealAnimationSupported;
}
/**
* Returns the duration of the icon animation if icon is animatable.
*

View File

@@ -52,9 +52,6 @@
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: icon going away -->
<integer name="starting_window_icon_exit_anim_duration">166</integer>
<!-- Animation duration when exit starting window: reveal app -->
<integer name="starting_window_app_reveal_anim_duration">333</integer>
</resources>

View File

@@ -15,6 +15,7 @@
*/
package com.android.wm.shell.startingsurface;
import static android.view.Choreographer.CALLBACK_COMMIT;
import static android.view.View.GONE;
import android.animation.Animator;
@@ -29,13 +30,12 @@ import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.Slog;
import android.view.Choreographer;
import android.view.SurfaceControl;
import android.view.SyncRtSurfaceTransactionApplier;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.view.animation.Transformation;
@@ -53,51 +53,36 @@ 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 ICON_EXIT_INTERPOLATOR = new PathInterpolator(1f, 0f, 1f, 1f);
private static final Interpolator APP_EXIT_INTERPOLATOR = new PathInterpolator(0f, 0f, 0f, 1f);
private static final int EXTRA_REVEAL_DELAY = 133;
private final Matrix mTmpTransform = new Matrix();
private final float[] mTmpFloat9 = new float[9];
private SurfaceControl mFirstWindowSurface;
private final SurfaceControl mFirstWindowSurface;
private final Rect mFirstWindowFrame = new Rect();
private final SplashScreenView mSplashScreenView;
private final int mMainWindowShiftLength;
private final int mIconShiftLength;
private final int mAppDuration;
private final int mIconDuration;
private final TransactionPool mTransactionPool;
private ValueAnimator mMainAnimator;
private Animation mShiftUpAnimation;
private AnimationSet mIconAnimationSet;
private ShiftUpAnimation mShiftUpAnimation;
private Runnable mFinishCallback;
SplashScreenExitAnimation(SplashScreenView view, SurfaceControl leash, Rect frame,
int appDuration, int iconDuration, int mainWindowShiftLength, int iconShiftLength,
TransactionPool pool, Runnable handleFinish) {
int appDuration, int mainWindowShiftLength, TransactionPool pool,
Runnable handleFinish) {
mSplashScreenView = view;
mFirstWindowSurface = leash;
if (frame != null) {
mFirstWindowFrame.set(frame);
}
mAppDuration = appDuration;
mIconDuration = iconDuration;
mMainWindowShiftLength = mainWindowShiftLength;
mIconShiftLength = iconShiftLength;
mFinishCallback = handleFinish;
mTransactionPool = pool;
}
void prepareAnimations() {
prepareRevealAnimation();
prepareShiftAnimation();
}
void startAnimations() {
if (mIconAnimationSet != null) {
mIconAnimationSet.start();
}
prepareRevealAnimation();
if (mMainAnimator != null) {
mMainAnimator.start();
}
@@ -114,8 +99,7 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
mMainAnimator.setInterpolator(APP_EXIT_INTERPOLATOR);
mMainAnimator.addListener(this);
final int startDelay = mIconDuration + EXTRA_REVEAL_DELAY;
final float transparentRatio = 0.95f;
final float transparentRatio = 0.8f;
final int globalHeight = mSplashScreenView.getHeight();
final int verticalCircleCenter = 0;
final int finalVerticalLength = globalHeight - verticalCircleCenter;
@@ -130,9 +114,8 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
final float[] stops = {0f, transparentRatio, 1f};
radialVanishAnimation.setRadialPaintParam(colors, stops);
radialVanishAnimation.setReady();
mMainAnimator.setStartDelay(startDelay);
if (mFirstWindowSurface != null) {
if (mFirstWindowSurface != null && mFirstWindowSurface.isValid()) {
// shift up main window
View occludeHoleView = new View(mSplashScreenView.getContext());
if (DEBUG_EXIT_ANIMATION_BLEND) {
@@ -144,59 +127,16 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
WindowManager.LayoutParams.MATCH_PARENT, mMainWindowShiftLength);
mSplashScreenView.addView(occludeHoleView, params);
mShiftUpAnimation = new ShiftUpAnimation(0, -mMainWindowShiftLength);
mShiftUpAnimation = new ShiftUpAnimation(0, -mMainWindowShiftLength, occludeHoleView);
mShiftUpAnimation.setDuration(mAppDuration);
mShiftUpAnimation.setInterpolator(APP_EXIT_INTERPOLATOR);
mShiftUpAnimation.setStartOffset(startDelay);
occludeHoleView.setAnimation(mShiftUpAnimation);
}
}
// shift down icon and branding view
private void prepareShiftAnimation() {
final View iconView = mSplashScreenView.getIconView();
if (iconView == null) {
return;
}
if (mIconShiftLength > 0) {
mIconAnimationSet = new AnimationSet(true /* shareInterpolator */);
if (DEBUG_EXIT_ANIMATION) {
Slog.v(TAG, "first exit animation, shift length: " + mIconShiftLength);
}
mIconAnimationSet.addAnimation(new TranslateYAnimation(0, mIconShiftLength));
mIconAnimationSet.addAnimation(new AlphaAnimation(1, 0));
mIconAnimationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (DEBUG_EXIT_ANIMATION) {
Slog.v(TAG, "first exit animation finished");
}
iconView.post(() -> iconView.setVisibility(GONE));
}
@Override
public void onAnimationRepeat(Animation animation) {
// ignore
}
});
mIconAnimationSet.setDuration(mIconDuration);
mIconAnimationSet.setInterpolator(ICON_EXIT_INTERPOLATOR);
iconView.setAnimation(mIconAnimationSet);
final View brandingView = mSplashScreenView.getBrandingView();
if (brandingView != null) {
brandingView.setAnimation(mIconAnimationSet);
}
}
}
private static class RadialVanishAnimation extends View {
private SplashScreenView mView;
private final SplashScreenView mView;
private int mInitRadius;
private int mFinishRadius;
private boolean mReady;
@@ -217,7 +157,7 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
mVanishMatrix.setScale(scale, scale);
mVanishMatrix.postTranslate(mCircleCenter.x, mCircleCenter.y);
mVanishPaint.getShader().setLocalMatrix(mVanishMatrix);
mView.postInvalidate();
postInvalidate();
});
mView.addView(this);
}
@@ -262,28 +202,57 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
}
private final class ShiftUpAnimation extends TranslateYAnimation {
ShiftUpAnimation(float fromYDelta, float toYDelta) {
final SyncRtSurfaceTransactionApplier mApplier;
ShiftUpAnimation(float fromYDelta, float toYDelta, View targetView) {
super(fromYDelta, toYDelta);
mApplier = new SyncRtSurfaceTransactionApplier(targetView);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (mFirstWindowSurface == null) {
if (mFirstWindowSurface == null || !mFirstWindowSurface.isValid()) {
return;
}
mTmpTransform.set(t.getMatrix());
// set the vsyncId to ensure the transaction doesn't get applied too early.
final SurfaceControl.Transaction tx = mTransactionPool.acquire();
tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
mTmpTransform.postTranslate(mFirstWindowFrame.left,
mFirstWindowFrame.top + mMainWindowShiftLength);
tx.setMatrix(mFirstWindowSurface, mTmpTransform, mTmpFloat9);
// TODO set the vsyncId to ensure the transaction doesn't get applied too early.
// Additionally, do you want to have this synchronized with your view animations?
// If so, you'll need to use SyncRtSurfaceTransactionApplier
tx.apply();
SyncRtSurfaceTransactionApplier.SurfaceParams
params = new SyncRtSurfaceTransactionApplier.SurfaceParams
.Builder(mFirstWindowSurface)
.withMatrix(mTmpTransform)
.withMergeTransaction(tx)
.build();
mApplier.scheduleApply(params);
mTransactionPool.release(tx);
}
void finish() {
if (mFirstWindowSurface == null || !mFirstWindowSurface.isValid()) {
return;
}
final SurfaceControl.Transaction tx = mTransactionPool.acquire();
tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
SyncRtSurfaceTransactionApplier.SurfaceParams
params = new SyncRtSurfaceTransactionApplier.SurfaceParams
.Builder(mFirstWindowSurface)
.withWindowCrop(null)
.withMergeTransaction(tx)
.build();
mApplier.scheduleApply(params);
mTransactionPool.release(tx);
Choreographer.getSfInstance().postCallback(CALLBACK_COMMIT,
mFirstWindowSurface::release, null);
}
}
private void reset() {
@@ -297,12 +266,8 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
mFinishCallback = null;
}
});
if (mFirstWindowSurface != null) {
final SurfaceControl.Transaction tx = mTransactionPool.acquire();
tx.setWindowCrop(mFirstWindowSurface, null);
tx.apply();
mFirstWindowSurface.release();
mFirstWindowSurface = null;
if (mShiftUpAnimation != null) {
mShiftUpAnimation.finish();
}
}

View File

@@ -75,20 +75,15 @@ public class SplashscreenContentDrawer {
private int mBrandingImageWidth;
private int mBrandingImageHeight;
private final int mAppRevealDuration;
private final int mIconExitDuration;
private int mMainWindowShiftLength;
private int mIconNormalExitDistance;
private int mIconEarlyExitDistance;
private final TransactionPool mTransactionPool;
private final SplashScreenWindowAttrs mTmpAttrs = new SplashScreenWindowAttrs();
private final Handler mSplashscreenWorkerHandler;
SplashscreenContentDrawer(Context context, int iconExitAnimDuration, int appRevealAnimDuration,
TransactionPool pool) {
SplashscreenContentDrawer(Context context, int appRevealAnimDuration, TransactionPool pool) {
mContext = context;
mIconProvider = new IconProvider(context);
mAppRevealDuration = appRevealAnimDuration;
mIconExitDuration = iconExitAnimDuration;
mTransactionPool = pool;
// Initialize Splashscreen worker thread
@@ -139,10 +134,6 @@ public class SplashscreenContentDrawer {
com.android.wm.shell.R.dimen.starting_surface_brand_image_height);
mMainWindowShiftLength = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length);
mIconNormalExitDistance = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.starting_surface_normal_exit_icon_distance);
mIconEarlyExitDistance = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.starting_surface_early_exit_icon_distance);
}
private int getSystemBGColor() {
@@ -406,6 +397,7 @@ public class SplashscreenContentDrawer {
}
if (mEmptyView) {
splashScreenView.setNotCopyable();
splashScreenView.setRevealAnimationSupported(false);
}
splashScreenView.makeSystemUIColorsTransparent();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -678,12 +670,10 @@ public class SplashscreenContentDrawer {
* Create and play the default exit animation for splash screen view.
*/
void applyExitAnimation(SplashScreenView view, SurfaceControl leash,
Rect frame, boolean isEarlyExit, Runnable finishCallback) {
Rect frame, Runnable finishCallback) {
final SplashScreenExitAnimation animation = new SplashScreenExitAnimation(view, leash,
frame, mAppRevealDuration, mIconExitDuration, mMainWindowShiftLength,
isEarlyExit ? mIconEarlyExitDistance : mIconNormalExitDistance, mTransactionPool,
frame, mAppRevealDuration, mMainWindowShiftLength, mTransactionPool,
finishCallback);
animation.prepareAnimations();
animation.startAnimations();
}
}

View File

@@ -35,7 +35,7 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseArray;
@@ -106,6 +106,8 @@ public class StartingSurfaceDrawer {
private final SplashscreenContentDrawer mSplashscreenContentDrawer;
private Choreographer mChoreographer;
private static final boolean DEBUG_ENABLE_REVEAL_ANIMATION =
SystemProperties.getBoolean("persist.debug.enable_reveal_animation", false);
/**
* @param splashScreenExecutor The thread used to control add and remove starting window.
*/
@@ -114,12 +116,10 @@ public class StartingSurfaceDrawer {
mContext = context;
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mSplashScreenExecutor = splashScreenExecutor;
final int iconExitAnimDuration = context.getResources().getInteger(
com.android.wm.shell.R.integer.starting_window_icon_exit_anim_duration);
final int appRevealAnimDuration = context.getResources().getInteger(
com.android.wm.shell.R.integer.starting_window_app_reveal_anim_duration);
mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconExitAnimDuration,
appRevealAnimDuration, pool);
mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, appRevealAnimDuration,
pool);
mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
}
@@ -467,20 +467,24 @@ public class StartingSurfaceDrawer {
if (DEBUG_SPLASH_SCREEN) {
Slog.v(TAG, "Removing splash screen window for task: " + taskId);
}
if (record.mContentView != null) {
if (leash != null || playRevealAnimation) {
mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
leash, frame, record.isEarlyExit(),
() -> removeWindowInner(record.mDecorView, true));
if (record.mContentView != null
&& record.mContentView.isRevealAnimationSupported()) {
if (playRevealAnimation) {
if (DEBUG_ENABLE_REVEAL_ANIMATION) {
mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
leash, frame,
() -> removeWindowInner(record.mDecorView, true));
} else {
// using the default exit animation from framework
removeWindowInner(record.mDecorView, false);
}
} else {
// TODO(183004107) Always hide decorView when playRevealAnimation is enabled
// from TaskOrganizerController#removeStartingWindow
// the SplashScreenView has been copied to client, skip default exit
// animation
removeWindowInner(record.mDecorView, false);
// the SplashScreenView has been copied to client, hide the view to skip
// default exit animation
removeWindowInner(record.mDecorView, true);
}
} else {
// no animation will be applied
// this is a blank splash screen, don't apply reveal animation
removeWindowInner(record.mDecorView, false);
}
}
@@ -514,12 +518,10 @@ public class StartingSurfaceDrawer {
* Record the view or surface for a starting window.
*/
private static class StartingWindowRecord {
private static final long EARLY_START_MINIMUM_TIME_MS = 250;
private final View mDecorView;
private final TaskSnapshotWindow mTaskSnapshotWindow;
private SplashScreenView mContentView;
private boolean mSetSplashScreen;
private long mContentCreateTime;
StartingWindowRecord(View decorView, TaskSnapshotWindow taskSnapshotWindow) {
mDecorView = decorView;
@@ -531,12 +533,7 @@ public class StartingSurfaceDrawer {
return;
}
mContentView = splashScreenView;
mContentCreateTime = SystemClock.uptimeMillis();
mSetSplashScreen = true;
}
boolean isEarlyExit() {
return SystemClock.uptimeMillis() - mContentCreateTime < EARLY_START_MINIMUM_TIME_MS;
}
}
}

View File

@@ -487,6 +487,12 @@ class SurfaceAnimator {
*/
public static final int ANIMATION_TYPE_FIXED_TRANSFORM = 1 << 6;
/**
* Animation when a reveal starting window animation is applied to app window.
* @hide
*/
public static final int ANIMATION_TYPE_STARTING_REVEAL = 1 << 7;
/**
* Bitmask to include all animation types. This is NOT an {@link AnimationType}
* @hide
@@ -505,7 +511,8 @@ class SurfaceAnimator {
ANIMATION_TYPE_RECENTS,
ANIMATION_TYPE_WINDOW_ANIMATION,
ANIMATION_TYPE_INSETS_CONTROL,
ANIMATION_TYPE_FIXED_TRANSFORM
ANIMATION_TYPE_FIXED_TRANSFORM,
ANIMATION_TYPE_STARTING_REVEAL
})
@Retention(RetentionPolicy.SOURCE)
@interface AnimationType {}
@@ -523,6 +530,7 @@ class SurfaceAnimator {
case ANIMATION_TYPE_WINDOW_ANIMATION: return "window_animation";
case ANIMATION_TYPE_INSETS_CONTROL: return "insets_animation";
case ANIMATION_TYPE_FIXED_TRANSFORM: return "fixed_rotation";
case ANIMATION_TYPE_STARTING_REVEAL: return "starting_reveal";
default: return "unknown type:" + type;
}
}

View File

@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL;
import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS;
import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDOW_CONFIGS;
@@ -38,6 +39,7 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController;
@@ -134,29 +136,72 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
}
}
void removeStartingWindow(Task task, boolean prepareAnimation) {
SurfaceControl firstWindowLeash = null;
Rect mainFrame = null;
// TODO enable shift up animation once we fix flicker test
// final boolean playShiftUpAnimation = !task.inMultiWindowMode();
// if (prepareAnimation && playShiftUpAnimation) {
// final ActivityRecord topActivity = task.topActivityWithStartingWindow();
// if (topActivity != null) {
// final WindowState mainWindow =
// topActivity.findMainWindow(false/* includeStartingApp */);
// if (mainWindow != null) {
// TODO create proper leash instead of the copied SC
// firstWindowLeash = new SurfaceControl(mainWindow.getSurfaceControl(),
// "TaskOrganizerController.removeStartingWindow");
// mainFrame = mainWindow.getRelativeFrame();
// }
// }
// }
try {
mTaskOrganizer.removeStartingWindow(task.mTaskId, firstWindowLeash, mainFrame,
/* TODO(183004107) Revert this when jankiness is solved
prepareAnimation); */ false);
// Capture the animation surface control for activity's main window
private class StartingWindowAnimationAdaptor implements AnimationAdapter {
private SurfaceControl mAnimationLeash;
@Override
public boolean getShowWallpaper() {
return false;
}
@Override
public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t,
int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
mAnimationLeash = animationLeash;
}
@Override
public void onAnimationCancelled(SurfaceControl animationLeash) {
if (mAnimationLeash == animationLeash) {
mAnimationLeash = null;
}
}
@Override
public long getDurationHint() {
return 0;
}
@Override
public long getStatusBarTransitionsStartTime() {
return 0;
}
@Override
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix + "StartingWindowAnimationAdaptor mCapturedLeash=");
pw.print(mAnimationLeash);
pw.println();
}
@Override
public void dumpDebug(ProtoOutputStream proto) {
}
}
void removeStartingWindow(Task task, boolean prepareAnimation) {
SurfaceControl windowAnimationLeash = null;
Rect mainFrame = null;
final boolean playShiftUpAnimation = !task.inMultiWindowMode();
if (prepareAnimation && playShiftUpAnimation) {
final ActivityRecord topActivity = task.topActivityWithStartingWindow();
if (topActivity != null) {
final WindowState mainWindow =
topActivity.findMainWindow(false/* includeStartingApp */);
if (mainWindow != null) {
final StartingWindowAnimationAdaptor adaptor =
new StartingWindowAnimationAdaptor();
final SurfaceControl.Transaction t = mainWindow.getPendingTransaction();
mainWindow.startAnimation(t, adaptor, false,
ANIMATION_TYPE_STARTING_REVEAL);
windowAnimationLeash = adaptor.mAnimationLeash;
mainFrame = mainWindow.getRelativeFrame();
}
}
}
try {
mTaskOrganizer.removeStartingWindow(task.mTaskId, windowAnimationLeash,
mainFrame, prepareAnimation);
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onStartTaskFinished callback", e);
}

View File

@@ -133,6 +133,7 @@ import static com.android.server.wm.MoveAnimationSpecProto.TO;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -2410,6 +2411,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
ProtoLog.d(WM_DEBUG_STARTING_WINDOW, "Starting window removed %s", this);
}
if (startingWindow && StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER) {
// cancel the remove starting window animation on shell
if (mActivityRecord != null) {
final WindowState mainWindow =
mActivityRecord.findMainWindow(false/* includeStartingApp */);
if (mainWindow != null && mainWindow.isSelfAnimating(0 /* flags */,
ANIMATION_TYPE_STARTING_REVEAL)) {
mainWindow.cancelAnimation();
}
}
}
ProtoLog.v(WM_DEBUG_FOCUS, "Remove client=%x, surfaceController=%s Callers=%s",
System.identityHashCode(mClient.asBinder()),
mWinAnimator.mSurfaceController,