Send home intent after reaching 3P launcher on swipe up

Also keep the 3P launcher's alpha at 0 during the gesture, and
don't send the home intent if user touches during the transition.

Bug: 139682945
Change-Id: Ie758f0b337bb173b34f5585ec1915b7ea1145094
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index b14da5c..630dd70 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -430,20 +430,6 @@
         final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
         anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
 
-            // Alpha interpolates between [1, 0] between progress values [start, end]
-            final float start = 0f;
-            final float end = 0.85f;
-
-            private float getWindowAlpha(float progress) {
-                if (progress <= start) {
-                    return 1f;
-                }
-                if (progress >= end) {
-                    return 0f;
-                }
-                return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
-            }
-
             @Override
             public void onUpdate(RectF currentRect, float progress) {
                 homeAnim.setPlayFraction(progress);
@@ -484,6 +470,24 @@
         return anim;
     }
 
+    /**
+     * @param progress The progress of the animation to the home screen.
+     * @return The current alpha to set on the animating app window.
+     */
+    protected float getWindowAlpha(float progress) {
+        // Alpha interpolates between [1, 0] between progress values [start, end]
+        final float start = 0f;
+        final float end = 0.85f;
+
+        if (progress <= start) {
+            return 1f;
+        }
+        if (progress >= end) {
+            return 0f;
+        }
+        return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
+    }
+
     public interface Factory {
 
         BaseSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs,
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
index c939de8..034f158 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -15,6 +15,8 @@
  */
 package com.android.quickstep;
 
+import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
 import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
 import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
 import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
@@ -34,6 +36,7 @@
 import android.graphics.RectF;
 import android.os.Bundle;
 import android.util.ArrayMap;
+import android.view.MotionEvent;
 
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimationSuccessListener;
@@ -97,6 +100,7 @@
     private final boolean mContinuingLastGesture;
     private final boolean mRunningOverHome;
     private final boolean mSwipeUpOverHome;
+    private boolean mTouchedHomeDuringTransition;
 
     private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f);
     private RunningWindowAnim mFinishAnimation;
@@ -105,13 +109,14 @@
             GestureState gestureState, InputConsumerController inputConsumer,
             boolean isLikelyToStartNewTask, boolean continuingLastGesture) {
         super(context, deviceState, gestureState, inputConsumer);
-        mLauncherAlpha.value = 1;
 
         mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture;
         mContinuingLastGesture = continuingLastGesture;
         mRunningOverHome = ActivityManagerWrapper.isHomeTask(mGestureState.getRunningTask());
         mSwipeUpOverHome = mRunningOverHome && !mInQuickSwitchMode;
 
+        // Keep the home launcher invisible until we decide to land there.
+        mLauncherAlpha.value = mRunningOverHome ? 1 : 0;
         if (mSwipeUpOverHome) {
             mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
         } else {
@@ -198,15 +203,27 @@
     @Override
     protected InputConsumer createNewInputProxyHandler() {
         // Just consume all input on the active task
-        return InputConsumer.NO_OP;
+        return new InputConsumer() {
+            @Override
+            public int getType() {
+                return InputConsumer.TYPE_NO_OP;
+            }
+
+            @Override
+            public void onMotionEvent(MotionEvent ev) {
+                mTouchedHomeDuringTransition = true;
+            }
+        };
     }
 
     @Override
     public void onMotionPauseChanged(boolean isPaused) {
         if (!mInQuickSwitchMode) {
             mIsMotionPaused = isPaused;
-            mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1)
-                    .setDuration(150).start();
+            if (mSwipeUpOverHome) {
+                mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1)
+                        .setDuration(150).start();
+            }
             performHapticFeedback();
         }
     }
@@ -315,7 +332,14 @@
                     // Send a home intent to clear the task stack
                     mContext.startActivity(mGestureState.getHomeIntent());
                 } else {
-                    mRecentsAnimationController.finish(true, null, true);
+                    mRecentsAnimationController.finish(true, () -> {
+                        if (!mTouchedHomeDuringTransition) {
+                            // If the user hasn't interacted with the screen during the transition,
+                            // send a home intent so launcher can go to the default home screen.
+                            // (If they are trying to touch something, we don't want to interfere.)
+                            mContext.startActivity(mGestureState.getHomeIntent());
+                        }
+                    }, true);
                 }
                 break;
             }
@@ -389,6 +413,8 @@
             };
 
             if (mGestureState.getEndTarget() == HOME && !mRunningOverHome) {
+                mRecentsAnimationController.enableInputProxy(mInputConsumer,
+                        this::createNewInputProxyHandler);
                 RectFSpringAnim anim = createWindowAnimationToHome(mCurrentShift.value, duration);
                 anim.addAnimatorListener(endListener);
                 anim.start(mEndVelocityPxPerMs);
@@ -445,11 +471,18 @@
             @Override
             public AnimatorPlaybackController createActivityAnimationToHome() {
                 AnimatorSet anim = new AnimatorSet();
-                anim.play(mLauncherAlpha.animateToValue(mLauncherAlpha.value, 1));
+                Animator fadeInLauncher = mLauncherAlpha.animateToValue(mLauncherAlpha.value, 1);
+                fadeInLauncher.setInterpolator(ACCEL_2);
+                anim.play(fadeInLauncher);
                 anim.setDuration(duration);
                 return AnimatorPlaybackController.wrap(anim, duration);
             }
         };
         return createWindowAnimationToHome(startProgress, factory);
     }
+
+    @Override
+    protected float getWindowAlpha(float progress) {
+        return 1 - ACCEL_1_5.getInterpolation(progress);
+    }
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index ccf98ae..727d757 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -558,6 +558,7 @@
                 dumpViewHierarchy();
                 log(action = "swiping up to home from " + getVisibleStateMessage());
                 final int finalState = mDevice.hasObject(By.pkg(getLauncherPackageName()))
+                        || isFallbackOverview()
                         ? NORMAL_STATE_ORDINAL : BACKGROUND_APP_STATE_ORDINAL;
 
                 try (LauncherInstrumentation.Closable c = addContextLayer(action)) {