Add a no-op animation for non-changing apps during change transition

Without this, other closing apps during a change transition would
immediately turn invisible because they had no animation. By adding
a no-op, it basically keeps everything visible and stationary until
the transition finishes.

Bug: 113252739
Test: Manual, wallpaper remains visible while maximizing freeform app
Change-Id: I968280ae2915eb571b33a73a1f182228bc8fec74
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index f3a363a..6dc73bb 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -29,6 +29,7 @@
 import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
 import static android.view.WindowManager.TRANSIT_NONE;
+import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
@@ -1662,6 +1663,15 @@
                     "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:"
                             + " anim=" + a + " transit=" + appTransitionToString(transit)
                             + " isEntrance=true" + " Callers=" + Debug.getCallers(3));
+        } else if (transit == TRANSIT_TASK_CHANGE_WINDOWING_MODE) {
+            // In the absence of a specific adapter, we just want to keep everything stationary.
+            a = new AlphaAnimation(1.f, 1.f);
+            a.setDuration(WindowChangeAnimationSpec.ANIMATION_DURATION);
+            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
+                Slog.v(TAG, "applyAnimation:"
+                        + " anim=" + a + " transit=" + appTransitionToString(transit)
+                        + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
+            }
         } else {
             int animAttr = 0;
             switch (transit) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index d915e10..a52f1af 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2340,11 +2340,6 @@
         return transit == TRANSIT_TASK_CHANGE_WINDOWING_MODE;
     }
 
-    private int getDefaultChangeTransitionDuration() {
-        return (int) (AppTransition.DEFAULT_APP_TRANSITION_DURATION
-                        * mWmService.getTransitionAnimationScaleLocked());
-    }
-
     boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
             boolean isVoiceInteraction) {
 
@@ -2378,17 +2373,17 @@
                 adapter = adapters.mAdapter;
                 thumbnailAdapter = adapters.mThumbnailAdapter;
             } else if (isChanging) {
-                int duration = getDefaultChangeTransitionDuration();
+                final float durationScale = mWmService.getTransitionAnimationScaleLocked();
                 mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y);
                 adapter = new LocalAnimationAdapter(
                         new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect,
-                                getDisplayContent().getDisplayInfo(), duration,
+                                getDisplayContent().getDisplayInfo(), durationScale,
                                 true /* isAppAnimation */, false /* isThumbnail */),
                         mWmService.mSurfaceAnimationRunner);
                 if (mThumbnail != null) {
                     thumbnailAdapter = new LocalAnimationAdapter(
                             new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect,
-                                    getDisplayContent().getDisplayInfo(), duration,
+                                    getDisplayContent().getDisplayInfo(), durationScale,
                                     true /* isAppAnimation */, true /* isThumbnail */),
                             mWmService.mSurfaceAnimationRunner);
                 }
diff --git a/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java b/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
index 7dd7c4f..775d5b2 100644
--- a/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
@@ -53,13 +53,15 @@
     private Animation mAnimation;
     private final boolean mIsThumbnail;
 
+    static final int ANIMATION_DURATION = AppTransition.DEFAULT_APP_TRANSITION_DURATION;
+
     public WindowChangeAnimationSpec(Rect startBounds, Rect endBounds, DisplayInfo displayInfo,
-            long duration, boolean isAppAnimation, boolean isThumbnail) {
+            float durationScale, boolean isAppAnimation, boolean isThumbnail) {
         mStartBounds = new Rect(startBounds);
         mEndBounds = new Rect(endBounds);
         mIsAppAnimation = isAppAnimation;
         mIsThumbnail = isThumbnail;
-        createBoundsInterpolator(duration, displayInfo);
+        createBoundsInterpolator((int) (ANIMATION_DURATION * durationScale), displayInfo);
     }
 
     @Override