Merge "Don't override with TasmFragmentRemoteAnimation for wallpaper/non-app" into sc-v2-dev am: ffe3162917

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16014032

Change-Id: I1209013acf69b8881e30d4bf0b852a590bc20682
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 909ca39..d965351 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -2371,12 +2371,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "457951957": {
-      "message": "\tNot visible=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
-    },
     "463993897": {
       "message": "Aborted waiting for drawn: %s",
       "level": "WARN",
@@ -3697,6 +3691,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "2024493888": {
+      "message": "\tWallpaper of display=%s is not visible",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+      "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
+    },
     "2028163120": {
       "message": "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s isEntrance=%s Callers=%s",
       "level": "VERBOSE",
@@ -3721,12 +3721,6 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/AppTransitionController.java"
     },
-    "2057434754": {
-      "message": "\tvisible=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
-    },
     "2060978050": {
       "message": "moveWindowTokenToDisplay: Attempted to move token: %s to non-exiting displayId=%d",
       "level": "WARN",
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index ffaf710..535a061 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -124,6 +124,7 @@
     @interface TransitContainerType {}
 
     private final ArrayMap<WindowContainer, Integer> mTempTransitionReasons = new ArrayMap<>();
+    private final ArrayList<WindowContainer> mTempTransitionWindows = new ArrayList<>();
 
     AppTransitionController(WindowManagerService service, DisplayContent displayContent) {
         mService = service;
@@ -523,26 +524,44 @@
         }
     }
 
+    private boolean transitionMayContainNonAppWindows(@TransitionOldType int transit) {
+        // We don't want to have the client to animate any non-app windows.
+        // Having {@code transit} of those types doesn't mean it will contain non-app windows, but
+        // non-app windows will only be included with those transition types. And we don't currently
+        // have any use case of those for TaskFragment transition.
+        // @see NonAppWindowAnimationAdapter#startNonAppWindowAnimations
+        if (transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY
+                || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER
+                || transit == TRANSIT_OLD_TASK_OPEN || transit == TRANSIT_OLD_TASK_TO_FRONT
+                || transit == TRANSIT_OLD_WALLPAPER_CLOSE) {
+            return true;
+        }
+
+        // Check if the wallpaper is going to participate in the transition. We don't want to have
+        // the client to animate the wallpaper windows.
+        // @see WallpaperAnimationAdapter#startWallpaperAnimations
+        return mDisplayContent.mWallpaperController.isWallpaperVisible();
+    }
+
     /**
-     * Overrides the pending transition with the remote animation defined by the
-     * {@link ITaskFragmentOrganizer} if all windows in the transition are children of
-     * {@link TaskFragment} that are organized by the same organizer.
-     *
-     * @return {@code true} if the transition is overridden.
+     * Finds the common {@link android.window.TaskFragmentOrganizer} that organizes all app windows
+     * in the current transition.
+     * @return {@code null} if there is no such organizer, or if there are more than one.
      */
-    private boolean overrideWithTaskFragmentRemoteAnimation(@TransitionOldType int transit,
-            ArraySet<Integer> activityTypes) {
-        final ArrayList<WindowContainer> allWindows = new ArrayList<>();
-        allWindows.addAll(mDisplayContent.mClosingApps);
-        allWindows.addAll(mDisplayContent.mOpeningApps);
-        allWindows.addAll(mDisplayContent.mChangingContainers);
+    @Nullable
+    private ITaskFragmentOrganizer findTaskFragmentOrganizerForAllWindows() {
+        mTempTransitionWindows.clear();
+        mTempTransitionWindows.addAll(mDisplayContent.mClosingApps);
+        mTempTransitionWindows.addAll(mDisplayContent.mOpeningApps);
+        mTempTransitionWindows.addAll(mDisplayContent.mChangingContainers);
 
         // It should only animated by the organizer if all windows are below the same leaf Task.
         Task leafTask = null;
-        for (int i = allWindows.size() - 1; i >= 0; i--) {
-            final ActivityRecord r = getAppFromContainer(allWindows.get(i));
+        for (int i = mTempTransitionWindows.size() - 1; i >= 0; i--) {
+            final ActivityRecord r = getAppFromContainer(mTempTransitionWindows.get(i));
             if (r == null) {
-                return false;
+                leafTask = null;
+                break;
             }
             // The activity may be a child of embedded Task, but we want to find the owner Task.
             // As a result, find the organized TaskFragment first.
@@ -561,26 +580,31 @@
                     ? organizedTaskFragment.getTask()
                     : r.getTask();
             if (task == null) {
-                return false;
+                leafTask = null;
+                break;
             }
             // We don't want the organizer to handle transition of other non-embedded Task.
             if (leafTask != null && leafTask != task) {
-                return false;
+                leafTask = null;
+                break;
             }
             final ActivityRecord rootActivity = task.getRootActivity();
             // We don't want the organizer to handle transition when the whole app is closing.
             if (rootActivity == null) {
-                return false;
+                leafTask = null;
+                break;
             }
             // We don't want the organizer to handle transition of non-embedded activity of other
             // app.
             if (r.getUid() != rootActivity.getUid() && !r.isEmbedded()) {
-                return false;
+                leafTask = null;
+                break;
             }
             leafTask = task;
         }
+        mTempTransitionWindows.clear();
         if (leafTask == null) {
-            return false;
+            return null;
         }
 
         // We don't support remote animation for Task with multiple TaskFragmentOrganizers.
@@ -599,12 +623,28 @@
         if (hasMultipleOrganizers) {
             ProtoLog.e(WM_DEBUG_APP_TRANSITIONS, "We don't support remote animation for"
                     + " Task with multiple TaskFragmentOrganizers.");
+            return null;
+        }
+        return organizer[0];
+    }
+
+    /**
+     * Overrides the pending transition with the remote animation defined by the
+     * {@link ITaskFragmentOrganizer} if all windows in the transition are children of
+     * {@link TaskFragment} that are organized by the same organizer.
+     *
+     * @return {@code true} if the transition is overridden.
+     */
+    private boolean overrideWithTaskFragmentRemoteAnimation(@TransitionOldType int transit,
+            ArraySet<Integer> activityTypes) {
+        if (transitionMayContainNonAppWindows(transit)) {
             return false;
         }
 
-        final RemoteAnimationDefinition definition = organizer[0] != null
+        final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizerForAllWindows();
+        final RemoteAnimationDefinition definition = organizer != null
                 ? mDisplayContent.mAtmService.mTaskFragmentOrganizerController
-                    .getRemoteAnimationDefinition(organizer[0])
+                    .getRemoteAnimationDefinition(organizer)
                 : null;
         final RemoteAnimationAdapter adapter = definition != null
                 ? definition.getAdapter(transit, activityTypes)
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index a663c62..22c8459 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -793,7 +793,7 @@
 
     private RemoteAnimationTarget[] createWallpaperAnimations() {
         ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "createWallpaperAnimations()");
-        return WallpaperAnimationAdapter.startWallpaperAnimations(mService, 0L, 0L,
+        return WallpaperAnimationAdapter.startWallpaperAnimations(mDisplayContent, 0L, 0L,
                 adapter -> {
                     synchronized (mService.mGlobalLock) {
                         // If the wallpaper animation is canceled, continue with the recents
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 16a45fe..ca1aed5 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -207,7 +207,7 @@
                 if (wrappers.mThumbnailAdapter != null
                         && wrappers.mThumbnailAdapter.mCapturedFinishCallback != null) {
                     wrappers.mThumbnailAdapter.mCapturedFinishCallback
-                            .onAnimationFinished(wrappers.mAdapter.mAnimationType,
+                            .onAnimationFinished(wrappers.mThumbnailAdapter.mAnimationType,
                                     wrappers.mThumbnailAdapter);
                 }
                 mPendingAnimations.remove(i);
@@ -218,7 +218,7 @@
 
     private RemoteAnimationTarget[] createWallpaperAnimations() {
         ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createWallpaperAnimations()");
-        return WallpaperAnimationAdapter.startWallpaperAnimations(mService,
+        return WallpaperAnimationAdapter.startWallpaperAnimations(mDisplayContent,
                 mRemoteAnimationAdapter.getDuration(),
                 mRemoteAnimationAdapter.getStatusBarTransitionDelay(),
                 adapter -> {
@@ -260,7 +260,7 @@
                     }
                     if (adapters.mThumbnailAdapter != null) {
                         adapters.mThumbnailAdapter.mCapturedFinishCallback
-                                .onAnimationFinished(adapters.mAdapter.mAnimationType,
+                                .onAnimationFinished(adapters.mThumbnailAdapter.mAnimationType,
                                         adapters.mThumbnailAdapter);
                     }
                     mPendingAnimations.remove(i);
diff --git a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
index 25f7269..0b20f37 100644
--- a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
@@ -64,18 +64,17 @@
      *
      * @return RemoteAnimationTarget[] targets for all the visible wallpaper windows
      */
-    public static RemoteAnimationTarget[] startWallpaperAnimations(WindowManagerService service,
+    public static RemoteAnimationTarget[] startWallpaperAnimations(DisplayContent displayContent,
             long durationHint, long statusBarTransitionDelay,
             Consumer<WallpaperAnimationAdapter> animationCanceledRunnable,
             ArrayList<WallpaperAnimationAdapter> adaptersOut) {
+        if (!displayContent.mWallpaperController.isWallpaperVisible()) {
+            ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
+                    "\tWallpaper of display=%s is not visible", displayContent);
+            return new RemoteAnimationTarget[0];
+        }
         final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
-        service.mRoot.forAllWallpaperWindows(wallpaperWindow -> {
-            if (!wallpaperWindow.getDisplayContent().mWallpaperController.isWallpaperVisible()) {
-                ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tNot visible=%s", wallpaperWindow);
-                return;
-            }
-
-            ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tvisible=%s", wallpaperWindow);
+        displayContent.forAllWallpaperWindows(wallpaperWindow -> {
             final WallpaperAnimationAdapter wallpaperAdapter = new WallpaperAnimationAdapter(
                     wallpaperWindow, durationHint, statusBarTransitionDelay,
                     animationCanceledRunnable);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 82140f4..5d0e34a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -43,6 +43,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
@@ -893,6 +894,33 @@
     }
 
     @Test
+    public void testOverrideTaskFragmentAdapter_noOverrideWithWallpaper() {
+        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+        final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
+                new TestRemoteAnimationRunner(), 10, 1);
+        setupTaskFragmentRemoteAnimation(organizer, adapter);
+
+        // Create a TaskFragment with embedded activity.
+        final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(
+                createTask(mDisplayContent), organizer);
+        final ActivityRecord activity = taskFragment.getTopMostActivity();
+        activity.allDrawn = true;
+        // Set wallpaper as visible.
+        final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
+                mock(IBinder.class), true, mDisplayContent, true /* ownerCanManageAppTokens */);
+        spyOn(mDisplayContent.mWallpaperController);
+        doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible();
+        spyOn(mDisplayContent.mAppTransition);
+
+        // Prepare a transition.
+        prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
+
+        // Should not be overridden when there is wallpaper in the transition.
+        verify(mDisplayContent.mAppTransition, never())
+                .overridePendingAppTransitionRemote(adapter, false /* sync */);
+    }
+
+    @Test
     public void testTransitionGoodToGoForTaskFragments() {
         final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
         final Task task = createTask(mDisplayContent);