348 lines
16 KiB
Java
348 lines
16 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2019 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 android.accessibilityservice;
|
||
|
|
||
|
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SINGLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_DOWN;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_LEFT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_RIGHT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_UP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_TRIPLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SINGLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_LEFT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_RIGHT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_UP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_TRIPLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SINGLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_DOWN;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_LEFT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_RIGHT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_UP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_TRIPLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_DOUBLE_TAP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_DOUBLE_TAP_AND_HOLD;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_PASSTHROUGH;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN_AND_LEFT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN_AND_RIGHT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_DOWN_AND_UP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT_AND_DOWN;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT_AND_RIGHT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_LEFT_AND_UP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT_AND_DOWN;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT_AND_LEFT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_RIGHT_AND_UP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP_AND_DOWN;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP_AND_LEFT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_SWIPE_UP_AND_RIGHT;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_TOUCH_EXPLORATION;
|
||
|
import static android.accessibilityservice.AccessibilityService.GESTURE_UNKNOWN;
|
||
|
|
||
|
import android.annotation.IntDef;
|
||
|
import android.annotation.NonNull;
|
||
|
import android.annotation.TestApi;
|
||
|
import android.content.pm.ParceledListSlice;
|
||
|
import android.os.Parcel;
|
||
|
import android.os.Parcelable;
|
||
|
import android.view.MotionEvent;
|
||
|
|
||
|
import java.lang.annotation.Retention;
|
||
|
import java.lang.annotation.RetentionPolicy;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
|
||
|
/**
|
||
|
* This class describes the gesture event including gesture id and which display it happens
|
||
|
* on.
|
||
|
* <p>
|
||
|
* <strong>Note:</strong> Accessibility services setting the
|
||
|
* {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE}
|
||
|
* flag can receive gestures.
|
||
|
*
|
||
|
* @see AccessibilityService#onGesture(AccessibilityGestureEvent)
|
||
|
*/
|
||
|
|
||
|
public final class AccessibilityGestureEvent implements Parcelable {
|
||
|
|
||
|
/** @hide */
|
||
|
@IntDef(prefix = { "GESTURE_" }, value = {
|
||
|
GESTURE_UNKNOWN,
|
||
|
GESTURE_TOUCH_EXPLORATION,
|
||
|
GESTURE_2_FINGER_SINGLE_TAP,
|
||
|
GESTURE_2_FINGER_DOUBLE_TAP,
|
||
|
GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD,
|
||
|
GESTURE_2_FINGER_TRIPLE_TAP,
|
||
|
GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD,
|
||
|
GESTURE_3_FINGER_SINGLE_TAP,
|
||
|
GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD,
|
||
|
GESTURE_3_FINGER_DOUBLE_TAP,
|
||
|
GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD,
|
||
|
GESTURE_3_FINGER_TRIPLE_TAP,
|
||
|
GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD,
|
||
|
GESTURE_DOUBLE_TAP,
|
||
|
GESTURE_DOUBLE_TAP_AND_HOLD,
|
||
|
GESTURE_SWIPE_UP,
|
||
|
GESTURE_SWIPE_UP_AND_LEFT,
|
||
|
GESTURE_SWIPE_UP_AND_DOWN,
|
||
|
GESTURE_SWIPE_UP_AND_RIGHT,
|
||
|
GESTURE_SWIPE_DOWN,
|
||
|
GESTURE_SWIPE_DOWN_AND_LEFT,
|
||
|
GESTURE_SWIPE_DOWN_AND_UP,
|
||
|
GESTURE_SWIPE_DOWN_AND_RIGHT,
|
||
|
GESTURE_SWIPE_LEFT,
|
||
|
GESTURE_SWIPE_LEFT_AND_UP,
|
||
|
GESTURE_SWIPE_LEFT_AND_RIGHT,
|
||
|
GESTURE_SWIPE_LEFT_AND_DOWN,
|
||
|
GESTURE_SWIPE_RIGHT,
|
||
|
GESTURE_SWIPE_RIGHT_AND_UP,
|
||
|
GESTURE_SWIPE_RIGHT_AND_LEFT,
|
||
|
GESTURE_SWIPE_RIGHT_AND_DOWN,
|
||
|
GESTURE_2_FINGER_SWIPE_DOWN,
|
||
|
GESTURE_2_FINGER_SWIPE_LEFT,
|
||
|
GESTURE_2_FINGER_SWIPE_RIGHT,
|
||
|
GESTURE_2_FINGER_SWIPE_UP,
|
||
|
GESTURE_3_FINGER_SWIPE_DOWN,
|
||
|
GESTURE_3_FINGER_SWIPE_LEFT,
|
||
|
GESTURE_3_FINGER_SWIPE_RIGHT,
|
||
|
GESTURE_3_FINGER_SWIPE_UP,
|
||
|
GESTURE_4_FINGER_DOUBLE_TAP,
|
||
|
GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD,
|
||
|
GESTURE_4_FINGER_SINGLE_TAP,
|
||
|
GESTURE_4_FINGER_SWIPE_DOWN,
|
||
|
GESTURE_4_FINGER_SWIPE_LEFT,
|
||
|
GESTURE_4_FINGER_SWIPE_RIGHT,
|
||
|
GESTURE_4_FINGER_SWIPE_UP,
|
||
|
GESTURE_4_FINGER_TRIPLE_TAP
|
||
|
})
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
public @interface GestureId {}
|
||
|
|
||
|
@GestureId
|
||
|
private final int mGestureId;
|
||
|
private final int mDisplayId;
|
||
|
private List<MotionEvent> mMotionEvents = new ArrayList<>();
|
||
|
|
||
|
/**
|
||
|
* Constructs an AccessibilityGestureEvent to be dispatched to an accessibility service.
|
||
|
*
|
||
|
* @param gestureId the id number of the gesture.
|
||
|
* @param displayId the display on which this gesture was performed.
|
||
|
* @param motionEvents the motion events that lead to this gesture.
|
||
|
*/
|
||
|
public AccessibilityGestureEvent(
|
||
|
int gestureId, int displayId, @NonNull List<MotionEvent> motionEvents) {
|
||
|
mGestureId = gestureId;
|
||
|
mDisplayId = displayId;
|
||
|
mMotionEvents.addAll(motionEvents);
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@TestApi
|
||
|
public AccessibilityGestureEvent(int gestureId, int displayId) {
|
||
|
this(gestureId, displayId, new ArrayList<MotionEvent>());
|
||
|
}
|
||
|
|
||
|
private AccessibilityGestureEvent(@NonNull Parcel parcel) {
|
||
|
mGestureId = parcel.readInt();
|
||
|
mDisplayId = parcel.readInt();
|
||
|
ParceledListSlice<MotionEvent> slice = parcel.readParcelable(getClass().getClassLoader(), android.content.pm.ParceledListSlice.class);
|
||
|
mMotionEvents = slice.getList();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the display id of the received-gesture display, for use with
|
||
|
* {@link android.hardware.display.DisplayManager#getDisplay(int)}.
|
||
|
*
|
||
|
* @return the display id.
|
||
|
*/
|
||
|
public int getDisplayId() {
|
||
|
return mDisplayId;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns performed gesture id.
|
||
|
*
|
||
|
* @return the performed gesture id.
|
||
|
*
|
||
|
*/
|
||
|
@GestureId public int getGestureId() {
|
||
|
return mGestureId;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the motion events that lead to this gesture.
|
||
|
*
|
||
|
*/
|
||
|
@NonNull
|
||
|
public List<MotionEvent> getMotionEvents() {
|
||
|
return mMotionEvents;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* When we asynchronously use {@link AccessibilityGestureEvent}, we should make a copy,
|
||
|
* because motionEvent may be recycled before we use async.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
@NonNull
|
||
|
public AccessibilityGestureEvent copyForAsync() {
|
||
|
return new AccessibilityGestureEvent(mGestureId, mDisplayId,
|
||
|
mMotionEvents.stream().map(MotionEvent::copy).toList());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* After we use {@link AccessibilityGestureEvent} asynchronously, we should recycle the
|
||
|
* MotionEvent, avoid memory leaks.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public void recycle() {
|
||
|
mMotionEvents.forEach(MotionEvent::recycle);
|
||
|
mMotionEvents.clear();
|
||
|
}
|
||
|
|
||
|
@NonNull
|
||
|
@Override
|
||
|
public String toString() {
|
||
|
StringBuilder stringBuilder = new StringBuilder("AccessibilityGestureEvent[");
|
||
|
stringBuilder.append("gestureId: ").append(gestureIdToString(mGestureId));
|
||
|
stringBuilder.append(", ");
|
||
|
stringBuilder.append("displayId: ").append(mDisplayId);
|
||
|
stringBuilder.append(", ");
|
||
|
stringBuilder.append("Motion Events: [");
|
||
|
for (int i = 0; i < mMotionEvents.size(); ++i) {
|
||
|
String action = MotionEvent.actionToString(mMotionEvents.get(i).getActionMasked());
|
||
|
stringBuilder.append(action);
|
||
|
if (i < (mMotionEvents.size() - 1)) {
|
||
|
stringBuilder.append(", ");
|
||
|
} else {
|
||
|
stringBuilder.append("]");
|
||
|
}
|
||
|
}
|
||
|
stringBuilder.append(']');
|
||
|
return stringBuilder.toString();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a string representation of the specified gesture id.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public static String gestureIdToString(int id) {
|
||
|
switch (id) {
|
||
|
case GESTURE_UNKNOWN: return "GESTURE_UNKNOWN";
|
||
|
case GESTURE_PASSTHROUGH: return "GESTURE_PASSTHROUGH";
|
||
|
case GESTURE_TOUCH_EXPLORATION: return "GESTURE_TOUCH_EXPLORATION";
|
||
|
case GESTURE_2_FINGER_SINGLE_TAP: return "GESTURE_2_FINGER_SINGLE_TAP";
|
||
|
case GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD:
|
||
|
return "GESTURE_2_FINGER_TRIPLE_TAP_AND_HOLD";
|
||
|
case GESTURE_2_FINGER_DOUBLE_TAP: return "GESTURE_2_FINGER_DOUBLE_TAP";
|
||
|
case GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD:
|
||
|
return "GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD";
|
||
|
case GESTURE_2_FINGER_TRIPLE_TAP: return "GESTURE_2_FINGER_TRIPLE_TAP";
|
||
|
case GESTURE_3_FINGER_SINGLE_TAP: return "GESTURE_3_FINGER_SINGLE_TAP";
|
||
|
case GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD:
|
||
|
return "GESTURE_3_FINGER_SINGLE_TAP_AND_HOLD";
|
||
|
case GESTURE_3_FINGER_DOUBLE_TAP: return "GESTURE_3_FINGER_DOUBLE_TAP";
|
||
|
case GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD:
|
||
|
return "GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD";
|
||
|
case GESTURE_3_FINGER_TRIPLE_TAP: return "GESTURE_3_FINGER_TRIPLE_TAP";
|
||
|
case GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD:
|
||
|
return "GESTURE_3_FINGER_TRIPLE_TAP_AND_HOLD";
|
||
|
case GESTURE_4_FINGER_SINGLE_TAP: return "GESTURE_4_FINGER_SINGLE_TAP";
|
||
|
case GESTURE_4_FINGER_DOUBLE_TAP: return "GESTURE_4_FINGER_DOUBLE_TAP";
|
||
|
case GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD:
|
||
|
return "GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD";
|
||
|
case GESTURE_4_FINGER_TRIPLE_TAP: return "GESTURE_4_FINGER_TRIPLE_TAP";
|
||
|
case GESTURE_DOUBLE_TAP: return "GESTURE_DOUBLE_TAP";
|
||
|
case GESTURE_DOUBLE_TAP_AND_HOLD: return "GESTURE_DOUBLE_TAP_AND_HOLD";
|
||
|
case GESTURE_SWIPE_DOWN: return "GESTURE_SWIPE_DOWN";
|
||
|
case GESTURE_SWIPE_DOWN_AND_LEFT: return "GESTURE_SWIPE_DOWN_AND_LEFT";
|
||
|
case GESTURE_SWIPE_DOWN_AND_UP: return "GESTURE_SWIPE_DOWN_AND_UP";
|
||
|
case GESTURE_SWIPE_DOWN_AND_RIGHT: return "GESTURE_SWIPE_DOWN_AND_RIGHT";
|
||
|
case GESTURE_SWIPE_LEFT: return "GESTURE_SWIPE_LEFT";
|
||
|
case GESTURE_SWIPE_LEFT_AND_UP: return "GESTURE_SWIPE_LEFT_AND_UP";
|
||
|
case GESTURE_SWIPE_LEFT_AND_RIGHT: return "GESTURE_SWIPE_LEFT_AND_RIGHT";
|
||
|
case GESTURE_SWIPE_LEFT_AND_DOWN: return "GESTURE_SWIPE_LEFT_AND_DOWN";
|
||
|
case GESTURE_SWIPE_RIGHT: return "GESTURE_SWIPE_RIGHT";
|
||
|
case GESTURE_SWIPE_RIGHT_AND_UP: return "GESTURE_SWIPE_RIGHT_AND_UP";
|
||
|
case GESTURE_SWIPE_RIGHT_AND_LEFT: return "GESTURE_SWIPE_RIGHT_AND_LEFT";
|
||
|
case GESTURE_SWIPE_RIGHT_AND_DOWN: return "GESTURE_SWIPE_RIGHT_AND_DOWN";
|
||
|
case GESTURE_SWIPE_UP: return "GESTURE_SWIPE_UP";
|
||
|
case GESTURE_SWIPE_UP_AND_LEFT: return "GESTURE_SWIPE_UP_AND_LEFT";
|
||
|
case GESTURE_SWIPE_UP_AND_DOWN: return "GESTURE_SWIPE_UP_AND_DOWN";
|
||
|
case GESTURE_SWIPE_UP_AND_RIGHT: return "GESTURE_SWIPE_UP_AND_RIGHT";
|
||
|
case GESTURE_2_FINGER_SWIPE_DOWN: return "GESTURE_2_FINGER_SWIPE_DOWN";
|
||
|
case GESTURE_2_FINGER_SWIPE_LEFT: return "GESTURE_2_FINGER_SWIPE_LEFT";
|
||
|
case GESTURE_2_FINGER_SWIPE_RIGHT: return "GESTURE_2_FINGER_SWIPE_RIGHT";
|
||
|
case GESTURE_2_FINGER_SWIPE_UP: return "GESTURE_2_FINGER_SWIPE_UP";
|
||
|
case GESTURE_3_FINGER_SWIPE_DOWN: return "GESTURE_3_FINGER_SWIPE_DOWN";
|
||
|
case GESTURE_3_FINGER_SWIPE_LEFT: return "GESTURE_3_FINGER_SWIPE_LEFT";
|
||
|
case GESTURE_3_FINGER_SWIPE_RIGHT: return "GESTURE_3_FINGER_SWIPE_RIGHT";
|
||
|
case GESTURE_3_FINGER_SWIPE_UP: return "GESTURE_3_FINGER_SWIPE_UP";
|
||
|
case GESTURE_4_FINGER_SWIPE_DOWN: return "GESTURE_4_FINGER_SWIPE_DOWN";
|
||
|
case GESTURE_4_FINGER_SWIPE_LEFT: return "GESTURE_4_FINGER_SWIPE_LEFT";
|
||
|
case GESTURE_4_FINGER_SWIPE_RIGHT: return "GESTURE_4_FINGER_SWIPE_RIGHT";
|
||
|
case GESTURE_4_FINGER_SWIPE_UP: return "GESTURE_4_FINGER_SWIPE_UP";
|
||
|
default: return Integer.toHexString(id);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
|
@Override
|
||
|
public int describeContents() {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void writeToParcel(@NonNull Parcel parcel, int flags) {
|
||
|
parcel.writeInt(mGestureId);
|
||
|
parcel.writeInt(mDisplayId);
|
||
|
parcel.writeParcelable(new ParceledListSlice<MotionEvent>(mMotionEvents), 0);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @see Parcelable.Creator
|
||
|
*/
|
||
|
public static final @NonNull Parcelable.Creator<AccessibilityGestureEvent> CREATOR =
|
||
|
new Parcelable.Creator<AccessibilityGestureEvent>() {
|
||
|
public AccessibilityGestureEvent createFromParcel(Parcel parcel) {
|
||
|
return new AccessibilityGestureEvent(parcel);
|
||
|
}
|
||
|
|
||
|
public AccessibilityGestureEvent[] newArray(int size) {
|
||
|
return new AccessibilityGestureEvent[size];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}
|