Add initial trackpad tapl tests
- go home
Bug: 281732733
Test: presubmit
Change-Id: I538d63bde2bf427a02c2bc355eab71546d667bf9
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java
new file mode 100644
index 0000000..e92dc8f
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java
@@ -0,0 +1,58 @@
+/*
+ * 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.quickstep;
+
+import static org.junit.Assume.assumeTrue;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.ui.TaplTestsLauncher3;
+import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class TaplTestsTrackpad extends AbstractQuickStepTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ TaplTestsLauncher3.initialize(this);
+ mLauncher.setSwipeFromTrackpad(true);
+ }
+
+ @After
+ public void tearDown() {
+ mLauncher.setSwipeFromTrackpad(false);
+ }
+
+ @Test
+ @PortraitLandscape
+ @NavigationModeSwitch
+ public void goHome() throws Exception {
+ assumeTrue(mLauncher.isTablet());
+
+ startTestActivity(2);
+ mLauncher.goHome();
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index df63ea6..ce50e22 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -20,6 +20,7 @@
import static android.content.pm.PackageManager.DONT_KILL_APP;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
+import static android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT;
import static com.android.launcher3.tapl.Folder.FOLDER_CONTENT_RES_ID;
import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName;
@@ -197,11 +198,18 @@
private boolean mCheckEventsForSuccessfulGestures = false;
private Runnable mOnLauncherCrashed;
+ private boolean mSwipeFromTrackpad = false;
+ private int mPointerCount = 0;
+
private static Pattern getTouchEventPattern(String prefix, String action) {
- // The pattern includes checks that we don't get a multi-touch events or other surprises.
+ return getTouchEventPattern(prefix, action, 1);
+ }
+
+ private static Pattern getTouchEventPattern(String prefix, String action, int pointerCount) {
return Pattern.compile(
prefix + ": MotionEvent.*?action=" + action + ".*?id\\[0\\]=0"
- + ".*?toolType\\[0\\]=TOOL_TYPE_FINGER.*?buttonState=0.*?pointerCount=1");
+ + ".*?toolType\\[0\\]=TOOL_TYPE_FINGER.*?buttonState=0.*?pointerCount="
+ + pointerCount);
}
private static Pattern getTouchEventPattern(String action) {
@@ -212,6 +220,10 @@
return getTouchEventPattern("TouchInteractionService.onInputEvent", action);
}
+ private static Pattern getTouchEventPatternTIS(String action, int pointerCount) {
+ return getTouchEventPattern("TouchInteractionService.onInputEvent", action, pointerCount);
+ }
+
private static Pattern getKeyEventPattern(String action, String keyCode) {
return Pattern.compile("Key event: KeyEvent.*action=" + action + ".*keyCode=" + keyCode);
}
@@ -703,6 +715,10 @@
mIgnoreTaskbarVisibility = ignoreTaskbarVisibility;
}
+ public void setSwipeFromTrackpad(boolean swipeFromTrackpad) {
+ mSwipeFromTrackpad = swipeFromTrackpad;
+ }
+
/**
* Sets expected rotation.
* TAPL periodically checks that Launcher didn't suddenly change the rotation to unexpected one.
@@ -993,7 +1009,7 @@
// otherwise waitForIdle may return immediately in case when there was a big enough
// pause in accessibility events prior to pressing Home.
final String action;
- if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
+ if (getNavigationModel() == NavigationModel.ZERO_BUTTON || mSwipeFromTrackpad) {
checkForAnomaly(false, true);
final Point displaySize = getRealDisplaySize();
@@ -1009,9 +1025,11 @@
} else {
action = "swiping up to home";
+ int startY = mSwipeFromTrackpad ? displaySize.y * 3 / 4 : displaySize.y - 1;
+ int endY = mSwipeFromTrackpad ? displaySize.y / 4 : displaySize.y / 2;
swipeToState(
- displaySize.x / 2, displaySize.y - 1,
- displaySize.x / 2, displaySize.y / 2,
+ displaySize.x / 2, startY,
+ displaySize.x / 2, endY,
ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME, NORMAL_STATE_ORDINAL,
gestureStartFromLauncher ? GestureScope.INSIDE_TO_OUTSIDE
: GestureScope.OUTSIDE_WITH_PILFER);
@@ -1052,14 +1070,16 @@
waitForLauncherInitialized();
final boolean launcherVisible =
isTablet() ? isLauncherContainerVisible() : isLauncherVisible();
- if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
+ if (getNavigationModel() == NavigationModel.ZERO_BUTTON || mSwipeFromTrackpad) {
final Point displaySize = getRealDisplaySize();
final GestureScope gestureScope =
launcherVisible ? GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
: GestureScope.OUTSIDE_WITH_KEYCODE;
// TODO(b/225505986): change startY and endY back to displaySize.y / 2 once the
// issue is solved.
- linearGesture(0, displaySize.y / 4, displaySize.x / 2, displaySize.y / 4,
+ int startX = mSwipeFromTrackpad ? displaySize.x / 4 : 0;
+ int endX = mSwipeFromTrackpad ? displaySize.x * 3 / 4 : displaySize.x / 2;
+ linearGesture(startX, displaySize.y / 4, endX, displaySize.y / 4,
10, false, gestureScope);
} else {
waitForNavigationUiObject("back").click();
@@ -1589,18 +1609,33 @@
// Inject a swipe gesture. Inject exactly 'steps' motion points, incrementing event time by a
// fixed interval each time.
public void linearGesture(int startX, int startY, int endX, int endY, int steps,
- boolean slowDown,
- GestureScope gestureScope) {
+ boolean slowDown, GestureScope gestureScope) {
log("linearGesture: " + startX + ", " + startY + " -> " + endX + ", " + endY);
final long downTime = SystemClock.uptimeMillis();
final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
+ if (mSwipeFromTrackpad) {
+ sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 1),
+ start, gestureScope);
+ sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 2),
+ start, gestureScope);
+ }
final long endTime = movePointer(
start, end, steps, false, downTime, downTime, slowDown, gestureScope);
+ if (mSwipeFromTrackpad) {
+ sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_UP, 2),
+ start, gestureScope);
+ sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_UP, 1),
+ start, gestureScope);
+ }
sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end, gestureScope);
}
+ private static int getPointerAction(int action, int index) {
+ return action + (index << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
+ }
+
long movePointer(Point start, Point end, int steps, boolean isDecelerating, long downTime,
long startTime, boolean slowDown, GestureScope gestureScope) {
long endTime = movePointer(downTime, startTime, steps * GESTURE_STEP_MS,
@@ -1624,22 +1659,44 @@
return getContext().getResources();
}
+ private static MotionEvent getTrackpadThreeFingerMotionEvent(long downTime, long eventTime,
+ int action, float x, float y, int pointerCount) {
+ MotionEvent.PointerProperties[] pointerProperties =
+ new MotionEvent.PointerProperties[pointerCount];
+ MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount];
+ for (int i = 0; i < pointerCount; i++) {
+ pointerProperties[i] = getPointerProperties(i);
+ pointerCoords[i] = getPointerCoords(x, y);
+ pointerCoords[i].setAxisValue(AXIS_GESTURE_SWIPE_FINGER_COUNT, 3);
+ }
+ return MotionEvent.obtain(downTime, eventTime, action, pointerCount, pointerProperties,
+ pointerCoords, 0, 0, 1.0f, 1.0f, 0, 0,
+ InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_CLASS_POINTER, 0, 0,
+ MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE);
+ }
+
private static MotionEvent getMotionEvent(long downTime, long eventTime, int action,
float x, float y) {
- MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
- properties.id = 0;
- properties.toolType = Configurator.getInstance().getToolType();
+ return MotionEvent.obtain(downTime, eventTime, action, 1,
+ new MotionEvent.PointerProperties[] {getPointerProperties(0)},
+ new MotionEvent.PointerCoords[] {getPointerCoords(x, y)},
+ 0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+ }
+ private static MotionEvent.PointerProperties getPointerProperties(int pointerId) {
+ MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
+ properties.id = pointerId;
+ properties.toolType = Configurator.getInstance().getToolType();
+ return properties;
+ }
+
+ private static MotionEvent.PointerCoords getPointerCoords(float x, float y) {
MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
coords.pressure = 1;
coords.size = 1;
coords.x = x;
coords.y = y;
-
- return MotionEvent.obtain(downTime, eventTime, action, 1,
- new MotionEvent.PointerProperties[]{properties},
- new MotionEvent.PointerCoords[]{coords},
- 0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+ return coords;
}
private boolean hasTIS() {
@@ -1655,17 +1712,23 @@
public void sendPointer(long downTime, long currentTime, int action, Point point,
GestureScope gestureScope) {
final boolean hasTIS = hasTIS();
- switch (action) {
+ int pointerCount = 1;
+
+ switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
&& gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE) {
+ && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE
+ && !mSwipeFromTrackpad) {
expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_DOWN);
}
if (hasTIS && (isTrackpadGestureEnabled()
|| getNavigationModel() != NavigationModel.THREE_BUTTON)) {
expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
}
+ if (mSwipeFromTrackpad) {
+ mPointerCount = 1;
+ }
break;
case MotionEvent.ACTION_UP:
if (hasTIS && gestureScope != GestureScope.INSIDE
@@ -1676,7 +1739,8 @@
}
if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
&& gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE) {
+ && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE
+ && !mSwipeFromTrackpad) {
expectEvent(TestProtocol.SEQUENCE_MAIN,
gestureScope == GestureScope.INSIDE
|| gestureScope == GestureScope.OUTSIDE_WITHOUT_PILFER
@@ -1696,9 +1760,29 @@
case MotionEvent.ACTION_HOVER_EXIT:
expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_HOVER_EXIT_TIS);
break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ mPointerCount++;
+ expectEvent(TestProtocol.SEQUENCE_TIS, getTouchEventPatternTIS(
+ "ACTION_POINTER_DOWN", mPointerCount));
+ pointerCount = mPointerCount;
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ pointerCount = mPointerCount;
+
+ // When the gesture is handled outside, it's cancelled within launcher.
+ if (gestureScope != GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
+ && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE) {
+ expectEvent(TestProtocol.SEQUENCE_TIS, getTouchEventPatternTIS(
+ "ACTION_POINTER_UP", mPointerCount));
+ }
+ mPointerCount--;
+ break;
}
- final MotionEvent event = getMotionEvent(downTime, currentTime, action, point.x, point.y);
+ final MotionEvent event = mSwipeFromTrackpad
+ ? getTrackpadThreeFingerMotionEvent(
+ downTime, currentTime, action, point.x, point.y, pointerCount)
+ : getMotionEvent(downTime, currentTime, action, point.x, point.y);
assertTrue("injectInputEvent failed",
mInstrumentation.getUiAutomation().injectInputEvent(event, true, false));
event.recycle();
@@ -1706,8 +1790,7 @@
public long movePointer(long downTime, long startTime, long duration, Point from, Point to,
GestureScope gestureScope) {
- return movePointer(
- downTime, startTime, duration, false, from, to, gestureScope);
+ return movePointer(downTime, startTime, duration, false, from, to, gestureScope);
}
public long movePointer(long downTime, long startTime, long duration, boolean isDecelerating,