Gracefully handle failed task launches during quick switch

When quick switching from home or overview, go to OverviewState if the
task launch failed. Otherwise we get stuck in BackgroundAppState.

Bug: 135038270
Change-Id: I42785c261cef0df95666bc106ec5ca6ef0553cc7
diff --git a/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java b/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java
index 2db8b39..274a347 100644
--- a/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java
+++ b/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java
@@ -61,4 +61,9 @@
         // Go does not support live tiles.
         return false;
     }
+
+    @Override
+    public void onLaunchTaskFailed(T activity) {
+        // Go does not support gestures from one task to another.
+    }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index ed511f5..cdc271f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -15,6 +15,9 @@
  */
 package com.android.launcher3.uioverrides.states;
 
+import android.os.Handler;
+import android.os.Looper;
+
 import com.android.launcher3.Launcher;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.quickstep.views.RecentsView;
@@ -27,6 +30,8 @@
  */
 public class QuickSwitchState extends BackgroundAppState {
 
+    private static final String TAG = "QuickSwitchState";
+
     public QuickSwitchState(int id) {
         super(id, LauncherLogProto.ContainerType.APP);
     }
@@ -48,7 +53,12 @@
     public void onStateTransitionEnd(Launcher launcher) {
         TaskView tasktolaunch = launcher.<RecentsView>getOverviewPanel().getTaskViewAt(0);
         if (tasktolaunch != null) {
-            tasktolaunch.launchTask(false);
+            tasktolaunch.launchTask(false, success -> {
+                if (!success) {
+                    launcher.getStateManager().goToState(OVERVIEW);
+                    tasktolaunch.notifyTaskLaunchFailed(TAG);
+                }
+            }, new Handler(Looper.getMainLooper()));
         } else {
             launcher.getStateManager().goToState(NORMAL);
         }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
index 2c42fd6..4ae6d87 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -224,4 +224,10 @@
     public boolean isInLiveTileMode() {
         return false;
     }
+
+    @Override
+    public void onLaunchTaskFailed(RecentsActivity activity) {
+        // TODO: probably go back to overview instead.
+        activity.<RecentsView>getOverviewPanel().startHome();
+    }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 7809e45..5449b47 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -512,4 +512,9 @@
         return launcher != null && launcher.getStateManager().getState() == OVERVIEW &&
                 launcher.isStarted();
     }
+
+    @Override
+    public void onLaunchTaskFailed(Launcher launcher) {
+        launcher.getStateManager().goToState(OVERVIEW);
+    }
 }
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 7d17f85..06abb80 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -746,6 +746,9 @@
                         ? 0 : (progress - mShiftAtGestureStart) / (1 - mShiftAtGestureStart));
     }
 
+    /**
+     * @param windowProgress 0 == app, 1 == overview
+     */
     private void updateSysUiFlags(float windowProgress) {
         if (mRecentsView != null) {
             TaskView centermostTask = mRecentsView.getTaskViewAt(mRecentsView
@@ -1249,7 +1252,17 @@
                 if (!mCanceled) {
                     TaskView nextTask = mRecentsView.getTaskView(taskId);
                     if (nextTask != null) {
-                        nextTask.launchTask(false /* animate */, true /* freezeTaskList */);
+                        nextTask.launchTask(false /* animate */, true /* freezeTaskList */,
+                                success -> {
+                            if (!success) {
+                                // We couldn't launch the task, so take user to overview so they can
+                                // decide what to do instead of staying in this broken state.
+                                endLauncherTransitionController();
+                                mActivityControlHelper.onLaunchTaskFailed(mActivity);
+                                nextTask.notifyTaskLaunchFailed(TAG);
+                                updateSysUiFlags(1 /* windowProgress == overview */);
+                            }
+                        }, mMainThreadHandler);
                         doLogGesture(NEW_TASK);
                     }
                     reset();
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index dcc1ace..8675c3e 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -93,6 +93,8 @@
 
     boolean isInLiveTileMode();
 
+    void onLaunchTaskFailed(T activity);
+
     interface ActivityInitListener {
 
         void register();