Merge "Fix bug with Launcher animation canceling, esp. around OverviewSplitSelect" into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 8782ee6..2e4e739 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -28,11 +28,10 @@
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
 import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
+import static com.android.quickstep.views.FloatingTaskView.PRIMARY_TRANSLATE_OFFSCREEN;
 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
-import static com.android.quickstep.views.RecentsView.FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN;
 import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
-import static com.android.quickstep.views.RecentsView.SPLIT_INSTRUCTIONS_FADE;
 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
 import static com.android.quickstep.views.RecentsView.TASK_THUMBNAIL_SPLASH_ALPHA;
 
@@ -112,6 +111,7 @@
             // TODO (b/238651489): Refactor state management to avoid need for double check
             FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView();
             if (floatingTask != null) {
+                // We are in split selection state currently, transitioning to another state
                 DragLayer dragLayer = mLauncher.getDragLayer();
                 RectF onScreenRectF = new RectF();
                 Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), floatingTask,
@@ -127,8 +127,8 @@
                 );
 
                 setter.setFloat(
-                        mRecentsView,
-                        FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN,
+                        mRecentsView.getFirstFloatingTaskView(),
+                        PRIMARY_TRANSLATE_OFFSCREEN,
                         mRecentsView.getPagedOrientationHandler()
                                 .getFloatingTaskOffscreenTranslationTarget(
                                         floatingTask,
@@ -140,14 +140,14 @@
                                 ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
                                 LINEAR
                         ));
-                setter.setFloat(
-                        mRecentsView,
-                        SPLIT_INSTRUCTIONS_FADE,
-                        1,
+                setter.setViewAlpha(
+                        mRecentsView.getSplitInstructionsView(),
+                        0,
                         config.getInterpolator(
                                 ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
                                 LINEAR
-                        ));
+                        )
+                );
             }
         }
 
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index eb739a6..7c96bf8 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -227,6 +227,11 @@
     }
 
     @Override
+    public void onStateTransitionFailed(RecentsState toState) {
+        reset();
+    }
+
+    @Override
     public void onStateTransitionComplete(RecentsState finalState) {
         if (finalState == HOME) {
             // Clean-up logic that occurs when recents is no longer in use/visible.
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 7a66ea0..c3bf041 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -14,6 +14,7 @@
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
@@ -49,6 +50,29 @@
  */
 public class FloatingTaskView extends FrameLayout {
 
+    public static final FloatProperty<FloatingTaskView> PRIMARY_TRANSLATE_OFFSCREEN =
+            new FloatProperty<FloatingTaskView>("floatingTaskPrimaryTranslateOffscreen") {
+        @Override
+        public void setValue(FloatingTaskView view, float translation) {
+            ((RecentsView) view.mActivity.getOverviewPanel()).getPagedOrientationHandler()
+                    .setFloatingTaskPrimaryTranslation(
+                            view,
+                            translation,
+                            view.mActivity.getDeviceProfile()
+                    );
+        }
+
+        @Override
+        public Float get(FloatingTaskView view) {
+            return ((RecentsView) view.mActivity.getOverviewPanel())
+                    .getPagedOrientationHandler()
+                    .getFloatingTaskPrimaryTranslation(
+                            view,
+                            view.mActivity.getDeviceProfile()
+                    );
+        }
+    };
+
     private FloatingTaskThumbnailView mThumbnailView;
     private SplitPlaceholderView mSplitPlaceholderView;
     private RectF mStartingPosition;
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index a870f9c..2539ed6 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -319,4 +319,10 @@
         super.applyThumbnailSplashAlpha();
         mSnapshotView2.setSplashAlpha(mTaskThumbnailSplashAlpha);
     }
+
+    @Override
+    void setThumbnailVisibility(int visibility) {
+        super.setThumbnailVisibility(visibility);
+        mSnapshotView2.setVisibility(visibility);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 6a33d36..de7ccad 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -120,6 +120,11 @@
     }
 
     @Override
+    public void onStateTransitionFailed(LauncherState toState) {
+        reset();
+    }
+
+    @Override
     public void onStateTransitionComplete(LauncherState finalState) {
         if (finalState == NORMAL || finalState == SPRING_LOADED) {
             // Clean-up logic that occurs when recents is no longer in use/visible.
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 69557a8..efaa644 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -397,39 +397,6 @@
                 }
             };
 
-    public static final FloatProperty<RecentsView> FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN =
-            new FloatProperty<RecentsView>("firstFloatingTaskTranslateOffscreen") {
-                @Override
-                public void setValue(RecentsView view, float translation) {
-                    view.getPagedOrientationHandler().setFloatingTaskPrimaryTranslation(
-                            view.mFirstFloatingTaskView,
-                            translation,
-                            view.mActivity.getDeviceProfile()
-                    );
-                }
-
-                @Override
-                public Float get(RecentsView view) {
-                    return view.getPagedOrientationHandler().getFloatingTaskPrimaryTranslation(
-                            view.mFirstFloatingTaskView,
-                            view.mActivity.getDeviceProfile()
-                    );
-                }
-            };
-
-    public static final FloatProperty<RecentsView> SPLIT_INSTRUCTIONS_FADE =
-            new FloatProperty<RecentsView>("splitInstructionsFade") {
-                @Override
-                public void setValue(RecentsView view, float fade) {
-                    view.mSplitInstructionsView.setAlpha(1 - fade);
-                }
-
-                @Override
-                public Float get(RecentsView view) {
-                    return 1 - view.mSplitInstructionsView.getAlpha();
-                }
-            };
-
     // OverScroll constants
     private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
 
@@ -2827,7 +2794,11 @@
 
         RectF startingTaskRect = new RectF();
         if (mSplitHiddenTaskView != null) {
-            mSplitHiddenTaskView.setVisibility(INVISIBLE);
+            // Split staging is initiated, hide the original TaskView thumbnail.
+            // Toggled back on in resetFromSplitSelectionState().
+            mSplitHiddenTaskView.setThumbnailVisibility(INVISIBLE);
+            anim.addFloat(mSplitHiddenTaskView, TaskView.ICON_ALPHA, 1, 0,
+                    clampToProgress(LINEAR, 0, 0.167f));
             mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                     mSplitHiddenTaskView.getThumbnail(),
                     mSplitHiddenTaskView.getThumbnail().getThumbnail(),
@@ -2855,6 +2826,8 @@
                 InteractionJankMonitorWrapper.end(
                         InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
             } else {
+                // If transition to split select was interrupted, clean up to prevent glitches
+                resetFromSplitSelectionState();
                 InteractionJankMonitorWrapper.cancel(
                         InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
             }
@@ -4222,7 +4195,9 @@
         resetTaskVisuals();
         mSplitHiddenTaskViewIndex = -1;
         if (mSplitHiddenTaskView != null) {
-            mSplitHiddenTaskView.setVisibility(VISIBLE);
+            // Toggle thumbnail visibility back on (turned off in
+            // createInitialSplitSelectAnimation()).
+            mSplitHiddenTaskView.setThumbnailVisibility(VISIBLE);
             mSplitHiddenTaskView = null;
         }
     }
@@ -5334,6 +5309,11 @@
         return mFirstFloatingTaskView;
     }
 
+    @Nullable
+    public SplitInstructionsView getSplitInstructionsView() {
+        return mSplitInstructionsView;
+    }
+
     /** Update the current activity locus id to show the enabled state of Overview */
     public void updateLocusId() {
         String locusId = "Overview";
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 34c2021..a84ea63 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -323,6 +323,19 @@
                 }
             };
 
+    public static final FloatProperty<TaskView> ICON_ALPHA =
+            new FloatProperty<TaskView>("iconAlpha") {
+                @Override
+                public void setValue(TaskView taskView, float v) {
+                    taskView.mIconView.setAlpha(v);
+                }
+
+                @Override
+                public Float get(TaskView taskView) {
+                    return taskView.mIconView.getAlpha();
+                }
+            };
+
     @Nullable
     protected Task mTask;
     protected TaskThumbnailView mSnapshotView;
@@ -1488,6 +1501,10 @@
         return display != null ? display.getDisplayId() : DEFAULT_DISPLAY;
     }
 
+    void setThumbnailVisibility(int visibility) {
+        mSnapshotView.setVisibility(visibility);
+    }
+
     /**
      * We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
      */
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index 2aa9dde..c44e1e1 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -342,6 +342,11 @@
             public void onAnimationSuccess(Animator animator) {
                 onStateTransitionEnd(state);
             }
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                onStateTransitionFailed(state);
+            }
         };
     }
 
@@ -354,6 +359,12 @@
         }
     }
 
+    private void onStateTransitionFailed(STATE_TYPE state) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            mListeners.get(i).onStateTransitionFailed(state);
+        }
+    }
+
     private void onStateTransitionEnd(STATE_TYPE state) {
         // Only change the stable states after the transitions have finished
         if (state != mCurrentStableState) {
@@ -588,6 +599,11 @@
 
         default void onStateTransitionStart(STATE_TYPE toState) { }
 
+        /**
+         * If the state transition animation fails (e.g. is canceled by the user), this fires.
+         */
+        default void onStateTransitionFailed(STATE_TYPE toState) { }
+
         default void onStateTransitionComplete(STATE_TYPE finalState) { }
     }