Merge "Account for tasks over splitscreen in RemoteTargetGluer" into main
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index 98d0ece..2e70703 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -20,11 +20,13 @@
 import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
 import static com.android.wm.shell.util.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS;
 
+import android.app.WindowConfiguration;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.Log;
 import android.view.RemoteAnimationTarget;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.util.SplitConfigurationOptions;
@@ -35,6 +37,8 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * Glues together the necessary components to animate a remote target using a
@@ -43,7 +47,9 @@
 public class RemoteTargetGluer {
     private static final String TAG = "RemoteTargetGluer";
 
-    private static final int DEFAULT_NUM_HANDLES = 2;
+    // This is the default number of handles to create when we don't know how many tasks are running
+    // (e.g. if we're in split screen). Allocate extra for potential tasks overlaid, like volume.
+    private static final int DEFAULT_NUM_HANDLES = 4;
 
     private RemoteTargetHandle[] mRemoteTargetHandles;
     private SplitConfigurationOptions.SplitBounds mSplitBounds;
@@ -107,7 +113,7 @@
         for (int i = 0; i < mRemoteTargetHandles.length; i++) {
             RemoteAnimationTarget primaryTaskTarget = targets.apps[i];
             mRemoteTargetHandles[i].mTransformParams.setTargetSet(
-                    createRemoteAnimationTargetsForTarget(targets, null));
+                    createRemoteAnimationTargetsForTarget(targets, Collections.emptyList()));
             mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
         }
         return mRemoteTargetHandles;
@@ -177,18 +183,42 @@
             RemoteAnimationTarget topLeftTarget = targets.findTask(mSplitBounds.leftTopTaskId);
             RemoteAnimationTarget bottomRightTarget = targets.findTask(
                     mSplitBounds.rightBottomTaskId);
+            List<RemoteAnimationTarget> overlayTargets = Arrays.stream(targets.apps).filter(
+                    target -> target.windowConfiguration.getWindowingMode()
+                            != WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW).toList();
 
             // remoteTargetHandle[0] denotes topLeft task, so we pass in the bottomRight to exclude,
             // vice versa
             mRemoteTargetHandles[0].mTransformParams.setTargetSet(
-                    createRemoteAnimationTargetsForTarget(targets, bottomRightTarget));
-            mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget,
-                    mSplitBounds);
+                    createRemoteAnimationTargetsForTarget(targets,
+                            Collections.singletonList(bottomRightTarget)));
+            mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget, mSplitBounds);
 
             mRemoteTargetHandles[1].mTransformParams.setTargetSet(
-                    createRemoteAnimationTargetsForTarget(targets, topLeftTarget));
-            mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(bottomRightTarget,
-                    mSplitBounds);
+                    createRemoteAnimationTargetsForTarget(targets,
+                            Collections.singletonList(topLeftTarget)));
+            mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(bottomRightTarget, mSplitBounds);
+
+            // Set the remaining overlay tasks to be their own TaskViewSimulator as fullscreen tasks
+            if (!overlayTargets.isEmpty()) {
+                ArrayList<RemoteAnimationTarget> targetsToExclude = new ArrayList<>();
+                targetsToExclude.add(topLeftTarget);
+                targetsToExclude.add(bottomRightTarget);
+                // Start i at 2 to account for top/left and bottom/right split handles already made
+                for (int i = 2; i < targets.apps.length; i++) {
+                    if (i >= mRemoteTargetHandles.length) {
+                        Log.e(TAG, String.format("Attempting to animate an untracked target"
+                                + " (%d handles allocated, but %d want to animate)",
+                                mRemoteTargetHandles.length, targets.apps.length));
+                        break;
+                    }
+                    mRemoteTargetHandles[i].mTransformParams.setTargetSet(
+                            createRemoteAnimationTargetsForTarget(targets, targetsToExclude));
+                    mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(
+                            overlayTargets.get(i - 2));
+                }
+
+            }
         }
         return mRemoteTargetHandles;
     }
@@ -214,32 +244,38 @@
     /**
      * Ensures that we aren't excluding ancillary targets such as home/recents
      *
-     * @param targetToExclude Will be excluded from the resulting return value.
-     *                        Pass in {@code null} to not exclude anything
+     * @param targetsToExclude Will be excluded from the resulting return value.
+     *                        Pass in an empty list to not exclude anything
      * @return RemoteAnimationTargets where all the app targets from the passed in
-     *         {@param targets} are included except {@param targetToExclude}
+     *         {@code targets} are included except {@code targetsToExclude}
      */
     private RemoteAnimationTargets createRemoteAnimationTargetsForTarget(
-            RemoteAnimationTargets targets,
-            RemoteAnimationTarget targetToExclude) {
-        ArrayList<RemoteAnimationTarget> targetsWithoutExcluded = new ArrayList<>();
+            @NonNull RemoteAnimationTargets targets,
+            @NonNull List<RemoteAnimationTarget> targetsToExclude) {
+        ArrayList<RemoteAnimationTarget> targetsToInclude = new ArrayList<>();
 
         for (RemoteAnimationTarget targetCompat : targets.unfilteredApps) {
-            if (targetCompat == targetToExclude) {
+            boolean skipTarget = false;
+            for (RemoteAnimationTarget excludingTarget : targetsToExclude) {
+                if (targetCompat == excludingTarget) {
+                    skipTarget = true;
+                    break;
+                }
+                if (excludingTarget != null
+                        && excludingTarget.taskInfo != null
+                        && targetCompat.taskInfo != null
+                        && excludingTarget.taskInfo.parentTaskId == targetCompat.taskInfo.taskId) {
+                    // Also exclude corresponding parent task
+                    skipTarget = true;
+                }
+            }
+            if (skipTarget) {
                 continue;
             }
-            if (targetToExclude != null
-                    && targetToExclude.taskInfo != null
-                    && targetCompat.taskInfo != null
-                    && targetToExclude.taskInfo.parentTaskId == targetCompat.taskInfo.taskId) {
-                // Also exclude corresponding parent task
-                continue;
-            }
-
-            targetsWithoutExcluded.add(targetCompat);
+            targetsToInclude.add(targetCompat);
         }
-        final RemoteAnimationTarget[] filteredApps = targetsWithoutExcluded.toArray(
-                new RemoteAnimationTarget[targetsWithoutExcluded.size()]);
+        final RemoteAnimationTarget[] filteredApps = targetsToInclude.toArray(
+                new RemoteAnimationTarget[0]);
         return new RemoteAnimationTargets(
                 filteredApps, targets.wallpapers, targets.nonApps, targets.targetMode);
     }