• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.server.accessibility;
2 
3 import android.util.MathUtils;
4 import android.view.MotionEvent;
5 
6 /**
7  * Some helper functions for gesture detection.
8  */
9 final class GestureUtils {
10 
GestureUtils()11     private GestureUtils() {
12         /* cannot be instantiated */
13     }
14 
isTap(MotionEvent down, MotionEvent up, int tapTimeSlop, int tapDistanceSlop, int actionIndex)15     public static boolean isTap(MotionEvent down, MotionEvent up, int tapTimeSlop,
16             int tapDistanceSlop, int actionIndex) {
17         return eventsWithinTimeAndDistanceSlop(down, up, tapTimeSlop, tapDistanceSlop, actionIndex);
18     }
19 
isMultiTap(MotionEvent firstUp, MotionEvent secondUp, int multiTapTimeSlop, int multiTapDistanceSlop, int actionIndex)20     public static boolean isMultiTap(MotionEvent firstUp, MotionEvent secondUp,
21             int multiTapTimeSlop, int multiTapDistanceSlop, int actionIndex) {
22         return eventsWithinTimeAndDistanceSlop(firstUp, secondUp, multiTapTimeSlop,
23                 multiTapDistanceSlop, actionIndex);
24     }
25 
eventsWithinTimeAndDistanceSlop(MotionEvent first, MotionEvent second, int timeout, int distance, int actionIndex)26     private static boolean eventsWithinTimeAndDistanceSlop(MotionEvent first, MotionEvent second,
27             int timeout, int distance, int actionIndex) {
28         if (isTimedOut(first, second, timeout)) {
29             return false;
30         }
31         final double deltaMove = computeDistance(first, second, actionIndex);
32         if (deltaMove >= distance) {
33             return false;
34         }
35         return true;
36     }
37 
computeDistance(MotionEvent first, MotionEvent second, int pointerIndex)38     public static double computeDistance(MotionEvent first, MotionEvent second, int pointerIndex) {
39          return MathUtils.dist(first.getX(pointerIndex), first.getY(pointerIndex),
40                  second.getX(pointerIndex), second.getY(pointerIndex));
41     }
42 
isTimedOut(MotionEvent firstUp, MotionEvent secondUp, int timeout)43     public static boolean isTimedOut(MotionEvent firstUp, MotionEvent secondUp, int timeout) {
44         final long deltaTime = secondUp.getEventTime() - firstUp.getEventTime();
45         return (deltaTime >= timeout);
46     }
47 
isSamePointerContext(MotionEvent first, MotionEvent second)48     public static boolean isSamePointerContext(MotionEvent first, MotionEvent second) {
49         return (first.getPointerIdBits() == second.getPointerIdBits()
50                 && first.getPointerId(first.getActionIndex())
51                         == second.getPointerId(second.getActionIndex()));
52     }
53 
54     /**
55      * Determines whether a two pointer gesture is a dragging one.
56      *
57      * @param event The event with the pointer data.
58      * @return True if the gesture is a dragging one.
59      */
isDraggingGesture(float firstPtrDownX, float firstPtrDownY, float secondPtrDownX, float secondPtrDownY, float firstPtrX, float firstPtrY, float secondPtrX, float secondPtrY, float maxDraggingAngleCos)60     public static boolean isDraggingGesture(float firstPtrDownX, float firstPtrDownY,
61             float secondPtrDownX, float secondPtrDownY, float firstPtrX, float firstPtrY,
62             float secondPtrX, float secondPtrY, float maxDraggingAngleCos) {
63 
64         // Check if the pointers are moving in the same direction.
65         final float firstDeltaX = firstPtrX - firstPtrDownX;
66         final float firstDeltaY = firstPtrY - firstPtrDownY;
67 
68         if (firstDeltaX == 0 && firstDeltaY == 0) {
69             return true;
70         }
71 
72         final float firstMagnitude =
73             (float) Math.sqrt(firstDeltaX * firstDeltaX + firstDeltaY * firstDeltaY);
74         final float firstXNormalized =
75             (firstMagnitude > 0) ? firstDeltaX / firstMagnitude : firstDeltaX;
76         final float firstYNormalized =
77             (firstMagnitude > 0) ? firstDeltaY / firstMagnitude : firstDeltaY;
78 
79         final float secondDeltaX = secondPtrX - secondPtrDownX;
80         final float secondDeltaY = secondPtrY - secondPtrDownY;
81 
82         if (secondDeltaX == 0 && secondDeltaY == 0) {
83             return true;
84         }
85 
86         final float secondMagnitude =
87             (float) Math.sqrt(secondDeltaX * secondDeltaX + secondDeltaY * secondDeltaY);
88         final float secondXNormalized =
89             (secondMagnitude > 0) ? secondDeltaX / secondMagnitude : secondDeltaX;
90         final float secondYNormalized =
91             (secondMagnitude > 0) ? secondDeltaY / secondMagnitude : secondDeltaY;
92 
93         final float angleCos =
94             firstXNormalized * secondXNormalized + firstYNormalized * secondYNormalized;
95 
96         if (angleCos < maxDraggingAngleCos) {
97             return false;
98         }
99 
100         return true;
101     }
102 }
103