Merge "Cleaning up some no-op calls during workspace binding" into main
diff --git a/quickstep/res/values/override.xml b/quickstep/res/values/override.xml
index 29779a7..cba1f5b 100644
--- a/quickstep/res/values/override.xml
+++ b/quickstep/res/values/override.xml
@@ -33,6 +33,8 @@
 
   <string name="taskbar_model_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarModelCallbacksFactory</string>
 
+  <string name="taskbar_view_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarViewCallbacksFactory</string>
+
   <string name="assist_state_manager_class" translatable="false"></string>
 
   <string name="launcher_restore_event_logger_class" translatable="false">com.android.quickstep.LauncherRestoreEventLoggerImpl</string>
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 747c9cb..8db343f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -120,8 +120,7 @@
      *
      * Use {@link #getStashDuration()} to query duration
      */
-    private static final long TASKBAR_STASH_DURATION =
-            InsetsController.ANIMATION_DURATION_RESIZE;
+    private static final long TASKBAR_STASH_DURATION = InsetsController.ANIMATION_DURATION_RESIZE;
 
     /**
      * How long to stash/unstash transient taskbar.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 666d98e..d9e2330 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -85,7 +85,7 @@
     private final TaskbarActivityContext mActivityContext;
 
     // Initialized in init.
-    private TaskbarViewController.TaskbarViewCallbacks mControllerCallbacks;
+    private TaskbarViewCallbacks mControllerCallbacks;
     private View.OnClickListener mIconClickListener;
     private View.OnLongClickListener mIconLongClickListener;
 
@@ -258,7 +258,7 @@
         return mIconTouchSize;
     }
 
-    protected void init(TaskbarViewController.TaskbarViewCallbacks callbacks) {
+    protected void init(TaskbarViewCallbacks callbacks) {
         // set taskbar pane title so that accessibility service know it window and focuses.
         setAccessibilityPaneTitle(getContext().getString(R.string.taskbar_a11y_title));
         mControllerCallbacks = callbacks;
@@ -267,6 +267,10 @@
 
         if (mAllAppsButton != null) {
             mAllAppsButton.setOnClickListener(mControllerCallbacks.getAllAppsButtonClickListener());
+            mAllAppsButton.setOnLongClickListener(
+                    mControllerCallbacks.getAllAppsButtonLongClickListener());
+            mAllAppsButton.setHapticFeedbackEnabled(
+                    mControllerCallbacks.isAllAppsButtonHapticFeedbackEnabled());
         }
         if (mTaskbarDivider != null) {
             mTaskbarDivider.setOnLongClickListener(
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
new file mode 100644
index 0000000..486e53c
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.taskbar;
+
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
+
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Callbacks for {@link TaskbarView} to interact with its controller.
+ */
+public class TaskbarViewCallbacks {
+
+    private final TaskbarActivityContext mActivity;
+    private final TaskbarControllers mControllers;
+    private final TaskbarView mTaskbarView;
+
+    public TaskbarViewCallbacks(TaskbarActivityContext activity, TaskbarControllers controllers,
+            TaskbarView taskbarView) {
+        mActivity = activity;
+        mControllers = controllers;
+        mTaskbarView = taskbarView;
+    }
+
+    public View.OnClickListener getIconOnClickListener() {
+        return mActivity.getItemOnClickListener();
+    }
+
+    public View.OnClickListener getAllAppsButtonClickListener() {
+        return v -> {
+            mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP);
+            mControllers.taskbarAllAppsController.toggle();
+        };
+    }
+
+    public View.OnLongClickListener getAllAppsButtonLongClickListener() {
+        return v -> {
+            mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS);
+            return true;
+        };
+    }
+
+    public boolean isAllAppsButtonHapticFeedbackEnabled() {
+        return false;
+    }
+
+    public View.OnLongClickListener getTaskbarDividerLongClickListener() {
+        return v -> {
+            mControllers.taskbarPinningController.showPinningView(v);
+            return true;
+        };
+    }
+
+    public View.OnTouchListener getTaskbarDividerRightClickListener() {
+        return (v, event) -> {
+            if (event.isFromSource(InputDevice.SOURCE_MOUSE)
+                    && event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
+                mControllers.taskbarPinningController.showPinningView(v);
+                return true;
+            }
+            return false;
+        };
+    }
+
+    public View.OnLongClickListener getIconOnLongClickListener() {
+        return mControllers.taskbarDragController::startDragOnLongClick;
+    }
+
+    /** Gets the hover listener for the provided icon view. */
+    public View.OnHoverListener getIconOnHoverListener(View icon) {
+        return new TaskbarHoverToolTipController(mActivity, mTaskbarView, icon);
+    }
+
+    /**
+     * Notifies launcher to update icon alignment.
+     */
+    public void notifyIconLayoutBoundsChanged() {
+        mControllers.uiController.onIconLayoutBoundsChanged();
+    }
+
+    /**
+     * Notifies the taskbar scrim when the visibility of taskbar changes.
+     */
+    public void notifyVisibilityChanged() {
+        mControllers.taskbarScrimViewController.onTaskbarVisibilityChanged(
+                mTaskbarView.getVisibility());
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacksFactory.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacksFactory.kt
new file mode 100644
index 0000000..ba0f5a0
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacksFactory.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.taskbar
+
+import android.content.Context
+import com.android.launcher3.R
+import com.android.launcher3.util.ResourceBasedOverride
+import com.android.launcher3.util.ResourceBasedOverride.Overrides
+
+/** Creates [TaskbarViewCallbacks] instances. */
+open class TaskbarViewCallbacksFactory : ResourceBasedOverride {
+
+    open fun create(
+        activity: TaskbarActivityContext,
+        controllers: TaskbarControllers,
+        taskbarView: TaskbarView,
+    ): TaskbarViewCallbacks = TaskbarViewCallbacks(activity, controllers, taskbarView)
+
+    companion object {
+        @JvmStatic
+        fun newInstance(context: Context): TaskbarViewCallbacksFactory {
+            return Overrides.getObject(
+                TaskbarViewCallbacksFactory::class.java,
+                context,
+                R.string.taskbar_view_callbacks_factory_class,
+            )
+        }
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 614dc14..5494853 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -26,7 +26,6 @@
 import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION;
 import static com.android.launcher3.config.FeatureFlags.enableTaskbarPinning;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
 import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_PERSISTENT;
 import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_TRANSIENT;
 import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
@@ -41,7 +40,6 @@
 import android.annotation.NonNull;
 import android.graphics.Rect;
 import android.util.Log;
-import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.animation.Interpolator;
@@ -193,7 +191,8 @@
 
     public void init(TaskbarControllers controllers) {
         mControllers = controllers;
-        mTaskbarView.init(new TaskbarViewCallbacks());
+        mTaskbarView.init(TaskbarViewCallbacksFactory.newInstance(mActivity).create(
+                mActivity, mControllers, mTaskbarView));
         mTaskbarView.getLayoutParams().height = mActivity.isPhoneMode()
                 ? mActivity.getResources().getDimensionPixelSize(R.dimen.taskbar_phone_size)
                 : mActivity.getDeviceProfile().taskbarHeight;
@@ -891,66 +890,4 @@
         mModelCallbacks.updateRunningApps();
     }
 
-    /**
-     * Callbacks for {@link TaskbarView} to interact with its controller.
-     */
-    public class TaskbarViewCallbacks {
-        private final float mSquaredTouchSlop = Utilities.squaredTouchSlop(mActivity);
-
-        private float mDownX, mDownY;
-        private boolean mCanceledStashHint;
-
-        public View.OnClickListener getIconOnClickListener() {
-            return mActivity.getItemOnClickListener();
-        }
-
-        public View.OnClickListener getAllAppsButtonClickListener() {
-            return v -> {
-                mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP);
-                mControllers.taskbarAllAppsController.toggle();
-            };
-        }
-
-        public View.OnLongClickListener getTaskbarDividerLongClickListener() {
-            return v -> {
-                mControllers.taskbarPinningController.showPinningView(v);
-                return true;
-            };
-        }
-
-        public View.OnTouchListener getTaskbarDividerRightClickListener() {
-            return (v, event) -> {
-                if (event.isFromSource(InputDevice.SOURCE_MOUSE)
-                        && event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
-                    mControllers.taskbarPinningController.showPinningView(v);
-                    return true;
-                }
-                return false;
-            };
-        }
-
-        public View.OnLongClickListener getIconOnLongClickListener() {
-            return mControllers.taskbarDragController::startDragOnLongClick;
-        }
-
-        /** Gets the hover listener for the provided icon view. */
-        public View.OnHoverListener getIconOnHoverListener(View icon) {
-            return new TaskbarHoverToolTipController(mActivity, mTaskbarView, icon);
-        }
-
-        /**
-         * Notifies launcher to update icon alignment.
-         */
-        public void notifyIconLayoutBoundsChanged() {
-            mControllers.uiController.onIconLayoutBoundsChanged();
-        }
-
-        /**
-         * Notifies the taskbar scrim when the visibility of taskbar changes.
-         */
-        public void notifyVisibilityChanged() {
-            mControllers.taskbarScrimViewController.onTaskbarVisibilityChanged(
-                    mTaskbarView.getVisibility());
-        }
-    }
 }
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
index a050464..36c591e 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
@@ -22,8 +22,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.tapl.KeyboardQuickSwitch;
-import com.android.launcher3.tapl.LaunchedAppState;
-import com.android.launcher3.tapl.Taskbar;
 import com.android.launcher3.taskbar.KeyboardQuickSwitchController;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 
@@ -38,7 +36,6 @@
     private enum TestSurface {
         HOME(true),
         LAUNCHED_APP(false),
-        TASKBAR_ALL_APPS(false),
         HOME_ALL_APPS(true),
         WIDGETS(true);
 
@@ -85,11 +82,6 @@
     }
 
     @Test
-    public void testDismiss_fromTaskbarAllApps() {
-        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.DISMISS);
-    }
-
-    @Test
     public void testDismiss_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.DISMISS);
     }
@@ -110,11 +102,6 @@
     }
 
     @Test
-    public void testLaunchLastTask_fromTaskbarAllApps() {
-        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_LAST_APP);
-    }
-
-    @Test
     public void testLaunchLastTask_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_LAST_APP);
     }
@@ -135,11 +122,6 @@
     }
 
     @Test
-    public void testLaunchSelectedTask_fromTaskbarAllApps() {
-        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_SELECTED_APP);
-    }
-
-    @Test
     public void testLaunchSelectedTask_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_SELECTED_APP);
     }
@@ -160,11 +142,6 @@
     }
 
     @Test
-    public void testLaunchOverviewTask_fromTaskbarAllApps() {
-        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_OVERVIEW);
-    }
-
-    @Test
     public void testLaunchOverviewTask_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_OVERVIEW);
     }
@@ -188,12 +165,6 @@
                 mLauncher.setIgnoreTaskbarVisibility(true);
                 kqs = mLauncher.getLaunchedAppState().showQuickSwitchView();
                 break;
-            case TASKBAR_ALL_APPS:
-                LaunchedAppState launchedApp = mLauncher.getLaunchedAppState();
-                Taskbar taskbar = mLauncher.isTransientTaskbar()
-                        ? launchedApp.swipeUpToUnstashTaskbar() : launchedApp.getTaskbar();
-                kqs = taskbar.openAllApps().showQuickSwitchView();
-                break;
             case HOME_ALL_APPS:
                 kqs = mLauncher.goHome().switchToAllApps().showQuickSwitchView();
                 break;
diff --git a/res/values/config.xml b/res/values/config.xml
index 1b74238..21d6024 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -89,6 +89,7 @@
     <string name="widget_holder_factory_class" translatable="false"></string>
     <string name="taskbar_search_session_controller_class" translatable="false"></string>
     <string name="taskbar_model_callbacks_factory_class" translatable="false"></string>
+    <string name="taskbar_view_callbacks_factory_class" translatable="false"></string>
     <string name="launcher_restore_event_logger_class" translatable="false"></string>
 
     <!-- View ID to use for QSB widget -->
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 2a0f030..2aabb7c 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -636,6 +636,9 @@
         @UiEvent(doc = "User tapped taskbar All Apps button.")
         LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP(1057),
 
+        @UiEvent(doc = "User long pressed taskbar All Apps button.")
+        LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS(1607),
+
         @UiEvent(doc = "User tapped on Share app system shortcut.")
         LAUNCHER_SYSTEM_SHORTCUT_APP_SHARE_TAP(1075),
 
diff --git a/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index 8eebdb2..5ef63da 100644
--- a/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -14,6 +14,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.util.concurrent.TimeUnit;
 
 public class PortraitLandscapeRunner implements TestRule {
     private static final String TAG = "PortraitLandscapeRunner";
@@ -49,7 +50,8 @@
 
                     mTest.mDevice.pressHome();
                     mTest.waitForLauncherCondition("Launcher activity wasn't created",
-                            launcher -> launcher != null);
+                            launcher -> launcher != null,
+                            TimeUnit.SECONDS.toMillis(20));
 
                     mTest.executeOnLauncher(launcher ->
                             launcher.getRotationHelper().forceAllowRotationForTesting(
diff --git a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
index 6c35f68..5283c6b 100644
--- a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
+++ b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
@@ -14,6 +14,8 @@
 import static com.android.launcher3.util.TestUtil.DUMMY_CLASS_NAME;
 import static com.android.launcher3.util.TestUtil.DUMMY_PACKAGE;
 import static com.android.launcher3.util.TestUtil.runOnExecutorSync;
+import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -38,6 +40,7 @@
 import com.android.launcher3.util.LauncherLayoutBuilder;
 import com.android.launcher3.util.LauncherModelHelper;
 import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.rule.TestStabilityRule;
 import com.android.launcher3.util.TestUtil;
 
 import org.junit.After;
@@ -123,6 +126,7 @@
     }
 
     @Test
+    @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/325283522
     public void testCacheUpdate_update_apps() {
         // Run on model executor so that no other task runs in the middle.
         runOnExecutorSync(MODEL_EXECUTOR, () -> {