Merge "Add FLAG_IS_ACCESSIBILITY_EVENT to KeyEvent and MotionEvent" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
24b5ca6b4b
@@ -2724,12 +2724,12 @@ package android.view {
|
||||
public final class InputDevice implements android.os.Parcelable {
|
||||
method @RequiresPermission("android.permission.DISABLE_INPUT_DEVICE") public void disable();
|
||||
method @RequiresPermission("android.permission.DISABLE_INPUT_DEVICE") public void enable();
|
||||
field public static final int ACCESSIBILITY_DEVICE_ID = -2; // 0xfffffffe
|
||||
}
|
||||
|
||||
public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable {
|
||||
method public static String actionToString(int);
|
||||
method public final void setDisplayId(int);
|
||||
field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
|
||||
field public static final int LAST_KEYCODE = 288; // 0x120
|
||||
}
|
||||
|
||||
@@ -2747,6 +2747,7 @@ package android.view {
|
||||
method public void setActionButton(int);
|
||||
method public void setButtonState(int);
|
||||
method public void setDisplayId(int);
|
||||
field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface RemotableViewMethod {
|
||||
|
||||
@@ -444,13 +444,6 @@ public final class InputDevice implements Parcelable {
|
||||
|
||||
private static final int VIBRATOR_ID_ALL = -1;
|
||||
|
||||
/**
|
||||
* The device id of input events generated inside accessibility service.
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public static final int ACCESSIBILITY_DEVICE_ID = -2;
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<InputDevice> CREATOR =
|
||||
new Parcelable.Creator<InputDevice>() {
|
||||
public InputDevice createFromParcel(Parcel in) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -1221,6 +1222,14 @@ public class KeyEvent extends InputEvent implements Parcelable {
|
||||
*/
|
||||
public static final int FLAG_FALLBACK = 0x400;
|
||||
|
||||
/**
|
||||
* This flag indicates that this event was modified by or generated from an accessibility
|
||||
* service. Value = 0x800
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public static final int FLAG_IS_ACCESSIBILITY_EVENT = INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
|
||||
|
||||
/**
|
||||
* Signifies that the key is being predispatched.
|
||||
* @hide
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
@@ -493,6 +494,14 @@ public final class MotionEvent extends InputEvent implements Parcelable {
|
||||
*/
|
||||
public static final int FLAG_NO_FOCUS_CHANGE = 0x40;
|
||||
|
||||
/**
|
||||
* This flag indicates that this event was modified by or generated from an accessibility
|
||||
* service. Value = 0x800
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public static final int FLAG_IS_ACCESSIBILITY_EVENT = INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
|
||||
|
||||
/**
|
||||
* Private flag that indicates when the system has detected that this motion event
|
||||
* may be inconsistent with respect to the sequence of previously delivered motion events,
|
||||
|
||||
@@ -20,6 +20,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@@ -157,4 +158,28 @@ public abstract class VerifiedInputEvent implements Parcelable {
|
||||
throw new IllegalArgumentException("Unexpected input event type in parcel.");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
VerifiedInputEvent that = (VerifiedInputEvent) o;
|
||||
return mType == that.mType
|
||||
&& getDeviceId() == that.getDeviceId()
|
||||
&& getEventTimeNanos() == that.getEventTimeNanos()
|
||||
&& getSource() == that.getSource()
|
||||
&& getDisplayId() == that.getDisplayId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int _hash = 1;
|
||||
_hash = 31 * _hash + mType;
|
||||
_hash = 31 * _hash + getDeviceId();
|
||||
_hash = 31 * _hash + Long.hashCode(getEventTimeNanos());
|
||||
_hash = 31 * _hash + getSource();
|
||||
_hash = 31 * _hash + getDisplayId();
|
||||
return _hash;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.view;
|
||||
|
||||
import static android.view.KeyEvent.FLAG_CANCELED;
|
||||
import static android.view.KeyEvent.FLAG_IS_ACCESSIBILITY_EVENT;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
@@ -72,6 +73,7 @@ public final class VerifiedKeyEvent extends VerifiedInputEvent implements Parcel
|
||||
*
|
||||
* @see KeyEvent#getFlags()
|
||||
* @see KeyEvent#FLAG_CANCELED
|
||||
* @see KeyEvent#FLAG_IS_ACCESSIBILITY_EVENT
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -125,6 +127,7 @@ public final class VerifiedKeyEvent extends VerifiedInputEvent implements Parcel
|
||||
// InputDispatcher only verifies a subset of the KeyEvent flags.
|
||||
// These values must be kept in sync with Input.cpp
|
||||
case FLAG_CANCELED:
|
||||
case FLAG_IS_ACCESSIBILITY_EVENT:
|
||||
return (mFlags & flag) != 0;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.view.MotionEvent.FLAG_IS_ACCESSIBILITY_EVENT;
|
||||
import static android.view.MotionEvent.FLAG_WINDOW_IS_OBSCURED;
|
||||
import static android.view.MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
|
||||
|
||||
@@ -83,6 +84,9 @@ public final class VerifiedMotionEvent extends VerifiedInputEvent implements Par
|
||||
* Returns the flags for this motion event.
|
||||
*
|
||||
* @see MotionEvent#getFlags()
|
||||
* @see MotionEvent#FLAG_IS_ACCESSIBILITY_EVENT
|
||||
* @see MotionEvent#FLAG_WINDOW_IS_OBSCURED
|
||||
* @see MotionEvent#FLAG_WINDOW_IS_PARTIALLY_OBSCURED
|
||||
* @hide
|
||||
*/
|
||||
private int mFlags;
|
||||
@@ -117,6 +121,7 @@ public final class VerifiedMotionEvent extends VerifiedInputEvent implements Par
|
||||
switch(flag) {
|
||||
// InputDispatcher only verifies a subset of the MotionEvent flags.
|
||||
// These values must be kept in sync with Input.cpp
|
||||
case FLAG_IS_ACCESSIBILITY_EVENT:
|
||||
case FLAG_WINDOW_IS_OBSCURED:
|
||||
case FLAG_WINDOW_IS_PARTIALLY_OBSCURED:
|
||||
return (mFlags & flag) != 0;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package android.view;
|
||||
|
||||
import static android.os.IInputConstants.POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY;
|
||||
import static android.os.IInputConstants.POLICY_FLAG_INPUTFILTER_TRUSTED;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.os.PowerManager;
|
||||
@@ -35,7 +34,6 @@ public interface WindowManagerPolicyConstants {
|
||||
int FLAG_WAKE = 0x00000001;
|
||||
int FLAG_VIRTUAL = 0x00000002;
|
||||
|
||||
int FLAG_INPUTFILTER_TRUSTED = POLICY_FLAG_INPUTFILTER_TRUSTED;
|
||||
int FLAG_INJECTED_FROM_ACCESSIBILITY = POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY;
|
||||
int FLAG_INJECTED = 0x01000000;
|
||||
int FLAG_TRUSTED = 0x02000000;
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.view
|
||||
|
||||
import android.view.InputDevice.SOURCE_TOUCHSCREEN
|
||||
import android.view.MotionEvent.ACTION_MOVE
|
||||
import android.view.MotionEvent.FLAG_IS_ACCESSIBILITY_EVENT
|
||||
import android.view.MotionEvent.FLAG_WINDOW_IS_OBSCURED
|
||||
import android.view.MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED
|
||||
import android.view.MotionEvent.FLAG_TAINTED
|
||||
@@ -49,6 +50,7 @@ class VerifiedMotionEventTest {
|
||||
assertEquals(RAW_Y, event.rawY, 0f)
|
||||
assertEquals(ACTION_MASKED, event.actionMasked)
|
||||
assertEquals(DOWN_TIME_NANOS, event.downTimeNanos)
|
||||
assertEquals(FLAGS, event.flags)
|
||||
assertEquals(META_STATE, event.metaState)
|
||||
assertEquals(BUTTON_STATE, event.buttonState)
|
||||
}
|
||||
@@ -128,8 +130,9 @@ class VerifiedMotionEventTest {
|
||||
assertNull(motionEvent.getFlag(0))
|
||||
// Flag that was not set
|
||||
assertEquals(false, motionEvent.getFlag(FLAG_WINDOW_IS_PARTIALLY_OBSCURED))
|
||||
// Flag that was set
|
||||
// Flags that were set
|
||||
assertEquals(true, motionEvent.getFlag(FLAG_WINDOW_IS_OBSCURED))
|
||||
assertEquals(true, motionEvent.getFlag(FLAG_IS_ACCESSIBILITY_EVENT))
|
||||
// Only 1 flag at a time is accepted
|
||||
assertNull(motionEvent.getFlag(
|
||||
FLAG_WINDOW_IS_PARTIALLY_OBSCURED or FLAG_WINDOW_IS_OBSCURED))
|
||||
@@ -153,7 +156,7 @@ class VerifiedMotionEventTest {
|
||||
private const val RAW_Y = 200f
|
||||
private const val ACTION_MASKED = ACTION_MOVE
|
||||
private const val DOWN_TIME_NANOS: Long = 1000
|
||||
private const val FLAGS = FLAG_WINDOW_IS_OBSCURED
|
||||
private const val FLAGS = FLAG_WINDOW_IS_OBSCURED or FLAG_IS_ACCESSIBILITY_EVENT
|
||||
private const val META_STATE = 11
|
||||
private const val BUTTON_STATE = 22
|
||||
|
||||
@@ -178,6 +181,7 @@ class VerifiedMotionEventTest {
|
||||
assertEquals(event1.rawY, event2.rawY, 0f)
|
||||
assertEquals(event1.actionMasked, event2.actionMasked)
|
||||
assertEquals(event1.downTimeNanos, event2.downTimeNanos)
|
||||
assertEquals(event1.flags, event2.flags)
|
||||
assertEquals(event1.metaState, event2.metaState)
|
||||
assertEquals(event1.buttonState, event2.buttonState)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowManagerPolicyConstants;
|
||||
|
||||
@@ -55,7 +56,6 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement
|
||||
*/
|
||||
private static final int EVENT_META_STATE = 0;
|
||||
private static final int EVENT_BUTTON_STATE = 0;
|
||||
private static final int EVENT_DEVICE_ID = 0;
|
||||
private static final int EVENT_EDGE_FLAGS = 0;
|
||||
private static final int EVENT_SOURCE = InputDevice.SOURCE_TOUCHSCREEN;
|
||||
private static final int EVENT_FLAGS = 0;
|
||||
@@ -122,9 +122,6 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement
|
||||
return;
|
||||
}
|
||||
cancelAnyPendingInjectedEvents();
|
||||
// The events injected from outside of system_server are not trusted. Remove the flag to
|
||||
// prevent accessibility service from impersonating a real input device.
|
||||
policyFlags &= ~WindowManagerPolicyConstants.FLAG_INPUTFILTER_TRUSTED;
|
||||
// Indicate that the input event is injected from accessibility, to let applications
|
||||
// distinguish it from events injected by other means.
|
||||
policyFlags |= WindowManagerPolicyConstants.FLAG_INJECTED_FROM_ACCESSIBILITY;
|
||||
@@ -483,8 +480,8 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement
|
||||
}
|
||||
return MotionEvent.obtain(downTime, eventTime, action, touchPointsSize,
|
||||
sPointerProps, sPointerCoords, EVENT_META_STATE, EVENT_BUTTON_STATE,
|
||||
EVENT_X_PRECISION, EVENT_Y_PRECISION, EVENT_DEVICE_ID, EVENT_EDGE_FLAGS,
|
||||
EVENT_SOURCE, EVENT_FLAGS);
|
||||
EVENT_X_PRECISION, EVENT_Y_PRECISION, KeyCharacterMap.VIRTUAL_KEYBOARD,
|
||||
EVENT_EDGE_FLAGS, EVENT_SOURCE, EVENT_FLAGS);
|
||||
}
|
||||
|
||||
private static int findPointByStrokeId(TouchPoint[] touchPoints, int touchPointsSize,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.accessibility;
|
||||
|
||||
import static android.view.KeyCharacterMap.VIRTUAL_KEYBOARD;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_HOVER_MOVE;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
@@ -112,6 +113,13 @@ public class MotionEventInjectorTest {
|
||||
private static final int CONTINUED_LINE_SEQUENCE_1 = 52;
|
||||
private static final int CONTINUED_LINE_SEQUENCE_2 = 53;
|
||||
|
||||
private static final float PRESSURE = 1;
|
||||
private static final float X_PRECISION = 1;
|
||||
private static final float Y_PRECISION = 1;
|
||||
private static final int EDGEFLAGS = 0;
|
||||
private static final float POINTER_SIZE = 1;
|
||||
private static final int METASTATE = 0;
|
||||
|
||||
MotionEventInjector mMotionEventInjector;
|
||||
IAccessibilityServiceClient mServiceInterface;
|
||||
List<GestureStep> mLineList = new ArrayList<>();
|
||||
@@ -152,14 +160,18 @@ public class MotionEventInjectorTest {
|
||||
CONTINUED_LINE_STROKE_ID_1, false, CONTINUED_LINE_INTERVAL, CONTINUED_LINE_MID1,
|
||||
CONTINUED_LINE_MID2, CONTINUED_LINE_END);
|
||||
|
||||
mClickDownEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, CLICK_POINT.x, CLICK_POINT.y, 0);
|
||||
mClickDownEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, CLICK_POINT.x, CLICK_POINT.y,
|
||||
PRESSURE, POINTER_SIZE, METASTATE, X_PRECISION, Y_PRECISION, VIRTUAL_KEYBOARD,
|
||||
EDGEFLAGS);
|
||||
mClickDownEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
|
||||
mClickUpEvent = MotionEvent.obtain(0, CLICK_DURATION, ACTION_UP, CLICK_POINT.x,
|
||||
CLICK_POINT.y, 0);
|
||||
CLICK_POINT.y, PRESSURE, POINTER_SIZE, METASTATE, X_PRECISION, Y_PRECISION,
|
||||
VIRTUAL_KEYBOARD, EDGEFLAGS);
|
||||
mClickUpEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
|
||||
|
||||
mHoverMoveEvent = MotionEvent.obtain(0, 0, ACTION_HOVER_MOVE, CLICK_POINT.x, CLICK_POINT.y,
|
||||
0);
|
||||
PRESSURE, POINTER_SIZE, METASTATE, X_PRECISION, Y_PRECISION, VIRTUAL_KEYBOARD,
|
||||
EDGEFLAGS);
|
||||
mHoverMoveEvent.setSource(InputDevice.SOURCE_MOUSE);
|
||||
|
||||
mIsLineStart = allOf(IS_ACTION_DOWN, isAtPoint(LINE_START), hasStandardInitialization(),
|
||||
@@ -874,12 +886,14 @@ public class MotionEventInjectorTest {
|
||||
return new TypeSafeMatcher<MotionEvent>() {
|
||||
@Override
|
||||
protected boolean matchesSafely(MotionEvent event) {
|
||||
return (0 == event.getActionIndex()) && (0 == event.getDeviceId())
|
||||
&& (0 == event.getEdgeFlags()) && (0 == event.getFlags())
|
||||
&& (0 == event.getMetaState()) && (0F == event.getOrientation())
|
||||
return (0 == event.getActionIndex()) && (VIRTUAL_KEYBOARD == event.getDeviceId())
|
||||
&& (EDGEFLAGS == event.getEdgeFlags()) && (0 == event.getFlags())
|
||||
&& (METASTATE == event.getMetaState()) && (0F == event.getOrientation())
|
||||
&& (0F == event.getTouchMajor()) && (0F == event.getTouchMinor())
|
||||
&& (1F == event.getXPrecision()) && (1F == event.getYPrecision())
|
||||
&& (1 == event.getPointerCount()) && (1F == event.getPressure())
|
||||
&& (X_PRECISION == event.getXPrecision())
|
||||
&& (Y_PRECISION == event.getYPrecision())
|
||||
&& (POINTER_SIZE == event.getSize())
|
||||
&& (1 == event.getPointerCount()) && (PRESSURE == event.getPressure())
|
||||
&& (InputDevice.SOURCE_TOUCHSCREEN == event.getSource());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user