diff options
8 files changed, 182 insertions, 147 deletions
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java index 933760c8bf18..8debe5d569a3 100644 --- a/core/java/android/window/SplashScreenView.java +++ b/core/java/android/window/SplashScreenView.java @@ -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; @@ -264,6 +265,25 @@ public final class SplashScreenView extends FrameLayout { } /** + * 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. * * @see android.R.attr#windowSplashScreenAnimatedIcon diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml index e8757b5d96f4..edf000b5e68a 100644 --- a/libs/WindowManager/Shell/res/values/config.xml +++ b/libs/WindowManager/Shell/res/values/config.xml @@ -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> 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 5bc2afd11fe8..3fe57c61c0bb 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 @@ -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(); } } 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 1d3a60b8193d..e2051fedf67e 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 @@ -76,20 +76,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 @@ -144,10 +139,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() { @@ -428,6 +419,7 @@ public class SplashscreenContentDrawer { } if (mEmptyView) { splashScreenView.setNotCopyable(); + splashScreenView.setRevealAnimationSupported(false); } splashScreenView.makeSystemUIColorsTransparent(); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); @@ -724,12 +716,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(); } } 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 6d3eeae43a96..2dc900945b53 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 @@ -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()); } @@ -471,20 +471,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); } } @@ -518,12 +522,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; @@ -535,12 +537,7 @@ public class StartingSurfaceDrawer { return; } mContentView = splashScreenView; - mContentCreateTime = SystemClock.uptimeMillis(); mSetSplashScreen = true; } - - boolean isEarlyExit() { - return SystemClock.uptimeMillis() - mContentCreateTime < EARLY_START_MINIMUM_TIME_MS; - } } } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 6e0efbf8bd51..ba188937cfea 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -488,6 +488,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; } } diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index ccc0916cf25b..fb481b41c0af 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -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 { } } + // 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 firstWindowLeash = null; + SurfaceControl windowAnimationLeash = 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(); -// } -// } -// } + 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, firstWindowLeash, mainFrame, - /* TODO(183004107) Revert this when jankiness is solved - prepareAnimation); */ false); - + mTaskOrganizer.removeStartingWindow(task.mTaskId, windowAnimationLeash, + mainFrame, prepareAnimation); } catch (RemoteException e) { Slog.e(TAG, "Exception sending onStartTaskFinished callback", e); } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 2e8d4cd4e7f8..b40223f6eed7 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -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, |