diff options
| author | 2025-02-11 06:09:17 -0800 | |
|---|---|---|
| committer | 2025-02-11 06:09:17 -0800 | |
| commit | a2f1f28ed673e4f26b4e53047830a6eb77d291d0 (patch) | |
| tree | 54c71e9c77166ba229e4814ef5107b063f9758ba | |
| parent | c463aa0443e257f35647b585326f8f76d5042e27 (diff) | |
| parent | 34594c3cfb47e44a4451502c75b04813cf9d9a06 (diff) | |
Merge changes Ida17429b,I3debc83d,If68332d6 into main
* changes:
InputVerifier: make action_button a field of the action enum
InputVerifier: use `let ... else` when converting flags and buttons
InputVerifier: put parameters into a struct
| -rw-r--r-- | libs/input/rust/input.rs | 40 | ||||
| -rw-r--r-- | libs/input/rust/input_verifier.rs | 1115 | ||||
| -rw-r--r-- | libs/input/rust/lib.rs | 84 |
3 files changed, 495 insertions, 744 deletions
diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs index 6eb2d73b1f..35ba04f5b6 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 @@ -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<u32> 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<u32> 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) @@ -219,7 +233,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..f87dd413c6 100644 --- a/libs/input/rust/input_verifier.rs +++ b/libs/input/rust/input_verifier.rs @@ -22,26 +22,50 @@ 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. + pub action: MotionAction, + + /// 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 pointer_count = event.pointer_properties.len(); if pointer_count < 1 { - return Err(format!("Invalid {} event: no pointers", action)); + return Err(format!("Invalid {} event: no pointers", event.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 { + match event.action { MotionAction::Down | MotionAction::HoverEnter | MotionAction::HoverExit @@ -49,32 +73,39 @@ fn verify_event( | 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 )); } } 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 )); } } 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 = 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 )); } } @@ -92,59 +123,43 @@ 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> { 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; + 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 - 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 => { + MotionAction::ButtonPress { action_button } => { if self.button_state.contains(action_button) { return Err(format!( "Duplicate BUTTON_PRESS; button state already contains {action_button:?}" @@ -152,24 +167,25 @@ impl ButtonVerifier { } self.button_state | action_button } - MotionAction::ButtonRelease => { + MotionAction::ButtonRelease { action_button } => { if !self.button_state.contains(action_button) { return Err(format!( - "Invalid BUTTON_RELEASE; button state doesn't contain {action_button:?}" + "Invalid BUTTON_RELEASE; button state doesn't contain {action_button:?}", )); } self.button_state - 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 {} 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 { - self.button_state = button_state; + if event.action != MotionAction::Down { + self.button_state = event.button_state; } Ok(()) } @@ -205,78 +221,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" }, + event.action, + 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 { 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 +285,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 +293,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 +344,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 +420,25 @@ impl InputVerifier { mod tests { use crate::input::MotionButton; 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; + const BASE_POINTER_PROPERTIES: [RustPointerProperties; 1] = [RustPointerProperties { id: 0 }]; + const BASE_EVENT: NotifyMotionArgs = NotifyMotionArgs { + device_id: DeviceId(1), + source: Source::Touchscreen, + action: MotionAction::Down, + 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 +449,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: MotionAction::Down, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_err()); } @@ -454,37 +463,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: MotionAction::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: MotionAction::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: MotionAction::Up, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); } @@ -494,56 +491,38 @@ 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: MotionAction::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 - | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - MotionButton::empty(), - &two_pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::PointerDown { action_index: 1 }, + 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 - | (0 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - MotionButton::empty(), - &two_pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::PointerUp { action_index: 0 }, + 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: MotionAction::Up, + pointer_properties: &pointer_1_properties, + ..BASE_EVENT + }) .is_ok()); } @@ -551,61 +530,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: MotionAction::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: MotionAction::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: MotionAction::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: MotionAction::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: MotionAction::Up, + ..BASE_EVENT + }) .is_ok()); } @@ -613,28 +571,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: MotionAction::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: MotionAction::Cancel, + flags: MotionFlags::CANCELED, + ..BASE_EVENT + }) .is_ok()); } @@ -642,28 +591,11 @@ 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: MotionAction::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: MotionAction::Cancel, ..BASE_EVENT }) .is_err()); } @@ -671,17 +603,8 @@ 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: MotionAction::Up, ..BASE_EVENT }) .is_err()); } @@ -689,53 +612,20 @@ 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: MotionAction::HoverEnter, ..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: MotionAction::HoverMove, ..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: MotionAction::HoverExit, ..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: MotionAction::HoverEnter, ..BASE_EVENT }) .is_ok()); } @@ -743,29 +633,12 @@ 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: MotionAction::HoverEnter, ..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: MotionAction::HoverEnter, ..BASE_EVENT }) .is_err()); } @@ -775,17 +648,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: MotionAction::Move, + ..BASE_EVENT + }) .is_ok()); } @@ -796,42 +665,29 @@ 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: MotionAction::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 - | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - MotionButton::empty(), - &two_pointer_properties, - MotionFlags::empty(), - MotionButton::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::PointerDown { action_index: 1 }, + 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: MotionAction::Move, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_err()); } @@ -839,17 +695,12 @@ 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: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_ok()); } @@ -857,17 +708,12 @@ 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: MotionAction::ButtonPress { action_button: MotionButton::empty() }, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -875,17 +721,14 @@ 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: MotionAction::ButtonPress { + action_button: MotionButton::Back | MotionButton::Forward + }, + button_state: MotionButton::Back | MotionButton::Forward, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -893,17 +736,12 @@ 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: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -911,64 +749,19 @@ 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: MotionAction::ButtonPress { 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, - ) - .is_err()); - } - - #[test] - 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(), - ) - .is_err()); - } - - #[test] - 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: MotionAction::ButtonRelease { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -976,28 +769,19 @@ 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: MotionAction::HoverEnter, + 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: MotionAction::HoverMove, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1005,39 +789,26 @@ 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: MotionAction::HoverEnter, + 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: MotionAction::ButtonPress { 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: MotionAction::HoverMove, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1045,40 +816,27 @@ 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: MotionAction::Down, + 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: MotionAction::ButtonPress { 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: MotionAction::Up, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1086,28 +844,19 @@ 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: MotionAction::ButtonPress { 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: MotionAction::ButtonPress { action_button: MotionButton::Back }, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1115,17 +864,12 @@ 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: MotionAction::ButtonRelease { action_button: MotionButton::Back }, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1133,28 +877,19 @@ 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: MotionAction::ButtonPress { 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: MotionAction::ButtonPress { action_button: MotionButton::Forward }, + button_state: MotionButton::Back | MotionButton::Forward, + ..BASE_MOUSE_EVENT + }) .is_ok()); } @@ -1162,52 +897,35 @@ 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: MotionAction::Down, + 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: MotionAction::ButtonPress { 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: MotionAction::ButtonPress { 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: MotionAction::Move, + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) .is_ok()); } @@ -1215,29 +933,20 @@ 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: MotionAction::Down, + 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: MotionAction::Move, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1245,41 +954,28 @@ 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: MotionAction::Down, + 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: MotionAction::ButtonPress { 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: MotionAction::Move, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) .is_err()); } @@ -1287,28 +983,19 @@ 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: MotionAction::ButtonPress { 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: MotionAction::Down, + 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..7638559553 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")] @@ -133,37 +133,46 @@ 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 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( - DeviceId(device_id), - Source::from_bits(source).unwrap(), - action, - motion_action_button.unwrap(), + let result = verifier.process_movement(NotifyMotionArgs { + device_id: DeviceId(device_id), + source: Source::from_bits(source).unwrap(), + action: motion_action, pointer_properties, - motion_flags.unwrap(), - motion_button_state.unwrap(), - ); + flags: motion_flags, + button_state: motion_button_state, + }); match result { Ok(()) => "".to_string(), Err(e) => e, @@ -230,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")); + } +} |