summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Prabir Pradhan <prabirmsp@google.com> 2023-06-22 23:08:18 +0000
committer Prabir Pradhan <prabirmsp@google.com> 2023-06-23 18:57:22 +0000
commit0762b1f7ddcdc92b4175fa858028c752a930e61a (patch)
tree7530b5253588cc8c4e24a0a6544f35f27237a821
parent89f7119821cad623418b6091fccab72d12e9cc01 (diff)
Re-organize and export libinput_rust as a rust library
We export some definitions from libinput_rust as the "input" crate so they can be used directly by other rust libraries. Bug: 278783893 Test: atest libinput_rust_test Change-Id: Icba79b67103f710d8bb1cb8892016bbd4e3e6ff9
-rw-r--r--libs/input/Android.bp61
-rw-r--r--libs/input/InputVerifier.cpp2
-rw-r--r--libs/input/rust/Android.bp72
-rw-r--r--libs/input/rust/input.rs126
-rw-r--r--libs/input/rust/input_verifier.rs (renamed from libs/input/input_verifier.rs)208
-rw-r--r--libs/input/rust/lib.rs88
6 files changed, 319 insertions, 238 deletions
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 30e4afe27d..f9f3d47301 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -109,62 +109,6 @@ cc_library_static {
],
}
-genrule {
- name: "libinput_cxx_bridge_code",
- tools: ["cxxbridge"],
- cmd: "$(location cxxbridge) $(in) >> $(out)",
- srcs: ["input_verifier.rs"],
- out: ["inputverifier_generated.cpp"],
-}
-
-genrule {
- name: "libinput_cxx_bridge_header",
- tools: ["cxxbridge"],
- cmd: "$(location cxxbridge) $(in) --header >> $(out)",
- srcs: ["input_verifier.rs"],
- out: ["input_verifier.rs.h"],
-}
-
-rust_defaults {
- name: "libinput_rust_defaults",
- srcs: ["input_verifier.rs"],
- host_supported: true,
- rustlibs: [
- "libbitflags",
- "libcxx",
- "libinput_bindgen",
- "liblogger",
- "liblog_rust",
- "inputconstants-rust",
- ],
-
- shared_libs: [
- "libbase",
- "liblog",
- ],
-}
-
-rust_ffi_static {
- name: "libinput_rust",
- crate_name: "input",
- defaults: ["libinput_rust_defaults"],
-}
-
-rust_test {
- name: "libinput_rust_test",
- defaults: ["libinput_rust_defaults"],
- whole_static_libs: [
- "libinput_from_rust_to_cpp",
- ],
- test_options: {
- unit_test: true,
- },
- test_suites: ["device_tests"],
- sanitize: {
- hwaddress: true,
- },
-}
-
cc_library {
name: "libinput",
cpp_std: "c++20",
@@ -176,7 +120,6 @@ cc_library {
"-Wno-unused-parameter",
],
srcs: [
- "FromRustToCpp.cpp",
"Input.cpp",
"InputDevice.cpp",
"InputEventLabels.cpp",
@@ -208,8 +151,6 @@ cc_library {
"toolbox_input_labels",
],
- generated_sources: ["libinput_cxx_bridge_code"],
-
shared_libs: [
"libbase",
"libcutils",
@@ -235,7 +176,7 @@ cc_library {
],
whole_static_libs: [
- "libinput_rust",
+ "libinput_rust_ffi",
],
export_static_lib_headers: [
diff --git a/libs/input/InputVerifier.cpp b/libs/input/InputVerifier.cpp
index 32b4ca0fc1..b0546a5243 100644
--- a/libs/input/InputVerifier.cpp
+++ b/libs/input/InputVerifier.cpp
@@ -18,7 +18,7 @@
#include <android-base/logging.h>
#include <input/InputVerifier.h>
-#include "input_verifier.rs.h"
+#include "input_cxx_bridge.rs.h"
using android::base::Error;
using android::base::Result;
diff --git a/libs/input/rust/Android.bp b/libs/input/rust/Android.bp
new file mode 100644
index 0000000000..018d199ce2
--- /dev/null
+++ b/libs/input/rust/Android.bp
@@ -0,0 +1,72 @@
+// Copyright 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+rust_defaults {
+ name: "libinput_rust_defaults",
+ crate_name: "input",
+ srcs: ["lib.rs"],
+ host_supported: true,
+ rustlibs: [
+ "libbitflags",
+ "libcxx",
+ "libinput_bindgen",
+ "liblogger",
+ "liblog_rust",
+ "inputconstants-rust",
+ ],
+ whole_static_libs: [
+ "libinput_from_rust_to_cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ ],
+}
+
+rust_library {
+ name: "libinput_rust",
+ defaults: ["libinput_rust_defaults"],
+}
+
+rust_ffi_static {
+ name: "libinput_rust_ffi",
+ defaults: ["libinput_rust_defaults"],
+}
+
+rust_test {
+ name: "libinput_rust_test",
+ defaults: ["libinput_rust_defaults"],
+ test_options: {
+ unit_test: true,
+ },
+ test_suites: ["device_tests"],
+ sanitize: {
+ hwaddress: true,
+ },
+}
+
+genrule {
+ name: "libinput_cxx_bridge_code",
+ tools: ["cxxbridge"],
+ cmd: "$(location cxxbridge) $(in) >> $(out)",
+ srcs: ["lib.rs"],
+ out: ["input_cxx_bridge_generated.cpp"],
+}
+
+genrule {
+ name: "libinput_cxx_bridge_header",
+ tools: ["cxxbridge"],
+ cmd: "$(location cxxbridge) $(in) --header >> $(out)",
+ srcs: ["lib.rs"],
+ out: ["input_cxx_bridge.rs.h"],
+}
diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs
new file mode 100644
index 0000000000..a308c26b2e
--- /dev/null
+++ b/libs/input/rust/input.rs
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Common definitions of the Android Input Framework in rust.
+
+use bitflags::bitflags;
+use std::fmt;
+
+/// The InputDevice ID.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+pub struct DeviceId(pub i32);
+
+/// A rust enum representation of a MotionEvent action.
+#[repr(u32)]
+pub enum MotionAction {
+ /// ACTION_DOWN
+ Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN,
+ /// ACTION_UP
+ Up = input_bindgen::AMOTION_EVENT_ACTION_UP,
+ /// ACTION_MOVE
+ Move = input_bindgen::AMOTION_EVENT_ACTION_MOVE,
+ /// ACTION_CANCEL
+ Cancel = input_bindgen::AMOTION_EVENT_ACTION_CANCEL,
+ /// ACTION_OUTSIDE
+ Outside = input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE,
+ /// ACTION_POINTER_DOWN
+ PointerDown {
+ /// The index of the affected pointer.
+ action_index: usize,
+ } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN,
+ /// ACTION_POINTER_UP
+ PointerUp {
+ /// The index of the affected pointer.
+ action_index: usize,
+ } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP,
+ /// ACTION_HOVER_ENTER
+ HoverEnter = input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER,
+ /// ACTION_HOVER_MOVE
+ HoverMove = input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE,
+ /// ACTION_HOVER_EXIT
+ HoverExit = input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT,
+ /// ACTION_SCROLL
+ Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL,
+ /// ACTION_BUTTON_PRESS
+ ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS,
+ /// ACTION_BUTTON_RELEASE
+ ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
+}
+
+impl fmt::Display for MotionAction {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ MotionAction::Down => write!(f, "DOWN"),
+ MotionAction::Up => write!(f, "UP"),
+ MotionAction::Move => write!(f, "MOVE"),
+ MotionAction::Cancel => write!(f, "CANCEL"),
+ MotionAction::Outside => write!(f, "OUTSIDE"),
+ MotionAction::PointerDown { action_index } => {
+ write!(f, "POINTER_DOWN({})", action_index)
+ }
+ MotionAction::PointerUp { action_index } => write!(f, "POINTER_UP({})", action_index),
+ MotionAction::HoverMove => write!(f, "HOVER_MOVE"),
+ 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"),
+ }
+ }
+}
+
+impl From<u32> for MotionAction {
+ fn from(action: u32) -> Self {
+ let (action_masked, action_index) = MotionAction::breakdown_action(action);
+ match action_masked {
+ input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down,
+ input_bindgen::AMOTION_EVENT_ACTION_UP => MotionAction::Up,
+ input_bindgen::AMOTION_EVENT_ACTION_MOVE => MotionAction::Move,
+ input_bindgen::AMOTION_EVENT_ACTION_CANCEL => MotionAction::Cancel,
+ input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE => MotionAction::Outside,
+ input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN => {
+ MotionAction::PointerDown { action_index }
+ }
+ input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP => {
+ MotionAction::PointerUp { action_index }
+ }
+ input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER => MotionAction::HoverEnter,
+ 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,
+ _ => 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)
+ >> input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ (action_masked, index.try_into().unwrap())
+ }
+}
+
+bitflags! {
+ /// MotionEvent flags.
+ pub struct MotionFlags: i32 {
+ /// FLAG_CANCELED
+ const CANCELED = input_bindgen::AMOTION_EVENT_FLAG_CANCELED;
+ }
+}
diff --git a/libs/input/input_verifier.rs b/libs/input/rust/input_verifier.rs
index 2e05a63149..1cc11297b6 100644
--- a/libs/input/input_verifier.rs
+++ b/libs/input/rust/input_verifier.rs
@@ -14,191 +14,45 @@
* limitations under the License.
*/
-//! Validate the incoming motion stream.
-//! This class is not thread-safe.
-//! State is stored in the "InputVerifier" object
-//! that can be created via the 'create' method.
-//! Usage:
-//! Box<InputVerifier> verifier = create("inputChannel name");
-//! result = process_movement(verifier, ...);
-//! if (result) {
-//! crash(result.error_message());
-//! }
+//! Contains the InputVerifier, used to validate a stream of input events.
+use crate::ffi::RustPointerProperties;
+use crate::input::{DeviceId, MotionAction, MotionFlags};
+use log::info;
use std::collections::HashMap;
use std::collections::HashSet;
-use bitflags::bitflags;
-use log::info;
-
-#[cxx::bridge(namespace = "android::input")]
-mod ffi {
- #[namespace = "android"]
- unsafe extern "C++" {
- include!("ffi/FromRustToCpp.h");
- fn shouldLog(tag: &str) -> bool;
- }
- #[namespace = "android::input::verifier"]
- extern "Rust" {
- type InputVerifier;
-
- fn create(name: String) -> Box<InputVerifier>;
- fn process_movement(
- verifier: &mut InputVerifier,
- device_id: i32,
- action: u32,
- pointer_properties: &[RustPointerProperties],
- flags: i32,
- ) -> String;
- }
-
- pub struct RustPointerProperties {
- id: i32,
- }
-}
-
-use crate::ffi::shouldLog;
-use crate::ffi::RustPointerProperties;
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-struct DeviceId(i32);
-
-fn process_movement(
- verifier: &mut InputVerifier,
- device_id: i32,
- action: u32,
- pointer_properties: &[RustPointerProperties],
- flags: i32,
-) -> String {
- let result = verifier.process_movement(
- DeviceId(device_id),
- action,
- pointer_properties,
- Flags::from_bits(flags).unwrap(),
- );
- match result {
- Ok(()) => "".to_string(),
- Err(e) => e,
- }
-}
-
-fn create(name: String) -> Box<InputVerifier> {
- Box::new(InputVerifier::new(&name))
-}
-
-#[repr(u32)]
-enum MotionAction {
- Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN,
- Up = input_bindgen::AMOTION_EVENT_ACTION_UP,
- Move = input_bindgen::AMOTION_EVENT_ACTION_MOVE,
- Cancel = input_bindgen::AMOTION_EVENT_ACTION_CANCEL,
- Outside = input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE,
- PointerDown { action_index: usize } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN,
- PointerUp { action_index: usize } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP,
- HoverEnter = input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER,
- HoverMove = input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE,
- HoverExit = input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT,
- Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL,
- ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS,
- ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
-}
-
-fn get_action_index(action: u32) -> usize {
- let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
- >> input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- index.try_into().unwrap()
-}
-
-impl From<u32> for MotionAction {
- fn from(action: u32) -> Self {
- let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK;
- let action_index = get_action_index(action);
- match action_masked {
- input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down,
- input_bindgen::AMOTION_EVENT_ACTION_UP => MotionAction::Up,
- input_bindgen::AMOTION_EVENT_ACTION_MOVE => MotionAction::Move,
- input_bindgen::AMOTION_EVENT_ACTION_CANCEL => MotionAction::Cancel,
- input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE => MotionAction::Outside,
- input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN => {
- MotionAction::PointerDown { action_index }
- }
- input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP => {
- MotionAction::PointerUp { action_index }
- }
- input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER => MotionAction::HoverEnter,
- 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,
- _ => panic!("Unknown action: {}", action),
- }
- }
-}
-
-bitflags! {
- struct Flags: i32 {
- const CANCELED = input_bindgen::AMOTION_EVENT_FLAG_CANCELED;
- }
-}
-
-fn motion_action_to_string(action: u32) -> String {
- match action.into() {
- MotionAction::Down => "DOWN".to_string(),
- MotionAction::Up => "UP".to_string(),
- MotionAction::Move => "MOVE".to_string(),
- MotionAction::Cancel => "CANCEL".to_string(),
- MotionAction::Outside => "OUTSIDE".to_string(),
- MotionAction::PointerDown { action_index } => {
- format!("POINTER_DOWN({})", action_index)
- }
- MotionAction::PointerUp { action_index } => {
- format!("POINTER_UP({})", action_index)
- }
- MotionAction::HoverMove => "HOVER_MOVE".to_string(),
- MotionAction::Scroll => "SCROLL".to_string(),
- MotionAction::HoverEnter => "HOVER_ENTER".to_string(),
- MotionAction::HoverExit => "HOVER_EXIT".to_string(),
- MotionAction::ButtonPress => "BUTTON_PRESS".to_string(),
- MotionAction::ButtonRelease => "BUTTON_RELEASE".to_string(),
- }
-}
-
-/**
- * Log all of the movements that are sent to this verifier. Helps to identify the streams that lead
- * to inconsistent events.
- * Enable this via "adb shell setprop log.tag.InputVerifierLogEvents DEBUG"
- */
-fn log_events() -> bool {
- shouldLog("InputVerifierLogEvents")
-}
-
-struct InputVerifier {
+/// The InputVerifier is used to validate a stream of input events.
+pub struct InputVerifier {
name: String,
+ should_log: bool,
touching_pointer_ids_by_device: HashMap<DeviceId, HashSet<i32>>,
}
impl InputVerifier {
- fn new(name: &str) -> Self {
+ /// Create a new InputVerifier.
+ pub fn new(name: &str, should_log: bool) -> Self {
logger::init(
logger::Config::default()
.with_tag_on_device("InputVerifier")
.with_min_level(log::Level::Trace),
);
- Self { name: name.to_owned(), touching_pointer_ids_by_device: HashMap::new() }
+ Self { name: name.to_owned(), should_log, touching_pointer_ids_by_device: HashMap::new() }
}
- fn process_movement(
+ /// Process a pointer movement event from an InputDevice.
+ /// If the event is not valid, we return an error string that describes the issue.
+ pub fn process_movement(
&mut self,
device_id: DeviceId,
action: u32,
pointer_properties: &[RustPointerProperties],
- flags: Flags,
+ flags: MotionFlags,
) -> Result<(), String> {
- if log_events() {
+ if self.should_log {
info!(
"Processing {} for device {:?} ({} pointer{}) on {}",
- motion_action_to_string(action),
+ MotionAction::from(action).to_string(),
device_id,
pointer_properties.len(),
if pointer_properties.len() == 1 { "" } else { "s" },
@@ -284,7 +138,7 @@ impl InputVerifier {
it.clear();
}
MotionAction::Cancel => {
- if flags.contains(Flags::CANCELED) {
+ if flags.contains(MotionFlags::CANCELED) {
return Err(format!(
"{}: For ACTION_CANCEL, must set FLAG_CANCELED",
self.name
@@ -325,20 +179,20 @@ impl InputVerifier {
#[cfg(test)]
mod tests {
+ use crate::input_verifier::InputVerifier;
use crate::DeviceId;
- use crate::Flags;
- use crate::InputVerifier;
+ use crate::MotionFlags;
use crate::RustPointerProperties;
#[test]
fn single_pointer_stream() {
- let mut verifier = InputVerifier::new("Test");
+ let mut verifier = InputVerifier::new("Test", /*should_log*/ false);
let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]);
assert!(verifier
.process_movement(
DeviceId(1),
input_bindgen::AMOTION_EVENT_ACTION_DOWN,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
assert!(verifier
@@ -346,7 +200,7 @@ mod tests {
DeviceId(1),
input_bindgen::AMOTION_EVENT_ACTION_MOVE,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
assert!(verifier
@@ -354,21 +208,21 @@ mod tests {
DeviceId(1),
input_bindgen::AMOTION_EVENT_ACTION_UP,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
}
#[test]
fn multi_device_stream() {
- let mut verifier = InputVerifier::new("Test");
+ let mut verifier = InputVerifier::new("Test", /*should_log*/ false);
let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]);
assert!(verifier
.process_movement(
DeviceId(1),
input_bindgen::AMOTION_EVENT_ACTION_DOWN,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
assert!(verifier
@@ -376,7 +230,7 @@ mod tests {
DeviceId(1),
input_bindgen::AMOTION_EVENT_ACTION_MOVE,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
assert!(verifier
@@ -384,7 +238,7 @@ mod tests {
DeviceId(2),
input_bindgen::AMOTION_EVENT_ACTION_DOWN,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
assert!(verifier
@@ -392,7 +246,7 @@ mod tests {
DeviceId(2),
input_bindgen::AMOTION_EVENT_ACTION_MOVE,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
assert!(verifier
@@ -400,21 +254,21 @@ mod tests {
DeviceId(1),
input_bindgen::AMOTION_EVENT_ACTION_UP,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_ok());
}
#[test]
fn test_invalid_up() {
- let mut verifier = InputVerifier::new("Test");
+ let mut verifier = InputVerifier::new("Test", /*should_log*/ false);
let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]);
assert!(verifier
.process_movement(
DeviceId(1),
input_bindgen::AMOTION_EVENT_ACTION_UP,
&pointer_properties,
- Flags::empty(),
+ MotionFlags::empty(),
)
.is_err());
}
diff --git a/libs/input/rust/lib.rs b/libs/input/rust/lib.rs
new file mode 100644
index 0000000000..25b2ecbcda
--- /dev/null
+++ b/libs/input/rust/lib.rs
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! The rust component of libinput.
+
+mod input;
+mod input_verifier;
+
+pub use input::{DeviceId, MotionAction, MotionFlags};
+pub use input_verifier::InputVerifier;
+
+#[cxx::bridge(namespace = "android::input")]
+mod ffi {
+ #[namespace = "android"]
+ unsafe extern "C++" {
+ include!("ffi/FromRustToCpp.h");
+ fn shouldLog(tag: &str) -> bool;
+ }
+
+ #[namespace = "android::input::verifier"]
+ extern "Rust" {
+ /// Used to validate the incoming motion stream.
+ /// This class is not thread-safe.
+ /// State is stored in the "InputVerifier" object
+ /// that can be created via the 'create' method.
+ /// Usage:
+ ///
+ /// ```ignore
+ /// Box<InputVerifier> verifier = create("inputChannel name");
+ /// result = process_movement(verifier, ...);
+ /// if (result) {
+ /// crash(result.error_message());
+ /// }
+ /// ```
+ type InputVerifier;
+ fn create(name: String) -> Box<InputVerifier>;
+ fn process_movement(
+ verifier: &mut InputVerifier,
+ device_id: i32,
+ action: u32,
+ pointer_properties: &[RustPointerProperties],
+ flags: i32,
+ ) -> String;
+ }
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+ pub struct RustPointerProperties {
+ pub id: i32,
+ }
+}
+
+use crate::ffi::RustPointerProperties;
+
+fn process_movement(
+ verifier: &mut InputVerifier,
+ device_id: i32,
+ action: u32,
+ pointer_properties: &[RustPointerProperties],
+ flags: i32,
+) -> String {
+ let result = verifier.process_movement(
+ DeviceId(device_id),
+ action,
+ pointer_properties,
+ MotionFlags::from_bits(flags).unwrap(),
+ );
+ match result {
+ Ok(()) => "".to_string(),
+ Err(e) => e,
+ }
+}
+
+fn create(name: String) -> Box<InputVerifier> {
+ Box::new(InputVerifier::new(&name, ffi::shouldLog("InputVerifierLogEvents")))
+}