Keyboard quick switch polish

- Added support for escape(backtick on some keyboards) keyboard keys
- Added support for d-pad left and right keyboard keys
- Fixed janky behaviour when quick switching too quickly.
- Removed unused code

Bug: 269618928
Test: Tried quick switch very quickly, tried escape, d-pad left and right keys in RTL and LTR modes
Change-Id: Ie03207cb349891e9c2de18502f3f65b7c8f9c018
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
index 94d62b2..745defc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
@@ -425,7 +425,7 @@
 
     @Override
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        return (mViewCallbacks != null && mViewCallbacks.onKeyUp(keyCode, event))
+        return (mViewCallbacks != null && mViewCallbacks.onKeyUp(keyCode, event, mIsRtl))
                 || super.onKeyUp(keyCode, event);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index f0f361e..c1f764f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -19,6 +19,7 @@
 
 import android.animation.Animator;
 import android.view.KeyEvent;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -125,18 +126,26 @@
     }
 
     private int launchTaskAt(int index) {
-        KeyboardQuickSwitchTaskView taskView = mKeyboardQuickSwitchView.getTaskAt(index);
+        if (mCloseAnimation != null) {
+            // Ignore taps on task views and alt key unpresses while the close animation is running.
+            return -1;
+        }
+        // Even with a valid index, this can be null if the user tries to quick switch before the
+        // views have been added in the KeyboardQuickSwitchView.
+        View taskView = mKeyboardQuickSwitchView.getTaskAt(index);
         GroupTask task = mControllerCallbacks.getTaskAt(index);
-        if (taskView == null || task == null) {
+        if (task == null) {
             return Math.max(0, index);
         } else if (task.task2 == null) {
             UI_HELPER_EXECUTOR.execute(() ->
                     ActivityManagerWrapper.getInstance().startActivityFromRecents(
                             task.task1.key,
                             mControllers.taskbarActivityContext.getActivityLaunchOptions(
-                                    taskView, null).options));
+                                    taskView == null ? mKeyboardQuickSwitchView : taskView, null)
+                                    .options));
         } else {
-            mControllers.uiController.launchSplitTasks(taskView, task);
+            mControllers.uiController.launchSplitTasks(
+                    taskView == null ? mKeyboardQuickSwitchView : taskView, task);
         }
         return -1;
     }
@@ -160,15 +169,26 @@
 
     class ViewCallbacks {
 
-        boolean onKeyUp(int keyCode, KeyEvent event) {
-            if (keyCode != KeyEvent.KEYCODE_TAB) {
+        boolean onKeyUp(int keyCode, KeyEvent event, boolean isRTL) {
+            if (keyCode != KeyEvent.KEYCODE_TAB
+                    && keyCode != KeyEvent.KEYCODE_DPAD_RIGHT
+                    && keyCode != KeyEvent.KEYCODE_DPAD_LEFT
+                    && keyCode != KeyEvent.KEYCODE_GRAVE
+                    && keyCode != KeyEvent.KEYCODE_ESCAPE) {
                 return false;
             }
+            if (keyCode == KeyEvent.KEYCODE_GRAVE || keyCode == KeyEvent.KEYCODE_ESCAPE) {
+                closeQuickSwitchView(true);
+                return true;
+            }
+            boolean traverseBackwards = (keyCode == KeyEvent.KEYCODE_TAB && event.isShiftPressed())
+                    || (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && !isRTL)
+                    || (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && isRTL);
             int taskCount = mControllerCallbacks.getTaskCount();
             int toIndex = mCurrentFocusIndex == -1
                     // Focus the second-most recent app if possible
                     ? (taskCount > 1 ? 1 : 0)
-                    : (event.isShiftPressed()
+                    : (traverseBackwards
                             // focus a more recent task or loop back to the opposite end
                             ? Math.max(0, mCurrentFocusIndex == 0
                                     ? taskCount - 1 : mCurrentFocusIndex - 1)
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 0b6e5d3..f02e41b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -387,8 +387,7 @@
     }
 
     @Override
-    public void launchSplitTasks(View taskView, GroupTask groupTask) {
-        super.launchSplitTasks(taskView, groupTask);
+    public void launchSplitTasks(@NonNull View taskView, @NonNull GroupTask groupTask) {
         mLauncher.launchSplitTasks(taskView, groupTask);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 6324715..fe779ec 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -23,6 +23,7 @@
 import android.view.View;
 
 import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.model.data.ItemInfo;
@@ -240,15 +241,6 @@
     }
 
     /**
-     * Closes the Keyboard Quick Switch View.
-     *
-     * No-op if the view is already closed
-     */
-    public void closeQuickSwitchView() {
-        mControllers.keyboardQuickSwitchController.closeQuickSwitchView();
-    }
-
-    /**
      * Launches the focused task and closes the Keyboard Quick Switch View.
      *
      * If the overlay or view are closed, or the overview task is focused, then Overview is
@@ -267,5 +259,5 @@
      *
      * No-op if the view is not yet open.
      */
-    public void launchSplitTasks(View taskview, GroupTask groupTask) { }
+    public void launchSplitTasks(@NonNull View taskview, @NonNull GroupTask groupTask) { }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 80ce369..46cd045 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1214,7 +1214,7 @@
      *
      * If the second split task is missing, launches the first task normally.
      */
-    public void launchSplitTasks(View taskView, GroupTask groupTask) {
+    public void launchSplitTasks(@NonNull View taskView, @NonNull GroupTask groupTask) {
         if (groupTask.task2 == null) {
             UI_HELPER_EXECUTOR.execute(() ->
                     ActivityManagerWrapper.getInstance().startActivityFromRecents(