Dismiss pip will fade task in and snap to it

Test: pip maps and dismiss when on overview
Fixes: 73097187
Change-Id: I6eedb8c2a57963f29d5655dd8f2bcdd350ed4792
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index e18708b..b763099 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -27,6 +27,8 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
+import android.animation.LayoutTransition;
+import android.animation.LayoutTransition.TransitionListener;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
@@ -57,6 +59,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewDebug;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ListView;
@@ -117,6 +120,7 @@
     private final Rect mTempRect = new Rect();
 
     private static final int DISMISS_TASK_DURATION = 300;
+    private static final int ADDITION_TASK_DURATION = 200;
     // The threshold at which we update the SystemUI flags when animating from the task into the app
     public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f;
 
@@ -169,8 +173,9 @@
             if (!mHandleTaskStackChanges) {
                 return;
             }
-            // TODO: Re-enable layout transitions for addition of the unpinned task
+
             reloadIfNeeded();
+            enableLayoutTransitions();
         }
 
         @Override
@@ -239,6 +244,7 @@
     private int mDownY;
 
     private PendingAnimation mPendingAnimation;
+    private LayoutTransition mLayoutTransition;
 
     @ViewDebug.ExportedProperty(category = "launcher")
     private float mContentAlpha = 1;
@@ -355,7 +361,7 @@
     public TaskView getTaskView(int taskId) {
         for (int i = 0; i < getTaskViewCount(); i++) {
             TaskView tv = (TaskView) getChildAt(i);
-            if (tv.getTask().key.id == taskId) {
+            if (tv.getTask().key != null && tv.getTask().key.id == taskId) {
                 return tv;
             }
         }
@@ -448,6 +454,9 @@
         final LayoutInflater inflater = LayoutInflater.from(getContext());
         final ArrayList<Task> tasks = new ArrayList<>(stack.getTasks());
 
+        // Unload existing visible task data
+        unloadVisibleTaskData();
+
         final int requiredTaskCount = tasks.size();
         if (getTaskViewCount() != requiredTaskCount) {
             if (oldChildCount > 0) {
@@ -455,7 +464,7 @@
             }
             for (int i = getChildCount(); i < requiredTaskCount; i++) {
                 final TaskView taskView = (TaskView) inflater.inflate(R.layout.task, this, false);
-                addView(taskView);
+                addView(taskView, 0);
             }
             while (getChildCount() > requiredTaskCount) {
                 final TaskView taskView = (TaskView) getChildAt(getChildCount() - 1);
@@ -466,9 +475,6 @@
             }
         }
 
-        // Unload existing visible task data
-        unloadVisibleTaskData();
-
         // Rebind and reset all task views
         for (int i = requiredTaskCount - 1; i >= 0; i--) {
             final int pageIndex = requiredTaskCount - i - 1;
@@ -635,9 +641,11 @@
         for (int i = 0; i < mHasVisibleTaskData.size(); i++) {
             if (mHasVisibleTaskData.valueAt(i)) {
                 TaskView taskView = getTaskView(mHasVisibleTaskData.keyAt(i));
-                Task task = taskView.getTask();
-                loader.unloadTaskData(task);
-                loader.getHighResThumbnailLoader().onTaskInvisible(task);
+                if (taskView != null) {
+                    Task task = taskView.getTask();
+                    loader.unloadTaskData(task);
+                    loader.getHighResThumbnailLoader().onTaskInvisible(task);
+                }
             }
         }
         mHasVisibleTaskData.clear();
@@ -766,6 +774,38 @@
         }
     }
 
+    private void enableLayoutTransitions() {
+        if (mLayoutTransition == null) {
+            mLayoutTransition = new LayoutTransition();
+            mLayoutTransition.enableTransitionType(LayoutTransition.APPEARING);
+            mLayoutTransition.setDuration(ADDITION_TASK_DURATION);
+            mLayoutTransition.setStartDelay(LayoutTransition.APPEARING, 0);
+
+            mLayoutTransition.addTransitionListener(new TransitionListener() {
+                @Override
+                public void startTransition(LayoutTransition transition, ViewGroup viewGroup,
+                    View view, int i) {
+                }
+
+                @Override
+                public void endTransition(LayoutTransition transition, ViewGroup viewGroup,
+                    View view, int i) {
+                    // When the unpinned task is added, snap to first page and disable transitions
+                    if (view instanceof TaskView) {
+                        snapToPage(0);
+                        disableLayoutTransitions();
+                    }
+
+                }
+            });
+        }
+        setLayoutTransition(mLayoutTransition);
+    }
+
+    private void disableLayoutTransitions() {
+        setLayoutTransition(null);
+    }
+
     public void setSwipeDownShouldLaunchApp(boolean swipeDownShouldLaunchApp) {
         mSwipeDownShouldLaunchApp = swipeDownShouldLaunchApp;
     }