blob: 0574245fa6f85f52dd7ae514bad333275e99d356 [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;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700210 /// FLAG_IS_ACCESSIBILITY_EVENT
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000211 const IS_ACCESSIBILITY_EVENT = IInputConstants::INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT as u32;
Linnan Lif3ec5482024-04-18 16:45:05 +0000212 /// FLAG_TAINTED
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000213 const TAINTED = IInputConstants::INPUT_EVENT_FLAG_TAINTED as u32;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700214 /// FLAG_TARGET_ACCESSIBILITY_FOCUS
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000215 const TARGET_ACCESSIBILITY_FOCUS = IInputConstants::MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS as u32;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000216 }
217}
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700218
219impl Source {
220 /// Return true if this source is from the provided class
221 pub fn is_from_class(&self, source_class: SourceClass) -> bool {
222 let class_bits = source_class as u32;
223 self.bits() & class_bits == class_bits
224 }
225}
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700226
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000227bitflags! {
228 /// Device class of the input device. These are duplicated from Eventhub.h
229 /// We need to make sure the two version remain in sync when adding new classes.
230 #[derive(Debug, PartialEq)]
231 pub struct DeviceClass: u32 {
232 /// The input device is a keyboard or has buttons
233 const Keyboard = IInputConstants::DEVICE_CLASS_KEYBOARD as u32;
234 /// The input device is an alpha-numeric keyboard (not just a dial pad)
235 const AlphabeticKey = IInputConstants::DEVICE_CLASS_ALPHAKEY as u32;
236 /// The input device is a touchscreen or a touchpad (either single-touch or multi-touch)
237 const Touch = IInputConstants::DEVICE_CLASS_TOUCH as u32;
238 /// The input device is a cursor device such as a trackball or mouse.
239 const Cursor = IInputConstants::DEVICE_CLASS_CURSOR as u32;
240 /// The input device is a multi-touch touchscreen or touchpad.
241 const MultiTouch = IInputConstants::DEVICE_CLASS_TOUCH_MT as u32;
242 /// The input device is a directional pad (implies keyboard, has DPAD keys).
243 const Dpad = IInputConstants::DEVICE_CLASS_DPAD as u32;
244 /// The input device is a gamepad (implies keyboard, has BUTTON keys).
245 const Gamepad = IInputConstants::DEVICE_CLASS_GAMEPAD as u32;
246 /// The input device has switches.
247 const Switch = IInputConstants::DEVICE_CLASS_SWITCH as u32;
248 /// The input device is a joystick (implies gamepad, has joystick absolute axes).
249 const Joystick = IInputConstants::DEVICE_CLASS_JOYSTICK as u32;
250 /// The input device has a vibrator (supports FF_RUMBLE).
251 const Vibrator = IInputConstants::DEVICE_CLASS_VIBRATOR as u32;
252 /// The input device has a microphone.
253 const Mic = IInputConstants::DEVICE_CLASS_MIC as u32;
254 /// The input device is an external stylus (has data we want to fuse with touch data).
255 const ExternalStylus = IInputConstants::DEVICE_CLASS_EXTERNAL_STYLUS as u32;
256 /// The input device has a rotary encoder
257 const RotaryEncoder = IInputConstants::DEVICE_CLASS_ROTARY_ENCODER as u32;
258 /// The input device has a sensor like accelerometer, gyro, etc
259 const Sensor = IInputConstants::DEVICE_CLASS_SENSOR as u32;
260 /// The input device has a battery
261 const Battery = IInputConstants::DEVICE_CLASS_BATTERY as u32;
262 /// The input device has sysfs controllable lights
263 const Light = IInputConstants::DEVICE_CLASS_LIGHT as u32;
264 /// The input device is a touchpad, requiring an on-screen cursor.
265 const Touchpad = IInputConstants::DEVICE_CLASS_TOUCHPAD as u32;
266 /// The input device is virtual (not a real device, not part of UI configuration).
267 const Virtual = IInputConstants::DEVICE_CLASS_VIRTUAL as u32;
268 /// The input device is external (not built-in).
269 const External = IInputConstants::DEVICE_CLASS_EXTERNAL as u32;
270 }
271}
272
273bitflags! {
274 /// Modifier state flags
Vaibhav Devmurari770b6e42024-06-10 10:29:26 +0000275 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000276 pub struct ModifierState: u32 {
277 /// No meta keys are pressed
278 const None = input_bindgen::AMETA_NONE;
279 /// This mask is used to check whether one of the ALT meta keys is pressed
280 const AltOn = input_bindgen::AMETA_ALT_ON;
281 /// This mask is used to check whether the left ALT meta key is pressed
282 const AltLeftOn = input_bindgen::AMETA_ALT_LEFT_ON;
283 /// This mask is used to check whether the right ALT meta key is pressed
284 const AltRightOn = input_bindgen::AMETA_ALT_RIGHT_ON;
285 /// This mask is used to check whether one of the SHIFT meta keys is pressed
286 const ShiftOn = input_bindgen::AMETA_SHIFT_ON;
287 /// This mask is used to check whether the left SHIFT meta key is pressed
288 const ShiftLeftOn = input_bindgen::AMETA_SHIFT_LEFT_ON;
289 /// This mask is used to check whether the right SHIFT meta key is pressed
290 const ShiftRightOn = input_bindgen::AMETA_SHIFT_RIGHT_ON;
291 /// This mask is used to check whether the SYM meta key is pressed
292 const SymOn = input_bindgen::AMETA_SYM_ON;
293 /// This mask is used to check whether the FUNCTION meta key is pressed
294 const FunctionOn = input_bindgen::AMETA_FUNCTION_ON;
295 /// This mask is used to check whether one of the CTRL meta keys is pressed
296 const CtrlOn = input_bindgen::AMETA_CTRL_ON;
297 /// This mask is used to check whether the left CTRL meta key is pressed
298 const CtrlLeftOn = input_bindgen::AMETA_CTRL_LEFT_ON;
299 /// This mask is used to check whether the right CTRL meta key is pressed
300 const CtrlRightOn = input_bindgen::AMETA_CTRL_RIGHT_ON;
301 /// This mask is used to check whether one of the META meta keys is pressed
302 const MetaOn = input_bindgen::AMETA_META_ON;
303 /// This mask is used to check whether the left META meta key is pressed
304 const MetaLeftOn = input_bindgen::AMETA_META_LEFT_ON;
305 /// This mask is used to check whether the right META meta key is pressed
306 const MetaRightOn = input_bindgen::AMETA_META_RIGHT_ON;
307 /// This mask is used to check whether the CAPS LOCK meta key is on
308 const CapsLockOn = input_bindgen::AMETA_CAPS_LOCK_ON;
309 /// This mask is used to check whether the NUM LOCK meta key is on
310 const NumLockOn = input_bindgen::AMETA_NUM_LOCK_ON;
311 /// This mask is used to check whether the SCROLL LOCK meta key is on
312 const ScrollLockOn = input_bindgen::AMETA_SCROLL_LOCK_ON;
313 }
314}
315
316/// A rust enum representation of a Keyboard type.
317#[repr(u32)]
318#[derive(Debug, Copy, Clone, Eq, PartialEq)]
319pub enum KeyboardType {
320 /// KEYBOARD_TYPE_NONE
321 None = input_bindgen::AINPUT_KEYBOARD_TYPE_NONE,
322 /// KEYBOARD_TYPE_NON_ALPHABETIC
323 NonAlphabetic = input_bindgen::AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC,
324 /// KEYBOARD_TYPE_ALPHABETIC
325 Alphabetic = input_bindgen::AINPUT_KEYBOARD_TYPE_ALPHABETIC,
326}
327
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700328#[cfg(test)]
329mod tests {
330 use crate::input::SourceClass;
331 use crate::Source;
332 #[test]
333 fn convert_source_class_pointer() {
334 let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
335 assert!(source.is_from_class(SourceClass::Pointer));
336 }
337}