blob: c46b7bb85c95ea253bee48bd86997844b80f9cf9 [file] [log] [blame]
Prabir Pradhan0762b1f2023-06-22 23:08:18 +00001/*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Common definitions of the Android Input Framework in rust.
18
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000019use crate::ffi::RustInputDeviceIdentifier;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000020use bitflags::bitflags;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000021use inputconstants::aidl::android::os::IInputConstants;
Prabir Pradhan29814f22024-06-18 14:53:10 +000022use inputconstants::aidl::android::os::MotionEventFlag::MotionEventFlag;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000023use std::fmt;
24
25/// The InputDevice ID.
26#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
27pub struct DeviceId(pub i32);
28
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000029/// The InputDevice equivalent for Rust inputflinger
30#[derive(Debug)]
31pub struct InputDevice {
32 /// InputDevice ID
33 pub device_id: DeviceId,
34 /// InputDevice unique identifier
35 pub identifier: RustInputDeviceIdentifier,
36 /// InputDevice classes (equivalent to EventHub InputDeviceClass)
37 pub classes: DeviceClass,
38}
39
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070040#[repr(u32)]
41pub enum SourceClass {
42 None = input_bindgen::AINPUT_SOURCE_CLASS_NONE,
43 Button = input_bindgen::AINPUT_SOURCE_CLASS_BUTTON,
44 Pointer = input_bindgen::AINPUT_SOURCE_CLASS_POINTER,
45 Navigation = input_bindgen::AINPUT_SOURCE_CLASS_NAVIGATION,
46 Position = input_bindgen::AINPUT_SOURCE_CLASS_POSITION,
47 Joystick = input_bindgen::AINPUT_SOURCE_CLASS_JOYSTICK,
48}
49
50bitflags! {
51 /// Source of the input device or input events.
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070052 #[derive(Debug, PartialEq)]
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070053 pub struct Source: u32 {
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070054 // Constants from SourceClass, added here for compatibility reasons
55 /// SourceClass::Button
56 const SourceClassButton = SourceClass::Button as u32;
57 /// SourceClass::Pointer
58 const SourceClassPointer = SourceClass::Pointer as u32;
59 /// SourceClass::Navigation
60 const SourceClassNavigation = SourceClass::Navigation as u32;
61 /// SourceClass::Position
62 const SourceClassPosition = SourceClass::Position as u32;
63 /// SourceClass::Joystick
64 const SourceClassJoystick = SourceClass::Joystick as u32;
65
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070066 /// SOURCE_UNKNOWN
67 const Unknown = input_bindgen::AINPUT_SOURCE_UNKNOWN;
68 /// SOURCE_KEYBOARD
69 const Keyboard = input_bindgen::AINPUT_SOURCE_KEYBOARD;
70 /// SOURCE_DPAD
71 const Dpad = input_bindgen::AINPUT_SOURCE_DPAD;
72 /// SOURCE_GAMEPAD
73 const Gamepad = input_bindgen::AINPUT_SOURCE_GAMEPAD;
74 /// SOURCE_TOUCHSCREEN
75 const Touchscreen = input_bindgen::AINPUT_SOURCE_TOUCHSCREEN;
76 /// SOURCE_MOUSE
77 const Mouse = input_bindgen::AINPUT_SOURCE_MOUSE;
78 /// SOURCE_STYLUS
79 const Stylus = input_bindgen::AINPUT_SOURCE_STYLUS;
80 /// SOURCE_BLUETOOTH_STYLUS
81 const BluetoothStylus = input_bindgen::AINPUT_SOURCE_BLUETOOTH_STYLUS;
82 /// SOURCE_TRACKBALL
83 const Trackball = input_bindgen::AINPUT_SOURCE_TRACKBALL;
84 /// SOURCE_MOUSE_RELATIVE
85 const MouseRelative = input_bindgen::AINPUT_SOURCE_MOUSE_RELATIVE;
86 /// SOURCE_TOUCHPAD
87 const Touchpad = input_bindgen::AINPUT_SOURCE_TOUCHPAD;
88 /// SOURCE_TOUCH_NAVIGATION
89 const TouchNavigation = input_bindgen::AINPUT_SOURCE_TOUCH_NAVIGATION;
90 /// SOURCE_JOYSTICK
91 const Joystick = input_bindgen::AINPUT_SOURCE_JOYSTICK;
92 /// SOURCE_HDMI
93 const HDMI = input_bindgen::AINPUT_SOURCE_HDMI;
94 /// SOURCE_SENSOR
95 const Sensor = input_bindgen::AINPUT_SOURCE_SENSOR;
96 /// SOURCE_ROTARY_ENCODER
97 const RotaryEncoder = input_bindgen::AINPUT_SOURCE_ROTARY_ENCODER;
98 }
99}
100
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000101/// A rust enum representation of a MotionEvent action.
102#[repr(u32)]
103pub enum MotionAction {
104 /// ACTION_DOWN
105 Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN,
106 /// ACTION_UP
107 Up = input_bindgen::AMOTION_EVENT_ACTION_UP,
108 /// ACTION_MOVE
109 Move = input_bindgen::AMOTION_EVENT_ACTION_MOVE,
110 /// ACTION_CANCEL
111 Cancel = input_bindgen::AMOTION_EVENT_ACTION_CANCEL,
112 /// ACTION_OUTSIDE
113 Outside = input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE,
114 /// ACTION_POINTER_DOWN
115 PointerDown {
116 /// The index of the affected pointer.
117 action_index: usize,
118 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN,
119 /// ACTION_POINTER_UP
120 PointerUp {
121 /// The index of the affected pointer.
122 action_index: usize,
123 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP,
124 /// ACTION_HOVER_ENTER
125 HoverEnter = input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER,
126 /// ACTION_HOVER_MOVE
127 HoverMove = input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE,
128 /// ACTION_HOVER_EXIT
129 HoverExit = input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT,
130 /// ACTION_SCROLL
131 Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL,
132 /// ACTION_BUTTON_PRESS
133 ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS,
134 /// ACTION_BUTTON_RELEASE
135 ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
136}
137
138impl fmt::Display for MotionAction {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 match self {
141 MotionAction::Down => write!(f, "DOWN"),
142 MotionAction::Up => write!(f, "UP"),
143 MotionAction::Move => write!(f, "MOVE"),
144 MotionAction::Cancel => write!(f, "CANCEL"),
145 MotionAction::Outside => write!(f, "OUTSIDE"),
146 MotionAction::PointerDown { action_index } => {
147 write!(f, "POINTER_DOWN({})", action_index)
148 }
149 MotionAction::PointerUp { action_index } => write!(f, "POINTER_UP({})", action_index),
150 MotionAction::HoverMove => write!(f, "HOVER_MOVE"),
151 MotionAction::Scroll => write!(f, "SCROLL"),
152 MotionAction::HoverEnter => write!(f, "HOVER_ENTER"),
153 MotionAction::HoverExit => write!(f, "HOVER_EXIT"),
154 MotionAction::ButtonPress => write!(f, "BUTTON_PRESS"),
155 MotionAction::ButtonRelease => write!(f, "BUTTON_RELEASE"),
156 }
157 }
158}
159
160impl From<u32> for MotionAction {
161 fn from(action: u32) -> Self {
162 let (action_masked, action_index) = MotionAction::breakdown_action(action);
163 match action_masked {
164 input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down,
165 input_bindgen::AMOTION_EVENT_ACTION_UP => MotionAction::Up,
166 input_bindgen::AMOTION_EVENT_ACTION_MOVE => MotionAction::Move,
167 input_bindgen::AMOTION_EVENT_ACTION_CANCEL => MotionAction::Cancel,
168 input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE => MotionAction::Outside,
169 input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN => {
170 MotionAction::PointerDown { action_index }
171 }
172 input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP => {
173 MotionAction::PointerUp { action_index }
174 }
175 input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER => MotionAction::HoverEnter,
176 input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE => MotionAction::HoverMove,
177 input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT => MotionAction::HoverExit,
178 input_bindgen::AMOTION_EVENT_ACTION_SCROLL => MotionAction::Scroll,
179 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => MotionAction::ButtonPress,
180 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => MotionAction::ButtonRelease,
181 _ => panic!("Unknown action: {}", action),
182 }
183 }
184}
185
186impl MotionAction {
187 fn breakdown_action(action: u32) -> (u32, usize) {
188 let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK;
189 let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
190 >> input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
191 (action_masked, index.try_into().unwrap())
192 }
193}
194
195bitflags! {
196 /// MotionEvent flags.
Prabir Pradhan29814f22024-06-18 14:53:10 +0000197 /// The source of truth for the flag definitions are the MotionEventFlag AIDL enum.
198 /// The flag values are redefined here as a bitflags API.
Siarhei Vishniakou93992432023-10-09 15:47:48 -0700199 #[derive(Debug)]
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700200 pub struct MotionFlags: u32 {
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700201 /// FLAG_WINDOW_IS_OBSCURED
Prabir Pradhan29814f22024-06-18 14:53:10 +0000202 const WINDOW_IS_OBSCURED = MotionEventFlag::WINDOW_IS_OBSCURED.0 as u32;
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700203 /// FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Prabir Pradhan29814f22024-06-18 14:53:10 +0000204 const WINDOW_IS_PARTIALLY_OBSCURED = MotionEventFlag::WINDOW_IS_PARTIALLY_OBSCURED.0 as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700205 /// FLAG_HOVER_EXIT_PENDING
Prabir Pradhan29814f22024-06-18 14:53:10 +0000206 const HOVER_EXIT_PENDING = MotionEventFlag::HOVER_EXIT_PENDING.0 as u32;
Linnan Lia3b18f42024-04-17 16:54:55 +0000207 /// FLAG_IS_GENERATED_GESTURE
Prabir Pradhan29814f22024-06-18 14:53:10 +0000208 const IS_GENERATED_GESTURE = MotionEventFlag::IS_GENERATED_GESTURE.0 as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700209 /// FLAG_CANCELED
Prabir Pradhan29814f22024-06-18 14:53:10 +0000210 const CANCELED = MotionEventFlag::CANCELED.0 as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700211 /// FLAG_NO_FOCUS_CHANGE
Prabir Pradhan29814f22024-06-18 14:53:10 +0000212 const NO_FOCUS_CHANGE = MotionEventFlag::NO_FOCUS_CHANGE.0 as u32;
Prabir Pradhancda32662024-06-11 15:31:40 +0000213 /// PRIVATE_FLAG_SUPPORTS_ORIENTATION
Prabir Pradhan29814f22024-06-18 14:53:10 +0000214 const PRIVATE_FLAG_SUPPORTS_ORIENTATION =
215 MotionEventFlag::PRIVATE_FLAG_SUPPORTS_ORIENTATION.0 as u32;
Prabir Pradhancda32662024-06-11 15:31:40 +0000216 /// PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION
Prabir Pradhan29814f22024-06-18 14:53:10 +0000217 const PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION =
218 MotionEventFlag::PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION.0 as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700219 /// FLAG_IS_ACCESSIBILITY_EVENT
Prabir Pradhan29814f22024-06-18 14:53:10 +0000220 const IS_ACCESSIBILITY_EVENT = MotionEventFlag::IS_ACCESSIBILITY_EVENT.0 as u32;
Linnan Lif3ec5482024-04-18 16:45:05 +0000221 /// FLAG_TAINTED
Prabir Pradhan29814f22024-06-18 14:53:10 +0000222 const TAINTED = MotionEventFlag::TAINTED.0 as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700223 /// FLAG_TARGET_ACCESSIBILITY_FOCUS
Prabir Pradhan29814f22024-06-18 14:53:10 +0000224 const TARGET_ACCESSIBILITY_FOCUS = MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS.0 as u32;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000225 }
226}
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700227
228impl Source {
229 /// Return true if this source is from the provided class
230 pub fn is_from_class(&self, source_class: SourceClass) -> bool {
231 let class_bits = source_class as u32;
232 self.bits() & class_bits == class_bits
233 }
234}
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700235
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000236bitflags! {
237 /// Device class of the input device. These are duplicated from Eventhub.h
238 /// We need to make sure the two version remain in sync when adding new classes.
239 #[derive(Debug, PartialEq)]
240 pub struct DeviceClass: u32 {
241 /// The input device is a keyboard or has buttons
242 const Keyboard = IInputConstants::DEVICE_CLASS_KEYBOARD as u32;
243 /// The input device is an alpha-numeric keyboard (not just a dial pad)
244 const AlphabeticKey = IInputConstants::DEVICE_CLASS_ALPHAKEY as u32;
245 /// The input device is a touchscreen or a touchpad (either single-touch or multi-touch)
246 const Touch = IInputConstants::DEVICE_CLASS_TOUCH as u32;
247 /// The input device is a cursor device such as a trackball or mouse.
248 const Cursor = IInputConstants::DEVICE_CLASS_CURSOR as u32;
249 /// The input device is a multi-touch touchscreen or touchpad.
250 const MultiTouch = IInputConstants::DEVICE_CLASS_TOUCH_MT as u32;
251 /// The input device is a directional pad (implies keyboard, has DPAD keys).
252 const Dpad = IInputConstants::DEVICE_CLASS_DPAD as u32;
253 /// The input device is a gamepad (implies keyboard, has BUTTON keys).
254 const Gamepad = IInputConstants::DEVICE_CLASS_GAMEPAD as u32;
255 /// The input device has switches.
256 const Switch = IInputConstants::DEVICE_CLASS_SWITCH as u32;
257 /// The input device is a joystick (implies gamepad, has joystick absolute axes).
258 const Joystick = IInputConstants::DEVICE_CLASS_JOYSTICK as u32;
259 /// The input device has a vibrator (supports FF_RUMBLE).
260 const Vibrator = IInputConstants::DEVICE_CLASS_VIBRATOR as u32;
261 /// The input device has a microphone.
262 const Mic = IInputConstants::DEVICE_CLASS_MIC as u32;
263 /// The input device is an external stylus (has data we want to fuse with touch data).
264 const ExternalStylus = IInputConstants::DEVICE_CLASS_EXTERNAL_STYLUS as u32;
265 /// The input device has a rotary encoder
266 const RotaryEncoder = IInputConstants::DEVICE_CLASS_ROTARY_ENCODER as u32;
267 /// The input device has a sensor like accelerometer, gyro, etc
268 const Sensor = IInputConstants::DEVICE_CLASS_SENSOR as u32;
269 /// The input device has a battery
270 const Battery = IInputConstants::DEVICE_CLASS_BATTERY as u32;
271 /// The input device has sysfs controllable lights
272 const Light = IInputConstants::DEVICE_CLASS_LIGHT as u32;
273 /// The input device is a touchpad, requiring an on-screen cursor.
274 const Touchpad = IInputConstants::DEVICE_CLASS_TOUCHPAD as u32;
275 /// The input device is virtual (not a real device, not part of UI configuration).
276 const Virtual = IInputConstants::DEVICE_CLASS_VIRTUAL as u32;
277 /// The input device is external (not built-in).
278 const External = IInputConstants::DEVICE_CLASS_EXTERNAL as u32;
279 }
280}
281
282bitflags! {
283 /// Modifier state flags
Vaibhav Devmurari770b6e42024-06-10 10:29:26 +0000284 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000285 pub struct ModifierState: u32 {
286 /// No meta keys are pressed
287 const None = input_bindgen::AMETA_NONE;
288 /// This mask is used to check whether one of the ALT meta keys is pressed
289 const AltOn = input_bindgen::AMETA_ALT_ON;
290 /// This mask is used to check whether the left ALT meta key is pressed
291 const AltLeftOn = input_bindgen::AMETA_ALT_LEFT_ON;
292 /// This mask is used to check whether the right ALT meta key is pressed
293 const AltRightOn = input_bindgen::AMETA_ALT_RIGHT_ON;
294 /// This mask is used to check whether one of the SHIFT meta keys is pressed
295 const ShiftOn = input_bindgen::AMETA_SHIFT_ON;
296 /// This mask is used to check whether the left SHIFT meta key is pressed
297 const ShiftLeftOn = input_bindgen::AMETA_SHIFT_LEFT_ON;
298 /// This mask is used to check whether the right SHIFT meta key is pressed
299 const ShiftRightOn = input_bindgen::AMETA_SHIFT_RIGHT_ON;
300 /// This mask is used to check whether the SYM meta key is pressed
301 const SymOn = input_bindgen::AMETA_SYM_ON;
302 /// This mask is used to check whether the FUNCTION meta key is pressed
303 const FunctionOn = input_bindgen::AMETA_FUNCTION_ON;
304 /// This mask is used to check whether one of the CTRL meta keys is pressed
305 const CtrlOn = input_bindgen::AMETA_CTRL_ON;
306 /// This mask is used to check whether the left CTRL meta key is pressed
307 const CtrlLeftOn = input_bindgen::AMETA_CTRL_LEFT_ON;
308 /// This mask is used to check whether the right CTRL meta key is pressed
309 const CtrlRightOn = input_bindgen::AMETA_CTRL_RIGHT_ON;
310 /// This mask is used to check whether one of the META meta keys is pressed
311 const MetaOn = input_bindgen::AMETA_META_ON;
312 /// This mask is used to check whether the left META meta key is pressed
313 const MetaLeftOn = input_bindgen::AMETA_META_LEFT_ON;
314 /// This mask is used to check whether the right META meta key is pressed
315 const MetaRightOn = input_bindgen::AMETA_META_RIGHT_ON;
316 /// This mask is used to check whether the CAPS LOCK meta key is on
317 const CapsLockOn = input_bindgen::AMETA_CAPS_LOCK_ON;
318 /// This mask is used to check whether the NUM LOCK meta key is on
319 const NumLockOn = input_bindgen::AMETA_NUM_LOCK_ON;
320 /// This mask is used to check whether the SCROLL LOCK meta key is on
321 const ScrollLockOn = input_bindgen::AMETA_SCROLL_LOCK_ON;
322 }
323}
324
325/// A rust enum representation of a Keyboard type.
326#[repr(u32)]
327#[derive(Debug, Copy, Clone, Eq, PartialEq)]
328pub enum KeyboardType {
329 /// KEYBOARD_TYPE_NONE
330 None = input_bindgen::AINPUT_KEYBOARD_TYPE_NONE,
331 /// KEYBOARD_TYPE_NON_ALPHABETIC
332 NonAlphabetic = input_bindgen::AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC,
333 /// KEYBOARD_TYPE_ALPHABETIC
334 Alphabetic = input_bindgen::AINPUT_KEYBOARD_TYPE_ALPHABETIC,
335}
336
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700337#[cfg(test)]
338mod tests {
339 use crate::input::SourceClass;
Prabir Pradhan29814f22024-06-18 14:53:10 +0000340 use crate::MotionFlags;
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700341 use crate::Source;
Prabir Pradhan29814f22024-06-18 14:53:10 +0000342 use inputconstants::aidl::android::os::MotionEventFlag::MotionEventFlag;
343
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700344 #[test]
345 fn convert_source_class_pointer() {
346 let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
347 assert!(source.is_from_class(SourceClass::Pointer));
348 }
Prabir Pradhan29814f22024-06-18 14:53:10 +0000349
350 /// Ensure all MotionEventFlag constants are re-defined in rust.
351 #[test]
352 fn all_motion_event_flags_defined() {
353 for flag in MotionEventFlag::enum_values() {
354 assert!(
355 MotionFlags::from_bits(flag.0 as u32).is_some(),
356 "MotionEventFlag value {flag:?} is not redefined as a rust MotionFlags"
357 );
358 }
359 }
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700360}