summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java32
-rw-r--r--services/tests/servicestests/res/raw/a11y_three_finger_swipe_down_gesture.log29
-rw-r--r--services/tests/servicestests/res/raw/a11y_touch_explore_gesture.log4
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java77
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/utils/GestureLogParser.java169
5 files changed, 293 insertions, 18 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index b3977829d1c3..e1af2c48789f 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -349,7 +349,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_DOUBLE_TAP_AND_HOLD,
event.getDisplayId(),
mGestureDetector.getMotionEvents());
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
mState.startDelegating();
}
@@ -367,7 +367,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_DOUBLE_TAP,
event.getDisplayId(),
mGestureDetector.getMotionEvents());
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
if (mSendTouchExplorationEndDelayed.isPending()) {
mSendTouchExplorationEndDelayed.forceSendAndRemove();
@@ -402,13 +402,9 @@ public class TouchExplorer extends BaseEventStreamTransformation
@Override
public boolean onGestureCompleted(AccessibilityGestureEvent gestureEvent) {
- if (DEBUG) {
- Slog.d(LOG_TAG, "Dispatching gesture event:" + gestureEvent.toString());
- }
endGestureDetection(true);
mSendTouchInteractionEndDelayed.cancel();
- mAms.onGesture(gestureEvent);
-
+ dispatchGesture(gestureEvent);
return true;
}
@@ -444,10 +440,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_UNKNOWN,
event.getDisplayId(),
mGestureDetector.getMotionEvents());
- if (DEBUG) {
- Slog.d(LOG_TAG, "Dispatching gesture event:" + gestureEvent.toString());
- }
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
return false;
}
@@ -658,7 +651,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_PASSTHROUGH,
event.getDisplayId(),
mGestureDetector.getMotionEvents());
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
computeDraggingPointerIdIfNeeded(event);
pointerIdBits = 1 << mDraggingPointerId;
@@ -682,7 +675,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_PASSTHROUGH,
event.getDisplayId(),
mGestureDetector.getMotionEvents());
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
mState.startDelegating();
mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags);
@@ -704,7 +697,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_PASSTHROUGH,
event.getDisplayId(),
mGestureDetector.getMotionEvents());
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
mState.startDelegating();
if (mState.isTouchExploring()) {
@@ -725,7 +718,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_PASSTHROUGH,
event.getDisplayId(),
mGestureDetector.getMotionEvents());
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
mState.startDelegating();
event = MotionEvent.obtainNoHistory(event);
@@ -1304,7 +1297,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
AccessibilityService.GESTURE_TOUCH_EXPLORATION,
mState.getLastReceivedEvent().getDisplayId(),
mGestureDetector.getMotionEvents());
- mAms.onGesture(gestureEvent);
+ dispatchGesture(gestureEvent);
}
if (!mEvents.isEmpty() && !mRawEvents.isEmpty()) {
// Deliver a down event.
@@ -1439,6 +1432,13 @@ public class TouchExplorer extends BaseEventStreamTransformation
}
}
+ private void dispatchGesture(AccessibilityGestureEvent gestureEvent) {
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "Dispatching gesture event:" + gestureEvent.toString());
+ }
+ mAms.onGesture(gestureEvent);
+ }
+
@Override
public String toString() {
return "TouchExplorer { "
diff --git a/services/tests/servicestests/res/raw/a11y_three_finger_swipe_down_gesture.log b/services/tests/servicestests/res/raw/a11y_three_finger_swipe_down_gesture.log
new file mode 100644
index 000000000000..cf791f2f3ecb
--- /dev/null
+++ b/services/tests/servicestests/res/raw/a11y_three_finger_swipe_down_gesture.log
@@ -0,0 +1,29 @@
+ * Gesture6_id30:Swipe down with 3 finger
+MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=500.0, y[0]=696.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=5273700, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_POINTER_DOWN(1), actionButton=0, id[0]=0, x[0]=500.0, y[0]=696.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=764.0, y[1]=801.0, toolType[1]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=0, eventTime=5273700, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=500.0, y[0]=696.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=764.0, y[1]=801.0, toolType[1]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=0, eventTime=5273709, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_POINTER_DOWN(2), actionButton=0, id[0]=0, x[0]=500.0, y[0]=696.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=764.0, y[1]=801.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=294.0, y[2]=849.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273709, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=500.0, y[0]=696.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=766.0, y[1]=811.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=294.0, y[2]=849.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273715, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=503.0, y[0]=699.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=773.0, y[1]=838.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=294.0, y[2]=849.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273725, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=521.0, y[0]=728.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=776.0, y[1]=862.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=305.0, y[2]=876.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273734, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=535.0, y[0]=765.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=782.0, y[1]=898.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=313.0, y[2]=911.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273741, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=545.0, y[0]=795.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=786.0, y[1]=918.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=323.0, y[2]=941.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273750, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=555.0, y[0]=832.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=790.0, y[1]=959.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=333.0, y[2]=976.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273758, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=560.0, y[0]=870.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=794.0, y[1]=988.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=339.0, y[2]=1020.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273767, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=565.0, y[0]=909.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=797.0, y[1]=1031.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=345.0, y[2]=1052.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273776, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=568.0, y[0]=948.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=801.0, y[1]=1060.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=348.0, y[2]=1102.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273784, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=570.0, y[0]=985.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=804.0, y[1]=1103.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=352.0, y[2]=1130.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273793, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=571.0, y[0]=1028.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=807.0, y[1]=1133.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=355.0, y[2]=1178.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273801, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=572.0, y[0]=1061.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=809.0, y[1]=1175.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=358.0, y[2]=1212.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273810, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=574.0, y[0]=1108.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=811.0, y[1]=1206.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=360.0, y[2]=1260.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273822, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=575.0, y[0]=1141.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=812.0, y[1]=1249.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=363.0, y[2]=1294.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273831, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=576.0, y[0]=1191.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=815.0, y[1]=1281.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=364.0, y[2]=1343.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273836, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=578.0, y[0]=1227.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=816.0, y[1]=1324.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=368.0, y[2]=1374.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273844, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=581.0, y[0]=1276.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=820.0, y[1]=1360.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=371.0, y[2]=1421.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273853, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=581.0, y[0]=1324.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=823.0, y[1]=1406.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=372.0, y[2]=1464.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273862, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=584.0, y[0]=1369.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=824.0, y[1]=1445.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=379.0, y[2]=1506.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273870, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=586.0, y[0]=1417.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=826.0, y[1]=1493.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=387.0, y[2]=1553.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273879, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=586.0, y[0]=1417.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=826.0, y[1]=1493.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=387.0, y[2]=1553.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273888, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_POINTER_UP(0), actionButton=0, id[0]=0, x[0]=586.0, y[0]=1417.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=826.0, y[1]=1493.0, toolType[1]=TOOL_TYPE_FINGER, id[2]=2, x[2]=387.0, y[2]=1553.0, toolType[2]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=3, historySize=0, eventTime=5273895, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_POINTER_UP(0), actionButton=0, id[0]=1, x[0]=826.0, y[0]=1493.0, toolType[0]=TOOL_TYPE_FINGER, id[1]=2, x[1]=387.0, y[1]=1553.0, toolType[1]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=0, eventTime=5273895, downTime=5273700, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_UP, actionButton=0, id[0]=2, x[0]=387.0, y[0]=1553.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=5273895, downTime=5273700, deviceId=4, source=0x1002, displayId=0 } \ No newline at end of file
diff --git a/services/tests/servicestests/res/raw/a11y_touch_explore_gesture.log b/services/tests/servicestests/res/raw/a11y_touch_explore_gesture.log
new file mode 100644
index 000000000000..3cfb0a72181f
--- /dev/null
+++ b/services/tests/servicestests/res/raw/a11y_touch_explore_gesture.log
@@ -0,0 +1,4 @@
+* Gesture4_id-2:Touch explore
+MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=825.0, y[0]=2028.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=5258108, downTime=5258108, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=825.0, y[0]=2028.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=5258133, downTime=5258108, deviceId=4, source=0x1002, displayId=0 }
+MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=825.0, y[0]=2028.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=5258141, downTime=5258108, deviceId=4, source=0x1002, displayId=0 } \ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
index 89bd625c8289..7bf0bb873fc3 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
@@ -35,7 +35,10 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_E
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+import android.accessibilityservice.AccessibilityGestureEvent;
+import android.accessibilityservice.AccessibilityService;
import android.content.Context;
import android.graphics.PointF;
import android.os.Looper;
@@ -51,6 +54,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.EventStreamTransformation;
+import com.android.server.accessibility.utils.GestureLogParser;
import com.android.server.testutils.OffsettableClock;
import org.junit.Before;
@@ -58,7 +62,15 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@@ -93,6 +105,11 @@ public class TouchExplorerTest {
private int mTouchSlop;
private long mLastDownTime = Integer.MIN_VALUE;
+ @Mock
+ private AccessibilityManagerService mMockAms;
+ @Captor
+ private ArgumentCaptor<AccessibilityGestureEvent> mGestureCaptor;
+
// mock package-private GestureManifold class
@Rule
public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
@@ -122,6 +139,7 @@ public class TouchExplorerTest {
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
if (Looper.myLooper() == null) {
Looper.prepare();
}
@@ -130,7 +148,7 @@ public class TouchExplorerTest {
AccessibilityManagerService ams = new AccessibilityManagerService(mContext);
mCaptor = new EventCaptor();
mHandler = new TestHandler();
- mTouchExplorer = new TouchExplorer(mContext, ams, null, mHandler);
+ mTouchExplorer = new TouchExplorer(mContext, mMockAms, null, mHandler);
mTouchExplorer.setNext(mCaptor);
}
@@ -395,6 +413,61 @@ public class TouchExplorerTest {
mTouchExplorer.setMultiFingerGesturesEnabled(false);
}
+ @Test
+ public void testTouchExploreGestureLog() {
+ passInGesture(com.android.frameworks.servicestests.R.raw.a11y_touch_explore_gesture,
+ AccessibilityService.GESTURE_TOUCH_EXPLORATION);
+ }
+ @Test
+ public void testThreeFingerSwipeDownGestureLog() {
+ passInGesture(
+ com.android.frameworks.servicestests.R.raw.a11y_three_finger_swipe_down_gesture,
+ AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN);
+ }
+
+ /**
+ * Used to play back event data of a gesture by parsing the log into MotionEvents and sending
+ * them to TouchExplorer.
+ * @param resourceId a raw resource that corresponds to a text file
+ * @param gestureId the id of the gesture expected to be dispatched
+ */
+ private void passInGesture(int resourceId, int gestureId) {
+ mTouchExplorer.setMultiFingerGesturesEnabled(true);
+ mTouchExplorer.setSendMotionEventsEnabled(true);
+ mTouchExplorer.setTwoFingerPassthroughEnabled(true);
+ List<Integer> actions = new ArrayList<>();
+ try (
+ InputStream fis = mContext.getResources().openRawResource(resourceId);
+ InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
+ BufferedReader br = new BufferedReader(isr);
+ ) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ if (line.isEmpty() || !line.contains("MotionEvent")) {
+ continue;
+ }
+
+ MotionEvent motionEvent = GestureLogParser.getMotionEventFromLogLine(line);
+ actions.add(motionEvent.getAction());
+ send(motionEvent);
+ }
+
+ // Fast forward to dispatch GESTURE_TOUCH_EXPLORATION
+ mHandler.fastForward(USER_INTENT_TIMEOUT);
+ } catch (IOException ioException) {
+ ioException.printStackTrace();
+ }
+
+ verify(mMockAms).onGesture(mGestureCaptor.capture());
+ AccessibilityGestureEvent gestureEvent = mGestureCaptor.getValue();
+ assertEquals(gestureId, gestureEvent.getGestureId());
+ List<MotionEvent> motionEvents = gestureEvent.getMotionEvents();
+ assertEquals(actions.size(), motionEvents.size());
+ for (int i = 0; i < actions.size(); i++) {
+ assertEquals((int) actions.get(i), motionEvents.get(i).getAction());
+ }
+ }
+
private static MotionEvent fromTouchscreen(MotionEvent ev) {
ev.setSource(InputDevice.SOURCE_TOUCHSCREEN);
return ev;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/utils/GestureLogParser.java b/services/tests/servicestests/src/com/android/server/accessibility/utils/GestureLogParser.java
new file mode 100644
index 000000000000..cd848f4a018d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/utils/GestureLogParser.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2020 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.server.accessibility.utils;
+
+import android.view.MotionEvent;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class helps parse a gesture event log into its individual MotionEvents
+ */
+public class GestureLogParser {
+ /** Gets a MotionEvent from a log line */
+ public static MotionEvent getMotionEventFromLogLine(String line) {
+ final int downTime;
+ final int eventTime;
+ int action;
+ final int pointerCount;
+
+ final MotionEvent.PointerProperties[] properties;
+ final MotionEvent.PointerCoords[] pointerCoords;
+ final int metaState;
+ final int buttonState = 0;
+ final int xPrecision = 1;
+ final int yPrecision = 1;
+ final int deviceId;
+ final int edgeFlags;
+ final int source;
+ final int flags;
+ final int actionIndex;
+
+ downTime = findInt(line, "downTime=(\\d+)");
+ eventTime = findInt(line, "eventTime=(\\d+)");
+ action = stringToAction(findString(line, "action=(\\w+)"));
+
+ // For pointer indices
+ Pattern p = Pattern.compile("action=(\\w+)\\((\\d)");
+ Matcher matcher = p.matcher(line);
+ if (matcher.find()) {
+ actionIndex = Integer.decode(matcher.group(2));
+ action = action | (actionIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
+ }
+
+ pointerCount = findInt(line, "pointerCount=(\\d+)");
+ metaState = findInt(line, "metaState=(\\d+)");
+ deviceId = findInt(line, "deviceId=(\\d+)");
+ edgeFlags = Integer.decode(findString(line, "edgeFlags=(\\w+)"));
+ source = Integer.decode(findString(line, "source=(\\w+)"));
+ flags = Integer.decode(findString(line, "flags=(\\w+)"));
+ properties = findProperties(line, pointerCount);
+ pointerCoords = findCoordinates(line, pointerCount);
+
+ return MotionEvent.obtain(downTime, eventTime, action,
+ pointerCount, properties, pointerCoords, metaState, buttonState,
+ xPrecision, yPrecision, deviceId, edgeFlags, source, flags);
+ }
+
+ private static int findInt(String eventText, String pattern) {
+ final Pattern p = Pattern.compile(pattern);
+ final Matcher matcher = p.matcher(eventText);
+ matcher.find();
+ return Integer.decode(matcher.group(1));
+ }
+
+ private static float findFloat(String eventText, String pattern) {
+ final Pattern p = Pattern.compile(pattern);
+ final Matcher matcher = p.matcher(eventText);
+ matcher.find();
+ return Float.parseFloat(matcher.group(1));
+ }
+
+ private static String findString(String eventText, String pattern) {
+ final Pattern p = Pattern.compile(pattern);
+ final Matcher matcher = p.matcher(eventText);
+ matcher.find();
+ return matcher.group(1);
+ }
+
+ private static MotionEvent.PointerCoords[] findCoordinates(String eventText, int pointerCount) {
+ if (pointerCount == 0) {
+ return null;
+ }
+
+ final MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[pointerCount];
+ float x;
+ float y;
+ for (int i = 0; i < pointerCount; i++) {
+
+ x = findFloat(eventText, "x\\[" + i + "\\]=([\\d.]+)");
+ y = findFloat(eventText, "y\\[" + i + "\\]=([\\d.]+)");
+
+ MotionEvent.PointerCoords pointerCoords = new MotionEvent.PointerCoords();
+ pointerCoords.x = x;
+ pointerCoords.y = y;
+ pointerCoords.pressure = 1;
+ pointerCoords.size = 1;
+
+ coords[i] = pointerCoords;
+ }
+ return coords;
+ }
+
+ private static MotionEvent.PointerProperties[] findProperties(
+ String eventText, int pointerCount) {
+ if (pointerCount == 0) {
+ return null;
+ }
+
+ final MotionEvent.PointerProperties[] props =
+ new MotionEvent.PointerProperties[pointerCount];
+ int id;
+ for (int i = 0; i < pointerCount; i++) {
+ id = findInt(eventText, "id\\[" + i + "\\]=([\\d])");
+ MotionEvent.PointerProperties pointerProps = new MotionEvent.PointerProperties();
+ pointerProps.id = id;
+ pointerProps.toolType = MotionEvent.TOOL_TYPE_FINGER;
+ props[i] = pointerProps;
+ }
+ return props;
+ }
+
+ private static int stringToAction(String action) {
+ switch (action) {
+ case "ACTION_DOWN":
+ return MotionEvent.ACTION_DOWN;
+ case "ACTION_UP":
+ return MotionEvent.ACTION_UP;
+ case "ACTION_CANCEL":
+ return MotionEvent.ACTION_CANCEL;
+ case "ACTION_OUTSIDE":
+ return MotionEvent.ACTION_OUTSIDE;
+ case "ACTION_MOVE":
+ return MotionEvent.ACTION_MOVE;
+ case "ACTION_HOVER_MOVE":
+ return MotionEvent.ACTION_HOVER_MOVE;
+ case "ACTION_SCROLL":
+ return MotionEvent.ACTION_SCROLL;
+ case "ACTION_HOVER_ENTER":
+ return MotionEvent.ACTION_HOVER_ENTER;
+ case "ACTION_HOVER_EXIT":
+ return MotionEvent.ACTION_HOVER_EXIT;
+ case "ACTION_BUTTON_PRESS":
+ return MotionEvent.ACTION_BUTTON_PRESS;
+ case "ACTION_BUTTON_RELEASE":
+ return MotionEvent.ACTION_BUTTON_RELEASE;
+ case "ACTION_POINTER_DOWN":
+ return MotionEvent.ACTION_POINTER_DOWN;
+ case "ACTION_POINTER_UP":
+ return MotionEvent.ACTION_POINTER_UP;
+ default:
+ return -1;
+ }
+ }
+}