Merge "Add animation type in SurfaceAnimator"
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 13dcb4c..9da185b 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1183,12 +1183,6 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/AppTransitionController.java"
     },
-    "292555239": {
-      "message": "ScreenRotation sill animating: mDisplayAnimator: %s\nmEnterBlackFrameAnimator: %s\nmRotateScreenAnimator: %s\nmScreenshotRotationAnimator: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
-    },
     "292904800": {
       "message": "Deferring rotation, animation in progress.",
       "level": "VERBOSE",
@@ -1693,6 +1687,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1346895820": {
+      "message": "ScreenRotation still animating: type: %d\nmDisplayAnimator: %s\nmEnterBlackFrameAnimator: %s\nmRotateScreenAnimator: %s\nmScreenshotRotationAnimator: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_ORIENTATION",
+      "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
+    },
     "1358462645": {
       "message": "Looking for focus: %s, flags=%d, canReceive=%b",
       "level": "VERBOSE",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b05c250..7af097b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -196,6 +196,7 @@
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.TaskPersister.DEBUG;
 import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
@@ -311,6 +312,8 @@
 import com.android.server.uri.UriPermissionOwner;
 import com.android.server.wm.ActivityMetricsLogger.TransitionInfoSnapshot;
 import com.android.server.wm.ActivityStack.ActivityState;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 import com.android.server.wm.WindowManagerService.H;
 import com.android.server.wm.utils.InsetUtils;
 
@@ -4080,7 +4083,8 @@
 
     @Override
     boolean applyAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
-            boolean isVoiceInteraction, @Nullable Runnable animationFinishedCallback) {
+            boolean isVoiceInteraction,
+            @Nullable OnAnimationFinishedCallback animationFinishedCallback) {
         if (mUseTransferredAnimation) {
             return false;
         }
@@ -4158,7 +4162,7 @@
             // We aren't delayed anything, but exiting windows rely on the animation finished
             // callback being called in case the ActivityRecord was pretending to be delayed,
             // which we might have done because we were in closing/opening apps list.
-            onAnimationFinished();
+            onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, null /* AnimationAdapter */);
             if (visible) {
                 // The token was made immediately visible, there will be no entrance animation.
                 // We need to inform the client the enter animation was finished.
@@ -6054,8 +6058,8 @@
     }
 
     @Override
-    protected void onAnimationFinished() {
-        super.onAnimationFinished();
+    protected void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
+        super.onAnimationFinished(type, anim);
 
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AR#onAnimationFinished");
         mTransit = TRANSIT_UNSET;
diff --git a/services/core/java/com/android/server/wm/AnimationAdapter.java b/services/core/java/com/android/server/wm/AnimationAdapter.java
index 1be3d61..0519b80 100644
--- a/services/core/java/com/android/server/wm/AnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/AnimationAdapter.java
@@ -21,6 +21,7 @@
 import android.view.SurfaceControl.Transaction;
 import android.view.animation.Animation;
 
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import java.io.PrintWriter;
@@ -47,9 +48,10 @@
      *                       component running the animation after {@code finishCallback} has been
      *                       invoked, or after the animation was cancelled.
      * @param t The Transaction to apply the initial frame of the animation.
+     * @param type The type of the animation.
      * @param finishCallback The callback to be invoked when the animation has finished.
      */
-    void startAnimation(SurfaceControl animationLeash, Transaction t,
+    void startAnimation(SurfaceControl animationLeash, Transaction t, @AnimationType int type,
             OnAnimationFinishedCallback finishCallback);
 
     /**
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 0798a91..f72020e 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -377,9 +377,9 @@
                     transitioningDecendants.add(app);
                 }
             }
-            wc.applyAnimation(animLp, transit, visible, voiceInteraction, () -> {
+            wc.applyAnimation(animLp, transit, visible, voiceInteraction, (type, anim) -> {
                 for (int j = 0; j < transitioningDecendants.size(); ++j) {
-                    transitioningDecendants.get(j).onAnimationFinished();
+                    transitioningDecendants.get(j).onAnimationFinished(type, anim);
                 }
             });
         }
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index 16aff9c..537ca08 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -20,6 +20,7 @@
 import static com.android.server.wm.AlphaAnimationSpecProto.FROM;
 import static com.android.server.wm.AlphaAnimationSpecProto.TO;
 import static com.android.server.wm.AnimationSpecProto.ALPHA;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_DIMMER;
 
 import android.annotation.Nullable;
 import android.graphics.Rect;
@@ -29,6 +30,8 @@
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import java.io.PrintWriter;
 
@@ -135,7 +138,7 @@
             mDimLayer = dimLayer;
             mDimming = true;
             final DimAnimatable dimAnimatable = new DimAnimatable(dimLayer);
-            mSurfaceAnimator = new SurfaceAnimator(dimAnimatable, () -> {
+            mSurfaceAnimator = new SurfaceAnimator(dimAnimatable, (type, anim) -> {
                 if (!mDimming) {
                     dimAnimatable.removeSurface();
                 }
@@ -157,8 +160,8 @@
     @VisibleForTesting
     interface SurfaceAnimatorStarter {
         void startAnimation(SurfaceAnimator surfaceAnimator, SurfaceControl.Transaction t,
-                AnimationAdapter anim, boolean hidden,
-                @Nullable Runnable animationFinishedCallback);
+                AnimationAdapter anim, boolean hidden, @AnimationType int type,
+                @Nullable OnAnimationFinishedCallback animationFinishedCallback);
     }
 
     Dimmer(WindowContainer host) {
@@ -345,7 +348,7 @@
         mSurfaceAnimatorStarter.startAnimation(animator, t, new LocalAnimationAdapter(
                 new AlphaAnimationSpec(startAlpha, endAlpha, getDimDuration(container)),
                 mHost.mWmService.mSurfaceAnimationRunner), false /* hidden */,
-                null /* animationFinishedCallback */);
+                ANIMATION_TYPE_DIMMER, null /* animationFinishedCallback */);
     }
 
     private long getDimDuration(WindowContainer container) {
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index db43480..e6c1969 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -24,6 +24,7 @@
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
 import static android.view.ViewRootImpl.sNewInsetsMode;
 
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_INSETS_CONTROL;
 import static com.android.server.wm.WindowManagerService.H.LAYOUT_AND_ASSIGN_WINDOW_LAYERS_IF_NEEDED;
 
 import android.annotation.NonNull;
@@ -34,11 +35,11 @@
 import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 
 import com.android.internal.util.function.TriConsumer;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import java.io.PrintWriter;
@@ -243,7 +244,8 @@
         mAdapter = new ControlAdapter();
         setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
         final Transaction t = mDisplayContent.getPendingTransaction();
-        mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */);
+        mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */,
+                ANIMATION_TYPE_INSETS_CONTROL, null /* animationFinishedCallback */);
         final SurfaceControl leash = mAdapter.mCapturedLeash;
         final long frameNumber = mFinishSeamlessRotateFrameNumber;
         mFinishSeamlessRotateFrameNumber = -1;
@@ -348,7 +350,7 @@
 
         @Override
         public void startAnimation(SurfaceControl animationLeash, Transaction t,
-                OnAnimationFinishedCallback finishCallback) {
+                @AnimationType int type, OnAnimationFinishedCallback finishCallback) {
             // TODO(b/118118435): We can remove the type check when implementing the transient bar
             //                    animation.
             if (mSource.getType() == ITYPE_IME) {
diff --git a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
index 5892239..7c1a616 100644
--- a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
@@ -24,6 +24,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import java.io.PrintWriter;
@@ -50,9 +51,9 @@
 
     @Override
     public void startAnimation(SurfaceControl animationLeash, Transaction t,
-            OnAnimationFinishedCallback finishCallback) {
+            @AnimationType int type, OnAnimationFinishedCallback finishCallback) {
         mAnimator.startAnimation(mSpec, animationLeash, t,
-                () -> finishCallback.onAnimationFinished(this));
+                () -> finishCallback.onAnimationFinished(type, this));
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index da9d074..944e0ae 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -30,6 +30,7 @@
 import static com.android.server.wm.BoundsAnimationController.FADE_IN;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
 import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
 
 import android.annotation.IntDef;
@@ -61,6 +62,7 @@
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.protolog.common.ProtoLog;
 import com.android.server.statusbar.StatusBarManagerInternal;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 import com.android.server.wm.utils.InsetUtils;
 
@@ -432,7 +434,8 @@
         ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "addAnimation(%s)", task.getName());
         final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task,
                 isRecentTaskInvisible);
-        task.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */);
+        task.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */,
+                ANIMATION_TYPE_RECENTS);
         task.commitPendingTransaction();
         mPendingAnimations.add(taskAdapter);
         return taskAdapter;
@@ -443,14 +446,16 @@
         ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
                 "removeAnimation(%d)", taskAdapter.mTask.mTaskId);
         taskAdapter.mTask.setCanAffectSystemUiFlags(true);
-        taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter);
+        taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter.mLastAnimationType,
+                taskAdapter);
         mPendingAnimations.remove(taskAdapter);
     }
 
     @VisibleForTesting
     void removeWallpaperAnimation(WallpaperAnimationAdapter wallpaperAdapter) {
         ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "removeWallpaperAnimation()");
-        wallpaperAdapter.getLeashFinishedCallback().onAnimationFinished(wallpaperAdapter);
+        wallpaperAdapter.getLeashFinishedCallback().onAnimationFinished(
+                wallpaperAdapter.getLastAnimationType(), wallpaperAdapter);
         mPendingWallpaperAnimations.remove(wallpaperAdapter);
     }
 
@@ -638,7 +643,7 @@
                         taskSnapshot.getColorSpace(), false /* containsSecureLayers */));
         mRecentScreenshotAnimator = new SurfaceAnimator(
                 animatable,
-                () -> {
+                (type, anim) -> {
                     ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "mRecentScreenshotAnimator finish");
                     mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */);
                 }, mService);
@@ -827,6 +832,7 @@
         private final Task mTask;
         private SurfaceControl mCapturedLeash;
         private OnAnimationFinishedCallback mCapturedFinishCallback;
+        private @AnimationType int mLastAnimationType;
         private final boolean mIsRecentTaskInvisible;
         private RemoteAnimationTarget mTarget;
         private final Point mPosition = new Point();
@@ -868,7 +874,7 @@
 
         @Override
         public void startAnimation(SurfaceControl animationLeash, Transaction t,
-                OnAnimationFinishedCallback finishCallback) {
+                @AnimationType int type, OnAnimationFinishedCallback finishCallback) {
             // Restore z-layering, position and stack crop until client has a chance to modify it.
             t.setLayer(animationLeash, mTask.getPrefixOrderIndex());
             t.setPosition(animationLeash, mPosition.x, mPosition.y);
@@ -877,6 +883,7 @@
             t.setWindowCrop(animationLeash, mTmpRect);
             mCapturedLeash = animationLeash;
             mCapturedFinishCallback = finishCallback;
+            mLastAnimationType = type;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 6f7eeab..d2dbab8 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -40,6 +40,7 @@
 import com.android.internal.util.FastPrintWriter;
 import com.android.server.protolog.ProtoLogImpl;
 import com.android.server.protolog.common.ProtoLog;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import java.io.PrintWriter;
@@ -180,12 +181,14 @@
                 if (wrappers.mAdapter != null
                         && wrappers.mAdapter.mCapturedFinishCallback != null) {
                     wrappers.mAdapter.mCapturedFinishCallback
-                            .onAnimationFinished(wrappers.mAdapter);
+                            .onAnimationFinished(wrappers.mAdapter.mAnimationType,
+                                    wrappers.mAdapter);
                 }
                 if (wrappers.mThumbnailAdapter != null
                         && wrappers.mThumbnailAdapter.mCapturedFinishCallback != null) {
                     wrappers.mThumbnailAdapter.mCapturedFinishCallback
-                            .onAnimationFinished(wrappers.mThumbnailAdapter);
+                            .onAnimationFinished(wrappers.mAdapter.mAnimationType,
+                                    wrappers.mThumbnailAdapter);
                 }
                 mPendingAnimations.remove(i);
             }
@@ -221,11 +224,13 @@
                     final RemoteAnimationRecord adapters = mPendingAnimations.get(i);
                     if (adapters.mAdapter != null) {
                         adapters.mAdapter.mCapturedFinishCallback
-                                .onAnimationFinished(adapters.mAdapter);
+                                .onAnimationFinished(adapters.mAdapter.mAnimationType,
+                                        adapters.mAdapter);
                     }
                     if (adapters.mThumbnailAdapter != null) {
                         adapters.mThumbnailAdapter.mCapturedFinishCallback
-                                .onAnimationFinished(adapters.mThumbnailAdapter);
+                                .onAnimationFinished(adapters.mAdapter.mAnimationType,
+                                        adapters.mThumbnailAdapter);
                     }
                     mPendingAnimations.remove(i);
                     ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tcontainer=%s",
@@ -234,7 +239,8 @@
 
                 for (int i = mPendingWallpaperAnimations.size() - 1; i >= 0; i--) {
                     final WallpaperAnimationAdapter adapter = mPendingWallpaperAnimations.get(i);
-                    adapter.getLeashFinishedCallback().onAnimationFinished(adapter);
+                    adapter.getLeashFinishedCallback().onAnimationFinished(
+                            adapter.getLastAnimationType(), adapter);
                     mPendingWallpaperAnimations.remove(i);
                     ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\twallpaper=%s", adapter.getToken());
                 }
@@ -393,6 +399,7 @@
         private final RemoteAnimationRecord mRecord;
         SurfaceControl mCapturedLeash;
         private OnAnimationFinishedCallback mCapturedFinishCallback;
+        private @AnimationType int mAnimationType;
         final Point mPosition = new Point();
         final Rect mStackBounds = new Rect();
 
@@ -410,7 +417,7 @@
 
         @Override
         public void startAnimation(SurfaceControl animationLeash, Transaction t,
-                OnAnimationFinishedCallback finishCallback) {
+                @AnimationType int type, OnAnimationFinishedCallback finishCallback) {
             ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation");
 
             // Restore z-layering, position and stack crop until client has a chance to modify it.
@@ -425,6 +432,7 @@
             }
             mCapturedLeash = animationLeash;
             mCapturedFinishCallback = finishCallback;
+            mAnimationType = type;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index e7aca89..f6cdac5 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -24,6 +24,7 @@
 import static com.android.server.wm.RotationAnimationSpecProto.START_LUMA;
 import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING;
 import static com.android.server.wm.ScreenRotationAnimationProto.STARTED;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
@@ -48,6 +49,8 @@
 
 import com.android.internal.R;
 import com.android.server.protolog.common.ProtoLog;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 import com.android.server.wm.utils.RotationAnimationUtils;
 
 import java.io.PrintWriter;
@@ -670,33 +673,35 @@
          * Start an animation defined by animationSpec on a new {@link SurfaceAnimator}.
          *
          * @param animatable The animatable used for the animation.
-         * @param animationSpec                The spec of the animation.
-         * @param animationFinishedCallback    Callback passed to the {@link SurfaceAnimator} and
-         *                                    called when the animation finishes.
+         * @param animationSpec The spec of the animation.
+         * @param animationFinishedCallback Callback passed to the {@link SurfaceAnimator}
+         *                                    and called when the animation finishes.
          * @return The newly created {@link SurfaceAnimator} that as been started.
          */
         private SurfaceAnimator startAnimation(
                 SurfaceAnimator.Animatable animatable,
                 LocalAnimationAdapter.AnimationSpec animationSpec,
-                Runnable animationFinishedCallback) {
+                OnAnimationFinishedCallback animationFinishedCallback) {
             SurfaceAnimator animator = new SurfaceAnimator(
                     animatable, animationFinishedCallback, mService);
 
             LocalAnimationAdapter localAnimationAdapter = new LocalAnimationAdapter(
                     animationSpec, mService.mSurfaceAnimationRunner);
             animator.startAnimation(mDisplayContent.getPendingTransaction(),
-                    localAnimationAdapter, false);
+                    localAnimationAdapter, false, ANIMATION_TYPE_SCREEN_ROTATION);
             return animator;
         }
 
-        private void onAnimationEnd() {
+        private void onAnimationEnd(@AnimationType int type, AnimationAdapter anim) {
             synchronized (mService.mGlobalLock) {
                 if (isAnimating()) {
                     ProtoLog.v(WM_DEBUG_ORIENTATION,
-                            "ScreenRotation sill animating: mDisplayAnimator: %s\n"
-                                    + "mEnterBlackFrameAnimator: "
-                                    + "%s\nmRotateScreenAnimator: %s\n"
+                            "ScreenRotation still animating: type: %d\n"
+                                    + "mDisplayAnimator: %s\n"
+                                    + "mEnterBlackFrameAnimator: %s\n"
+                                    + "mRotateScreenAnimator: %s\n"
                                     + "mScreenshotRotationAnimator: %s",
+                            type,
                             mDisplayAnimator != null
                                     ? mDisplayAnimator.isAnimating() : null,
                             mEnterBlackFrameAnimator != null
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index cb1676f..7164cd8 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -23,6 +23,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.util.Slog;
@@ -33,6 +34,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * A class that can run animations on objects that have a set of child surfaces. We do this by
@@ -47,6 +50,7 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "SurfaceAnimator" : TAG_WM;
     private final WindowManagerService mService;
     private AnimationAdapter mAnimation;
+    private @AnimationType int mAnimationType;
 
     @VisibleForTesting
     SurfaceControl mLeash;
@@ -55,30 +59,32 @@
     private final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
     @VisibleForTesting
     @Nullable
-    final Runnable mStaticAnimationFinishedCallback;
+    final OnAnimationFinishedCallback mStaticAnimationFinishedCallback;
     @Nullable
-    private Runnable mAnimationFinishedCallback;
+    private OnAnimationFinishedCallback mAnimationFinishedCallback;
     private boolean mAnimationStartDelayed;
 
     /**
      * @param animatable The object to animate.
-     * @param animationFinishedCallback Callback to invoke when an animation has finished running.
+     * @param staticAnimationFinishedCallback Callback to invoke when an animation has finished
+     *                                         running.
      */
-    SurfaceAnimator(Animatable animatable, @Nullable Runnable animationFinishedCallback,
+    SurfaceAnimator(Animatable animatable,
+            @Nullable OnAnimationFinishedCallback staticAnimationFinishedCallback,
             WindowManagerService service) {
         mAnimatable = animatable;
         mService = service;
-        mStaticAnimationFinishedCallback = animationFinishedCallback;
-        mInnerAnimationFinishedCallback = getFinishedCallback(animationFinishedCallback);
+        mStaticAnimationFinishedCallback = staticAnimationFinishedCallback;
+        mInnerAnimationFinishedCallback = getFinishedCallback(staticAnimationFinishedCallback);
     }
 
     private OnAnimationFinishedCallback getFinishedCallback(
-            @Nullable Runnable animationFinishedCallback) {
-        return anim -> {
+            @Nullable OnAnimationFinishedCallback staticAnimationFinishedCallback) {
+        return (type, anim) -> {
             synchronized (mService.mGlobalLock) {
                 final SurfaceAnimator target = mService.mAnimationTransferMap.remove(anim);
                 if (target != null) {
-                    target.mInnerAnimationFinishedCallback.onAnimationFinished(anim);
+                    target.mInnerAnimationFinishedCallback.onAnimationFinished(type, anim);
                     return;
                 }
 
@@ -91,13 +97,14 @@
                     if (anim != mAnimation) {
                         return;
                     }
-                    final Runnable animationFinishCallback = mAnimationFinishedCallback;
+                    final OnAnimationFinishedCallback animationFinishCallback =
+                            mAnimationFinishedCallback;
                     reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */);
-                    if (animationFinishedCallback != null) {
-                        animationFinishedCallback.run();
+                    if (staticAnimationFinishedCallback != null) {
+                        staticAnimationFinishedCallback.onAnimationFinished(type, anim);
                     }
                     if (animationFinishCallback != null) {
-                        animationFinishCallback.run();
+                        animationFinishCallback.onAnimationFinished(type, anim);
                     }
                 };
                 if (!mAnimatable.shouldDeferAnimationFinish(resetAndInvokeFinish)) {
@@ -120,9 +127,11 @@
      * @param animationFinishedCallback The callback being triggered when the animation finishes.
      */
     void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
-            @Nullable Runnable animationFinishedCallback) {
+            @AnimationType int type,
+            @Nullable OnAnimationFinishedCallback animationFinishedCallback) {
         cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
         mAnimation = anim;
+        mAnimationType = type;
         mAnimationFinishedCallback = animationFinishedCallback;
         final SurfaceControl surface = mAnimatable.getSurfaceControl();
         if (surface == null) {
@@ -137,11 +146,12 @@
             if (DEBUG_ANIM) Slog.i(TAG, "Animation start delayed");
             return;
         }
-        mAnimation.startAnimation(mLeash, t, mInnerAnimationFinishedCallback);
+        mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
     }
 
-    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
-        startAnimation(t, anim, hidden, null /* animationFinishedCallback */);
+    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
+            @AnimationType int type) {
+        startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */);
     }
 
     /**
@@ -165,7 +175,7 @@
         mAnimationStartDelayed = false;
         if (delayed && mAnimation != null) {
             mAnimation.startAnimation(mLeash, mAnimatable.getPendingTransaction(),
-                    mInnerAnimationFinishedCallback);
+                    mAnimationType, mInnerAnimationFinishedCallback);
             mAnimatable.commitPendingTransaction();
         }
     }
@@ -245,6 +255,7 @@
         cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
         mLeash = from.mLeash;
         mAnimation = from.mAnimation;
+        mAnimationType = from.mAnimationType;
         mAnimationFinishedCallback = from.mAnimationFinishedCallback;
 
         // Cancel source animation, but don't let animation runner cancel the animation.
@@ -272,7 +283,8 @@
         if (DEBUG_ANIM) Slog.i(TAG, "Cancelling animation restarting=" + restarting);
         final SurfaceControl leash = mLeash;
         final AnimationAdapter animation = mAnimation;
-        final Runnable animationFinishedCallback = mAnimationFinishedCallback;
+        final @AnimationType int animationType = mAnimationType;
+        final OnAnimationFinishedCallback animationFinishedCallback = mAnimationFinishedCallback;
         reset(t, false);
         if (animation != null) {
             if (!mAnimationStartDelayed && forwardCancel) {
@@ -280,10 +292,10 @@
             }
             if (!restarting) {
                 if (mStaticAnimationFinishedCallback != null) {
-                    mStaticAnimationFinishedCallback.run();
+                    mStaticAnimationFinishedCallback.onAnimationFinished(animationType, animation);
                 }
                 if (animationFinishedCallback != null) {
-                    animationFinishedCallback.run();
+                    animationFinishedCallback.onAnimationFinished(animationType, animation);
                 }
             }
         }
@@ -325,6 +337,7 @@
         mLeash = null;
         mAnimation = null;
         mAnimationFinishedCallback = null;
+        mAnimationType = ANIMATION_TYPE_NONE;
 
         if (reparent) {
             // Make sure to inform the animatable after the surface was reparented (or reparent
@@ -392,12 +405,72 @@
         }
     }
 
+
+    /**
+     * No animation is specified.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_NONE = 0;
+
+    /**
+     * Animation for an app transition.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_APP_TRANSITION = 1;
+
+    /**
+     * Animation for screen rotation.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_SCREEN_ROTATION = 2;
+
+    /**
+     * Animation for dimming.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_DIMMER = 3;
+
+    /**
+     * Animation for recent apps.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_RECENTS = 4;
+
+    /**
+     * Animation for a {@link WindowState} without animating the activity.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_WINDOW_ANIMATION = 5;
+
+    /**
+     * Animation to control insets. This is actually not an animation, but is used to give the
+     * client a leash over the system window causing insets.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_INSETS_CONTROL = 6;
+
+    /**
+     * The type of the animation.
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "ANIMATION_TYPE_" }, value = {
+            ANIMATION_TYPE_NONE,
+            ANIMATION_TYPE_APP_TRANSITION,
+            ANIMATION_TYPE_SCREEN_ROTATION,
+            ANIMATION_TYPE_DIMMER,
+            ANIMATION_TYPE_RECENTS,
+            ANIMATION_TYPE_WINDOW_ANIMATION,
+            ANIMATION_TYPE_INSETS_CONTROL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface AnimationType {}
+
     /**
      * Callback to be passed into {@link AnimationAdapter#startAnimation} to be invoked by the
      * component that is running the animation when the animation is finished.
      */
     interface OnAnimationFinishedCallback {
-        void onAnimationFinished(AnimationAdapter anim);
+        void onAnimationFinished(@AnimationType int type, AnimationAdapter anim);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
index 801e521..bd70599 100644
--- a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
@@ -18,6 +18,7 @@
 import static com.android.server.wm.AnimationAdapterProto.REMOTE;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS;
 import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
 
 import android.graphics.Point;
 import android.os.SystemClock;
@@ -26,6 +27,7 @@
 import android.view.SurfaceControl;
 
 import com.android.server.protolog.common.ProtoLog;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -40,6 +42,7 @@
     private final WallpaperWindowToken mWallpaperToken;
     private SurfaceControl mCapturedLeash;
     private SurfaceAnimator.OnAnimationFinishedCallback mCapturedLeashFinishCallback;
+    private @AnimationType int mLastAnimationType;
 
     private long mDurationHint;
     private long mStatusBarTransitionDelay;
@@ -77,7 +80,7 @@
                     wallpaperWindow, durationHint, statusBarTransitionDelay,
                     animationCanceledRunnable);
             wallpaperWindow.startAnimation(wallpaperWindow.getPendingTransaction(),
-                    wallpaperAdapter, false /* hidden */);
+                    wallpaperAdapter, false /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION);
             targets.add(wallpaperAdapter.createRemoteAnimationTarget());
             adaptersOut.add(wallpaperAdapter);
         });
@@ -110,6 +113,13 @@
     }
 
     /**
+     * @return the type of animation.
+     */
+    @AnimationType int getLastAnimationType() {
+        return mLastAnimationType;
+    }
+
+    /**
      * @return the wallpaper window
      */
     WallpaperWindowToken getToken() {
@@ -124,13 +134,14 @@
 
     @Override
     public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t,
-            SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
+            @AnimationType int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
         ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation");
 
         // Restore z-layering until client has a chance to modify it.
         t.setLayer(animationLeash, mWallpaperToken.getPrefixOrderIndex());
         mCapturedLeash = animationLeash;
         mCapturedLeashFinishCallback = finishCallback;
+        mLastAnimationType = type;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index d828ca6..8672315 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -31,6 +31,7 @@
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -74,6 +75,8 @@
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.protolog.common.ProtoLog;
 import com.android.server.wm.SurfaceAnimator.Animatable;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -1851,19 +1854,24 @@
      * @param anim The animation to run.
      * @param hidden Whether our container is currently hidden. TODO This should use isVisible at
      *               some point but the meaning is too weird to work for all containers.
+     * @param type The type of animation defined as {@link AnimationType}.
      * @param animationFinishedCallback The callback being triggered when the animation finishes.
      */
     void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
-            @Nullable Runnable animationFinishedCallback) {
-        if (DEBUG_ANIM) Slog.v(TAG, "Starting animation on " + this + ": " + anim);
+            @AnimationType int type,
+            @Nullable OnAnimationFinishedCallback animationFinishedCallback) {
+        if (DEBUG_ANIM) {
+            Slog.v(TAG, "Starting animation on " + this + ": type=" + type + ", anim=" + anim);
+        }
 
         // TODO: This should use isVisible() but because isVisible has a really weird meaning at
         // the moment this doesn't work for all animatable window containers.
-        mSurfaceAnimator.startAnimation(t, anim, hidden, animationFinishedCallback);
+        mSurfaceAnimator.startAnimation(t, anim, hidden, type, animationFinishedCallback);
     }
 
-    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
-        startAnimation(t, anim, hidden, null /* animationFinishedCallback */);
+    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
+            @AnimationType int type) {
+        startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */);
     }
 
     void transferAnimation(WindowContainer from) {
@@ -1916,7 +1924,8 @@
      * @see #getAnimationAdapter
      */
     boolean applyAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
-            boolean isVoiceInteraction, @Nullable Runnable animationFinishedCallback) {
+            boolean isVoiceInteraction,
+            @Nullable OnAnimationFinishedCallback animationFinishedCallback) {
         if (mWmService.mDisableTransitionAnimation) {
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
                     "applyAnimation: transition animation is disabled or skipped. "
@@ -1937,7 +1946,7 @@
                 AnimationAdapter thumbnailAdapter = adapters.second;
                 if (adapter != null) {
                     startAnimation(getPendingTransaction(), adapter, !isVisible(),
-                            animationFinishedCallback);
+                            ANIMATION_TYPE_APP_TRANSITION, animationFinishedCallback);
                     if (adapter.getShowWallpaper()) {
                         getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                     }
@@ -2128,7 +2137,7 @@
     /**
      * Called when an animation has finished running.
      */
-    protected void onAnimationFinished() {
+    protected void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
         mWmService.onAnimationFinished();
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index 8948f6f..90e3be7 100644
--- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -20,6 +20,7 @@
 import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
 
 import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 import static com.android.server.wm.WindowContainerThumbnailProto.HEIGHT;
 import static com.android.server.wm.WindowContainerThumbnailProto.SURFACE_ANIMATOR;
 import static com.android.server.wm.WindowContainerThumbnailProto.WIDTH;
@@ -40,6 +41,7 @@
 
 import com.android.server.protolog.common.ProtoLog;
 import com.android.server.wm.SurfaceAnimator.Animatable;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 
 import java.util.function.Supplier;
 
@@ -85,7 +87,7 @@
             // We can't use a delegating constructor since we need to
             // reference this::onAnimationFinished
             mSurfaceAnimator =
-                new SurfaceAnimator(this, null /* animationFinishedCallback */,
+                new SurfaceAnimator(this, this::onAnimationFinished /* animationFinishedCallback */,
                         container.mWmService);
         }
         mWidth = thumbnailHeader.getWidth();
@@ -130,14 +132,19 @@
                 new WindowAnimationSpec(anim, position,
                         mWindowContainer.getDisplayContent().mAppTransition.canSkipFirstFrame(),
                         mWindowContainer.getDisplayContent().getWindowCornerRadius()),
-                mWindowContainer.mWmService.mSurfaceAnimationRunner), false /* hidden */);
+                mWindowContainer.mWmService.mSurfaceAnimationRunner), false /* hidden */,
+                ANIMATION_TYPE_RECENTS, null /* animationFinishedCallback */);
     }
 
     /**
      * Start animation with existing adapter.
      */
     void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
-        mSurfaceAnimator.startAnimation(t, anim, hidden);
+        mSurfaceAnimator.startAnimation(t, anim, hidden, ANIMATION_TYPE_RECENTS,
+                null /* animationFinishedCallback */);
+    }
+
+    private void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
     }
 
     void setShowing(Transaction pendingTransaction, boolean show) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index fc04126..1faf48f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -115,6 +115,7 @@
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RESIZE;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+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;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
@@ -231,6 +232,7 @@
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.protolog.common.ProtoLog;
 import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.utils.WmDisplayCutout;
 
 import java.io.PrintWriter;
@@ -5027,12 +5029,13 @@
     }
 
     private void startAnimation(Transaction t, AnimationAdapter adapter) {
-        startAnimation(t, adapter, mWinAnimator.mLastHidden, null /* animationFinishedCallback */);
+        startAnimation(t, adapter, mWinAnimator.mLastHidden, ANIMATION_TYPE_WINDOW_ANIMATION,
+                null /* animationFinishedCallback */);
     }
 
     @Override
-    protected void onAnimationFinished() {
-        super.onAnimationFinished();
+    protected void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
+        super.onAnimationFinished(type, anim);
         mWinAnimator.onAnimationFinished();
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
index 71390db..0f54895 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
@@ -21,6 +21,7 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 
 import static org.junit.Assert.assertFalse;
@@ -69,8 +70,10 @@
         final AnimatingActivityRegistry registry =
                 activity1.getStack().getAnimatingActivityRegistry();
 
-        activity1.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */);
-        activity2.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */);
+        activity1.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
+        activity2.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         assertTrue(activity1.isAnimating(TRANSITION));
         assertTrue(activity2.isAnimating(TRANSITION));
 
@@ -91,8 +94,10 @@
         final AnimatingActivityRegistry registry =
                 window1.getStack().getAnimatingActivityRegistry();
 
-        window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
-        window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
+        window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
+        window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         assertTrue(window1.isAnimating(TRANSITION));
         assertTrue(window2.isAnimating(TRANSITION));
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
index b0f3b42..6e78a27 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
@@ -20,6 +20,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -70,7 +71,8 @@
     public void clipAfterAnim_boundsLayerIsCreated() {
         mActivity.mNeedsAnimationBoundsLayer = true;
 
-        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         verify(mTransaction).reparent(eq(mActivity.getSurfaceControl()),
                 eq(mActivity.mSurfaceAnimator.mLeash));
         verify(mTransaction).reparent(eq(mActivity.mSurfaceAnimator.mLeash),
@@ -82,7 +84,8 @@
         mActivity.mNeedsAnimationBoundsLayer = true;
         mActivity.mNeedsZBoost = true;
 
-        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         verify(mTransaction).setLayer(eq(mActivity.mAnimationBoundsLayer),
                 intThat(layer -> layer >= ActivityRecord.Z_BOOST_BASE));
     }
@@ -91,15 +94,18 @@
     @FlakyTest(bugId = 131005232)
     public void clipAfterAnim_boundsLayerIsDestroyed() {
         mActivity.mNeedsAnimationBoundsLayer = true;
-        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         final SurfaceControl leash = mActivity.mSurfaceAnimator.mLeash;
         final SurfaceControl animationBoundsLayer = mActivity.mAnimationBoundsLayer;
         final ArgumentCaptor<SurfaceAnimator.OnAnimationFinishedCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         SurfaceAnimator.OnAnimationFinishedCallback.class);
-        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
+                callbackCaptor.capture());
 
-        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        callbackCaptor.getValue().onAnimationFinished(
+                ANIMATION_TYPE_APP_TRANSITION, mSpec);
         verify(mTransaction).remove(eq(leash));
         verify(mTransaction).remove(eq(animationBoundsLayer));
         assertThat(mActivity.mNeedsAnimationBoundsLayer).isFalse();
@@ -108,7 +114,8 @@
     @Test
     public void clipAfterAnimCancelled_boundsLayerIsDestroyed() {
         mActivity.mNeedsAnimationBoundsLayer = true;
-        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         final SurfaceControl leash = mActivity.mSurfaceAnimator.mLeash;
         final SurfaceControl animationBoundsLayer = mActivity.mAnimationBoundsLayer;
 
@@ -123,7 +130,8 @@
     public void clipNoneAnim_boundsLayerIsNotCreated() {
         mActivity.mNeedsAnimationBoundsLayer = false;
 
-        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mActivity.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         verify(mTransaction).reparent(eq(mActivity.getSurfaceControl()),
                 eq(mActivity.mSurfaceAnimator.mLeash));
         assertThat(mActivity.mAnimationBoundsLayer).isNull();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 7344fa4..77ceeed 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -22,11 +22,13 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_DIMMER;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.when;
@@ -37,6 +39,9 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
+import com.android.server.wm.SurfaceAnimator.AnimationType;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -114,11 +119,11 @@
     private static class SurfaceAnimatorStarterImpl implements Dimmer.SurfaceAnimatorStarter {
         @Override
         public void startAnimation(SurfaceAnimator surfaceAnimator, SurfaceControl.Transaction t,
-                AnimationAdapter anim, boolean hidden,
-                @Nullable Runnable animationFinishedCallback) {
-            surfaceAnimator.mStaticAnimationFinishedCallback.run();
+                AnimationAdapter anim, boolean hidden, @AnimationType int type,
+                @Nullable OnAnimationFinishedCallback animationFinishedCallback) {
+            surfaceAnimator.mStaticAnimationFinishedCallback.onAnimationFinished(type, anim);
             if (animationFinishedCallback != null) {
-                animationFinishedCallback.run();
+                animationFinishedCallback.onAnimationFinished(type, anim);
             }
         }
     }
@@ -224,7 +229,7 @@
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mSurfaceAnimatorStarter).startAnimation(any(SurfaceAnimator.class), any(
                 SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean(),
-                isNull());
+                eq(ANIMATION_TYPE_DIMMER), isNull());
         verify(mHost.getPendingTransaction()).remove(dimLayer);
     }
 
@@ -282,7 +287,7 @@
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mSurfaceAnimatorStarter, never()).startAnimation(any(SurfaceAnimator.class), any(
                 SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean(),
-                isNull());
+                eq(ANIMATION_TYPE_DIMMER), isNull());
         verify(mTransaction).remove(dimLayer);
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 945928d..7753a32 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -37,6 +37,7 @@
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -103,14 +104,15 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         AnimationAdapter adapter = mController.addAnimation(activity.getTask(),
                 false /* isRecentTaskInvisible */);
-        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_RECENTS,
+                mFinishedCallback);
 
         // Remove the app window so that the animation target can not be created
         activity.removeImmediately();
         mController.startAnimation();
 
         // Verify that the finish callback to reparent the leash is called
-        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+        verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_RECENTS), eq(adapter));
         // Verify the animation canceled callback to the app was made
         verify(mMockRunner).onAnimationCanceled(null /* taskSnapshot */);
         verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
@@ -122,7 +124,8 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         AnimationAdapter adapter = mController.addAnimation(activity.getTask(),
                 false /* isRecentTaskInvisible */);
-        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_RECENTS,
+                mFinishedCallback);
 
         // Remove the app window so that the animation target can not be created
         activity.removeImmediately();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index a23425f..be25597 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -18,6 +18,8 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -108,7 +110,7 @@
         overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID;
         overrideWindow.mActivityRecord.mSurfaceAnimator.startAnimation(
                 overrideWindow.getPendingTransaction(), mock(AnimationAdapter.class),
-                false /* hidden */);
+                false /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
         mPolicy.addNonHighRefreshRatePackage("com.android.test");
         assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
     }
@@ -124,7 +126,7 @@
 
         cameraUsingWindow.mActivityRecord.mSurfaceAnimator.startAnimation(
                 cameraUsingWindow.getPendingTransaction(), mock(AnimationAdapter.class),
-                false /* hidden */);
+                false /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
         assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 1a57596..3a724a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -25,6 +25,8 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -97,7 +99,8 @@
         try {
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
                     new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-            adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+            adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                    mFinishedCallback);
             mController.goodToGo();
             mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
@@ -122,7 +125,8 @@
             verify(mMockTransaction).setWindowCrop(mMockLeash, 100, 50);
 
             finishedCaptor.getValue().onAnimationFinished();
-            verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+            verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
+                    eq(adapter));
         } finally {
             mDisplayContent.mOpeningApps.clear();
         }
@@ -133,7 +137,8 @@
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
                 new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                mFinishedCallback);
         mController.goodToGo();
 
         adapter.onAnimationCancelled(mMockLeash);
@@ -146,14 +151,16 @@
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
                 new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                mFinishedCallback);
         mController.goodToGo();
 
         mClock.fastForward(2500);
         mHandler.timeAdvance();
 
         verify(mMockRunner).onAnimationCancelled();
-        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+        verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
+                eq(adapter));
     }
 
     @Test
@@ -164,7 +171,8 @@
                     "testWin");
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-            adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+            adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                    mFinishedCallback);
             mController.goodToGo();
 
             mClock.fastForward(2500);
@@ -176,7 +184,8 @@
             mHandler.timeAdvance();
 
             verify(mMockRunner).onAnimationCancelled();
-            verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+            verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
+                    eq(adapter));
         } finally {
             mWm.setAnimationScale(2, 1.0f);
         }
@@ -205,7 +214,8 @@
                 new Point(50, 100), new Rect(50, 100, 150, 150), null);
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win2.mActivityRecord,
                 new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                mFinishedCallback);
         mController.goodToGo();
         mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
         final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
@@ -225,11 +235,13 @@
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
                 new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                mFinishedCallback);
         win.mActivityRecord.removeImmediately();
         mController.goodToGo();
         verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
-        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+        verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
+                eq(adapter));
     }
 
     @Test
@@ -242,9 +254,10 @@
                     new Rect(0, 0, 200, 200));
             assertNotNull(record.mThumbnailAdapter);
             ((AnimationAdapter) record.mAdapter)
-                    .startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+                    .startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION,
+                            mFinishedCallback);
             ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash,
-                    mMockTransaction, mThumbnailFinishedCallback);
+                    mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback);
             mController.goodToGo();
             mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
@@ -272,8 +285,10 @@
             verify(mMockTransaction).setPosition(mMockThumbnailLeash, 0, 0);
 
             finishedCaptor.getValue().onAnimationFinished();
-            verify(mFinishedCallback).onAnimationFinished(eq(record.mAdapter));
-            verify(mThumbnailFinishedCallback).onAnimationFinished(eq(record.mThumbnailAdapter));
+            verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_WINDOW_ANIMATION),
+                    eq(record.mAdapter));
+            verify(mThumbnailFinishedCallback).onAnimationFinished(
+                    eq(ANIMATION_TYPE_WINDOW_ANIMATION), eq(record.mThumbnailAdapter));
         } finally {
             mDisplayContent.mChangingApps.clear();
         }
@@ -290,7 +305,8 @@
         try {
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
                     new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-            adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+            adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                    mFinishedCallback);
             mController.goodToGo();
             mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
@@ -318,7 +334,8 @@
         try {
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
                     new Point(50, 100), new Rect(50, 100, 150, 150), null).mAdapter;
-            adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+            adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                    mFinishedCallback);
             mController.goodToGo();
             mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 2894241..552c476 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -22,6 +22,8 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -39,6 +41,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.SurfaceAnimator.Animatable;
+import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import org.junit.After;
@@ -89,25 +92,30 @@
 
     @Test
     public void testRunAnimation() {
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_RECENTS);
         final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                 OnAnimationFinishedCallback.class);
         assertAnimating(mAnimatable);
         verify(mTransaction).reparent(eq(mAnimatable.mSurface), eq(mAnimatable.mLeash));
-        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_RECENTS),
+                callbackCaptor.capture());
 
-        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_RECENTS, mSpec);
         assertNotAnimating(mAnimatable);
         assertTrue(mAnimatable.mFinishedCallbackCalled);
+        assertEquals(ANIMATION_TYPE_RECENTS, mAnimatable.mFinishedAnimationType);
         verify(mTransaction).remove(eq(mAnimatable.mLeash));
         // TODO: Verify reparenting once we use mPendingTransaction to reparent it back
     }
 
     @Test
     public void testOverrideAnimation() {
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         final SurfaceControl firstLeash = mAnimatable.mLeash;
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
 
         verify(mTransaction).remove(eq(firstLeash));
         assertFalse(mAnimatable.mFinishedCallbackCalled);
@@ -115,34 +123,40 @@
         final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                 OnAnimationFinishedCallback.class);
         assertAnimating(mAnimatable);
-        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
+                callbackCaptor.capture());
 
         // First animation was finished, but this shouldn't cancel the second animation
-        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
         assertTrue(mAnimatable.mSurfaceAnimator.isAnimating());
 
         // Second animation was finished
-        verify(mSpec2).startAnimation(any(), any(), callbackCaptor.capture());
-        callbackCaptor.getValue().onAnimationFinished(mSpec2);
+        verify(mSpec2).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
+                callbackCaptor.capture());
+        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec2);
         assertNotAnimating(mAnimatable);
         assertTrue(mAnimatable.mFinishedCallbackCalled);
+        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
     }
 
     @Test
     public void testCancelAnimation() {
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         assertAnimating(mAnimatable);
         mAnimatable.mSurfaceAnimator.cancelAnimation();
         assertNotAnimating(mAnimatable);
         verify(mSpec).onAnimationCancelled(any());
         assertTrue(mAnimatable.mFinishedCallbackCalled);
+        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
         verify(mTransaction).remove(eq(mAnimatable.mLeash));
     }
 
     @Test
     public void testCancelWithNullFinishCallbackAnimation() {
         SurfaceAnimator animator = new SurfaceAnimator(mAnimatable, null, mWm);
-        animator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        animator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         assertTrue(animator.isAnimating());
         assertNotNull(animator.getAnimation());
         animator.cancelAnimation();
@@ -155,32 +169,37 @@
     @Test
     public void testDelayingAnimationStart() {
         mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         verifyZeroInteractions(mSpec);
         assertAnimating(mAnimatable);
         assertTrue(mAnimatable.mSurfaceAnimator.isAnimationStartDelayed());
         mAnimatable.mSurfaceAnimator.endDelayingAnimationStart();
-        verify(mSpec).startAnimation(any(), any(), any());
+        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION), any());
     }
 
     @Test
     public void testDelayingAnimationStartAndCancelled() {
         mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         mAnimatable.mSurfaceAnimator.cancelAnimation();
         verifyZeroInteractions(mSpec);
         assertNotAnimating(mAnimatable);
         assertTrue(mAnimatable.mFinishedCallbackCalled);
+        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
         verify(mTransaction).remove(eq(mAnimatable.mLeash));
     }
 
     @Test
     public void testTransferAnimation() {
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
 
         final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                 OnAnimationFinishedCallback.class);
-        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
+                callbackCaptor.capture());
         final SurfaceControl leash = mAnimatable.mLeash;
 
         mAnimatable2.mSurfaceAnimator.transferAnimation(mAnimatable.mSurfaceAnimator);
@@ -188,15 +207,17 @@
         assertAnimating(mAnimatable2);
         assertEquals(leash, mAnimatable2.mSurfaceAnimator.mLeash);
         verify(mTransaction, never()).remove(eq(leash));
-        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
         assertNotAnimating(mAnimatable2);
         assertTrue(mAnimatable2.mFinishedCallbackCalled);
+        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
         verify(mTransaction).remove(eq(leash));
     }
 
     @Test
     public void testOnAnimationLeashLostWhenAnimatableParentSurfaceControlNull() {
-        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
         spyOn(mAnimatable);
 
         // Verify onAnimationLeashLost will be called even animatable's parent surface control lost.
@@ -215,13 +236,14 @@
         final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
 
         // Finish the animation but then make sure we are deferring.
-        onFinishedCallback.onAnimationFinished(mSpec);
+        onFinishedCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
         assertAnimating(mDeferFinishAnimatable);
 
         // Now end defer finishing.
         mDeferFinishAnimatable.mEndDeferFinishCallback.run();
         assertNotAnimating(mAnimatable2);
         assertTrue(mDeferFinishAnimatable.mFinishedCallbackCalled);
+        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mDeferFinishAnimatable.mFinishedAnimationType);
         verify(mTransaction).remove(eq(mDeferFinishAnimatable.mLeash));
     }
 
@@ -229,7 +251,7 @@
     public void testDeferFinishDoNotFinishNextAnimation() {
         // Start the first animation.
         final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
-        onFinishedCallback.onAnimationFinished(mSpec);
+        onFinishedCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
         // The callback is the resetAndInvokeFinish in {@link SurfaceAnimator#getFinishedCallback}.
         final Runnable firstDeferFinishCallback = mDeferFinishAnimatable.mEndDeferFinishCallback;
 
@@ -247,11 +269,12 @@
 
     private OnAnimationFinishedCallback startDeferFinishAnimatable(AnimationAdapter anim) {
         mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, anim,
-                true /* hidden */);
+                true /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
         final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                 OnAnimationFinishedCallback.class);
         assertAnimating(mDeferFinishAnimatable);
-        verify(anim).startAnimation(any(), any(), callbackCaptor.capture());
+        verify(anim).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
+                callbackCaptor.capture());
         return callbackCaptor.getValue();
     }
 
@@ -274,6 +297,7 @@
         final SurfaceAnimator mSurfaceAnimator;
         SurfaceControl mLeash;
         boolean mFinishedCallbackCalled;
+        @AnimationType int mFinishedAnimationType;
 
         MyAnimatable(WindowManagerService wm, SurfaceSession session, Transaction transaction) {
             mSession = session;
@@ -343,7 +367,11 @@
             return 1;
         }
 
-        private final Runnable mFinishedCallback = () -> mFinishedCallbackCalled = true;
+        private final SurfaceAnimator.OnAnimationFinishedCallback mFinishedCallback = (
+                type, anim) -> {
+            mFinishedCallbackCalled = true;
+            mFinishedAnimationType = type;
+        };
     }
 
     private static class DeferFinishAnimatable extends MyAnimatable {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 05d048d..4a87701 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -34,6 +34,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -61,6 +62,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
@@ -829,7 +832,8 @@
         wc.getDisplayContent().mAppTransition.overridePendingAppTransitionRemote(adapter);
         spyOn(wc);
         doReturn(true).when(wc).okToAnimate();
-        final Runnable onAnimationFinishedCallback = mock(Runnable.class);
+        final OnAnimationFinishedCallback onAnimationFinishedCallback =
+                mock(OnAnimationFinishedCallback.class);
 
         // Make sure animating state is as expected after applied animation.
         assertTrue(wc.applyAnimation(null, TRANSIT_TASK_OPEN, true, false,
@@ -837,16 +841,18 @@
         assertEquals(wc.getTopMostActivity(), act);
         assertTrue(wc.isAnimating());
         assertTrue(act.isAnimating(PARENTS));
-        verify(onAnimationFinishedCallback, times(0)).run();
+        verify(onAnimationFinishedCallback, times(0)).onAnimationFinished(
+                eq(ANIMATION_TYPE_APP_TRANSITION), any());
 
         // Make sure animation finish callback will be received and reset animating state after
         // animation finish.
         wc.getDisplayContent().mAppTransition.goodToGo(TRANSIT_TASK_OPEN, act,
                 mDisplayContent.mOpeningApps);
-        verify(wc).onAnimationFinished();
+        verify(wc).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), any());
         assertFalse(wc.isAnimating());
         assertFalse(act.isAnimating(PARENTS));
-        verify(onAnimationFinishedCallback, times(1)).run();
+        verify(onAnimationFinishedCallback, times(1)).onAnimationFinished(
+                eq(ANIMATION_TYPE_APP_TRANSITION), any());
     }
 
     /* Used so we can gain access to some protected members of the {@link WindowContainer} class */