Add ExtendedLongPressTimeoutRule to all AbstractLauncherUiTest

When devices run slow in pre/post-submit, it is possible for a drag to be processed at a long press before the first move event can be created and dispatched. Added a rule to artificially increase this long press timeout in tests.

Flag: N/A
Fixes: 319257820
Test: TAPL tests
Change-Id: I24e0f3baec15db7558351d0cb2bd93a4e49640e8
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 077ca60..3444dc2 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -59,6 +59,7 @@
 import com.android.launcher3.testcomponent.TestCommandReceiver;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.ExtendedLongPressTimeoutRule;
 import com.android.launcher3.util.rule.FailureWatcher;
 import com.android.launcher3.util.rule.SamplerRule;
 import com.android.launcher3.util.rule.ScreenRecordRule;
@@ -105,6 +106,9 @@
     @Rule
     public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule();
 
+    @Rule
+    public ExtendedLongPressTimeoutRule mLongPressTimeoutRule = new ExtendedLongPressTimeoutRule();
+
     public FallbackRecentsTest() throws RemoteException {
         Instrumentation instrumentation = getInstrumentation();
         Context context = instrumentation.getContext();
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 972be80..d8635f9 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -66,6 +66,7 @@
 import com.android.launcher3.util.SimpleBroadcastReceiver;
 import com.android.launcher3.util.TestUtil;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.ExtendedLongPressTimeoutRule;
 import com.android.launcher3.util.rule.FailureWatcher;
 import com.android.launcher3.util.rule.SamplerRule;
 import com.android.launcher3.util.rule.ScreenRecordRule;
@@ -219,6 +220,9 @@
     @Rule
     public SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
 
+    @Rule
+    public ExtendedLongPressTimeoutRule mLongPressTimeoutRule = new ExtendedLongPressTimeoutRule();
+
     public static void initialize(AbstractLauncherUiTest test) throws Exception {
         test.reinitializeLauncherData();
         test.mDevice.pressHome();
diff --git a/tests/src/com/android/launcher3/util/rule/ExtendedLongPressTimeoutRule.java b/tests/src/com/android/launcher3/util/rule/ExtendedLongPressTimeoutRule.java
new file mode 100644
index 0000000..702988c
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/ExtendedLongPressTimeoutRule.java
@@ -0,0 +1,74 @@
+/*
+ * 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.util.rule;
+
+import android.content.ContentResolver;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.ViewConfiguration;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+public class ExtendedLongPressTimeoutRule implements TestRule {
+
+    private static final String TAG = "ExtendedLongPressTimeoutRule";
+
+    private static final float LONG_PRESS_TIMEOUT_MULTIPLIER = 10f;
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                ContentResolver contentResolver = InstrumentationRegistry.getInstrumentation()
+                        .getContext()
+                        .getContentResolver();
+                int prevLongPressTimeout = Settings.Secure.getInt(
+                        contentResolver,
+                        Settings.Secure.LONG_PRESS_TIMEOUT,
+                        ViewConfiguration.getLongPressTimeout());
+                int newLongPressTimeout =
+                        (int) (prevLongPressTimeout * LONG_PRESS_TIMEOUT_MULTIPLIER);
+
+                try {
+                    Log.d(TAG, "In try-block: Setting long press timeout from "
+                            + prevLongPressTimeout + "ms to " + newLongPressTimeout + "ms");
+                    Settings.Secure.putInt(
+                            contentResolver,
+                            Settings.Secure.LONG_PRESS_TIMEOUT,
+                            (int) (prevLongPressTimeout * LONG_PRESS_TIMEOUT_MULTIPLIER));
+
+                    base.evaluate();
+                } catch (Exception e) {
+                    Log.e(TAG, "Error", e);
+                    throw e;
+                } finally {
+                    Log.d(TAG, "In finally-block: resetting long press timeout to "
+                            + prevLongPressTimeout + "ms");
+                    Settings.Secure.putInt(
+                            contentResolver,
+                            Settings.Secure.LONG_PRESS_TIMEOUT,
+                            prevLongPressTimeout);
+                }
+            }
+        };
+    }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 0e523c3..c7d3754 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1919,17 +1919,21 @@
     }
 
     private static MotionEvent getMotionEvent(long downTime, long eventTime, int action,
-            float x, float y, int source) {
+            float x, float y, int source, int toolType) {
         return MotionEvent.obtain(downTime, eventTime, action, 1,
-                new MotionEvent.PointerProperties[]{getPointerProperties(0)},
+                new MotionEvent.PointerProperties[]{getPointerProperties(0, toolType)},
                 new MotionEvent.PointerCoords[]{getPointerCoords(x, y)},
                 0, 0, 1.0f, 1.0f, 0, 0, source, 0);
     }
 
     private static MotionEvent.PointerProperties getPointerProperties(int pointerId) {
+        return getPointerProperties(pointerId, Configurator.getInstance().getToolType());
+    }
+
+    private static MotionEvent.PointerProperties getPointerProperties(int pointerId, int toolType) {
         MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
         properties.id = pointerId;
-        properties.toolType = Configurator.getInstance().getToolType();
+        properties.toolType = toolType;
         return properties;
     }
 
@@ -1975,6 +1979,19 @@
 
     public void sendPointer(long downTime, long currentTime, int action, Point point,
             GestureScope gestureScope, int source, boolean isRightClick) {
+        sendPointer(
+                downTime,
+                currentTime,
+                action,
+                point,
+                gestureScope,
+                source,
+                isRightClick,
+                Configurator.getInstance().getToolType());
+    }
+
+    public void sendPointer(long downTime, long currentTime, int action, Point point,
+            GestureScope gestureScope, int source, boolean isRightClick, int toolType) {
         final boolean hasTIS = hasTIS();
         int pointerCount = mPointerCount;
 
@@ -2009,13 +2026,13 @@
                 ? getTrackpadMotionEvent(
                 downTime, currentTime, action, point.x, point.y, pointerCount,
                 mTrackpadGestureType)
-                : getMotionEvent(downTime, currentTime, action, point.x, point.y, source);
+                : getMotionEvent(downTime, currentTime, action, point.x, point.y, source, toolType);
         if (action == MotionEvent.ACTION_BUTTON_PRESS
                 || action == MotionEvent.ACTION_BUTTON_RELEASE) {
             event.setActionButton(MotionEvent.BUTTON_PRIMARY);
         }
         if (isRightClick) {
-            event.setButtonState(event.getButtonState() & MotionEvent.BUTTON_SECONDARY);
+            event.setButtonState(event.getButtonState() | MotionEvent.BUTTON_SECONDARY);
         }
         injectEvent(event);
     }
@@ -2114,15 +2131,19 @@
             @NonNull final UiObject2 target, @NonNull String resName, Pattern longClickEvent) {
         final Point targetCenter = target.getVisibleCenter();
         final long downTime = SystemClock.uptimeMillis();
+        // Use stylus secondary button press to prevent using the exteded long press timeout rule
+        // unnecessarily
         sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetCenter,
-                GestureScope.DONT_EXPECT_PILFER);
+                GestureScope.DONT_EXPECT_PILFER, InputDevice.SOURCE_TOUCHSCREEN,
+                /* isRightClick= */ true, MotionEvent.TOOL_TYPE_STYLUS);
         try {
             expectEvent(TestProtocol.SEQUENCE_MAIN, longClickEvent);
             final UiObject2 result = waitForLauncherObject(resName);
             return result;
         } finally {
             sendPointer(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, targetCenter,
-                    GestureScope.DONT_EXPECT_PILFER);
+                    GestureScope.DONT_EXPECT_PILFER, InputDevice.SOURCE_TOUCHSCREEN,
+                    /* isRightClick= */ true, MotionEvent.TOOL_TYPE_STYLUS);
         }
     }