From 21a46533f21facb9fa8636ac8f917294348a760e Mon Sep 17 00:00:00 2001 From: Harry Cutts Date: Fri, 31 Jan 2025 11:16:08 +0000 Subject: InputVerifier: put parameters into a struct This makes it clearer which parameter is which when calling, and also allows us to make the tests much more succinct by using struct update syntax. Bug: 245989146 Test: $ atest --host libinput_rust_test Flag: EXEMPT refactor Change-Id: If68332d652186b7283435cbc41af78bf12aa5b94 --- libs/input/rust/input.rs | 4 +- libs/input/rust/input_verifier.rs | 1139 +++++++++++++++---------------------- libs/input/rust/lib.rs | 16 +- 3 files changed, 470 insertions(+), 689 deletions(-) diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs index 6eb2d73b1f..30e1c860e6 100644 --- a/libs/input/rust/input.rs +++ b/libs/input/rust/input.rs @@ -50,7 +50,7 @@ pub enum SourceClass { bitflags! { /// Source of the input device or input events. - #[derive(Debug, PartialEq)] + #[derive(Clone, Copy, Debug, PartialEq)] pub struct Source: u32 { // Constants from SourceClass, added here for compatibility reasons /// SourceClass::Button @@ -219,7 +219,7 @@ 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)] + #[derive(Clone, Copy, Debug)] pub struct MotionFlags: u32 { /// FLAG_WINDOW_IS_OBSCURED const WINDOW_IS_OBSCURED = MotionEventFlag::WINDOW_IS_OBSCURED.0 as u32; diff --git a/libs/input/rust/input_verifier.rs b/libs/input/rust/input_verifier.rs index 6d94316272..f05936bfe1 100644 --- a/libs/input/rust/input_verifier.rs +++ b/libs/input/rust/input_verifier.rs @@ -22,23 +22,60 @@ use log::info; use std::collections::HashMap; use std::collections::HashSet; -fn verify_event( - action: MotionAction, - action_button: MotionButton, - pointer_properties: &[RustPointerProperties], - flags: &MotionFlags, - verify_buttons: bool, -) -> Result<(), String> { - let pointer_count = pointer_properties.len(); +/// Represents a movement or state change event from a pointer device. The Rust equivalent of the +/// C++ NotifyMotionArgs struct. +#[derive(Clone, Copy)] +pub struct NotifyMotionArgs<'a> { + /// The ID of the device that emitted the event. + pub device_id: DeviceId, + + /// The type of device that emitted the event. + pub source: Source, + + /// The type of event that took place, as one of the `input_bindgen::AMOTION_EVENT_…` constants. + pub action: u32, + + /// For `BUTTON_PRESS` and `BUTTON_RELEASE` actions, the button being pressed or released. + pub action_button: MotionButton, + + /// The properties of each of the pointers involved in the event. + pub pointer_properties: &'a [RustPointerProperties], + + /// Flags applied to the event. + pub flags: MotionFlags, + + /// The set of buttons that were pressed at the time of the event. + /// + /// 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` | + pub button_state: MotionButton, +} + +/// Verifies the properties of an event that should always be true, regardless of the current state. +fn verify_event(event: NotifyMotionArgs<'_>, verify_buttons: bool) -> Result<(), String> { + let action: MotionAction = event.action.into(); + let pointer_count = event.pointer_properties.len(); if pointer_count < 1 { - return Err(format!("Invalid {} event: no pointers", action)); + return Err(format!("Invalid {action} event: no pointers")); } - if action_button != MotionButton::empty() + if event.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" + "Invalid {} event: has action button {:?} but is not a button action", + action, event.action_button )); } match action { @@ -55,9 +92,10 @@ fn verify_event( } MotionAction::Cancel => { - if !flags.contains(MotionFlags::CANCELED) { + if !event.flags.contains(MotionFlags::CANCELED) { return Err(format!( - "For ACTION_CANCEL, must set FLAG_CANCELED. Received flags: {flags:#?}", + "For ACTION_CANCEL, must set FLAG_CANCELED. Received flags: {:#?}", + event.flags )); } } @@ -70,7 +108,7 @@ fn verify_event( MotionAction::ButtonPress | MotionAction::ButtonRelease => { if verify_buttons { - let button_count = action_button.iter().count(); + let button_count = event.action_button.iter().count(); if button_count != 1 { return Err(format!( "Invalid {action} event: must specify a single action button, not \ @@ -92,84 +130,70 @@ struct ButtonVerifier { 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` | + /// for which we haven't seen BUTTON_PRESS events yet (see [`NotifyMotionArgs::button_state`]). pending_buttons: MotionButton, } impl ButtonVerifier { - pub fn process_action( - &mut self, - action: MotionAction, - action_button: MotionButton, - button_state: MotionButton, - ) -> Result<(), String> { + pub fn process_event(&mut self, event: NotifyMotionArgs<'_>) -> Result<(), String> { + let action: MotionAction = event.action.into(); 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) + if action != MotionAction::ButtonPress + || !self.pending_buttons.contains(event.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 + self.pending_buttons, action, event.action_button )); } else { - self.pending_buttons -= action_button; + self.pending_buttons -= event.action_button; } } let expected_state = match action { MotionAction::Down => { - if self.button_state - button_state != MotionButton::empty() { + if self.button_state - event.button_state != MotionButton::empty() { return Err(format!( "DOWN event button state is missing {:?}", - self.button_state - button_state + self.button_state - event.button_state )); } - self.pending_buttons = button_state - self.button_state; + self.pending_buttons = event.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 + event.button_state } MotionAction::ButtonPress => { - if self.button_state.contains(action_button) { + if self.button_state.contains(event.action_button) { return Err(format!( - "Duplicate BUTTON_PRESS; button state already contains {action_button:?}" + "Duplicate BUTTON_PRESS; button state already contains {:?}", + event.action_button )); } - self.button_state | action_button + self.button_state | event.action_button } MotionAction::ButtonRelease => { - if !self.button_state.contains(action_button) { + if !self.button_state.contains(event.action_button) { return Err(format!( - "Invalid BUTTON_RELEASE; button state doesn't contain {action_button:?}" + "Invalid BUTTON_RELEASE; button state doesn't contain {:?}", + event.action_button )); } - self.button_state - action_button + self.button_state - event.action_button } _ => self.button_state, }; - if button_state != expected_state { + if event.button_state != expected_state { return Err(format!( - "Expected {action} button state to be {expected_state:?}, but was {button_state:?}" + "Expected {action} button state to be {expected_state:?}, but was {:?}", + event.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; + self.button_state = event.button_state; } Ok(()) } @@ -205,78 +229,61 @@ impl InputVerifier { /// 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) { + pub fn process_movement(&mut self, event: NotifyMotionArgs<'_>) -> Result<(), String> { + if !event.source.is_from_class(SourceClass::Pointer) { // Skip non-pointer sources like MOUSE_RELATIVE for now return Ok(()); } if self.should_log { info!( "Processing {} for device {:?} ({} pointer{}) on {}", - MotionAction::from(action).to_string(), - device_id, - pointer_properties.len(), - if pointer_properties.len() == 1 { "" } else { "s" }, + MotionAction::from(event.action).to_string(), + event.device_id, + event.pointer_properties.len(), + if event.pointer_properties.len() == 1 { "" } else { "s" }, self.name ); } - verify_event( - action.into(), - action_button, - pointer_properties, - &flags, - self.verify_buttons, - )?; + verify_event(event, self.verify_buttons)?; if self.verify_buttons { - self.button_verifier_by_device.entry(device_id).or_default().process_action( - action.into(), - action_button, - button_state, - )?; + self.button_verifier_by_device + .entry(event.device_id) + .or_default() + .process_event(event)?; } - match action.into() { + match event.action.into() { MotionAction::Down => { - if self.touching_pointer_ids_by_device.contains_key(&device_id) { + if self.touching_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Invalid DOWN event - pointers already down for device {:?}: {:?}", - self.name, device_id, self.touching_pointer_ids_by_device + self.name, event.device_id, self.touching_pointer_ids_by_device )); } - let it = self.touching_pointer_ids_by_device.entry(device_id).or_default(); - it.insert(pointer_properties[0].id); + let it = self.touching_pointer_ids_by_device.entry(event.device_id).or_default(); + it.insert(event.pointer_properties[0].id); } MotionAction::PointerDown { action_index } => { - if !self.touching_pointer_ids_by_device.contains_key(&device_id) { + if !self.touching_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Received POINTER_DOWN but no pointers are currently down \ for device {:?}", - self.name, device_id + self.name, event.device_id )); } - let it = self.touching_pointer_ids_by_device.get_mut(&device_id).unwrap(); - if it.len() != pointer_properties.len() - 1 { + let it = self.touching_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); + if it.len() != event.pointer_properties.len() - 1 { return Err(format!( "{}: There are currently {} touching pointers, but the incoming \ POINTER_DOWN event has {}", self.name, it.len(), - pointer_properties.len() + event.pointer_properties.len() )); } - let pointer_id = pointer_properties[action_index].id; + let pointer_id = event.pointer_properties[action_index].id; if it.contains(&pointer_id) { return Err(format!( "{}: Pointer with id={} already present found in the properties", @@ -286,7 +293,7 @@ impl InputVerifier { it.insert(pointer_id); } MotionAction::Move => { - if !self.ensure_touching_pointers_match(device_id, pointer_properties) { + if !self.ensure_touching_pointers_match(event.device_id, event.pointer_properties) { return Err(format!( "{}: ACTION_MOVE touching pointers don't match", self.name @@ -294,49 +301,49 @@ impl InputVerifier { } } MotionAction::PointerUp { action_index } => { - if !self.ensure_touching_pointers_match(device_id, pointer_properties) { + if !self.ensure_touching_pointers_match(event.device_id, event.pointer_properties) { return Err(format!( "{}: ACTION_POINTER_UP touching pointers don't match", self.name )); } - let it = self.touching_pointer_ids_by_device.get_mut(&device_id).unwrap(); - let pointer_id = pointer_properties[action_index].id; + let it = self.touching_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); + let pointer_id = event.pointer_properties[action_index].id; it.remove(&pointer_id); } MotionAction::Up => { - if !self.touching_pointer_ids_by_device.contains_key(&device_id) { + if !self.touching_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{} Received ACTION_UP but no pointers are currently down for device {:?}", - self.name, device_id + self.name, event.device_id )); } - let it = self.touching_pointer_ids_by_device.get_mut(&device_id).unwrap(); + let it = self.touching_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); if it.len() != 1 { return Err(format!( "{}: Got ACTION_UP, but we have pointers: {:?} for device {:?}", - self.name, it, device_id + self.name, it, event.device_id )); } - let pointer_id = pointer_properties[0].id; + let pointer_id = event.pointer_properties[0].id; if !it.contains(&pointer_id) { return Err(format!( "{}: Got ACTION_UP, but pointerId {} is not touching. Touching pointers:\ {:?} for device {:?}", - self.name, pointer_id, it, device_id + self.name, pointer_id, it, event.device_id )); } - self.touching_pointer_ids_by_device.remove(&device_id); + self.touching_pointer_ids_by_device.remove(&event.device_id); } MotionAction::Cancel => { - if !self.ensure_touching_pointers_match(device_id, pointer_properties) { + if !self.ensure_touching_pointers_match(event.device_id, event.pointer_properties) { return Err(format!( "{}: Got ACTION_CANCEL, but the pointers don't match. \ Existing pointers: {:?}", self.name, self.touching_pointer_ids_by_device )); } - self.touching_pointer_ids_by_device.remove(&device_id); + self.touching_pointer_ids_by_device.remove(&event.device_id); } /* * The hovering protocol currently supports a single pointer only, because we do not @@ -345,41 +352,41 @@ impl InputVerifier { * eventually supported. */ MotionAction::HoverEnter => { - if self.hovering_pointer_ids_by_device.contains_key(&device_id) { + if self.hovering_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Invalid HOVER_ENTER event - pointers already hovering for device {:?}:\ {:?}", - self.name, device_id, self.hovering_pointer_ids_by_device + self.name, event.device_id, self.hovering_pointer_ids_by_device )); } - let it = self.hovering_pointer_ids_by_device.entry(device_id).or_default(); - it.insert(pointer_properties[0].id); + let it = self.hovering_pointer_ids_by_device.entry(event.device_id).or_default(); + it.insert(event.pointer_properties[0].id); } MotionAction::HoverMove => { // For compatibility reasons, we allow HOVER_MOVE without a prior HOVER_ENTER. // If there was no prior HOVER_ENTER, just start a new hovering pointer. - let it = self.hovering_pointer_ids_by_device.entry(device_id).or_default(); - it.insert(pointer_properties[0].id); + let it = self.hovering_pointer_ids_by_device.entry(event.device_id).or_default(); + it.insert(event.pointer_properties[0].id); } MotionAction::HoverExit => { - if !self.hovering_pointer_ids_by_device.contains_key(&device_id) { + if !self.hovering_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Invalid HOVER_EXIT event - no pointers are hovering for device {:?}", - self.name, device_id + self.name, event.device_id )); } - let pointer_id = pointer_properties[0].id; - let it = self.hovering_pointer_ids_by_device.get_mut(&device_id).unwrap(); + let pointer_id = event.pointer_properties[0].id; + let it = self.hovering_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); it.remove(&pointer_id); if !it.is_empty() { return Err(format!( "{}: Removed hovering pointer {}, but pointers are still\ hovering for device {:?}: {:?}", - self.name, pointer_id, device_id, it + self.name, pointer_id, event.device_id, it )); } - self.hovering_pointer_ids_by_device.remove(&device_id); + self.hovering_pointer_ids_by_device.remove(&event.device_id); } _ => return Ok(()), } @@ -421,11 +428,25 @@ impl InputVerifier { mod tests { use crate::input::MotionButton; use crate::input_verifier::InputVerifier; + use crate::input_verifier::NotifyMotionArgs; use crate::DeviceId; use crate::MotionFlags; use crate::RustPointerProperties; use crate::Source; + const BASE_POINTER_PROPERTIES: [RustPointerProperties; 1] = [RustPointerProperties { id: 0 }]; + const BASE_EVENT: NotifyMotionArgs = NotifyMotionArgs { + device_id: DeviceId(1), + source: Source::Touchscreen, + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action_button: MotionButton::empty(), + pointer_properties: &BASE_POINTER_PROPERTIES, + flags: MotionFlags::empty(), + button_state: MotionButton::empty(), + }; + const BASE_MOUSE_EVENT: NotifyMotionArgs = + NotifyMotionArgs { source: Source::Mouse, ..BASE_EVENT }; + #[test] /** * Send a DOWN event with 2 pointers and ensure that it's marked as invalid. @@ -436,15 +457,11 @@ mod tests { let pointer_properties = Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_err()); } @@ -454,37 +471,25 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_UP, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); } @@ -494,56 +499,40 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); // POINTER 1 DOWN let two_pointer_properties = Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN + .process_movement(NotifyMotionArgs { + action: 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(), - ) + pointer_properties: &two_pointer_properties, + ..BASE_EVENT + }) .is_ok()); // POINTER 0 UP assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP + .process_movement(NotifyMotionArgs { + action: 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(), - ) + pointer_properties: &two_pointer_properties, + ..BASE_EVENT + }) .is_ok()); // ACTION_UP for pointer id=1 let pointer_1_properties = Vec::from([RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), - &pointer_1_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_UP, + pointer_properties: &pointer_1_properties, + ..BASE_EVENT + }) .is_ok()); } @@ -551,61 +540,40 @@ mod tests { fn multi_device_stream() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(1), + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(1), + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(2), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(2), + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(2), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(2), + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(1), + action: input_bindgen::AMOTION_EVENT_ACTION_UP, + ..BASE_EVENT + }) .is_ok()); } @@ -613,28 +581,19 @@ mod tests { fn action_cancel() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + flags: MotionFlags::empty(), + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_CANCEL, - MotionButton::empty(), - &pointer_properties, - MotionFlags::CANCELED, - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_CANCEL, + flags: MotionFlags::CANCELED, + ..BASE_EVENT + }) .is_ok()); } @@ -642,28 +601,17 @@ mod tests { fn invalid_action_cancel() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_CANCEL, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), // forgot to set FLAG_CANCELED - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_CANCEL, + ..BASE_EVENT + }) .is_err()); } @@ -671,17 +619,11 @@ mod tests { fn invalid_up() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_UP, + ..BASE_EVENT + }) .is_err()); } @@ -689,53 +631,32 @@ mod tests { fn correct_hover_sequence() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + ..BASE_EVENT + }) .is_ok()); } @@ -743,29 +664,18 @@ mod tests { fn double_hover_enter() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + ..BASE_EVENT + }) .is_err()); } @@ -775,17 +685,13 @@ mod tests { fn relative_mouse_move() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(2), - Source::MouseRelative, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(2), + source: Source::MouseRelative, + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + ..BASE_EVENT + }) .is_ok()); } @@ -796,42 +702,30 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); // POINTER 1 DOWN let two_pointer_properties = Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN + .process_movement(NotifyMotionArgs { + action: 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(), - ) + pointer_properties: &two_pointer_properties, + ..BASE_EVENT + }) .is_ok()); // MOVE event with 1 pointer missing (the pointer with id = 1). It should be rejected assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_err()); } @@ -839,17 +733,13 @@ mod tests { fn correct_button_press() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Primary, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_ok()); } @@ -857,17 +747,13 @@ mod tests { fn button_press_without_action_button() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::empty(), + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -875,17 +761,13 @@ mod tests { fn button_press_with_multiple_action_buttons() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Back | MotionButton::Forward, + button_state: MotionButton::Back | MotionButton::Forward, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -893,17 +775,13 @@ mod tests { fn button_press_without_action_button_in_state() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Primary, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -911,28 +789,21 @@ mod tests { fn button_release_with_action_button_in_state() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Primary, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, + action_button: MotionButton::Primary, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -940,17 +811,13 @@ mod tests { fn nonbutton_action_with_action_button() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + action_button: MotionButton::Primary, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -958,17 +825,13 @@ mod tests { fn nonbutton_action_with_action_button_and_state() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + action_button: MotionButton::Primary, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -976,28 +839,21 @@ mod tests { fn nonbutton_action_with_button_state_change() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + action_button: MotionButton::empty(), + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, + action_button: MotionButton::empty(), + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1005,39 +861,29 @@ mod tests { fn nonbutton_action_missing_button_state() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + action_button: MotionButton::empty(), + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Back, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, + action_button: MotionButton::empty(), + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1045,40 +891,30 @@ mod tests { fn up_without_button_release() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action_button: MotionButton::empty(), + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Primary, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_UP, + action_button: MotionButton::empty(), + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1086,28 +922,21 @@ mod tests { fn button_press_for_already_pressed_button() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Back, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Back, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1115,17 +944,13 @@ mod tests { fn button_release_for_unpressed_button() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, + action_button: MotionButton::Back, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1133,28 +958,21 @@ mod tests { fn correct_multiple_button_presses_without_down() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Back, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Forward, + button_state: MotionButton::Back | MotionButton::Forward, + ..BASE_MOUSE_EVENT + }) .is_ok()); } @@ -1162,52 +980,39 @@ mod tests { fn correct_down_with_button_press() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action_button: MotionButton::empty(), + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Primary, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Secondary, + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action_button: MotionButton::empty(), + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) .is_ok()); } @@ -1215,29 +1020,22 @@ mod tests { fn down_with_button_state_change_not_followed_by_button_press() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action_button: MotionButton::empty(), + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action_button: MotionButton::empty(), + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1245,41 +1043,31 @@ mod tests { fn down_with_button_state_change_not_followed_by_enough_button_presses() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action_button: MotionButton::empty(), + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) .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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Primary, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::Primary, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action_button: MotionButton::empty(), + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1287,28 +1075,21 @@ mod tests { fn down_missing_already_pressed_button() { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - 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, - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + action_button: MotionButton::Back, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Mouse, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - MotionButton::empty(), - &pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action_button: MotionButton::empty(), + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } } diff --git a/libs/input/rust/lib.rs b/libs/input/rust/lib.rs index 6db4356da1..3a347c4c4a 100644 --- a/libs/input/rust/lib.rs +++ b/libs/input/rust/lib.rs @@ -27,7 +27,7 @@ pub use input::{ DeviceClass, DeviceId, InputDevice, KeyboardType, ModifierState, MotionAction, MotionButton, MotionFlags, Source, }; -pub use input_verifier::InputVerifier; +pub use input_verifier::{InputVerifier, NotifyMotionArgs}; pub use keyboard_classifier::KeyboardClassifier; #[cxx::bridge(namespace = "android::input")] @@ -155,15 +155,15 @@ fn process_movement( buttons need to be added to MotionButton." ); } - let result = verifier.process_movement( - DeviceId(device_id), - Source::from_bits(source).unwrap(), + let result = verifier.process_movement(NotifyMotionArgs { + device_id: DeviceId(device_id), + source: Source::from_bits(source).unwrap(), action, - motion_action_button.unwrap(), + action_button: motion_action_button.unwrap(), pointer_properties, - motion_flags.unwrap(), - motion_button_state.unwrap(), - ); + flags: motion_flags.unwrap(), + button_state: motion_button_state.unwrap(), + }); match result { Ok(()) => "".to_string(), Err(e) => e, -- cgit v1.2.3-59-g8ed1b From c932b0717a30853f5ce2ad20c43f7a42d690ad32 Mon Sep 17 00:00:00 2001 From: Harry Cutts Date: Fri, 31 Jan 2025 16:47:55 +0000 Subject: InputVerifier: use `let ... else` when converting flags and buttons Bug: 245989146 Test: enable the verifier, check everything works as usual Flag: EXEMPT refactor Change-Id: I3debc83da82168f9c5a7e3eccb2f8dc6edbabaed --- libs/input/rust/lib.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libs/input/rust/lib.rs b/libs/input/rust/lib.rs index 3a347c4c4a..8b8a39ecca 100644 --- a/libs/input/rust/lib.rs +++ b/libs/input/rust/lib.rs @@ -133,36 +133,33 @@ fn process_movement( flags: u32, button_state: u32, ) -> String { - let motion_flags = MotionFlags::from_bits(flags); - if motion_flags.is_none() { + let Some(motion_flags) = MotionFlags::from_bits(flags) else { panic!( "The conversion of flags 0x{:08x} failed, please check if some flags have not been \ added to MotionFlags.", flags ); - } - let motion_action_button = MotionButton::from_bits(action_button); - if motion_action_button.is_none() { + }; + let Some(motion_action_button) = MotionButton::from_bits(action_button) else { 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() { + }; + let Some(motion_button_state) = MotionButton::from_bits(button_state) else { 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(NotifyMotionArgs { device_id: DeviceId(device_id), source: Source::from_bits(source).unwrap(), action, - action_button: motion_action_button.unwrap(), + action_button: motion_action_button, pointer_properties, - flags: motion_flags.unwrap(), - button_state: motion_button_state.unwrap(), + flags: motion_flags, + button_state: motion_button_state, }); match result { Ok(()) => "".to_string(), -- cgit v1.2.3-59-g8ed1b From 34594c3cfb47e44a4451502c75b04813cf9d9a06 Mon Sep 17 00:00:00 2001 From: Harry Cutts Date: Fri, 31 Jan 2025 16:59:14 +0000 Subject: InputVerifier: make action_button a field of the action enum Only MotionEvents with a button press or release action should have an action button. Let's express this in the data structure by making action_button a field of the relevant MotionActions, instead of a separate field of MotionEvent that could potentially be set on non-button actions. This involves moving the translation from input_bindgen constants to MotionAction into lib.rs, which I think makes more sense (as it keeps the language interfacing code contained there), but also means we have to move one piece of validation there too. Bug: 245989146 Test: $ atest --host libinput_rust_test Test: enable the verifier, check everything works as usual Flag: EXEMPT refactor Change-Id: Ida17429b0e12247b63a3ae44bab63e421d9fff0f --- libs/input/rust/input.rs | 36 +++-- libs/input/rust/input_verifier.rs | 302 +++++++++++++------------------------- libs/input/rust/lib.rs | 57 ++++++- 3 files changed, 184 insertions(+), 211 deletions(-) diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs index 30e1c860e6..35ba04f5b6 100644 --- a/libs/input/rust/input.rs +++ b/libs/input/rust/input.rs @@ -101,7 +101,7 @@ bitflags! { /// A rust enum representation of a MotionEvent action. #[repr(u32)] -#[derive(Eq, PartialEq)] +#[derive(Clone, Copy, Eq, PartialEq)] pub enum MotionAction { /// ACTION_DOWN Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN, @@ -132,9 +132,15 @@ pub enum MotionAction { /// ACTION_SCROLL Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL, /// ACTION_BUTTON_PRESS - ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + ButtonPress { + /// The button being pressed. + action_button: MotionButton, + } = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, /// ACTION_BUTTON_RELEASE - ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, + ButtonRelease { + /// The button being released. + action_button: MotionButton, + } = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, } impl fmt::Display for MotionAction { @@ -153,14 +159,20 @@ impl fmt::Display for MotionAction { MotionAction::Scroll => write!(f, "SCROLL"), MotionAction::HoverEnter => write!(f, "HOVER_ENTER"), MotionAction::HoverExit => write!(f, "HOVER_EXIT"), - MotionAction::ButtonPress => write!(f, "BUTTON_PRESS"), - MotionAction::ButtonRelease => write!(f, "BUTTON_RELEASE"), + MotionAction::ButtonPress { action_button } => { + write!(f, "BUTTON_PRESS({action_button:?})") + } + MotionAction::ButtonRelease { action_button } => { + write!(f, "BUTTON_RELEASE({action_button:?})") + } } } } -impl From for MotionAction { - fn from(action: u32) -> Self { +impl MotionAction { + /// Creates a [`MotionAction`] from an `AMOTION_EVENT_ACTION_…` constant and an action button + /// (which should be empty for all actions except `BUTTON_PRESS` and `…_RELEASE`). + pub fn from_code(action: u32, action_button: MotionButton) -> Self { let (action_masked, action_index) = MotionAction::breakdown_action(action); match action_masked { input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down, @@ -178,14 +190,16 @@ impl From for MotionAction { input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE => MotionAction::HoverMove, input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT => MotionAction::HoverExit, input_bindgen::AMOTION_EVENT_ACTION_SCROLL => MotionAction::Scroll, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => MotionAction::ButtonPress, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => MotionAction::ButtonRelease, + input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => { + MotionAction::ButtonPress { action_button } + } + input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => { + MotionAction::ButtonRelease { action_button } + } _ => panic!("Unknown action: {}", action), } } -} -impl MotionAction { fn breakdown_action(action: u32) -> (u32, usize) { let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK; let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) diff --git a/libs/input/rust/input_verifier.rs b/libs/input/rust/input_verifier.rs index f05936bfe1..f87dd413c6 100644 --- a/libs/input/rust/input_verifier.rs +++ b/libs/input/rust/input_verifier.rs @@ -32,11 +32,8 @@ pub struct NotifyMotionArgs<'a> { /// The type of device that emitted the event. pub source: Source, - /// The type of event that took place, as one of the `input_bindgen::AMOTION_EVENT_…` constants. - pub action: u32, - - /// For `BUTTON_PRESS` and `BUTTON_RELEASE` actions, the button being pressed or released. - pub action_button: MotionButton, + /// The type of event that took place. + pub action: MotionAction, /// The properties of each of the pointers involved in the event. pub pointer_properties: &'a [RustPointerProperties], @@ -64,21 +61,11 @@ pub struct NotifyMotionArgs<'a> { /// Verifies the properties of an event that should always be true, regardless of the current state. fn verify_event(event: NotifyMotionArgs<'_>, verify_buttons: bool) -> Result<(), String> { - let action: MotionAction = event.action.into(); let pointer_count = event.pointer_properties.len(); if pointer_count < 1 { - return Err(format!("Invalid {action} event: no pointers")); - } - if event.action_button != MotionButton::empty() - && action != MotionAction::ButtonPress - && action != MotionAction::ButtonRelease - { - return Err(format!( - "Invalid {} event: has action button {:?} but is not a button action", - action, event.action_button - )); + return Err(format!("Invalid {} event: no pointers", event.action)); } - match action { + match event.action { MotionAction::Down | MotionAction::HoverEnter | MotionAction::HoverExit @@ -86,7 +73,8 @@ fn verify_event(event: NotifyMotionArgs<'_>, verify_buttons: bool) -> Result<(), | MotionAction::Up => { if pointer_count != 1 { return Err(format!( - "Invalid {action} event: there are {pointer_count} pointers in the event", + "Invalid {} event: there are {} pointers in the event", + event.action, pointer_count )); } } @@ -102,17 +90,22 @@ fn verify_event(event: NotifyMotionArgs<'_>, verify_buttons: bool) -> Result<(), MotionAction::PointerDown { action_index } | MotionAction::PointerUp { action_index } => { if action_index >= pointer_count { - return Err(format!("Got {action}, but event has {pointer_count} pointer(s)")); + return Err(format!( + "Got {}, but event has {} pointer(s)", + event.action, pointer_count + )); } } - MotionAction::ButtonPress | MotionAction::ButtonRelease => { + MotionAction::ButtonPress { action_button } + | MotionAction::ButtonRelease { action_button } => { if verify_buttons { - let button_count = event.action_button.iter().count(); + 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" + "Invalid {} event: must specify a single action button, not {} action \ + buttons", + event.action, button_count )); } } @@ -136,23 +129,24 @@ struct ButtonVerifier { impl ButtonVerifier { pub fn process_event(&mut self, event: NotifyMotionArgs<'_>) -> Result<(), String> { - let action: MotionAction = event.action.into(); 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(event.action_button) - { - return Err(format!( - "After DOWN event, expected BUTTON_PRESS event(s) for {:?}, but got {} with \ - action button {:?}", - self.pending_buttons, action, event.action_button - )); - } else { - self.pending_buttons -= event.action_button; + match event.action { + MotionAction::ButtonPress { action_button } + if self.pending_buttons.contains(action_button) => + { + self.pending_buttons -= action_button; + } + _ => { + return Err(format!( + "After DOWN event, expected BUTTON_PRESS event(s) for {:?}, but got {}", + self.pending_buttons, event.action + )); + } } } - let expected_state = match action { + let expected_state = match event.action { MotionAction::Down => { if self.button_state - event.button_state != MotionButton::empty() { return Err(format!( @@ -165,34 +159,32 @@ impl ButtonVerifier { // extra buttons are valid on DOWN actions, so bypass the expected state check. event.button_state } - MotionAction::ButtonPress => { - if self.button_state.contains(event.action_button) { + MotionAction::ButtonPress { action_button } => { + if self.button_state.contains(action_button) { return Err(format!( - "Duplicate BUTTON_PRESS; button state already contains {:?}", - event.action_button + "Duplicate BUTTON_PRESS; button state already contains {action_button:?}" )); } - self.button_state | event.action_button + self.button_state | action_button } - MotionAction::ButtonRelease => { - if !self.button_state.contains(event.action_button) { + MotionAction::ButtonRelease { action_button } => { + if !self.button_state.contains(action_button) { return Err(format!( - "Invalid BUTTON_RELEASE; button state doesn't contain {:?}", - event.action_button + "Invalid BUTTON_RELEASE; button state doesn't contain {action_button:?}", )); } - self.button_state - event.action_button + self.button_state - action_button } _ => self.button_state, }; if event.button_state != expected_state { return Err(format!( - "Expected {action} button state to be {expected_state:?}, but was {:?}", - event.button_state + "Expected {} button state to be {:?}, but was {:?}", + event.action, expected_state, event.button_state )); } // DOWN events can have pending buttons, so don't update the state for them. - if action != MotionAction::Down { + if event.action != MotionAction::Down { self.button_state = event.button_state; } Ok(()) @@ -237,7 +229,7 @@ impl InputVerifier { if self.should_log { info!( "Processing {} for device {:?} ({} pointer{}) on {}", - MotionAction::from(event.action).to_string(), + event.action, event.device_id, event.pointer_properties.len(), if event.pointer_properties.len() == 1 { "" } else { "s" }, @@ -254,7 +246,7 @@ impl InputVerifier { .process_event(event)?; } - match event.action.into() { + match event.action { MotionAction::Down => { if self.touching_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( @@ -430,6 +422,7 @@ mod tests { use crate::input_verifier::InputVerifier; use crate::input_verifier::NotifyMotionArgs; use crate::DeviceId; + use crate::MotionAction; use crate::MotionFlags; use crate::RustPointerProperties; use crate::Source; @@ -438,8 +431,7 @@ mod tests { const BASE_EVENT: NotifyMotionArgs = NotifyMotionArgs { device_id: DeviceId(1), source: Source::Touchscreen, - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, - action_button: MotionButton::empty(), + action: MotionAction::Down, pointer_properties: &BASE_POINTER_PROPERTIES, flags: MotionFlags::empty(), button_state: MotionButton::empty(), @@ -458,7 +450,7 @@ mod tests { Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action: MotionAction::Down, pointer_properties: &pointer_properties, ..BASE_EVENT }) @@ -472,21 +464,21 @@ mod tests { let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action: MotionAction::Down, pointer_properties: &pointer_properties, ..BASE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action: MotionAction::Move, pointer_properties: &pointer_properties, ..BASE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_UP, + action: MotionAction::Up, pointer_properties: &pointer_properties, ..BASE_EVENT }) @@ -500,7 +492,7 @@ mod tests { let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action: MotionAction::Down, pointer_properties: &pointer_properties, ..BASE_EVENT }) @@ -510,8 +502,7 @@ mod tests { Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN - | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), + action: MotionAction::PointerDown { action_index: 1 }, pointer_properties: &two_pointer_properties, ..BASE_EVENT }) @@ -519,8 +510,7 @@ mod tests { // POINTER 0 UP assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP - | (0 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), + action: MotionAction::PointerUp { action_index: 0 }, pointer_properties: &two_pointer_properties, ..BASE_EVENT }) @@ -529,7 +519,7 @@ mod tests { let pointer_1_properties = Vec::from([RustPointerProperties { id: 1 }]); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_UP, + action: MotionAction::Up, pointer_properties: &pointer_1_properties, ..BASE_EVENT }) @@ -543,35 +533,35 @@ mod tests { assert!(verifier .process_movement(NotifyMotionArgs { device_id: DeviceId(1), - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action: MotionAction::Down, ..BASE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { device_id: DeviceId(1), - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action: MotionAction::Move, ..BASE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { device_id: DeviceId(2), - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action: MotionAction::Down, ..BASE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { device_id: DeviceId(2), - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action: MotionAction::Move, ..BASE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { device_id: DeviceId(1), - action: input_bindgen::AMOTION_EVENT_ACTION_UP, + action: MotionAction::Up, ..BASE_EVENT }) .is_ok()); @@ -583,14 +573,14 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action: MotionAction::Down, flags: MotionFlags::empty(), ..BASE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_CANCEL, + action: MotionAction::Cancel, flags: MotionFlags::CANCELED, ..BASE_EVENT }) @@ -602,16 +592,10 @@ mod tests { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::Down, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_CANCEL, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::Cancel, ..BASE_EVENT }) .is_err()); } @@ -620,10 +604,7 @@ mod tests { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_UP, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::Up, ..BASE_EVENT }) .is_err()); } @@ -632,31 +613,19 @@ mod tests { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverMove, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverExit, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_ok()); } @@ -665,17 +634,11 @@ mod tests { let mut verifier = InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - ..BASE_EVENT - }) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_err()); } @@ -689,7 +652,7 @@ mod tests { .process_movement(NotifyMotionArgs { device_id: DeviceId(2), source: Source::MouseRelative, - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action: MotionAction::Move, ..BASE_EVENT }) .is_ok()); @@ -703,7 +666,7 @@ mod tests { let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, + action: MotionAction::Down, pointer_properties: &pointer_properties, ..BASE_EVENT }) @@ -713,8 +676,7 @@ mod tests { Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN - | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), + action: MotionAction::PointerDown { action_index: 1 }, pointer_properties: &two_pointer_properties, ..BASE_EVENT }) @@ -722,7 +684,7 @@ mod tests { // MOVE event with 1 pointer missing (the pointer with id = 1). It should be rejected assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, + action: MotionAction::Move, pointer_properties: &pointer_properties, ..BASE_EVENT }) @@ -735,8 +697,7 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Primary, + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) @@ -749,8 +710,7 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::empty(), + action: MotionAction::ButtonPress { action_button: MotionButton::empty() }, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) @@ -763,8 +723,9 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Back | MotionButton::Forward, + action: MotionAction::ButtonPress { + action_button: MotionButton::Back | MotionButton::Forward + }, button_state: MotionButton::Back | MotionButton::Forward, ..BASE_MOUSE_EVENT }) @@ -777,8 +738,7 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Primary, + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) @@ -791,44 +751,14 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Primary, + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, - action_button: MotionButton::Primary, - button_state: MotionButton::Primary, - ..BASE_MOUSE_EVENT - }) - .is_err()); - } - - #[test] - fn nonbutton_action_with_action_button() { - let mut verifier = - InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - action_button: MotionButton::Primary, - button_state: MotionButton::empty(), - ..BASE_MOUSE_EVENT - }) - .is_err()); - } - - #[test] - fn nonbutton_action_with_action_button_and_state() { - let mut verifier = - InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); - assert!(verifier - .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - action_button: MotionButton::Primary, + action: MotionAction::ButtonRelease { action_button: MotionButton::Primary }, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) @@ -841,16 +771,14 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - action_button: MotionButton::empty(), + action: MotionAction::HoverEnter, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - action_button: MotionButton::empty(), + action: MotionAction::HoverMove, button_state: MotionButton::Back, ..BASE_MOUSE_EVENT }) @@ -863,24 +791,21 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - action_button: MotionButton::empty(), + action: MotionAction::HoverEnter, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Back, + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, button_state: MotionButton::Back, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - action_button: MotionButton::empty(), + action: MotionAction::HoverMove, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) @@ -893,16 +818,14 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, - action_button: MotionButton::empty(), + action: MotionAction::Down, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Primary, + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) @@ -910,8 +833,7 @@ mod tests { // This UP event shouldn't change the button state; a BUTTON_RELEASE before it should. assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_UP, - action_button: MotionButton::empty(), + action: MotionAction::Up, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) @@ -924,16 +846,14 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Back, + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, button_state: MotionButton::Back, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Back, + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, button_state: MotionButton::Back, ..BASE_MOUSE_EVENT }) @@ -946,8 +866,7 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, - action_button: MotionButton::Back, + action: MotionAction::ButtonRelease { action_button: MotionButton::Back }, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) @@ -960,16 +879,14 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Back, + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, button_state: MotionButton::Back, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Forward, + action: MotionAction::ButtonPress { action_button: MotionButton::Forward }, button_state: MotionButton::Back | MotionButton::Forward, ..BASE_MOUSE_EVENT }) @@ -982,24 +899,21 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, - action_button: MotionButton::empty(), + action: MotionAction::Down, button_state: MotionButton::Primary | MotionButton::Secondary, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Primary, + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Secondary, + action: MotionAction::ButtonPress { action_button: MotionButton::Secondary }, button_state: MotionButton::Primary | MotionButton::Secondary, ..BASE_MOUSE_EVENT }) @@ -1008,8 +922,7 @@ mod tests { // enough BUTTON_PRESSes were sent. assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, - action_button: MotionButton::empty(), + action: MotionAction::Move, button_state: MotionButton::Primary | MotionButton::Secondary, ..BASE_MOUSE_EVENT }) @@ -1022,8 +935,7 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, - action_button: MotionButton::empty(), + action: MotionAction::Down, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) @@ -1031,8 +943,7 @@ mod tests { // The DOWN event itself is OK, but it needs to be immediately followed by a BUTTON_PRESS. assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, - action_button: MotionButton::empty(), + action: MotionAction::Move, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) @@ -1045,8 +956,7 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, - action_button: MotionButton::empty(), + action: MotionAction::Down, button_state: MotionButton::Primary | MotionButton::Secondary, ..BASE_MOUSE_EVENT }) @@ -1055,16 +965,14 @@ mod tests { // BUTTON_PRESSes, one for each button. assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Primary, + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_MOVE, - action_button: MotionButton::empty(), + action: MotionAction::Move, button_state: MotionButton::Primary, ..BASE_MOUSE_EVENT }) @@ -1077,16 +985,14 @@ mod tests { InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, - action_button: MotionButton::Back, + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, button_state: MotionButton::Back, ..BASE_MOUSE_EVENT }) .is_ok()); assert!(verifier .process_movement(NotifyMotionArgs { - action: input_bindgen::AMOTION_EVENT_ACTION_DOWN, - action_button: MotionButton::empty(), + action: MotionAction::Down, button_state: MotionButton::empty(), ..BASE_MOUSE_EVENT }) diff --git a/libs/input/rust/lib.rs b/libs/input/rust/lib.rs index 8b8a39ecca..7638559553 100644 --- a/libs/input/rust/lib.rs +++ b/libs/input/rust/lib.rs @@ -152,11 +152,23 @@ fn process_movement( buttons need to be added to MotionButton." ); }; + let motion_action = MotionAction::from_code(action, motion_action_button); + if motion_action_button != MotionButton::empty() { + match motion_action { + MotionAction::ButtonPress { action_button: _ } + | MotionAction::ButtonRelease { action_button: _ } => {} + _ => { + return format!( + "Invalid {motion_action} event: has action button {motion_action_button:?} but \ + is not a button action" + ); + } + } + } let result = verifier.process_movement(NotifyMotionArgs { device_id: DeviceId(device_id), source: Source::from_bits(source).unwrap(), - action, - action_button: motion_action_button, + action: motion_action, pointer_properties, flags: motion_flags, button_state: motion_button_state, @@ -227,3 +239,44 @@ fn process_key( } classifier.process_key(DeviceId(device_id), evdev_code, modifier_state.unwrap()); } + +#[cfg(test)] +mod tests { + use crate::create_input_verifier; + use crate::process_movement; + use crate::RustPointerProperties; + + const BASE_POINTER_PROPERTIES: [RustPointerProperties; 1] = [RustPointerProperties { id: 0 }]; + + #[test] + fn verify_nonbutton_action_with_action_button() { + let mut verifier = create_input_verifier("Test".to_string(), /*verify_buttons*/ true); + assert!(process_movement( + &mut verifier, + 1, + input_bindgen::AINPUT_SOURCE_MOUSE, + input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY, + &BASE_POINTER_PROPERTIES, + 0, + 0, + ) + .contains("button action")); + } + + #[test] + fn verify_nonbutton_action_with_action_button_and_button_state() { + let mut verifier = create_input_verifier("Test".to_string(), /*verify_buttons*/ true); + assert!(process_movement( + &mut verifier, + 1, + input_bindgen::AINPUT_SOURCE_MOUSE, + input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY, + &BASE_POINTER_PROPERTIES, + 0, + input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY, + ) + .contains("button action")); + } +} -- cgit v1.2.3-59-g8ed1b