Define MotionEventFlag as an AIDL enum
This allows us to loop through all enum values defined in AIDL in native
code in a unit test to verify that they are all redefined in various
languages. This will help catch missed flag redefinitions in presubmit
rather than as runtime crashes.
Bug: 346613247
Test: libinput_rust_test
Flag: NONE no behavior change
Change-Id: I48c5119e28a91315c3bbc561616eb48750bfb804
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index d782f42..c2a7ebb 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -30,6 +30,7 @@
"android/os/InputEventInjectionResult.aidl",
"android/os/InputEventInjectionSync.aidl",
"android/os/InputConfig.aidl",
+ "android/os/MotionEventFlag.aidl",
"android/os/PointerIconType.aidl",
],
}
diff --git a/libs/input/android/os/IInputConstants.aidl b/libs/input/android/os/IInputConstants.aidl
index a77dfa5..e23fc94 100644
--- a/libs/input/android/os/IInputConstants.aidl
+++ b/libs/input/android/os/IInputConstants.aidl
@@ -49,130 +49,24 @@
const int POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY = 0x20000;
/**
- * This flag indicates that the window that received this motion event is partly
- * or wholly obscured by another visible window above it and the event directly passed through
- * the obscured area.
- *
- * A security sensitive application can check this flag to identify situations in which
- * a malicious application may have covered up part of its content for the purpose
- * of misleading the user or hijacking touches. An appropriate response might be
- * to drop the suspect touches or to take additional precautions to confirm the user's
- * actual intent.
- */
- const int MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1;
-
- /**
- * This flag indicates that the window that received this motion event is partly
- * or wholly obscured by another visible window above it and the event did not directly pass
- * through the obscured area.
- *
- * A security sensitive application can check this flag to identify situations in which
- * a malicious application may have covered up part of its content for the purpose
- * of misleading the user or hijacking touches. An appropriate response might be
- * to drop the suspect touches or to take additional precautions to confirm the user's
- * actual intent.
- *
- * Unlike FLAG_WINDOW_IS_OBSCURED, this is only true if the window that received this event is
- * obstructed in areas other than the touched location.
- */
- const int MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2;
-
- /**
- * This private flag is only set on {@link #ACTION_HOVER_MOVE} events and indicates that
- * this event will be immediately followed by a {@link #ACTION_HOVER_EXIT}. It is used to
- * prevent generating redundant {@link #ACTION_HOVER_ENTER} events.
- * @hide
- */
- const int MOTION_EVENT_FLAG_HOVER_EXIT_PENDING = 0x4;
-
- /**
- * This flag indicates that the event has been generated by a gesture generator. It
- * provides a hint to the GestureDetector to not apply any touch slop.
- *
- * @hide
- */
- const int MOTION_EVENT_FLAG_IS_GENERATED_GESTURE = 0x8;
-
- /**
- * This flag is only set for events with {@link #ACTION_POINTER_UP} and {@link #ACTION_CANCEL}.
- * It indicates that the pointer going up was an unintentional user touch. When FLAG_CANCELED
- * is set, the typical actions that occur in response for a pointer going up (such as click
- * handlers, end of drawing) should be aborted. This flag is typically set when the user was
- * accidentally touching the screen, such as by gripping the device, or placing the palm on the
- * screen.
- *
- * @see #ACTION_POINTER_UP
- * @see #ACTION_CANCEL
+ * Common input event flag used for both motion and key events for a gesture or pointer being
+ * canceled.
*/
const int INPUT_EVENT_FLAG_CANCELED = 0x20;
/**
- * This flag indicates that the event will not cause a focus change if it is directed to an
- * unfocused window, even if it an {@link #ACTION_DOWN}. This is typically used with pointer
- * gestures to allow the user to direct gestures to an unfocused window without bringing the
- * window into focus.
- * @hide
- */
- const int MOTION_EVENT_FLAG_NO_FOCUS_CHANGE = 0x40;
-
- /**
- * This flag indicates that the event has a valid value for AXIS_ORIENTATION.
- *
- * This is a private flag that is not used in Java.
- * @hide
- */
- const int MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION = 0x80;
-
- /**
- * This flag indicates that the pointers' AXIS_ORIENTATION can be used to precisely determine
- * the direction in which the tool is pointing. The value of the orientation axis will be in
- * the range [-pi, pi], which represents a full circle. This is usually supported by devices
- * like styluses.
- *
- * Conversely, AXIS_ORIENTATION cannot be used to tell which direction the tool is pointing
- * when this flag is not set. In this case, the axis value will have a range of [-pi/2, pi/2],
- * which represents half a circle. This is usually the case for devices like touchscreens and
- * touchpads, for which it is difficult to tell which direction along the major axis of the
- * touch ellipse the finger is pointing.
- *
- * This is a private flag that is not used in Java.
- * @hide
- */
- const int MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = 0x100;
-
- /**
- * The input event was generated or modified by accessibility service.
- * Shared by both KeyEvent and MotionEvent flags, so this value should not overlap with either
- * set of flags, including in input/Input.h and in android/input.h.
+ * Common input event flag used for both motion and key events, indicating that the event
+ * was generated or modified by accessibility service.
*/
const int INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT = 0x800;
/**
- * 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.
- *
- * @hide
- * @see #isTainted
- * @see #setTainted
+ * Common input event flag used for both motion and key events, indicating that the system has
+ * detected this event may be inconsistent with the current event sequence or gesture, such as
+ * when a pointer move event is sent but the pointer is not down.
*/
const int INPUT_EVENT_FLAG_TAINTED = 0x80000000;
- /**
- * Private flag indicating that this event was synthesized by the system and should be delivered
- * to the accessibility focused view first. When being dispatched such an event is not handled
- * by predecessors of the accessibility focused view and after the event reaches that view the
- * flag is cleared and normal event dispatch is performed. This ensures that the platform can
- * click on any view that has accessibility focus which is semantically equivalent to asking the
- * view to perform a click accessibility action but more generic as views not implementing click
- * action correctly can still be activated.
- *
- * @hide
- * @see #isTargetAccessibilityFocus()
- * @see #setTargetAccessibilityFocus(boolean)
- */
- const int MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS = 0x40000000;
-
/* The default pointer acceleration value. */
const int DEFAULT_POINTER_ACCELERATION = 3;
diff --git a/libs/input/android/os/MotionEventFlag.aidl b/libs/input/android/os/MotionEventFlag.aidl
new file mode 100644
index 0000000..2093b06
--- /dev/null
+++ b/libs/input/android/os/MotionEventFlag.aidl
@@ -0,0 +1,152 @@
+/**
+ * Copyright 2024, 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.os;
+
+import android.os.IInputConstants;
+
+/**
+ * Flag definitions for MotionEvents.
+ * @hide
+ */
+@Backing(type="int")
+enum MotionEventFlag {
+
+ /**
+ * This flag indicates that the window that received this motion event is partly
+ * or wholly obscured by another visible window above it and the event directly passed through
+ * the obscured area.
+ *
+ * A security sensitive application can check this flag to identify situations in which
+ * a malicious application may have covered up part of its content for the purpose
+ * of misleading the user or hijacking touches. An appropriate response might be
+ * to drop the suspect touches or to take additional precautions to confirm the user's
+ * actual intent.
+ */
+ WINDOW_IS_OBSCURED = 0x1,
+
+ /**
+ * This flag indicates that the window that received this motion event is partly
+ * or wholly obscured by another visible window above it and the event did not directly pass
+ * through the obscured area.
+ *
+ * A security sensitive application can check this flag to identify situations in which
+ * a malicious application may have covered up part of its content for the purpose
+ * of misleading the user or hijacking touches. An appropriate response might be
+ * to drop the suspect touches or to take additional precautions to confirm the user's
+ * actual intent.
+ *
+ * Unlike FLAG_WINDOW_IS_OBSCURED, this is only true if the window that received this event is
+ * obstructed in areas other than the touched location.
+ */
+ WINDOW_IS_PARTIALLY_OBSCURED = 0x2,
+
+ /**
+ * This private flag is only set on {@link #ACTION_HOVER_MOVE} events and indicates that
+ * this event will be immediately followed by a {@link #ACTION_HOVER_EXIT}. It is used to
+ * prevent generating redundant {@link #ACTION_HOVER_ENTER} events.
+ * @hide
+ */
+ HOVER_EXIT_PENDING = 0x4,
+
+ /**
+ * This flag indicates that the event has been generated by a gesture generator. It
+ * provides a hint to the GestureDetector to not apply any touch slop.
+ *
+ * @hide
+ */
+ IS_GENERATED_GESTURE = 0x8,
+
+ /**
+ * This flag is only set for events with {@link #ACTION_POINTER_UP} and {@link #ACTION_CANCEL}.
+ * It indicates that the pointer going up was an unintentional user touch. When FLAG_CANCELED
+ * is set, the typical actions that occur in response for a pointer going up (such as click
+ * handlers, end of drawing) should be aborted. This flag is typically set when the user was
+ * accidentally touching the screen, such as by gripping the device, or placing the palm on the
+ * screen.
+ *
+ * @see #ACTION_POINTER_UP
+ * @see #ACTION_CANCEL
+ */
+ CANCELED = IInputConstants.INPUT_EVENT_FLAG_CANCELED,
+
+ /**
+ * This flag indicates that the event will not cause a focus change if it is directed to an
+ * unfocused window, even if it an {@link #ACTION_DOWN}. This is typically used with pointer
+ * gestures to allow the user to direct gestures to an unfocused window without bringing the
+ * window into focus.
+ * @hide
+ */
+ NO_FOCUS_CHANGE = 0x40,
+
+ /**
+ * This flag indicates that the event has a valid value for AXIS_ORIENTATION.
+ *
+ * This is a private flag that is not used in Java.
+ * @hide
+ */
+ PRIVATE_FLAG_SUPPORTS_ORIENTATION = 0x80,
+
+ /**
+ * This flag indicates that the pointers' AXIS_ORIENTATION can be used to precisely determine
+ * the direction in which the tool is pointing. The value of the orientation axis will be in
+ * the range [-pi, pi], which represents a full circle. This is usually supported by devices
+ * like styluses.
+ *
+ * Conversely, AXIS_ORIENTATION cannot be used to tell which direction the tool is pointing
+ * when this flag is not set. In this case, the axis value will have a range of [-pi/2, pi/2],
+ * which represents half a circle. This is usually the case for devices like touchscreens and
+ * touchpads, for which it is difficult to tell which direction along the major axis of the
+ * touch ellipse the finger is pointing.
+ *
+ * This is a private flag that is not used in Java.
+ * @hide
+ */
+ PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = 0x100,
+
+ /**
+ * The input event was generated or modified by accessibility service.
+ * Shared by both KeyEvent and MotionEvent flags, so this value should not overlap with either
+ * set of flags, including in input/Input.h and in android/input.h.
+ */
+ IS_ACCESSIBILITY_EVENT = IInputConstants.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.
+ *
+ * @hide
+ * @see #isTainted
+ * @see #setTainted
+ */
+ TAINTED = IInputConstants.INPUT_EVENT_FLAG_TAINTED,
+
+ /**
+ * Private flag indicating that this event was synthesized by the system and should be delivered
+ * to the accessibility focused view first. When being dispatched such an event is not handled
+ * by predecessors of the accessibility focused view and after the event reaches that view the
+ * flag is cleared and normal event dispatch is performed. This ensures that the platform can
+ * click on any view that has accessibility focus which is semantically equivalent to asking the
+ * view to perform a click accessibility action but more generic as views not implementing click
+ * action correctly can still be activated.
+ *
+ * @hide
+ * @see #isTargetAccessibilityFocus()
+ * @see #setTargetAccessibilityFocus(boolean)
+ */
+ TARGET_ACCESSIBILITY_FOCUS = 0x40000000,
+}
diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs
index 564d94d..c46b7bb 100644
--- a/libs/input/rust/input.rs
+++ b/libs/input/rust/input.rs
@@ -19,6 +19,7 @@
use crate::ffi::RustInputDeviceIdentifier;
use bitflags::bitflags;
use inputconstants::aidl::android::os::IInputConstants;
+use inputconstants::aidl::android::os::MotionEventFlag::MotionEventFlag;
use std::fmt;
/// The InputDevice ID.
@@ -193,31 +194,34 @@
bitflags! {
/// MotionEvent flags.
+ /// The source of truth for the flag definitions are the MotionEventFlag AIDL enum.
+ /// The flag values are redefined here as a bitflags API.
#[derive(Debug)]
pub struct MotionFlags: u32 {
/// FLAG_WINDOW_IS_OBSCURED
- const WINDOW_IS_OBSCURED = IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED as u32;
+ const WINDOW_IS_OBSCURED = MotionEventFlag::WINDOW_IS_OBSCURED.0 as u32;
/// FLAG_WINDOW_IS_PARTIALLY_OBSCURED
- const WINDOW_IS_PARTIALLY_OBSCURED = IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED as u32;
+ const WINDOW_IS_PARTIALLY_OBSCURED = MotionEventFlag::WINDOW_IS_PARTIALLY_OBSCURED.0 as u32;
/// FLAG_HOVER_EXIT_PENDING
- const HOVER_EXIT_PENDING = IInputConstants::MOTION_EVENT_FLAG_HOVER_EXIT_PENDING as u32;
+ const HOVER_EXIT_PENDING = MotionEventFlag::HOVER_EXIT_PENDING.0 as u32;
/// FLAG_IS_GENERATED_GESTURE
- const IS_GENERATED_GESTURE = IInputConstants::MOTION_EVENT_FLAG_IS_GENERATED_GESTURE as u32;
+ const IS_GENERATED_GESTURE = MotionEventFlag::IS_GENERATED_GESTURE.0 as u32;
/// FLAG_CANCELED
- const CANCELED = IInputConstants::INPUT_EVENT_FLAG_CANCELED as u32;
+ const CANCELED = MotionEventFlag::CANCELED.0 as u32;
/// FLAG_NO_FOCUS_CHANGE
- const NO_FOCUS_CHANGE = IInputConstants::MOTION_EVENT_FLAG_NO_FOCUS_CHANGE as u32;
+ const NO_FOCUS_CHANGE = MotionEventFlag::NO_FOCUS_CHANGE.0 as u32;
/// PRIVATE_FLAG_SUPPORTS_ORIENTATION
- const PRIVATE_SUPPORTS_ORIENTATION = IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION as u32;
+ const PRIVATE_FLAG_SUPPORTS_ORIENTATION =
+ MotionEventFlag::PRIVATE_FLAG_SUPPORTS_ORIENTATION.0 as u32;
/// PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION
- const PRIVATE_SUPPORTS_DIRECTIONAL_ORIENTATION =
- IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION as u32;
+ const PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION =
+ MotionEventFlag::PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION.0 as u32;
/// FLAG_IS_ACCESSIBILITY_EVENT
- const IS_ACCESSIBILITY_EVENT = IInputConstants::INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT as u32;
+ const IS_ACCESSIBILITY_EVENT = MotionEventFlag::IS_ACCESSIBILITY_EVENT.0 as u32;
/// FLAG_TAINTED
- const TAINTED = IInputConstants::INPUT_EVENT_FLAG_TAINTED as u32;
+ const TAINTED = MotionEventFlag::TAINTED.0 as u32;
/// FLAG_TARGET_ACCESSIBILITY_FOCUS
- const TARGET_ACCESSIBILITY_FOCUS = IInputConstants::MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS as u32;
+ const TARGET_ACCESSIBILITY_FOCUS = MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS.0 as u32;
}
}
@@ -333,10 +337,24 @@
#[cfg(test)]
mod tests {
use crate::input::SourceClass;
+ use crate::MotionFlags;
use crate::Source;
+ use inputconstants::aidl::android::os::MotionEventFlag::MotionEventFlag;
+
#[test]
fn convert_source_class_pointer() {
let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
assert!(source.is_from_class(SourceClass::Pointer));
}
+
+ /// Ensure all MotionEventFlag constants are re-defined in rust.
+ #[test]
+ fn all_motion_event_flags_defined() {
+ for flag in MotionEventFlag::enum_values() {
+ assert!(
+ MotionFlags::from_bits(flag.0 as u32).is_some(),
+ "MotionEventFlag value {flag:?} is not redefined as a rust MotionFlags"
+ );
+ }
+ }
}