diff options
-rw-r--r-- | include/android/input.h | 2 | ||||
-rw-r--r-- | include/input/InputVerifier.h | 5 | ||||
-rw-r--r-- | libs/input/Android.bp | 7 | ||||
-rw-r--r-- | libs/input/InputTransport.cpp | 6 | ||||
-rw-r--r-- | libs/input/InputVerifier.cpp | 9 | ||||
-rw-r--r-- | libs/input/rust/input.rs | 22 | ||||
-rw-r--r-- | libs/input/rust/input_verifier.rs | 641 | ||||
-rw-r--r-- | libs/input/rust/lib.rs | 26 | ||||
-rw-r--r-- | libs/input/tests/InputVerifier_test.cpp | 4 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 10 | ||||
-rw-r--r-- | services/inputflinger/reader/mapper/CursorInputMapper.h | 1 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 70 | ||||
-rw-r--r-- | services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp | 4 |
13 files changed, 31 insertions, 776 deletions
diff --git a/include/android/input.h b/include/android/input.h index 5f445509fa..ee98d7aee9 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -849,7 +849,6 @@ enum { * Refer to the documentation on the MotionEvent class for descriptions of each button. */ enum { - // LINT.IfChange(AMOTION_EVENT_BUTTON) /** primary */ AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0, /** secondary */ @@ -862,7 +861,6 @@ enum { AMOTION_EVENT_BUTTON_FORWARD = 1 << 4, AMOTION_EVENT_BUTTON_STYLUS_PRIMARY = 1 << 5, AMOTION_EVENT_BUTTON_STYLUS_SECONDARY = 1 << 6, - // LINT.ThenChange(/frameworks/native/libs/input/rust/input.rs) }; /** diff --git a/include/input/InputVerifier.h b/include/input/InputVerifier.h index 7d3fb469c6..14dd463425 100644 --- a/include/input/InputVerifier.h +++ b/include/input/InputVerifier.h @@ -47,10 +47,9 @@ public: InputVerifier(const std::string& name); android::base::Result<void> processMovement(int32_t deviceId, int32_t source, int32_t action, - int32_t actionButton, uint32_t pointerCount, + uint32_t pointerCount, const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords, int32_t flags, - int32_t buttonState); + const PointerCoords* pointerCoords, int32_t flags); void resetDevice(int32_t deviceId); diff --git a/libs/input/Android.bp b/libs/input/Android.bp index d9c10ad678..389fb7f6ab 100644 --- a/libs/input/Android.bp +++ b/libs/input/Android.bp @@ -91,13 +91,6 @@ rust_bindgen { "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_DOWN", "--allowlist-var=AMOTION_EVENT_ACTION_DOWN", "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT", - "--allowlist-var=AMOTION_EVENT_BUTTON_PRIMARY", - "--allowlist-var=AMOTION_EVENT_BUTTON_SECONDARY", - "--allowlist-var=AMOTION_EVENT_BUTTON_TERTIARY", - "--allowlist-var=AMOTION_EVENT_BUTTON_BACK", - "--allowlist-var=AMOTION_EVENT_BUTTON_FORWARD", - "--allowlist-var=AMOTION_EVENT_BUTTON_STYLUS_PRIMARY", - "--allowlist-var=AMOTION_EVENT_BUTTON_STYLUS_SECONDARY", "--allowlist-var=MAX_POINTER_ID", "--allowlist-var=AINPUT_SOURCE_CLASS_NONE", "--allowlist-var=AINPUT_SOURCE_CLASS_BUTTON", diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index d388d48e8d..56ccaab9ad 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -651,9 +651,9 @@ status_t InputPublisher::publishMotionEvent( const status_t status = mChannel->sendMessage(&msg); if (status == OK && verifyEvents()) { - Result<void> result = mInputVerifier.processMovement(deviceId, source, action, actionButton, - pointerCount, pointerProperties, - pointerCoords, flags, buttonState); + Result<void> result = + mInputVerifier.processMovement(deviceId, source, action, pointerCount, + pointerProperties, pointerCoords, flags); if (!result.ok()) { LOG(ERROR) << "Bad stream: " << result.error(); return BAD_VALUE; diff --git a/libs/input/InputVerifier.cpp b/libs/input/InputVerifier.cpp index e8d4c733bd..cec244539e 100644 --- a/libs/input/InputVerifier.cpp +++ b/libs/input/InputVerifier.cpp @@ -34,10 +34,9 @@ InputVerifier::InputVerifier(const std::string& name) : mVerifier(android::input::verifier::create(rust::String::lossy(name))){}; Result<void> InputVerifier::processMovement(DeviceId deviceId, int32_t source, int32_t action, - int32_t actionButton, uint32_t pointerCount, + uint32_t pointerCount, const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords, int32_t flags, - int32_t buttonState) { + const PointerCoords* pointerCoords, int32_t flags) { std::vector<RustPointerProperties> rpp; for (size_t i = 0; i < pointerCount; i++) { rpp.emplace_back(RustPointerProperties{.id = pointerProperties[i].id}); @@ -45,9 +44,7 @@ Result<void> InputVerifier::processMovement(DeviceId deviceId, int32_t source, i rust::Slice<const RustPointerProperties> properties{rpp.data(), rpp.size()}; rust::String errorMessage = android::input::verifier::process_movement(*mVerifier, deviceId, source, action, - actionButton, properties, - static_cast<uint32_t>(flags), - static_cast<uint32_t>(buttonState)); + properties, static_cast<uint32_t>(flags)); if (errorMessage.empty()) { return {}; } else { diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs index 5e487ab946..90f509d97f 100644 --- a/libs/input/rust/input.rs +++ b/libs/input/rust/input.rs @@ -101,7 +101,6 @@ bitflags! { /// A rust enum representation of a MotionEvent action. #[repr(u32)] -#[derive(PartialEq)] pub enum MotionAction { /// ACTION_DOWN Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN, @@ -195,27 +194,6 @@ impl MotionAction { } bitflags! { - /// MotionEvent buttons. - #[derive(Clone, Copy, Debug, Default, PartialEq)] - pub struct MotionButton: u32 { - /// Primary button (e.g. the left mouse button) - const Primary = input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY; - /// Secondary button (e.g. the right mouse button) - const Secondary = input_bindgen::AMOTION_EVENT_BUTTON_SECONDARY; - /// Tertiary button (e.g. the middle mouse button) - const Tertiary = input_bindgen::AMOTION_EVENT_BUTTON_TERTIARY; - /// Back button - const Back = input_bindgen::AMOTION_EVENT_BUTTON_BACK; - /// Forward button - const Forward = input_bindgen::AMOTION_EVENT_BUTTON_FORWARD; - /// Primary stylus button - const StylusPrimary = input_bindgen::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY; - /// Secondary stylus button - const StylusSecondary = input_bindgen::AMOTION_EVENT_BUTTON_STYLUS_SECONDARY; - } -} - -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. diff --git a/libs/input/rust/input_verifier.rs b/libs/input/rust/input_verifier.rs index 55dc56f6e3..b1d7760682 100644 --- a/libs/input/rust/input_verifier.rs +++ b/libs/input/rust/input_verifier.rs @@ -17,14 +17,13 @@ //! Contains the InputVerifier, used to validate a stream of input events. use crate::ffi::RustPointerProperties; -use crate::input::{DeviceId, MotionAction, MotionButton, MotionFlags, Source, SourceClass}; +use crate::input::{DeviceId, MotionAction, MotionFlags, Source, SourceClass}; use log::info; use std::collections::HashMap; use std::collections::HashSet; fn verify_event( action: MotionAction, - action_button: MotionButton, pointer_properties: &[RustPointerProperties], flags: &MotionFlags, ) -> Result<(), String> { @@ -32,14 +31,6 @@ fn verify_event( if pointer_count < 1 { return Err(format!("Invalid {} event: no pointers", action)); } - if action_button != MotionButton::empty() - && action != MotionAction::ButtonPress - && action != MotionAction::ButtonRelease - { - return Err(format!( - "Invalid {action} event: has action button {action_button:?} but is not a button action" - )); - } match action { MotionAction::Down | MotionAction::HoverEnter @@ -69,118 +60,17 @@ fn verify_event( } } - MotionAction::ButtonPress | MotionAction::ButtonRelease => { - let button_count = action_button.iter().count(); - if button_count != 1 { - return Err(format!( - "Invalid {action} event: must specify a single action button, not \ - {button_count} action buttons" - )); - } - } - _ => {} } Ok(()) } -/// Keeps track of the button state for a single device and verifies events against it. -#[derive(Default)] -struct ButtonVerifier { - /// The current button state of the device. - button_state: MotionButton, - - /// The set of "pending buttons", which were seen in the last DOWN event's button state but - /// for which we haven't seen BUTTON_PRESS events yet. - /// - /// We allow DOWN events to include buttons in their state for which BUTTON_PRESS events haven't - /// been sent yet. In that case, the DOWN should be immediately followed by BUTTON_PRESS events - /// for those buttons, building up to a button state matching that of the DOWN. For example, if - /// the user presses the primary and secondary buttons at exactly the same time, we'd expect - /// this sequence: - /// - /// | Action | Action button | Button state | - /// |----------------|---------------|------------------------| - /// | `HOVER_EXIT` | - | - | - /// | `DOWN` | - | `PRIMARY`, `SECONDARY` | - /// | `BUTTON_PRESS` | `PRIMARY` | `PRIMARY` | - /// | `BUTTON_PRESS` | `SECONDARY` | `PRIMARY`, `SECONDARY` | - /// | `MOVE` | - | `PRIMARY`, `SECONDARY` | - pending_buttons: MotionButton, -} - -impl ButtonVerifier { - pub fn process_action( - &mut self, - action: MotionAction, - action_button: MotionButton, - button_state: MotionButton, - ) -> Result<(), String> { - if !self.pending_buttons.is_empty() { - // We just saw a DOWN with some additional buttons in its state, so it should be - // immediately followed by ButtonPress events for those buttons. - if action != MotionAction::ButtonPress || !self.pending_buttons.contains(action_button) - { - return Err(format!( - "After DOWN event, expected BUTTON_PRESS event(s) for {:?}, but got {} with \ - action button {:?}", - self.pending_buttons, action, action_button - )); - } else { - self.pending_buttons -= action_button; - } - } - let expected_state = match action { - MotionAction::Down => { - if self.button_state - button_state != MotionButton::empty() { - return Err(format!( - "DOWN event button state is missing {:?}", - self.button_state - button_state - )); - } - self.pending_buttons = button_state - self.button_state; - // We've already checked that the state isn't missing any already-down buttons, and - // extra buttons are valid on DOWN actions, so bypass the expected state check. - button_state - } - MotionAction::ButtonPress => { - if self.button_state.contains(action_button) { - return Err(format!( - "Duplicate BUTTON_PRESS; button state already contains {action_button:?}" - )); - } - self.button_state | action_button - } - MotionAction::ButtonRelease => { - if !self.button_state.contains(action_button) { - return Err(format!( - "Invalid BUTTON_RELEASE; button state doesn't contain {action_button:?}" - )); - } - self.button_state - action_button - } - _ => self.button_state, - }; - if button_state != expected_state { - return Err(format!( - "Expected {action} button state to be {expected_state:?}, but was {button_state:?}" - )); - } - // DOWN events can have pending buttons, so don't update the state for them. - if action != MotionAction::Down { - self.button_state = button_state; - } - Ok(()) - } -} - /// The InputVerifier is used to validate a stream of input events. pub struct InputVerifier { name: String, should_log: bool, touching_pointer_ids_by_device: HashMap<DeviceId, HashSet<i32>>, hovering_pointer_ids_by_device: HashMap<DeviceId, HashSet<i32>>, - button_verifier_by_device: HashMap<DeviceId, ButtonVerifier>, } impl InputVerifier { @@ -196,22 +86,18 @@ impl InputVerifier { should_log, touching_pointer_ids_by_device: HashMap::new(), hovering_pointer_ids_by_device: HashMap::new(), - button_verifier_by_device: HashMap::new(), } } /// Process a pointer movement event from an InputDevice. /// If the event is not valid, we return an error string that describes the issue. - #[allow(clippy::too_many_arguments)] pub fn process_movement( &mut self, device_id: DeviceId, source: Source, action: u32, - action_button: MotionButton, pointer_properties: &[RustPointerProperties], flags: MotionFlags, - button_state: MotionButton, ) -> Result<(), String> { if !source.is_from_class(SourceClass::Pointer) { // Skip non-pointer sources like MOUSE_RELATIVE for now @@ -228,13 +114,7 @@ impl InputVerifier { ); } - verify_event(action.into(), action_button, pointer_properties, &flags)?; - - self.button_verifier_by_device.entry(device_id).or_default().process_action( - action.into(), - action_button, - button_state, - )?; + verify_event(action.into(), pointer_properties, &flags)?; match action.into() { MotionAction::Down => { @@ -408,7 +288,6 @@ impl InputVerifier { #[cfg(test)] mod tests { - use crate::input::MotionButton; use crate::input_verifier::InputVerifier; use crate::DeviceId; use crate::MotionFlags; @@ -428,10 +307,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_err()); } @@ -445,10 +322,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -456,10 +331,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -467,10 +340,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); } @@ -484,10 +355,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); // POINTER 1 DOWN @@ -499,10 +368,8 @@ mod tests { Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - MotionButton::empty(), &two_pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); // POINTER 0 UP @@ -512,10 +379,8 @@ mod tests { Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP | (0 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - MotionButton::empty(), &two_pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); // ACTION_UP for pointer id=1 @@ -525,10 +390,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), &pointer_1_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); } @@ -542,10 +405,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -553,10 +414,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -564,10 +423,8 @@ mod tests { DeviceId(2), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -575,10 +432,8 @@ mod tests { DeviceId(2), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -586,10 +441,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); } @@ -603,10 +456,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -614,10 +465,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_CANCEL, - MotionButton::empty(), &pointer_properties, MotionFlags::CANCELED, - MotionButton::empty(), ) .is_ok()); } @@ -631,10 +480,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); assert!(verifier @@ -642,10 +489,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_CANCEL, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), // forgot to set FLAG_CANCELED - MotionButton::empty(), ) .is_err()); } @@ -659,10 +504,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_err()); } @@ -676,10 +519,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); @@ -688,10 +529,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); @@ -700,10 +539,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); @@ -712,10 +549,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); } @@ -729,10 +564,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); @@ -741,10 +574,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_err()); } @@ -760,10 +591,8 @@ mod tests { DeviceId(2), Source::MouseRelative, input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); } @@ -778,10 +607,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); // POINTER 1 DOWN @@ -793,10 +620,8 @@ mod tests { Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - MotionButton::empty(), &two_pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_ok()); // MOVE event with 1 pointer missing (the pointer with id = 1). It should be rejected @@ -805,470 +630,8 @@ mod tests { DeviceId(1), Source::Touchscreen, input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_err()); - } - - #[test] - fn correct_button_press() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_ok()); - } - - #[test] - fn button_press_without_action_button() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_err()); - } - - #[test] - fn button_press_with_multiple_action_buttons() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Back | MotionButton::Forward, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back | MotionButton::Forward, - ) - .is_err()); - } - - #[test] - fn button_press_without_action_button_in_state() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_err()); - } - - #[test] - fn button_release_with_action_button_in_state() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_err()); - } - - #[test] - fn nonbutton_action_with_action_button() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_err()); - } - - #[test] - fn nonbutton_action_with_action_button_and_state() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_err()); - } - - #[test] - fn nonbutton_action_with_button_state_change() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back, - ) - .is_err()); - } - - #[test] - fn nonbutton_action_missing_button_state() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Back, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_err()); - } - - #[test] - fn up_without_button_release() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_ok()); - // This UP event shouldn't change the button state; a BUTTON_RELEASE before it should. - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_err()); - } - - #[test] - fn button_press_for_already_pressed_button() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Back, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Back, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back, - ) - .is_err()); - } - - #[test] - fn button_release_for_unpressed_button() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, - MotionButton::Back, - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) - .is_err()); - } - - #[test] - fn correct_multiple_button_presses_without_down() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Back, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Forward, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back | MotionButton::Forward, - ) - .is_ok()); - } - - #[test] - fn correct_down_with_button_press() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary | MotionButton::Secondary, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Secondary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary | MotionButton::Secondary, - ) - .is_ok()); - // Also check that the MOVE afterwards is OK, as that's where errors would be raised if not - // enough BUTTON_PRESSes were sent. - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary | MotionButton::Secondary, - ) - .is_ok()); - } - - #[test] - fn down_with_button_state_change_not_followed_by_button_press() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_ok()); - // The DOWN event itself is OK, but it needs to be immediately followed by a BUTTON_PRESS. - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_err()); - } - - #[test] - fn down_with_button_state_change_not_followed_by_enough_button_presses() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary | MotionButton::Secondary, - ) - .is_ok()); - // The DOWN event itself is OK, but it needs to be immediately followed by two - // BUTTON_PRESSes, one for each button. - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Primary, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) - .is_err()); - } - - #[test] - fn down_missing_already_pressed_button() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - MotionButton::Back, - &pointer_properties, - MotionFlags::empty(), - MotionButton::Back, - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), &pointer_properties, MotionFlags::empty(), - MotionButton::empty(), ) .is_err()); } diff --git a/libs/input/rust/lib.rs b/libs/input/rust/lib.rs index 1d5793bcb3..4f4ea8568b 100644 --- a/libs/input/rust/lib.rs +++ b/libs/input/rust/lib.rs @@ -24,8 +24,8 @@ mod keyboard_classifier; pub use data_store::{DataStore, DefaultFileReaderWriter}; pub use input::{ - DeviceClass, DeviceId, InputDevice, KeyboardType, ModifierState, MotionAction, MotionButton, - MotionFlags, Source, + DeviceClass, DeviceId, InputDevice, KeyboardType, ModifierState, MotionAction, MotionFlags, + Source, }; pub use input_verifier::InputVerifier; pub use keyboard_classifier::KeyboardClassifier; @@ -58,16 +58,13 @@ mod ffi { type InputVerifier; #[cxx_name = create] fn create_input_verifier(name: String) -> Box<InputVerifier>; - #[allow(clippy::too_many_arguments)] fn process_movement( verifier: &mut InputVerifier, device_id: i32, source: u32, action: u32, - action_button: u32, pointer_properties: &[RustPointerProperties], flags: u32, - button_state: u32, ) -> String; fn reset_device(verifier: &mut InputVerifier, device_id: i32); } @@ -122,16 +119,13 @@ fn create_input_verifier(name: String) -> Box<InputVerifier> { Box::new(InputVerifier::new(&name, ffi::shouldLog("InputVerifierLogEvents"))) } -#[allow(clippy::too_many_arguments)] fn process_movement( verifier: &mut InputVerifier, device_id: i32, source: u32, action: u32, - action_button: u32, pointer_properties: &[RustPointerProperties], flags: u32, - button_state: u32, ) -> String { let motion_flags = MotionFlags::from_bits(flags); if motion_flags.is_none() { @@ -141,28 +135,12 @@ fn process_movement( flags ); } - let motion_action_button = MotionButton::from_bits(action_button); - if motion_action_button.is_none() { - panic!( - "The conversion of action button 0x{action_button:08x} failed, please check if some \ - buttons need to be added to MotionButton." - ); - } - let motion_button_state = MotionButton::from_bits(button_state); - if motion_button_state.is_none() { - panic!( - "The conversion of button state 0x{button_state:08x} failed, please check if some \ - buttons need to be added to MotionButton." - ); - } let result = verifier.process_movement( DeviceId(device_id), Source::from_bits(source).unwrap(), action, - motion_action_button.unwrap(), pointer_properties, motion_flags.unwrap(), - motion_button_state.unwrap(), ); match result { Ok(()) => "".to_string(), diff --git a/libs/input/tests/InputVerifier_test.cpp b/libs/input/tests/InputVerifier_test.cpp index 8e0d9068c1..5bb1d56040 100644 --- a/libs/input/tests/InputVerifier_test.cpp +++ b/libs/input/tests/InputVerifier_test.cpp @@ -49,9 +49,9 @@ TEST(InputVerifierTest, ProcessSourceClassPointer) { const Result<void> result = verifier.processMovement(/*deviceId=*/0, AINPUT_SOURCE_CLASS_POINTER, - AMOTION_EVENT_ACTION_DOWN, /*actionButton=*/0, + AMOTION_EVENT_ACTION_DOWN, /*pointerCount=*/properties.size(), properties.data(), - coords.data(), /*flags=*/0, /*buttonState=*/0); + coords.data(), /*flags=*/0); ASSERT_RESULT_OK(result); } diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index a8cd7f9e25..4c4182d4c0 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -4541,9 +4541,8 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) { args.displayId.toString().c_str())); Result<void> result = it->second.processMovement(args.deviceId, args.source, args.action, - args.actionButton, args.getPointerCount(), - args.pointerProperties.data(), args.pointerCoords.data(), - args.flags, args.buttonState); + args.getPointerCount(), args.pointerProperties.data(), + args.pointerCoords.data(), args.flags); if (!result.ok()) { LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump(); } @@ -4744,10 +4743,9 @@ bool InputDispatcher::shouldRejectInjectedMotionLocked(const MotionEvent& motion Result<void> result = verifier.processMovement(deviceId, motionEvent.getSource(), motionEvent.getAction(), - motionEvent.getActionButton(), motionEvent.getPointerCount(), + motionEvent.getPointerCount(), motionEvent.getPointerProperties(), - motionEvent.getSamplePointerCoords(), flags, - motionEvent.getButtonState()); + motionEvent.getSamplePointerCoords(), flags); if (!result.ok()) { logDispatchStateLocked(); LOG(ERROR) << "Inconsistent event: " << motionEvent << ", reason: " << result.error(); diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h index 773619c865..83199227b1 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.h +++ b/services/inputflinger/reader/mapper/CursorInputMapper.h @@ -115,7 +115,6 @@ private: ui::Rotation mOrientation{ui::ROTATION_0}; FloatRect mBoundsInLogicalDisplay{}; - // The button state as of the last sync. int32_t mButtonState; nsecs_t mDownTime; nsecs_t mLastEventTime; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 40368114a2..b6e27a87f8 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -12371,69 +12371,43 @@ protected: } void injectDown(int fromSource = AINPUT_SOURCE_TOUCHSCREEN) { - bool consumeButtonPress = false; switch (fromSource) { - case AINPUT_SOURCE_TOUCHSCREEN: { + case AINPUT_SOURCE_TOUCHSCREEN: ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionDown(*mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, {50, 50})) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; break; - } - case AINPUT_SOURCE_STYLUS: { - PointerBuilder pointer = PointerBuilder(0, ToolType::STYLUS).x(50).y(50); + case AINPUT_SOURCE_STYLUS: ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_STYLUS) .buttonState( AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) - .pointer(pointer) - .build())); - ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, - injectMotionEvent(*mDispatcher, - MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS, - AINPUT_SOURCE_STYLUS) - .actionButton( - AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) - .buttonState( - AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) - .pointer(pointer) + .pointer(PointerBuilder(0, ToolType::STYLUS) + .x(50) + .y(50)) .build())); - consumeButtonPress = true; break; - } - case AINPUT_SOURCE_MOUSE: { - PointerBuilder pointer = - PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50); + case AINPUT_SOURCE_MOUSE: ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE) .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) - .pointer(pointer) + .pointer(PointerBuilder(MOUSE_POINTER_ID, + ToolType::MOUSE) + .x(50) + .y(50)) .build())); - ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, - injectMotionEvent(*mDispatcher, - MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS, - AINPUT_SOURCE_MOUSE) - .actionButton(AMOTION_EVENT_BUTTON_PRIMARY) - .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) - .pointer(pointer) - .build())); - consumeButtonPress = true; break; - } - default: { + default: FAIL() << "Source " << fromSource << " doesn't support drag and drop"; - } } // Window should receive motion event. mWindow->consumeMotionDown(ui::LogicalDisplayId::DEFAULT); - if (consumeButtonPress) { - mWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS)); - } // Spy window should also receive motion event mSpyWindow->consumeMotionDown(ui::LogicalDisplayId::DEFAULT); } @@ -12633,16 +12607,6 @@ TEST_F(InputDispatcherDragTests, StylusDragAndDrop) { // Move to another window and release button, expect to drop item. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, - MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE, - AINPUT_SOURCE_STYLUS) - .actionButton(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) - .buttonState(0) - .pointer(PointerBuilder(0, ToolType::STYLUS).x(150).y(50)) - .build())) - << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; - mDragWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE)); - ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, - injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_STYLUS) .buttonState(0) .pointer(PointerBuilder(0, ToolType::STYLUS).x(150).y(50)) @@ -12884,18 +12848,6 @@ TEST_F(InputDispatcherDragTests, MouseDragAndDrop) { // drop to another window. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, - MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE, - AINPUT_SOURCE_MOUSE) - .actionButton(AMOTION_EVENT_BUTTON_PRIMARY) - .buttonState(0) - .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE) - .x(150) - .y(50)) - .build())) - << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; - mDragWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE)); - ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, - injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE) .buttonState(0) .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE) diff --git a/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp index abce931eff..31db2fedc7 100644 --- a/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp +++ b/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp @@ -48,9 +48,9 @@ public: auto [it, _] = mVerifiers.emplace(args.displayId, "Fuzz Verifier"); InputVerifier& verifier = it->second; const Result<void> result = - verifier.processMovement(args.deviceId, args.source, args.action, args.actionButton, + verifier.processMovement(args.deviceId, args.source, args.action, args.getPointerCount(), args.pointerProperties.data(), - args.pointerCoords.data(), args.flags, args.buttonState); + args.pointerCoords.data(), args.flags); if (result.ok()) { return args; } |