blob: d0dbd6fa165b830055236d565b4ad17511b7d261 [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
19use bitflags::bitflags;
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -070020use inputconstants::aidl::android::os::IInputConstants::INPUT_EVENT_FLAG_CANCELED;
21use inputconstants::aidl::android::os::IInputConstants::INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
22use inputconstants::aidl::android::os::IInputConstants::INPUT_EVENT_FLAG_TAINTED;
23use inputconstants::aidl::android::os::IInputConstants::MOTION_EVENT_FLAG_HOVER_EXIT_PENDING;
24use inputconstants::aidl::android::os::IInputConstants::MOTION_EVENT_FLAG_IS_GENERATED_GESTURE;
25use inputconstants::aidl::android::os::IInputConstants::MOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
26use inputconstants::aidl::android::os::IInputConstants::MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS;
27use inputconstants::aidl::android::os::IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
28use inputconstants::aidl::android::os::IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000029use std::fmt;
30
31/// The InputDevice ID.
32#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
33pub struct DeviceId(pub i32);
34
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070035#[repr(u32)]
36pub enum SourceClass {
37 None = input_bindgen::AINPUT_SOURCE_CLASS_NONE,
38 Button = input_bindgen::AINPUT_SOURCE_CLASS_BUTTON,
39 Pointer = input_bindgen::AINPUT_SOURCE_CLASS_POINTER,
40 Navigation = input_bindgen::AINPUT_SOURCE_CLASS_NAVIGATION,
41 Position = input_bindgen::AINPUT_SOURCE_CLASS_POSITION,
42 Joystick = input_bindgen::AINPUT_SOURCE_CLASS_JOYSTICK,
43}
44
45bitflags! {
46 /// Source of the input device or input events.
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070047 #[derive(Debug, PartialEq)]
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070048 pub struct Source: u32 {
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070049 // Constants from SourceClass, added here for compatibility reasons
50 /// SourceClass::Button
51 const SourceClassButton = SourceClass::Button as u32;
52 /// SourceClass::Pointer
53 const SourceClassPointer = SourceClass::Pointer as u32;
54 /// SourceClass::Navigation
55 const SourceClassNavigation = SourceClass::Navigation as u32;
56 /// SourceClass::Position
57 const SourceClassPosition = SourceClass::Position as u32;
58 /// SourceClass::Joystick
59 const SourceClassJoystick = SourceClass::Joystick as u32;
60
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070061 /// SOURCE_UNKNOWN
62 const Unknown = input_bindgen::AINPUT_SOURCE_UNKNOWN;
63 /// SOURCE_KEYBOARD
64 const Keyboard = input_bindgen::AINPUT_SOURCE_KEYBOARD;
65 /// SOURCE_DPAD
66 const Dpad = input_bindgen::AINPUT_SOURCE_DPAD;
67 /// SOURCE_GAMEPAD
68 const Gamepad = input_bindgen::AINPUT_SOURCE_GAMEPAD;
69 /// SOURCE_TOUCHSCREEN
70 const Touchscreen = input_bindgen::AINPUT_SOURCE_TOUCHSCREEN;
71 /// SOURCE_MOUSE
72 const Mouse = input_bindgen::AINPUT_SOURCE_MOUSE;
73 /// SOURCE_STYLUS
74 const Stylus = input_bindgen::AINPUT_SOURCE_STYLUS;
75 /// SOURCE_BLUETOOTH_STYLUS
76 const BluetoothStylus = input_bindgen::AINPUT_SOURCE_BLUETOOTH_STYLUS;
77 /// SOURCE_TRACKBALL
78 const Trackball = input_bindgen::AINPUT_SOURCE_TRACKBALL;
79 /// SOURCE_MOUSE_RELATIVE
80 const MouseRelative = input_bindgen::AINPUT_SOURCE_MOUSE_RELATIVE;
81 /// SOURCE_TOUCHPAD
82 const Touchpad = input_bindgen::AINPUT_SOURCE_TOUCHPAD;
83 /// SOURCE_TOUCH_NAVIGATION
84 const TouchNavigation = input_bindgen::AINPUT_SOURCE_TOUCH_NAVIGATION;
85 /// SOURCE_JOYSTICK
86 const Joystick = input_bindgen::AINPUT_SOURCE_JOYSTICK;
87 /// SOURCE_HDMI
88 const HDMI = input_bindgen::AINPUT_SOURCE_HDMI;
89 /// SOURCE_SENSOR
90 const Sensor = input_bindgen::AINPUT_SOURCE_SENSOR;
91 /// SOURCE_ROTARY_ENCODER
92 const RotaryEncoder = input_bindgen::AINPUT_SOURCE_ROTARY_ENCODER;
93 }
94}
95
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000096/// A rust enum representation of a MotionEvent action.
97#[repr(u32)]
98pub enum MotionAction {
99 /// ACTION_DOWN
100 Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN,
101 /// ACTION_UP
102 Up = input_bindgen::AMOTION_EVENT_ACTION_UP,
103 /// ACTION_MOVE
104 Move = input_bindgen::AMOTION_EVENT_ACTION_MOVE,
105 /// ACTION_CANCEL
106 Cancel = input_bindgen::AMOTION_EVENT_ACTION_CANCEL,
107 /// ACTION_OUTSIDE
108 Outside = input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE,
109 /// ACTION_POINTER_DOWN
110 PointerDown {
111 /// The index of the affected pointer.
112 action_index: usize,
113 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN,
114 /// ACTION_POINTER_UP
115 PointerUp {
116 /// The index of the affected pointer.
117 action_index: usize,
118 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP,
119 /// ACTION_HOVER_ENTER
120 HoverEnter = input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER,
121 /// ACTION_HOVER_MOVE
122 HoverMove = input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE,
123 /// ACTION_HOVER_EXIT
124 HoverExit = input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT,
125 /// ACTION_SCROLL
126 Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL,
127 /// ACTION_BUTTON_PRESS
128 ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS,
129 /// ACTION_BUTTON_RELEASE
130 ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
131}
132
133impl fmt::Display for MotionAction {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 match self {
136 MotionAction::Down => write!(f, "DOWN"),
137 MotionAction::Up => write!(f, "UP"),
138 MotionAction::Move => write!(f, "MOVE"),
139 MotionAction::Cancel => write!(f, "CANCEL"),
140 MotionAction::Outside => write!(f, "OUTSIDE"),
141 MotionAction::PointerDown { action_index } => {
142 write!(f, "POINTER_DOWN({})", action_index)
143 }
144 MotionAction::PointerUp { action_index } => write!(f, "POINTER_UP({})", action_index),
145 MotionAction::HoverMove => write!(f, "HOVER_MOVE"),
146 MotionAction::Scroll => write!(f, "SCROLL"),
147 MotionAction::HoverEnter => write!(f, "HOVER_ENTER"),
148 MotionAction::HoverExit => write!(f, "HOVER_EXIT"),
149 MotionAction::ButtonPress => write!(f, "BUTTON_PRESS"),
150 MotionAction::ButtonRelease => write!(f, "BUTTON_RELEASE"),
151 }
152 }
153}
154
155impl From<u32> for MotionAction {
156 fn from(action: u32) -> Self {
157 let (action_masked, action_index) = MotionAction::breakdown_action(action);
158 match action_masked {
159 input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down,
160 input_bindgen::AMOTION_EVENT_ACTION_UP => MotionAction::Up,
161 input_bindgen::AMOTION_EVENT_ACTION_MOVE => MotionAction::Move,
162 input_bindgen::AMOTION_EVENT_ACTION_CANCEL => MotionAction::Cancel,
163 input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE => MotionAction::Outside,
164 input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN => {
165 MotionAction::PointerDown { action_index }
166 }
167 input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP => {
168 MotionAction::PointerUp { action_index }
169 }
170 input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER => MotionAction::HoverEnter,
171 input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE => MotionAction::HoverMove,
172 input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT => MotionAction::HoverExit,
173 input_bindgen::AMOTION_EVENT_ACTION_SCROLL => MotionAction::Scroll,
174 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => MotionAction::ButtonPress,
175 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => MotionAction::ButtonRelease,
176 _ => panic!("Unknown action: {}", action),
177 }
178 }
179}
180
181impl MotionAction {
182 fn breakdown_action(action: u32) -> (u32, usize) {
183 let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK;
184 let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
185 >> input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
186 (action_masked, index.try_into().unwrap())
187 }
188}
189
190bitflags! {
191 /// MotionEvent flags.
Siarhei Vishniakou93992432023-10-09 15:47:48 -0700192 #[derive(Debug)]
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700193 pub struct MotionFlags: u32 {
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700194 /// FLAG_WINDOW_IS_OBSCURED
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700195 const WINDOW_IS_OBSCURED = MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED as u32;
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700196 /// FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700197 const WINDOW_IS_PARTIALLY_OBSCURED = MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED as u32;
198 /// FLAG_HOVER_EXIT_PENDING
199 const HOVER_EXIT_PENDING = MOTION_EVENT_FLAG_HOVER_EXIT_PENDING as u32;
Linnan Lia3b18f42024-04-17 16:54:55 +0000200 /// FLAG_IS_GENERATED_GESTURE
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700201 const IS_GENERATED_GESTURE = MOTION_EVENT_FLAG_IS_GENERATED_GESTURE as u32;
202 /// FLAG_CANCELED
203 const CANCELED = INPUT_EVENT_FLAG_CANCELED as u32;
204 /// FLAG_NO_FOCUS_CHANGE
205 const NO_FOCUS_CHANGE = MOTION_EVENT_FLAG_NO_FOCUS_CHANGE as u32;
206 /// FLAG_IS_ACCESSIBILITY_EVENT
207 const IS_ACCESSIBILITY_EVENT = INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT as u32;
Linnan Lif3ec5482024-04-18 16:45:05 +0000208 /// FLAG_TAINTED
Siarhei Vishniakouc40f6e02024-04-25 15:49:29 -0700209 const TAINTED = INPUT_EVENT_FLAG_TAINTED as u32;
210 /// FLAG_TARGET_ACCESSIBILITY_FOCUS
211 const TARGET_ACCESSIBILITY_FOCUS = MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS as u32;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000212 }
213}
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700214
215impl Source {
216 /// Return true if this source is from the provided class
217 pub fn is_from_class(&self, source_class: SourceClass) -> bool {
218 let class_bits = source_class as u32;
219 self.bits() & class_bits == class_bits
220 }
221}
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700222
223#[cfg(test)]
224mod tests {
225 use crate::input::SourceClass;
226 use crate::Source;
227 #[test]
228 fn convert_source_class_pointer() {
229 let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
230 assert!(source.is_from_class(SourceClass::Pointer));
231 }
232}