Recycle tasks that are split when split select anim complete for reuse

Re-land this CL after memory leak and performance regression for time were fixed.

Change-Id: I726a5d7e970869e54e9ece736f97802b8d01b02e
Fix: 376428479
Fix: 383033231
Bug: 381352866
Flag: EXEMPT bugfix
Test: Manual verification of heap dumps
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 5c9627d..5f8fbf0 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1298,7 +1298,6 @@
     @Override
     public void onViewRemoved(View child) {
         super.onViewRemoved(child);
-
         // Clear the task data for the removed child if it was visible unless:
         // - It's the initial taskview for entering split screen, we only pretend to dismiss the
         // task
@@ -1306,22 +1305,25 @@
         if (child instanceof TaskView) {
             mTaskViewCount = Math.max(0, --mTaskViewCount);
             if (child != mSplitHiddenTaskView && child != mMovingTaskView) {
-                TaskView taskView = (TaskView) child;
-                for (int i : taskView.getTaskIds()) {
-                    mHasVisibleTaskData.delete(i);
-                }
-                if (child instanceof GroupedTaskView) {
-                    mGroupedTaskViewPool.recycle((GroupedTaskView) taskView);
-                } else if (child instanceof DesktopTaskView) {
-                    mDesktopTaskViewPool.recycle((DesktopTaskView) taskView);
-                } else {
-                    mTaskViewPool.recycle(taskView);
-                }
-                mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, !hasTaskViews());
+                clearAndRecycleTaskView((TaskView) child);
             }
         }
     }
 
+    private void clearAndRecycleTaskView(TaskView taskView) {
+        for (int i : taskView.getTaskIds()) {
+            mHasVisibleTaskData.delete(i);
+        }
+        if (taskView instanceof GroupedTaskView) {
+            mGroupedTaskViewPool.recycle((GroupedTaskView) taskView);
+        } else if (taskView instanceof DesktopTaskView) {
+            mDesktopTaskViewPool.recycle((DesktopTaskView) taskView);
+        } else {
+            mTaskViewPool.recycle(taskView);
+        }
+        mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, !hasTaskViews());
+    }
+
     @Override
     public void onViewAdded(View child) {
         super.onViewAdded(child);
@@ -5478,6 +5480,13 @@
         mSplitHiddenTaskViewIndex = -1;
         if (mSplitHiddenTaskView != null) {
             mSplitHiddenTaskView.setThumbnailVisibility(VISIBLE, INVALID_TASK_ID);
+            // mSplitHiddenTaskView is set when split select animation starts. The TaskView is only
+            // removed when when the animation finishes. So in the case of overview being dismissed
+            // during the animation, we should not call clearAndRecycleTaskView() because it has
+            // not been removed yet.
+            if (mSplitHiddenTaskView.getParent() == null) {
+                clearAndRecycleTaskView(mSplitHiddenTaskView);
+            }
             mSplitHiddenTaskView = null;
         }
     }