blob: 564d94dbb4df3c0074d9a3071fc4b0398c8175b8 [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 Pradhan0762b1f2023-06-22 23:08:18 +000022use std::fmt;
23
24/// The InputDevice ID.
25#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
26pub struct DeviceId(pub i32);
27
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000028/// The InputDevice equivalent for Rust inputflinger
29#[derive(Debug)]
30pub struct InputDevice {
31 /// InputDevice ID
32 pub device_id: DeviceId,
33 /// InputDevice unique identifier
34 pub identifier: RustInputDeviceIdentifier,
35 /// InputDevice classes (equivalent to EventHub InputDeviceClass)
36 pub classes: DeviceClass,
37}
38
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070039#[repr(u32)]
40pub enum SourceClass {
41 None = input_bindgen::AINPUT_SOURCE_CLASS_NONE,
42 Button = input_bindgen::AINPUT_SOURCE_CLASS_BUTTON,
43 Pointer = input_bindgen::AINPUT_SOURCE_CLASS_POINTER,
44 Navigation = input_bindgen::AINPUT_SOURCE_CLASS_NAVIGATION,
45 Position = input_bindgen::AINPUT_SOURCE_CLASS_POSITION,
46 Joystick = input_bindgen::AINPUT_SOURCE_CLASS_JOYSTICK,
47}
48
49bitflags! {
50 /// Source of the input device or input events.
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070051 #[derive(Debug, PartialEq)]
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070052 pub struct Source: u32 {
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070053 // Constants from SourceClass, added here for compatibility reasons
54 /// SourceClass::Button
55 const SourceClassButton = SourceClass::Button as u32;
56 /// SourceClass::Pointer
57 const SourceClassPointer = SourceClass::Pointer as u32;
58 /// SourceClass::Navigation
59 const SourceClassNavigation = SourceClass::Navigation as u32;
60 /// SourceClass::Position
61 const SourceClassPosition = SourceClass::Position as u32;
62 /// SourceClass::Joystick
63 const SourceClassJoystick = SourceClass::Joystick as u32;
64
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070065 /// SOURCE_UNKNOWN
66 const Unknown = input_bindgen::AINPUT_SOURCE_UNKNOWN;
67 /// SOURCE_KEYBOARD
68 const Keyboard = input_bindgen::AINPUT_SOURCE_KEYBOARD;
69 /// SOURCE_DPAD
70 const Dpad = input_bindgen::AINPUT_SOURCE_DPAD;
71 /// SOURCE_GAMEPAD
72 const Gamepad = input_bindgen::AINPUT_SOURCE_GAMEPAD;
73 /// SOURCE_TOUCHSCREEN
74 const Touchscreen = input_bindgen::AINPUT_SOURCE_TOUCHSCREEN;
75 /// SOURCE_MOUSE
76 const Mouse = input_bindgen::AINPUT_SOURCE_MOUSE;
77 /// SOURCE_STYLUS
78 const Stylus = input_bindgen::AINPUT_SOURCE_STYLUS;
79 /// SOURCE_BLUETOOTH_STYLUS
80 const BluetoothStylus = input_bindgen::AINPUT_SOURCE_BLUETOOTH_STYLUS;
81 /// SOURCE_TRACKBALL
82 const Trackball = input_bindgen::AINPUT_SOURCE_TRACKBALL;
83 /// SOURCE_MOUSE_RELATIVE
84 const MouseRelative = input_bindgen::AINPUT_SOURCE_MOUSE_RELATIVE;
85 /// SOURCE_TOUCHPAD
86 const Touchpad = input_bindgen::AINPUT_SOURCE_TOUCHPAD;
87 /// SOURCE_TOUCH_NAVIGATION
88 const TouchNavigation = input_bindgen::AINPUT_SOURCE_TOUCH_NAVIGATION;
89 /// SOURCE_JOYSTICK
90 const Joystick = input_bindgen::AINPUT_SOURCE_JOYSTICK;
91 /// SOURCE_HDMI
92 const HDMI = input_bindgen::AINPUT_SOURCE_HDMI;
93 /// SOURCE_SENSOR
94 const Sensor = input_bindgen::AINPUT_SOURCE_SENSOR;
95 /// SOURCE_ROTARY_ENCODER
96 const RotaryEncoder = input_bindgen::AINPUT_SOURCE_ROTARY_ENCODER;
97 }
98}
99
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000100/// A rust enum representation of a MotionEvent action.
101#[repr(u32)]
102pub enum MotionAction {
103 /// ACTION_DOWN
104 Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN,
105 /// ACTION_UP
106 Up = input_bindgen::AMOTION_EVENT_ACTION_UP,
107 /// ACTION_MOVE
108 Move = input_bindgen::AMOTION_EVENT_ACTION_MOVE,
109 /// ACTION_CANCEL
110 Cancel = input_bindgen::AMOTION_EVENT_ACTION_CANCEL,
111 /// ACTION_OUTSIDE
112 Outside = input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE,
113 /// ACTION_POINTER_DOWN
114 PointerDown {
115 /// The index of the affected pointer.
116 action_index: usize,
117 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN,
118 /// ACTION_POINTER_UP
119 PointerUp {
120 /// The index of the affected pointer.
121 action_index: usize,
122 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP,
123 /// ACTION_HOVER_ENTER
124 HoverEnter = input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER,
125 /// ACTION_HOVER_MOVE
126 HoverMove = input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE,
127 /// ACTION_HOVER_EXIT
128 HoverExit = input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT,
129 /// ACTION_SCROLL
130 Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL,
131 /// ACTION_BUTTON_PRESS
132 ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS,
133 /// ACTION_BUTTON_RELEASE
134 ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
135}
136
137impl fmt::Display for MotionAction {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 match self {
140 MotionAction::Down => write!(f, "DOWN"),
141 MotionAction::Up => write!(f, "UP"),
142 MotionAction::Move => write!(f, "MOVE"),
143 MotionAction::Cancel => write!(f, "CANCEL"),
144 MotionAction::Outside => write!(f, "OUTSIDE"),
145 MotionAction::PointerDown { action_index } => {
146 write!(f, "POINTER_DOWN({})", action_index)
147 }
148 MotionAction::PointerUp { action_index } => write!(f, "POINTER_UP({})", action_index),
149 MotionAction::HoverMove => write!(f, "HOVER_MOVE"),
150 MotionAction::Scroll => write!(f, "SCROLL"),
151 MotionAction::HoverEnter => write!(f, "HOVER_ENTER"),
152 MotionAction::HoverExit => write!(f, "HOVER_EXIT"),
153 MotionAction::ButtonPress => write!(f, "BUTTON_PRESS"),
154 MotionAction::ButtonRelease => write!(f, "BUTTON_RELEASE"),
155 }
156 }
157}
158
159impl From<u32> for MotionAction {
160 fn from(action: u32) -> Self {
161 let (action_masked, action_index) = MotionAction::breakdown_action(action);
162 match action_masked {
163 input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down,
164 input_bindgen::AMOTION_EVENT_ACTION_UP => MotionAction::Up,
165 input_bindgen::AMOTION_EVENT_ACTION_MOVE => MotionAction::Move,
166 input_bindgen::AMOTION_EVENT_ACTION_CANCEL => MotionAction::Cancel,
167 input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE => MotionAction::Outside,
168 input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN => {
169 MotionAction::PointerDown { action_index }
170 }
171 input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP => {
172 MotionAction::PointerUp { action_index }
173 }
174 input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER => MotionAction::HoverEnter,
175 input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE => MotionAction::HoverMove,
176 input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT => MotionAction::HoverExit,
177 input_bindgen::AMOTION_EVENT_ACTION_SCROLL => MotionAction::Scroll,
178 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => MotionAction::ButtonPress,
179 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => MotionAction::ButtonRelease,
180 _ => panic!("Unknown action: {}", action),
181 }
182 }
183}
184
185impl MotionAction {
186 fn breakdown_action(action: u32) -> (u32, usize) {
187 let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK;
188 let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
189 >> input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
190 (action_masked, index.try_into().unwrap())
191 }
192}
193
194bitflags! {
195 /// MotionEvent flags.
Siarhei Vishniakou93992432023-10-09 15:47:48 -0700196 #[derive(Debug)]
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700197 pub struct MotionFlags: u32 {
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700198 /// FLAG_WINDOW_IS_OBSCURED
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000199 const WINDOW_IS_OBSCURED = IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED as u32;
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700200 /// FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000201 const WINDOW_IS_PARTIALLY_OBSCURED = IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700202 /// FLAG_HOVER_EXIT_PENDING
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000203 const HOVER_EXIT_PENDING = IInputConstants::MOTION_EVENT_FLAG_HOVER_EXIT_PENDING as u32;
Linnan Lia3b18f42024-04-17 16:54:55 +0000204 /// FLAG_IS_GENERATED_GESTURE
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000205 const IS_GENERATED_GESTURE = IInputConstants::MOTION_EVENT_FLAG_IS_GENERATED_GESTURE as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700206 /// FLAG_CANCELED
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000207 const CANCELED = IInputConstants::INPUT_EVENT_FLAG_CANCELED as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700208 /// FLAG_NO_FOCUS_CHANGE
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000209 const NO_FOCUS_CHANGE = IInputConstants::MOTION_EVENT_FLAG_NO_FOCUS_CHANGE as u32;
Prabir Pradhan7cf348d2024-06-11 15:31:40 +0000210 /// PRIVATE_FLAG_SUPPORTS_ORIENTATION
211 const PRIVATE_SUPPORTS_ORIENTATION = IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION as u32;
212 /// PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION
213 const PRIVATE_SUPPORTS_DIRECTIONAL_ORIENTATION =
214 IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700215 /// FLAG_IS_ACCESSIBILITY_EVENT
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000216 const IS_ACCESSIBILITY_EVENT = IInputConstants::INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT as u32;
Linnan Lif3ec5482024-04-18 16:45:05 +0000217 /// FLAG_TAINTED
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000218 const TAINTED = IInputConstants::INPUT_EVENT_FLAG_TAINTED as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700219 /// FLAG_TARGET_ACCESSIBILITY_FOCUS
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000220 const TARGET_ACCESSIBILITY_FOCUS = IInputConstants::MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS as u32;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000221 }
222}
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700223
224impl Source {
225 /// Return true if this source is from the provided class
226 pub fn is_from_class(&self, source_class: SourceClass) -> bool {
227 let class_bits = source_class as u32;
228 self.bits() & class_bits == class_bits
229 }
230}
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700231
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000232bitflags! {
233 /// Device class of the input device. These are duplicated from Eventhub.h
234 /// We need to make sure the two version remain in sync when adding new classes.
235 #[derive(Debug, PartialEq)]
236 pub struct DeviceClass: u32 {
237 /// The input device is a keyboard or has buttons
238 const Keyboard = IInputConstants::DEVICE_CLASS_KEYBOARD as u32;
239 /// The input device is an alpha-numeric keyboard (not just a dial pad)
240 const AlphabeticKey = IInputConstants::DEVICE_CLASS_ALPHAKEY as u32;
241 /// The input device is a touchscreen or a touchpad (either single-touch or multi-touch)
242 const Touch = IInputConstants::DEVICE_CLASS_TOUCH as u32;
243 /// The input device is a cursor device such as a trackball or mouse.
244 const Cursor = IInputConstants::DEVICE_CLASS_CURSOR as u32;
245 /// The input device is a multi-touch touchscreen or touchpad.
246 const MultiTouch = IInputConstants::DEVICE_CLASS_TOUCH_MT as u32;
247 /// The input device is a directional pad (implies keyboard, has DPAD keys).
248 const Dpad = IInputConstants::DEVICE_CLASS_DPAD as u32;
249 /// The input device is a gamepad (implies keyboard, has BUTTON keys).
250 const Gamepad = IInputConstants::DEVICE_CLASS_GAMEPAD as u32;
251 /// The input device has switches.
252 const Switch = IInputConstants::DEVICE_CLASS_SWITCH as u32;
253 /// The input device is a joystick (implies gamepad, has joystick absolute axes).
254 const Joystick = IInputConstants::DEVICE_CLASS_JOYSTICK as u32;
255 /// The input device has a vibrator (supports FF_RUMBLE).
256 const Vibrator = IInputConstants::DEVICE_CLASS_VIBRATOR as u32;
257 /// The input device has a microphone.
258 const Mic = IInputConstants::DEVICE_CLASS_MIC as u32;
259 /// The input device is an external stylus (has data we want to fuse with touch data).
260 const ExternalStylus = IInputConstants::DEVICE_CLASS_EXTERNAL_STYLUS as u32;
261 /// The input device has a rotary encoder
262 const RotaryEncoder = IInputConstants::DEVICE_CLASS_ROTARY_ENCODER as u32;
263 /// The input device has a sensor like accelerometer, gyro, etc
264 const Sensor = IInputConstants::DEVICE_CLASS_SENSOR as u32;
265 /// The input device has a battery
266 const Battery = IInputConstants::DEVICE_CLASS_BATTERY as u32;
267 /// The input device has sysfs controllable lights
268 const Light = IInputConstants::DEVICE_CLASS_LIGHT as u32;
269 /// The input device is a touchpad, requiring an on-screen cursor.
270 const Touchpad = IInputConstants::DEVICE_CLASS_TOUCHPAD as u32;
271 /// The input device is virtual (not a real device, not part of UI configuration).
272 const Virtual = IInputConstants::DEVICE_CLASS_VIRTUAL as u32;
273 /// The input device is external (not built-in).
274 const External = IInputConstants::DEVICE_CLASS_EXTERNAL as u32;
275 }
276}
277
278bitflags! {
279 /// Modifier state flags
Vaibhav Devmurari770b6e42024-06-10 10:29:26 +0000280 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000281 pub struct ModifierState: u32 {
282 /// No meta keys are pressed
283 const None = input_bindgen::AMETA_NONE;
284 /// This mask is used to check whether one of the ALT meta keys is pressed
285 const AltOn = input_bindgen::AMETA_ALT_ON;
286 /// This mask is used to check whether the left ALT meta key is pressed
287 const AltLeftOn = input_bindgen::AMETA_ALT_LEFT_ON;
288 /// This mask is used to check whether the right ALT meta key is pressed
289 const AltRightOn = input_bindgen::AMETA_ALT_RIGHT_ON;
290 /// This mask is used to check whether one of the SHIFT meta keys is pressed
291 const ShiftOn = input_bindgen::AMETA_SHIFT_ON;
292 /// This mask is used to check whether the left SHIFT meta key is pressed
293 const ShiftLeftOn = input_bindgen::AMETA_SHIFT_LEFT_ON;
294 /// This mask is used to check whether the right SHIFT meta key is pressed
295 const ShiftRightOn = input_bindgen::AMETA_SHIFT_RIGHT_ON;
296 /// This mask is used to check whether the SYM meta key is pressed
297 const SymOn = input_bindgen::AMETA_SYM_ON;
298 /// This mask is used to check whether the FUNCTION meta key is pressed
299 const FunctionOn = input_bindgen::AMETA_FUNCTION_ON;
300 /// This mask is used to check whether one of the CTRL meta keys is pressed
301 const CtrlOn = input_bindgen::AMETA_CTRL_ON;
302 /// This mask is used to check whether the left CTRL meta key is pressed
303 const CtrlLeftOn = input_bindgen::AMETA_CTRL_LEFT_ON;
304 /// This mask is used to check whether the right CTRL meta key is pressed
305 const CtrlRightOn = input_bindgen::AMETA_CTRL_RIGHT_ON;
306 /// This mask is used to check whether one of the META meta keys is pressed
307 const MetaOn = input_bindgen::AMETA_META_ON;
308 /// This mask is used to check whether the left META meta key is pressed
309 const MetaLeftOn = input_bindgen::AMETA_META_LEFT_ON;
310 /// This mask is used to check whether the right META meta key is pressed
311 const MetaRightOn = input_bindgen::AMETA_META_RIGHT_ON;
312 /// This mask is used to check whether the CAPS LOCK meta key is on
313 const CapsLockOn = input_bindgen::AMETA_CAPS_LOCK_ON;
314 /// This mask is used to check whether the NUM LOCK meta key is on
315 const NumLockOn = input_bindgen::AMETA_NUM_LOCK_ON;
316 /// This mask is used to check whether the SCROLL LOCK meta key is on
317 const ScrollLockOn = input_bindgen::AMETA_SCROLL_LOCK_ON;
318 }
319}
320
321/// A rust enum representation of a Keyboard type.
322#[repr(u32)]
323#[derive(Debug, Copy, Clone, Eq, PartialEq)]
324pub enum KeyboardType {
325 /// KEYBOARD_TYPE_NONE
326 None = input_bindgen::AINPUT_KEYBOARD_TYPE_NONE,
327 /// KEYBOARD_TYPE_NON_ALPHABETIC
328 NonAlphabetic = input_bindgen::AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC,
329 /// KEYBOARD_TYPE_ALPHABETIC
330 Alphabetic = input_bindgen::AINPUT_KEYBOARD_TYPE_ALPHABETIC,
331}
332
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700333#[cfg(test)]
334mod tests {
335 use crate::input::SourceClass;
336 use crate::Source;
337 #[test]
338 fn convert_source_class_pointer() {
339 let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
340 assert!(source.is_from_class(SourceClass::Pointer));
341 }
342}