1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.accessibilityservice; 18 19 20 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP; 21 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD; 22 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SINGLE_TAP; 23 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_DOWN; 24 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_LEFT; 25 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_RIGHT; 26 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_UP; 27 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_TRIPLE_TAP; 28 import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD; 29 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP; 30 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD; 31 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SINGLE_TAP; 32 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD; 33 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN; 34 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_LEFT; 35 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_RIGHT; 36 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_UP; 37 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_TRIPLE_TAP; 38 import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD; 39 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP; 40 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD; 41 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SINGLE_TAP; 42 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_DOWN; 43 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_LEFT; 44 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_RIGHT; 45 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_UP; 46 import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_TRIPLE_TAP; 47 import static android.accessibilityservice.AccessibilityService.GESTURE_DOUBLE_TAP; 48 import static android.accessibilityservice.AccessibilityService.GESTURE_DOUBLE_TAP_AND_HOLD; 49 import static android.accessibilityservice.AccessibilityService.GESTURE_PASSTHROUGH; 50 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN; 51 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN_AND_LEFT; 52 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN_AND_RIGHT; 53 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN_AND_UP; 54 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT; 55 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT_AND_DOWN; 56 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT_AND_RIGHT; 57 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT_AND_UP; 58 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT; 59 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT_AND_DOWN; 60 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT_AND_LEFT; 61 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT_AND_UP; 62 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP; 63 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP_AND_DOWN; 64 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP_AND_LEFT; 65 import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP_AND_RIGHT; 66 import static android.accessibilityservice.AccessibilityService.GESTURE_TOUCH_EXPLORATION; 67 import static android.accessibilityservice.AccessibilityService.GESTURE_UNKNOWN; 68 69 import android.annotation.IntDef; 70 import android.annotation.NonNull; 71 import android.annotation.TestApi; 72 import android.content.pm.ParceledListSlice; 73 import android.os.Parcel; 74 import android.os.Parcelable; 75 import android.view.MotionEvent; 76 77 import java.lang.annotation.Retention; 78 import java.lang.annotation.RetentionPolicy; 79 import java.util.ArrayList; 80 import java.util.List; 81 82 /** 83 * This class describes the gesture event including gesture id and which display it happens 84 * on. 85 * <p> 86 * <strong>Note:</strong> Accessibility services setting the 87 * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE} 88 * flag can receive gestures. 89 * 90 * @see AccessibilityService#onGesture(AccessibilityGestureEvent) 91 */ 92 93 public final class AccessibilityGestureEvent implements Parcelable { 94 95 /** @hide */ 96 @IntDef(prefix = { "GESTURE_" }, value = { 97 GESTURE_UNKNOWN, 98 GESTURE_TOUCH_EXPLORATION, 99 GESTURE_2_FINGER_SINGLE_TAP, 100 GESTURE_2_FINGER_DOUBLE_TAP, 101 GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD, 102 GESTURE_2_FINGER_TRIPLE_TAP, 103 GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD, 104 GESTURE_3_FINGER_SINGLE_TAP, 105 GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD, 106 GESTURE_3_FINGER_DOUBLE_TAP, 107 GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD, 108 GESTURE_3_FINGER_TRIPLE_TAP, 109 GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD, 110 GESTURE_DOUBLE_TAP, 111 GESTURE_DOUBLE_TAP_AND_HOLD, 112 GESTURE_SWIPE_UP, 113 GESTURE_SWIPE_UP_AND_LEFT, 114 GESTURE_SWIPE_UP_AND_DOWN, 115 GESTURE_SWIPE_UP_AND_RIGHT, 116 GESTURE_SWIPE_DOWN, 117 GESTURE_SWIPE_DOWN_AND_LEFT, 118 GESTURE_SWIPE_DOWN_AND_UP, 119 GESTURE_SWIPE_DOWN_AND_RIGHT, 120 GESTURE_SWIPE_LEFT, 121 GESTURE_SWIPE_LEFT_AND_UP, 122 GESTURE_SWIPE_LEFT_AND_RIGHT, 123 GESTURE_SWIPE_LEFT_AND_DOWN, 124 GESTURE_SWIPE_RIGHT, 125 GESTURE_SWIPE_RIGHT_AND_UP, 126 GESTURE_SWIPE_RIGHT_AND_LEFT, 127 GESTURE_SWIPE_RIGHT_AND_DOWN, 128 GESTURE_2_FINGER_SWIPE_DOWN, 129 GESTURE_2_FINGER_SWIPE_LEFT, 130 GESTURE_2_FINGER_SWIPE_RIGHT, 131 GESTURE_2_FINGER_SWIPE_UP, 132 GESTURE_3_FINGER_SWIPE_DOWN, 133 GESTURE_3_FINGER_SWIPE_LEFT, 134 GESTURE_3_FINGER_SWIPE_RIGHT, 135 GESTURE_3_FINGER_SWIPE_UP, 136 GESTURE_4_FINGER_DOUBLE_TAP, 137 GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD, 138 GESTURE_4_FINGER_SINGLE_TAP, 139 GESTURE_4_FINGER_SWIPE_DOWN, 140 GESTURE_4_FINGER_SWIPE_LEFT, 141 GESTURE_4_FINGER_SWIPE_RIGHT, 142 GESTURE_4_FINGER_SWIPE_UP, 143 GESTURE_4_FINGER_TRIPLE_TAP 144 }) 145 @Retention(RetentionPolicy.SOURCE) 146 public @interface GestureId {} 147 148 @GestureId 149 private final int mGestureId; 150 private final int mDisplayId; 151 private List<MotionEvent> mMotionEvents = new ArrayList<>(); 152 153 /** @hide */ AccessibilityGestureEvent( int gestureId, int displayId, @NonNull List<MotionEvent> motionEvents)154 public AccessibilityGestureEvent( 155 int gestureId, int displayId, @NonNull List<MotionEvent> motionEvents) { 156 mGestureId = gestureId; 157 mDisplayId = displayId; 158 mMotionEvents.addAll(motionEvents); 159 } 160 161 /** @hide */ 162 @TestApi AccessibilityGestureEvent(int gestureId, int displayId)163 public AccessibilityGestureEvent(int gestureId, int displayId) { 164 this(gestureId, displayId, new ArrayList<MotionEvent>()); 165 } 166 AccessibilityGestureEvent(@onNull Parcel parcel)167 private AccessibilityGestureEvent(@NonNull Parcel parcel) { 168 mGestureId = parcel.readInt(); 169 mDisplayId = parcel.readInt(); 170 ParceledListSlice<MotionEvent> slice = parcel.readParcelable(getClass().getClassLoader()); 171 mMotionEvents = slice.getList(); 172 } 173 174 /** 175 * Returns the display id of the received-gesture display, for use with 176 * {@link android.hardware.display.DisplayManager#getDisplay(int)}. 177 * 178 * @return the display id. 179 */ getDisplayId()180 public int getDisplayId() { 181 return mDisplayId; 182 } 183 184 /** 185 * Returns performed gesture id. 186 * 187 * @return the performed gesture id. 188 * 189 */ getGestureId()190 @GestureId public int getGestureId() { 191 return mGestureId; 192 } 193 194 /** 195 * Returns the motion events that lead to this gesture. 196 * 197 */ 198 @NonNull getMotionEvents()199 public List<MotionEvent> getMotionEvents() { 200 return mMotionEvents; 201 } 202 203 @NonNull 204 @Override toString()205 public String toString() { 206 StringBuilder stringBuilder = new StringBuilder("AccessibilityGestureEvent["); 207 stringBuilder.append("gestureId: ").append(gestureIdToString(mGestureId)); 208 stringBuilder.append(", "); 209 stringBuilder.append("displayId: ").append(mDisplayId); 210 stringBuilder.append(", "); 211 stringBuilder.append("Motion Events: ["); 212 for (int i = 0; i < mMotionEvents.size(); ++i) { 213 String action = MotionEvent.actionToString(mMotionEvents.get(i).getActionMasked()); 214 stringBuilder.append(action); 215 if (i < (mMotionEvents.size() - 1)) { 216 stringBuilder.append(", "); 217 } else { 218 stringBuilder.append("]"); 219 } 220 } 221 stringBuilder.append(']'); 222 return stringBuilder.toString(); 223 } 224 225 /** 226 * Returns a string representation of the specified gesture id. 227 */ 228 @NonNull gestureIdToString(int id)229 public static String gestureIdToString(int id) { 230 switch (id) { 231 case GESTURE_UNKNOWN: return "GESTURE_UNKNOWN"; 232 case GESTURE_PASSTHROUGH: return "GESTURE_PASSTHROUGH"; 233 case GESTURE_TOUCH_EXPLORATION: return "GESTURE_TOUCH_EXPLORATION"; 234 case GESTURE_2_FINGER_SINGLE_TAP: return "GESTURE_2_FINGER_SINGLE_TAP"; 235 case GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD: 236 return "GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD"; 237 case GESTURE_2_FINGER_DOUBLE_TAP: return "GESTURE_2_FINGER_DOUBLE_TAP"; 238 case GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD: 239 return "GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD"; 240 case GESTURE_2_FINGER_TRIPLE_TAP: return "GESTURE_2_FINGER_TRIPLE_TAP"; 241 case GESTURE_3_FINGER_SINGLE_TAP: return "GESTURE_3_FINGER_SINGLE_TAP"; 242 case GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD: 243 return "GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD"; 244 case GESTURE_3_FINGER_DOUBLE_TAP: return "GESTURE_3_FINGER_DOUBLE_TAP"; 245 case GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD: 246 return "GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD"; 247 case GESTURE_3_FINGER_TRIPLE_TAP: return "GESTURE_3_FINGER_TRIPLE_TAP"; 248 case GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD: 249 return "GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD"; 250 case GESTURE_4_FINGER_SINGLE_TAP: return "GESTURE_4_FINGER_SINGLE_TAP"; 251 case GESTURE_4_FINGER_DOUBLE_TAP: return "GESTURE_4_FINGER_DOUBLE_TAP"; 252 case GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD: 253 return "GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD"; 254 case GESTURE_4_FINGER_TRIPLE_TAP: return "GESTURE_4_FINGER_TRIPLE_TAP"; 255 case GESTURE_DOUBLE_TAP: return "GESTURE_DOUBLE_TAP"; 256 case GESTURE_DOUBLE_TAP_AND_HOLD: return "GESTURE_DOUBLE_TAP_AND_HOLD"; 257 case GESTURE_SWIPE_DOWN: return "GESTURE_SWIPE_DOWN"; 258 case GESTURE_SWIPE_DOWN_AND_LEFT: return "GESTURE_SWIPE_DOWN_AND_LEFT"; 259 case GESTURE_SWIPE_DOWN_AND_UP: return "GESTURE_SWIPE_DOWN_AND_UP"; 260 case GESTURE_SWIPE_DOWN_AND_RIGHT: return "GESTURE_SWIPE_DOWN_AND_RIGHT"; 261 case GESTURE_SWIPE_LEFT: return "GESTURE_SWIPE_LEFT"; 262 case GESTURE_SWIPE_LEFT_AND_UP: return "GESTURE_SWIPE_LEFT_AND_UP"; 263 case GESTURE_SWIPE_LEFT_AND_RIGHT: return "GESTURE_SWIPE_LEFT_AND_RIGHT"; 264 case GESTURE_SWIPE_LEFT_AND_DOWN: return "GESTURE_SWIPE_LEFT_AND_DOWN"; 265 case GESTURE_SWIPE_RIGHT: return "GESTURE_SWIPE_RIGHT"; 266 case GESTURE_SWIPE_RIGHT_AND_UP: return "GESTURE_SWIPE_RIGHT_AND_UP"; 267 case GESTURE_SWIPE_RIGHT_AND_LEFT: return "GESTURE_SWIPE_RIGHT_AND_LEFT"; 268 case GESTURE_SWIPE_RIGHT_AND_DOWN: return "GESTURE_SWIPE_RIGHT_AND_DOWN"; 269 case GESTURE_SWIPE_UP: return "GESTURE_SWIPE_UP"; 270 case GESTURE_SWIPE_UP_AND_LEFT: return "GESTURE_SWIPE_UP_AND_LEFT"; 271 case GESTURE_SWIPE_UP_AND_DOWN: return "GESTURE_SWIPE_UP_AND_DOWN"; 272 case GESTURE_SWIPE_UP_AND_RIGHT: return "GESTURE_SWIPE_UP_AND_RIGHT"; 273 case GESTURE_2_FINGER_SWIPE_DOWN: return "GESTURE_2_FINGER_SWIPE_DOWN"; 274 case GESTURE_2_FINGER_SWIPE_LEFT: return "GESTURE_2_FINGER_SWIPE_LEFT"; 275 case GESTURE_2_FINGER_SWIPE_RIGHT: return "GESTURE_2_FINGER_SWIPE_RIGHT"; 276 case GESTURE_2_FINGER_SWIPE_UP: return "GESTURE_2_FINGER_SWIPE_UP"; 277 case GESTURE_3_FINGER_SWIPE_DOWN: return "GESTURE_3_FINGER_SWIPE_DOWN"; 278 case GESTURE_3_FINGER_SWIPE_LEFT: return "GESTURE_3_FINGER_SWIPE_LEFT"; 279 case GESTURE_3_FINGER_SWIPE_RIGHT: return "GESTURE_3_FINGER_SWIPE_RIGHT"; 280 case GESTURE_3_FINGER_SWIPE_UP: return "GESTURE_3_FINGER_SWIPE_UP"; 281 case GESTURE_4_FINGER_SWIPE_DOWN: return "GESTURE_4_FINGER_SWIPE_DOWN"; 282 case GESTURE_4_FINGER_SWIPE_LEFT: return "GESTURE_4_FINGER_SWIPE_LEFT"; 283 case GESTURE_4_FINGER_SWIPE_RIGHT: return "GESTURE_4_FINGER_SWIPE_RIGHT"; 284 case GESTURE_4_FINGER_SWIPE_UP: return "GESTURE_4_FINGER_SWIPE_UP"; 285 default: return Integer.toHexString(id); 286 } 287 } 288 289 /** 290 * {@inheritDoc} 291 */ 292 @Override describeContents()293 public int describeContents() { 294 return 0; 295 } 296 297 @Override writeToParcel(@onNull Parcel parcel, int flags)298 public void writeToParcel(@NonNull Parcel parcel, int flags) { 299 parcel.writeInt(mGestureId); 300 parcel.writeInt(mDisplayId); 301 parcel.writeParcelable(new ParceledListSlice<MotionEvent>(mMotionEvents), 0); 302 } 303 304 /** 305 * @see Parcelable.Creator 306 */ 307 public static final @NonNull Parcelable.Creator<AccessibilityGestureEvent> CREATOR = 308 new Parcelable.Creator<AccessibilityGestureEvent>() { 309 public AccessibilityGestureEvent createFromParcel(Parcel parcel) { 310 return new AccessibilityGestureEvent(parcel); 311 } 312 313 public AccessibilityGestureEvent[] newArray(int size) { 314 return new AccessibilityGestureEvent[size]; 315 } 316 }; 317 318 } 319