summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/test-current.txt3
-rw-r--r--core/java/android/view/InputDevice.java7
-rw-r--r--core/java/android/view/KeyEvent.java9
-rw-r--r--core/java/android/view/MotionEvent.java9
-rw-r--r--core/java/android/view/VerifiedInputEvent.java25
-rw-r--r--core/java/android/view/VerifiedKeyEvent.java3
-rw-r--r--core/java/android/view/VerifiedMotionEvent.java5
-rw-r--r--core/java/android/view/WindowManagerPolicyConstants.java2
-rw-r--r--core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt8
-rw-r--r--services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java30
11 files changed, 84 insertions, 26 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a4ac61b1f086..cb60b011d00e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -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 {
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 782a992d28e5..4f1354d7eee6 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -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) {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 37f0a64df613..cda9b233576c 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -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;
@@ -1222,6 +1223,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
*/
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 0483d0ba7615..69ff64f3d6a5 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -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;
@@ -494,6 +495,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,
* such as when a pointer move event is sent but the pointer is not down.
diff --git a/core/java/android/view/VerifiedInputEvent.java b/core/java/android/view/VerifiedInputEvent.java
index e2db50165f77..cc6fbe7f5171 100644
--- a/core/java/android/view/VerifiedInputEvent.java
+++ b/core/java/android/view/VerifiedInputEvent.java
@@ -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;
+ }
}
diff --git a/core/java/android/view/VerifiedKeyEvent.java b/core/java/android/view/VerifiedKeyEvent.java
index 77a7d0944521..fc357cc9d278 100644
--- a/core/java/android/view/VerifiedKeyEvent.java
+++ b/core/java/android/view/VerifiedKeyEvent.java
@@ -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;
diff --git a/core/java/android/view/VerifiedMotionEvent.java b/core/java/android/view/VerifiedMotionEvent.java
index 7d8345928bf0..948575cf3104 100644
--- a/core/java/android/view/VerifiedMotionEvent.java
+++ b/core/java/android/view/VerifiedMotionEvent.java
@@ -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;
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 81c934dffa47..bbef3e6aeefa 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -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;
diff --git a/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt b/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt
index 2c4851f0ab4e..29ad0aa43672 100644
--- a/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt
+++ b/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt
@@ -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)
}
diff --git a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
index ea2c7d2a41e9..2673cd1ac3b8 100644
--- a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
+++ b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
@@ -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,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
index a71b481372d8..d4908ee78a1d 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
@@ -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());
}