blob: 09a004c1bba97f314932dcc92473b94fb36006ef [file] [log] [blame]
Siarhei Vishniakou473174e2017-12-27 16:44:42 -08001/*
2 * Copyright (C) 2019 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#define LOG_TAG "InputClassifier"
18
19#include "InputClassifier.h"
20
21#include <algorithm>
Siarhei Vishniakoua028c442019-02-04 14:33:23 -080022#include <android-base/stringprintf.h>
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080023#include <cmath>
24#include <inttypes.h>
25#include <log/log.h>
26#if defined(__linux__)
27 #include <pthread.h>
28#endif
29#include <server_configurable_flags/get_flags.h>
Siarhei Vishniakoua028c442019-02-04 14:33:23 -080030#include <unordered_set>
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080031
32#include <android/hardware/input/classifier/1.0/IInputClassifier.h>
33
Siarhei Vishniakoua028c442019-02-04 14:33:23 -080034#define INDENT1 " "
35#define INDENT2 " "
36#define INDENT3 " "
37#define INDENT4 " "
38#define INDENT5 " "
39
40using android::base::StringPrintf;
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080041using android::hardware::hidl_bitfield;
42using android::hardware::hidl_vec;
43using namespace android::hardware::input;
44
45namespace android {
46
47static constexpr bool DEBUG = false;
48
49// Category (=namespace) name for the input settings that are applied at boot time
50static const char* INPUT_NATIVE_BOOT = "input_native_boot";
51// Feature flag name for the deep press feature
52static const char* DEEP_PRESS_ENABLED = "deep_press_enabled";
53
54//Max number of elements to store in mEvents.
55static constexpr size_t MAX_EVENTS = 5;
56
57template<class K, class V>
58static V getValueForKey(const std::unordered_map<K, V>& map, K key, V defaultValue) {
59 auto it = map.find(key);
60 if (it == map.end()) {
61 return defaultValue;
62 }
63 return it->second;
64}
65
66static common::V1_0::Source getSource(uint32_t source) {
67 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_UNKNOWN) ==
68 common::V1_0::Source::UNKNOWN, "SOURCE_UNKNOWN mismatch");
69 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_KEYBOARD) ==
70 common::V1_0::Source::KEYBOARD, "SOURCE_KEYBOARD mismatch");
71 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_DPAD) ==
72 common::V1_0::Source::DPAD, "SOURCE_DPAD mismatch");
73 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_GAMEPAD) ==
74 common::V1_0::Source::GAMEPAD, "SOURCE_GAMEPAD mismatch");
75 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCHSCREEN) ==
76 common::V1_0::Source::TOUCHSCREEN, "SOURCE_TOUCHSCREEN mismatch");
77 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_MOUSE) ==
78 common::V1_0::Source::MOUSE, "SOURCE_MOUSE mismatch");
79 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_STYLUS) ==
80 common::V1_0::Source::STYLUS, "SOURCE_STYLUS mismatch");
81 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_BLUETOOTH_STYLUS) ==
82 common::V1_0::Source::BLUETOOTH_STYLUS, "SOURCE_BLUETOOTH_STYLUS mismatch");
83 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TRACKBALL) ==
84 common::V1_0::Source::TRACKBALL, "SOURCE_TRACKBALL mismatch");
85 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_MOUSE_RELATIVE) ==
86 common::V1_0::Source::MOUSE_RELATIVE, "SOURCE_MOUSE_RELATIVE mismatch");
87 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCHPAD) ==
88 common::V1_0::Source::TOUCHPAD, "SOURCE_TOUCHPAD mismatch");
89 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCH_NAVIGATION) ==
90 common::V1_0::Source::TOUCH_NAVIGATION, "SOURCE_TOUCH_NAVIGATION mismatch");
91 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_JOYSTICK) ==
92 common::V1_0::Source::JOYSTICK, "SOURCE_JOYSTICK mismatch");
93 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_ROTARY_ENCODER) ==
94 common::V1_0::Source::ROTARY_ENCODER, "SOURCE_ROTARY_ENCODER mismatch");
95 static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_ANY) ==
96 common::V1_0::Source::ANY, "SOURCE_ANY mismatch");
97 return static_cast<common::V1_0::Source>(source);
98}
99
100static common::V1_0::Action getAction(int32_t actionMasked) {
101 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_DOWN) ==
102 common::V1_0::Action::DOWN, "ACTION_DOWN mismatch");
103 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_UP) ==
104 common::V1_0::Action::UP, "ACTION_UP mismatch");
105 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_MOVE) ==
106 common::V1_0::Action::MOVE, "ACTION_MOVE mismatch");
107 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_CANCEL) ==
108 common::V1_0::Action::CANCEL, "ACTION_CANCEL mismatch");
109 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_OUTSIDE) ==
110 common::V1_0::Action::OUTSIDE, "ACTION_OUTSIDE mismatch");
111 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_POINTER_DOWN) ==
112 common::V1_0::Action::POINTER_DOWN, "ACTION_POINTER_DOWN mismatch");
113 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_POINTER_UP) ==
114 common::V1_0::Action::POINTER_UP, "ACTION_POINTER_UP mismatch");
115 static_assert(static_cast<common::V1_0::Action>( AMOTION_EVENT_ACTION_HOVER_MOVE) ==
116 common::V1_0::Action::HOVER_MOVE, "ACTION_HOVER_MOVE mismatch");
117 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_SCROLL) ==
118 common::V1_0::Action::SCROLL, "ACTION_SCROLL mismatch");
119 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_HOVER_ENTER) ==
120 common::V1_0::Action::HOVER_ENTER, "ACTION_HOVER_ENTER mismatch");
121 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_HOVER_EXIT) ==
122 common::V1_0::Action::HOVER_EXIT, "ACTION_HOVER_EXIT mismatch");
123 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_BUTTON_PRESS) ==
124 common::V1_0::Action::BUTTON_PRESS, "ACTION_BUTTON_PRESS mismatch");
125 static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_BUTTON_RELEASE) ==
126 common::V1_0::Action::BUTTON_RELEASE, "ACTION_BUTTON_RELEASE mismatch");
127 return static_cast<common::V1_0::Action>(actionMasked);
128}
129
130static common::V1_0::Button getActionButton(int32_t actionButton) {
131 static_assert(static_cast<common::V1_0::Button>(0) ==
132 common::V1_0::Button::NONE, "BUTTON_NONE mismatch");
133 static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_PRIMARY) ==
134 common::V1_0::Button::PRIMARY, "BUTTON_PRIMARY mismatch");
135 static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_SECONDARY) ==
136 common::V1_0::Button::SECONDARY, "BUTTON_SECONDARY mismatch");
137 static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_TERTIARY) ==
138 common::V1_0::Button::TERTIARY, "BUTTON_TERTIARY mismatch");
139 static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_BACK) ==
140 common::V1_0::Button::BACK, "BUTTON_BACK mismatch");
141 static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_FORWARD) ==
142 common::V1_0::Button::FORWARD, "BUTTON_FORWARD mismatch");
143 static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) ==
144 common::V1_0::Button::STYLUS_PRIMARY, "BUTTON_STYLUS_PRIMARY mismatch");
145 static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY) ==
146 common::V1_0::Button::STYLUS_SECONDARY, "BUTTON_STYLUS_SECONDARY mismatch");
147 return static_cast<common::V1_0::Button>(actionButton);
148}
149
150static hidl_bitfield<common::V1_0::Flag> getFlags(int32_t flags) {
151 static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED) ==
152 common::V1_0::Flag::WINDOW_IS_OBSCURED);
153 static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE) ==
154 common::V1_0::Flag::IS_GENERATED_GESTURE);
155 static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_TAINTED) ==
156 common::V1_0::Flag::TAINTED);
157 return static_cast<hidl_bitfield<common::V1_0::Flag>>(flags);
158}
159
160static hidl_bitfield<common::V1_0::PolicyFlag> getPolicyFlags(int32_t flags) {
161 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_WAKE) ==
162 common::V1_0::PolicyFlag::WAKE);
163 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_VIRTUAL) ==
164 common::V1_0::PolicyFlag::VIRTUAL);
165 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_FUNCTION) ==
166 common::V1_0::PolicyFlag::FUNCTION);
167 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_GESTURE) ==
168 common::V1_0::PolicyFlag::GESTURE);
169 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_INJECTED) ==
170 common::V1_0::PolicyFlag::INJECTED);
171 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_TRUSTED) ==
172 common::V1_0::PolicyFlag::TRUSTED);
173 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_FILTERED) ==
174 common::V1_0::PolicyFlag::FILTERED);
175 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_DISABLE_KEY_REPEAT) ==
176 common::V1_0::PolicyFlag::DISABLE_KEY_REPEAT);
177 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_INTERACTIVE) ==
178 common::V1_0::PolicyFlag::INTERACTIVE);
179 static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_PASS_TO_USER) ==
180 common::V1_0::PolicyFlag::PASS_TO_USER);
181 return static_cast<hidl_bitfield<common::V1_0::PolicyFlag>>(flags);
182}
183
184static hidl_bitfield<common::V1_0::EdgeFlag> getEdgeFlags(int32_t flags) {
185 static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_NONE) ==
186 common::V1_0::EdgeFlag::NONE);
187 static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_TOP) ==
188 common::V1_0::EdgeFlag::TOP);
189 static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_BOTTOM) ==
190 common::V1_0::EdgeFlag::BOTTOM);
191 static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_LEFT) ==
192 common::V1_0::EdgeFlag::LEFT);
193 static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_RIGHT) ==
194 common::V1_0::EdgeFlag::RIGHT);
195 return static_cast<hidl_bitfield<common::V1_0::EdgeFlag>>(flags);
196}
197
198static hidl_bitfield<common::V1_0::Meta> getMetastate(int32_t state) {
199 static_assert(static_cast<common::V1_0::Meta>(AMETA_NONE) ==
200 common::V1_0::Meta::NONE);
201 static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_ON) ==
202 common::V1_0::Meta::ALT_ON);
203 static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_LEFT_ON) ==
204 common::V1_0::Meta::ALT_LEFT_ON);
205 static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_RIGHT_ON) ==
206 common::V1_0::Meta::ALT_RIGHT_ON);
207 static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_ON) ==
208 common::V1_0::Meta::SHIFT_ON);
209 static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_LEFT_ON) ==
210 common::V1_0::Meta::SHIFT_LEFT_ON);
211 static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_RIGHT_ON) ==
212 common::V1_0::Meta::SHIFT_RIGHT_ON);
213 static_assert(static_cast<common::V1_0::Meta>(AMETA_SYM_ON) ==
214 common::V1_0::Meta::SYM_ON);
215 static_assert(static_cast<common::V1_0::Meta>(AMETA_FUNCTION_ON) ==
216 common::V1_0::Meta::FUNCTION_ON);
217 static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_ON) ==
218 common::V1_0::Meta::CTRL_ON);
219 static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_LEFT_ON) ==
220 common::V1_0::Meta::CTRL_LEFT_ON);
221 static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_RIGHT_ON) ==
222 common::V1_0::Meta::CTRL_RIGHT_ON);
223 static_assert(static_cast<common::V1_0::Meta>(AMETA_META_ON) ==
224 common::V1_0::Meta::META_ON);
225 static_assert(static_cast<common::V1_0::Meta>(AMETA_META_LEFT_ON) ==
226 common::V1_0::Meta::META_LEFT_ON);
227 static_assert(static_cast<common::V1_0::Meta>(AMETA_META_RIGHT_ON) ==
228 common::V1_0::Meta::META_RIGHT_ON);
229 static_assert(static_cast<common::V1_0::Meta>(AMETA_CAPS_LOCK_ON) ==
230 common::V1_0::Meta::CAPS_LOCK_ON);
231 static_assert(static_cast<common::V1_0::Meta>(AMETA_NUM_LOCK_ON) ==
232 common::V1_0::Meta::NUM_LOCK_ON);
233 static_assert(static_cast<common::V1_0::Meta>(AMETA_SCROLL_LOCK_ON) ==
234 common::V1_0::Meta::SCROLL_LOCK_ON);
235 return static_cast<hidl_bitfield<common::V1_0::Meta>>(state);
236}
237
238static hidl_bitfield<common::V1_0::Button> getButtonState(int32_t buttonState) {
239 // No need for static_assert here.
240 // The button values have already been asserted in getActionButton(..) above
241 return static_cast<hidl_bitfield<common::V1_0::Button>>(buttonState);
242}
243
244static common::V1_0::ToolType getToolType(int32_t toolType) {
245 static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_UNKNOWN) ==
246 common::V1_0::ToolType::UNKNOWN);
247 static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_FINGER) ==
248 common::V1_0::ToolType::FINGER);
249 static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_STYLUS) ==
250 common::V1_0::ToolType::STYLUS);
251 static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_MOUSE) ==
252 common::V1_0::ToolType::MOUSE);
253 static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_ERASER) ==
254 common::V1_0::ToolType::ERASER);
255 return static_cast<common::V1_0::ToolType>(toolType);
256}
257
258static common::V1_0::Axis getAxis(uint64_t axis) {
259 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_X) ==
260 common::V1_0::Axis::X);
261 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_Y) ==
262 common::V1_0::Axis::Y);
263 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_PRESSURE) ==
264 common::V1_0::Axis::PRESSURE);
265 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_SIZE) ==
266 common::V1_0::Axis::SIZE);
267 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOUCH_MAJOR) ==
268 common::V1_0::Axis::TOUCH_MAJOR);
269 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOUCH_MINOR) ==
270 common::V1_0::Axis::TOUCH_MINOR);
271 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOOL_MAJOR) ==
272 common::V1_0::Axis::TOOL_MAJOR);
273 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOOL_MINOR) ==
274 common::V1_0::Axis::TOOL_MINOR);
275 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_ORIENTATION) ==
276 common::V1_0::Axis::ORIENTATION);
277 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_VSCROLL) ==
278 common::V1_0::Axis::VSCROLL);
279 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HSCROLL) ==
280 common::V1_0::Axis::HSCROLL);
281 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_Z) ==
282 common::V1_0::Axis::Z);
283 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RX) ==
284 common::V1_0::Axis::RX);
285 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RY) ==
286 common::V1_0::Axis::RY);
287 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RZ) ==
288 common::V1_0::Axis::RZ);
289 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HAT_X) ==
290 common::V1_0::Axis::HAT_X);
291 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HAT_Y) ==
292 common::V1_0::Axis::HAT_Y);
293 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_LTRIGGER) ==
294 common::V1_0::Axis::LTRIGGER);
295 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RTRIGGER) ==
296 common::V1_0::Axis::RTRIGGER);
297 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_THROTTLE) ==
298 common::V1_0::Axis::THROTTLE);
299 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RUDDER) ==
300 common::V1_0::Axis::RUDDER);
301 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_WHEEL) ==
302 common::V1_0::Axis::WHEEL);
303 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GAS) ==
304 common::V1_0::Axis::GAS);
305 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_BRAKE) ==
306 common::V1_0::Axis::BRAKE);
307 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_DISTANCE) ==
308 common::V1_0::Axis::DISTANCE);
309 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TILT) ==
310 common::V1_0::Axis::TILT);
311 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_SCROLL) ==
312 common::V1_0::Axis::SCROLL);
313 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RELATIVE_X) ==
314 common::V1_0::Axis::RELATIVE_X);
315 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RELATIVE_Y) ==
316 common::V1_0::Axis::RELATIVE_Y);
317 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_1) ==
318 common::V1_0::Axis::GENERIC_1);
319 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_2) ==
320 common::V1_0::Axis::GENERIC_2);
321 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_3) ==
322 common::V1_0::Axis::GENERIC_3);
323 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_4) ==
324 common::V1_0::Axis::GENERIC_4);
325 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_5) ==
326 common::V1_0::Axis::GENERIC_5);
327 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_6) ==
328 common::V1_0::Axis::GENERIC_6);
329 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_7) ==
330 common::V1_0::Axis::GENERIC_7);
331 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_8) ==
332 common::V1_0::Axis::GENERIC_8);
333 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_9) ==
334 common::V1_0::Axis::GENERIC_9);
335 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_10) ==
336 common::V1_0::Axis::GENERIC_10);
337 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_11) ==
338 common::V1_0::Axis::GENERIC_11);
339 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_12) ==
340 common::V1_0::Axis::GENERIC_12);
341 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_13) ==
342 common::V1_0::Axis::GENERIC_13);
343 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_14) ==
344 common::V1_0::Axis::GENERIC_14);
345 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_15) ==
346 common::V1_0::Axis::GENERIC_15);
347 static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_16) ==
348 common::V1_0::Axis::GENERIC_16);
349 return static_cast<common::V1_0::Axis>(axis);
350}
351
352static common::V1_0::VideoFrame getHalVideoFrame(const TouchVideoFrame& frame) {
353 common::V1_0::VideoFrame out;
354 out.width = frame.getWidth();
355 out.height = frame.getHeight();
356 out.data = frame.getData();
357 struct timeval timestamp = frame.getTimestamp();
358 out.timestamp = seconds_to_nanoseconds(timestamp.tv_sec) +
359 microseconds_to_nanoseconds(timestamp.tv_usec);
360 return out;
361}
362
363static std::vector<common::V1_0::VideoFrame> convertVideoFrames(
364 const std::vector<TouchVideoFrame>& frames) {
365 std::vector<common::V1_0::VideoFrame> out;
366 for (const TouchVideoFrame& frame : frames) {
367 out.push_back(getHalVideoFrame(frame));
368 }
369 return out;
370}
371
372static uint8_t getActionIndex(int32_t action) {
373 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
374 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
375}
376
377static void getHidlPropertiesAndCoords(const NotifyMotionArgs& args,
378 std::vector<common::V1_0::PointerProperties>* outPointerProperties,
379 std::vector<common::V1_0::PointerCoords>* outPointerCoords) {
380 outPointerProperties->reserve(args.pointerCount);
381 outPointerCoords->reserve(args.pointerCount);
382 for (size_t i = 0; i < args.pointerCount; i++) {
383 common::V1_0::PointerProperties properties;
384 properties.id = args.pointerProperties[i].id;
385 properties.toolType = getToolType(args.pointerProperties[i].toolType);
386 outPointerProperties->push_back(properties);
387
388 common::V1_0::PointerCoords coords;
389 BitSet64 bits (args.pointerCoords[i].bits);
390 std::vector<float> values;
391 size_t index = 0;
392 while (!bits.isEmpty()) {
393 uint32_t axis = bits.clearFirstMarkedBit();
394 coords.bits |= 1 << static_cast<uint64_t>(getAxis(axis));
395 float value = args.pointerCoords[i].values[index++];
396 values.push_back(value);
397 }
398 coords.values = values;
399 outPointerCoords->push_back(coords);
400 }
401}
402
403static common::V1_0::MotionEvent getMotionEvent(const NotifyMotionArgs& args) {
404 common::V1_0::MotionEvent event;
405 event.deviceId = args.deviceId;
406 event.source = getSource(args.source);
407 event.displayId = args.displayId;
408 event.downTime = args.downTime;
409 event.eventTime = args.eventTime;
410 event.action = getAction(args.action & AMOTION_EVENT_ACTION_MASK);
411 event.actionIndex = getActionIndex(args.action);
412 event.actionButton = getActionButton(args.actionButton);
413 event.flags = getFlags(args.flags);
414 event.policyFlags = getPolicyFlags(args.policyFlags);
415 event.edgeFlags = getEdgeFlags(args.edgeFlags);
416 event.metaState = getMetastate(args.metaState);
417 event.buttonState = getButtonState(args.buttonState);
418 event.xPrecision = args.xPrecision;
419 event.yPrecision = args.yPrecision;
420
421 std::vector<common::V1_0::PointerProperties> pointerProperties;
422 std::vector<common::V1_0::PointerCoords> pointerCoords;
423 getHidlPropertiesAndCoords(args, /*out*/&pointerProperties, /*out*/&pointerCoords);
424 event.pointerProperties = pointerProperties;
425 event.pointerCoords = pointerCoords;
426
427 event.deviceTimestamp = args.deviceTimestamp;
428 event.frames = convertVideoFrames(args.videoFrames);
429
430 return event;
431}
432
433static MotionClassification getMotionClassification(common::V1_0::Classification classification) {
434 static_assert(MotionClassification::NONE ==
435 static_cast<MotionClassification>(common::V1_0::Classification::NONE));
436 static_assert(MotionClassification::AMBIGUOUS_GESTURE ==
437 static_cast<MotionClassification>(common::V1_0::Classification::AMBIGUOUS_GESTURE));
438 static_assert(MotionClassification::DEEP_PRESS ==
439 static_cast<MotionClassification>(common::V1_0::Classification::DEEP_PRESS));
440 return static_cast<MotionClassification>(classification);
441}
442
443static bool isTouchEvent(const NotifyMotionArgs& args) {
444 return args.source == AINPUT_SOURCE_TOUCHPAD || args.source == AINPUT_SOURCE_TOUCHSCREEN;
445}
446
447// Check if the "deep touch" feature is on.
448static bool deepPressEnabled() {
449 std::string flag_value = server_configurable_flags::GetServerConfigurableFlag(
450 INPUT_NATIVE_BOOT, DEEP_PRESS_ENABLED, "true");
451 std::transform(flag_value.begin(), flag_value.end(), flag_value.begin(), ::tolower);
452 if (flag_value == "1" || flag_value == "true") {
453 ALOGI("Deep press feature enabled.");
454 return true;
455 }
456 ALOGI("Deep press feature is not enabled.");
457 return false;
458}
459
460
461// --- ClassifierEvent ---
462
463ClassifierEvent::ClassifierEvent(std::unique_ptr<NotifyMotionArgs> args) :
464 type(ClassifierEventType::MOTION), args(std::move(args)) { };
465ClassifierEvent::ClassifierEvent(std::unique_ptr<NotifyDeviceResetArgs> args) :
466 type(ClassifierEventType::DEVICE_RESET), args(std::move(args)) { };
467ClassifierEvent::ClassifierEvent(ClassifierEventType type, std::unique_ptr<NotifyArgs> args) :
468 type(type), args(std::move(args)) { };
469
470ClassifierEvent::ClassifierEvent(ClassifierEvent&& other) :
471 type(other.type), args(std::move(other.args)) { };
472
473ClassifierEvent& ClassifierEvent::operator=(ClassifierEvent&& other) {
474 type = other.type;
475 args = std::move(other.args);
476 return *this;
477}
478
479ClassifierEvent ClassifierEvent::createHalResetEvent() {
480 return ClassifierEvent(ClassifierEventType::HAL_RESET, nullptr);
481}
482
483ClassifierEvent ClassifierEvent::createExitEvent() {
484 return ClassifierEvent(ClassifierEventType::EXIT, nullptr);
485}
486
487std::optional<int32_t> ClassifierEvent::getDeviceId() const {
488 switch (type) {
489 case ClassifierEventType::MOTION: {
490 NotifyMotionArgs* motionArgs = static_cast<NotifyMotionArgs*>(args.get());
491 return motionArgs->deviceId;
492 }
493 case ClassifierEventType::DEVICE_RESET: {
494 NotifyDeviceResetArgs* deviceResetArgs =
495 static_cast<NotifyDeviceResetArgs*>(args.get());
496 return deviceResetArgs->deviceId;
497 }
498 case ClassifierEventType::HAL_RESET: {
499 return std::nullopt;
500 }
501 case ClassifierEventType::EXIT: {
502 return std::nullopt;
503 }
504 }
505}
506
507// --- MotionClassifier ---
508
509MotionClassifier::MotionClassifier(
510 sp<android::hardware::input::classifier::V1_0::IInputClassifier> service) :
511 mEvents(MAX_EVENTS), mService(service) {
512 mHalThread = std::thread(&MotionClassifier::callInputClassifierHal, this);
513#if defined(__linux__)
514 // Set the thread name for debugging
515 pthread_setname_np(mHalThread.native_handle(), "InputClassifier");
516#endif
Siarhei Vishniakou6dbc3f62019-02-04 14:30:11 -0800517 // Under normal operation, we do not need to reset the HAL here. But in the case where system
518 // crashed, but HAL didn't, we may be connecting to an existing HAL process that might already
519 // have received events in the past. That means, that HAL could be in an inconsistent state
520 // once it receives events from the newly created MotionClassifier.
521 mEvents.push(ClassifierEvent::createHalResetEvent());
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800522}
523
524MotionClassifier::~MotionClassifier() {
525 requestExit();
526 mHalThread.join();
527}
528
529void MotionClassifier::ensureHalThread(const char* function) {
530 if (DEBUG) {
531 if (std::this_thread::get_id() != mHalThread.get_id()) {
532 ALOGE("Function %s should only be called from InputClassifier thread", function);
533 }
534 }
535}
536
537/**
538 * Obtain the classification from the HAL for a given MotionEvent.
539 * Should only be called from the InputClassifier thread (mHalThread).
540 * Should not be called from the thread that notifyMotion runs on.
541 *
542 * There is no way to provide a timeout for a HAL call. So if the HAL takes too long
543 * to return a classification, this would directly impact the touch latency.
544 * To remove any possibility of negatively affecting the touch latency, the HAL
545 * is called from a dedicated thread.
546 */
547void MotionClassifier::callInputClassifierHal() {
548 ensureHalThread(__func__);
549 while (true) {
550 ClassifierEvent event = mEvents.pop();
551 switch (event.type) {
552 case ClassifierEventType::MOTION: {
553 NotifyMotionArgs* motionArgs = static_cast<NotifyMotionArgs*>(event.args.get());
554 common::V1_0::MotionEvent motionEvent = getMotionEvent(*motionArgs);
555 common::V1_0::Classification halClassification = mService->classify(motionEvent);
556 updateClassification(motionArgs->deviceId, motionArgs->eventTime,
557 getMotionClassification(halClassification));
558 break;
559 }
560 case ClassifierEventType::DEVICE_RESET: {
561 const int32_t deviceId = *(event.getDeviceId());
562 mService->resetDevice(deviceId);
563 setClassification(deviceId, MotionClassification::NONE);
564 break;
565 }
566 case ClassifierEventType::HAL_RESET: {
567 mService->reset();
568 clearClassifications();
569 break;
570 }
571 case ClassifierEventType::EXIT: {
572 clearClassifications();
573 return;
574 }
575 }
576 }
577}
578
579void MotionClassifier::requestExit() {
580 reset();
581 mEvents.push(ClassifierEvent::createExitEvent());
582}
583
584void MotionClassifier::updateClassification(int32_t deviceId, nsecs_t eventTime,
585 MotionClassification classification) {
586 std::scoped_lock lock(mLock);
587 const nsecs_t lastDownTime = getValueForKey(mLastDownTimes, deviceId, static_cast<nsecs_t>(0));
588 if (eventTime < lastDownTime) {
589 // HAL just finished processing an event that belonged to an earlier gesture,
590 // but new gesture is already in progress. Drop this classification.
591 ALOGW("Received late classification. Late by at least %" PRId64 " ms.",
592 nanoseconds_to_milliseconds(lastDownTime - eventTime));
593 return;
594 }
595 mClassifications[deviceId] = classification;
596}
597
598void MotionClassifier::setClassification(int32_t deviceId, MotionClassification classification) {
599 std::scoped_lock lock(mLock);
600 mClassifications[deviceId] = classification;
601}
602
603void MotionClassifier::clearClassifications() {
604 std::scoped_lock lock(mLock);
605 mClassifications.clear();
606}
607
608MotionClassification MotionClassifier::getClassification(int32_t deviceId) {
609 std::scoped_lock lock(mLock);
610 return getValueForKey(mClassifications, deviceId, MotionClassification::NONE);
611}
612
613void MotionClassifier::updateLastDownTime(int32_t deviceId, nsecs_t downTime) {
614 std::scoped_lock lock(mLock);
615 mLastDownTimes[deviceId] = downTime;
616 mClassifications[deviceId] = MotionClassification::NONE;
617}
618
619MotionClassification MotionClassifier::classify(const NotifyMotionArgs& args) {
620 if (!mService) {
621 // If HAL is not present, do nothing
622 return MotionClassification::NONE;
623 }
624 if ((args.action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN) {
625 updateLastDownTime(args.deviceId, args.downTime);
626 }
627
628 ClassifierEvent event(std::make_unique<NotifyMotionArgs>(args));
629 bool elementAdded = mEvents.push(std::move(event));
630 if (!elementAdded) {
631 // Queue should not ever overfill. Suspect HAL is slow.
632 ALOGE("Dropped element with eventTime %" PRIu64, args.eventTime);
633 reset();
634 return MotionClassification::NONE;
635 }
636 return getClassification(args.deviceId);
637}
638
639void MotionClassifier::reset() {
640 mEvents.clear();
641 mEvents.push(ClassifierEvent::createHalResetEvent());
642}
643
644/**
645 * Per-device reset. Clear the outstanding events that are going to be sent to HAL.
646 * Request InputClassifier thread to call resetDevice for this particular device.
647 */
648void MotionClassifier::reset(const NotifyDeviceResetArgs& args) {
649 int32_t deviceId = args.deviceId;
650 // Clear the pending events right away, to avoid unnecessary work done by the HAL.
651 mEvents.erase([deviceId](const ClassifierEvent& event) {
652 std::optional<int32_t> eventDeviceId = event.getDeviceId();
653 return eventDeviceId && (*eventDeviceId == deviceId);
654 });
655 mEvents.push(std::make_unique<NotifyDeviceResetArgs>(args));
656}
657
Siarhei Vishniakoua028c442019-02-04 14:33:23 -0800658void MotionClassifier::dump(std::string& dump) {
659 std::scoped_lock lock(mLock);
660 std::string serviceStatus = mService->ping().isOk() ? "running" : " not responding";
661 dump += StringPrintf(INDENT2 "mService status: %s\n", serviceStatus.c_str());
662 dump += StringPrintf(INDENT2 "mEvents: %zu element(s) (max=%zu)\n",
663 mEvents.size(), MAX_EVENTS);
664 dump += INDENT2 "mClassifications, mLastDownTimes:\n";
665 dump += INDENT3 "Device Id\tClassification\tLast down time";
666 // Combine mClassifications and mLastDownTimes into a single table.
667 // Create a superset of device ids.
668 std::unordered_set<int32_t> deviceIds;
669 std::for_each(mClassifications.begin(), mClassifications.end(),
670 [&deviceIds](auto pair){ deviceIds.insert(pair.first); });
671 std::for_each(mLastDownTimes.begin(), mLastDownTimes.end(),
672 [&deviceIds](auto pair){ deviceIds.insert(pair.first); });
673 for(int32_t deviceId : deviceIds) {
674 const MotionClassification classification =
675 getValueForKey(mClassifications, deviceId, MotionClassification::NONE);
676 const nsecs_t downTime = getValueForKey(mLastDownTimes, deviceId, static_cast<nsecs_t>(0));
677 dump += StringPrintf("\n" INDENT4 "%" PRId32 "\t%s\t%" PRId64,
678 deviceId, motionClassificationToString(classification), downTime);
679 }
680}
681
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800682// --- InputClassifier ---
683
684InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener) :
685 mListener(listener) {
686 if (deepPressEnabled()) {
687 sp<android::hardware::input::classifier::V1_0::IInputClassifier> service =
688 classifier::V1_0::IInputClassifier::getService();
689 if (service) {
690 mMotionClassifier = std::make_unique<MotionClassifier>(service);
691 } else {
692 ALOGI("Could not obtain InputClassifier HAL");
693 }
694 }
695};
696
697void InputClassifier::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
698 // pass through
699 mListener->notifyConfigurationChanged(args);
700}
701
702void InputClassifier::notifyKey(const NotifyKeyArgs* args) {
703 // pass through
704 mListener->notifyKey(args);
705}
706
707void InputClassifier::notifyMotion(const NotifyMotionArgs* args) {
708 if (mMotionClassifier && isTouchEvent(*args)) {
709 // We only cover touch events, for now.
710 NotifyMotionArgs newArgs = NotifyMotionArgs(*args);
711 newArgs.classification = mMotionClassifier->classify(newArgs);
712 args = &newArgs;
713 }
714 mListener->notifyMotion(args);
715}
716
717void InputClassifier::notifySwitch(const NotifySwitchArgs* args) {
718 // pass through
719 mListener->notifySwitch(args);
720}
721
722void InputClassifier::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
723 if (mMotionClassifier) {
724 mMotionClassifier->reset(*args);
725 }
726 // continue to next stage
727 mListener->notifyDeviceReset(args);
728}
729
Siarhei Vishniakoua028c442019-02-04 14:33:23 -0800730void InputClassifier::dump(std::string& dump) {
731 dump += "Input Classifier State:\n";
732
733 dump += INDENT1 "Motion Classifier:\n";
734 if (mMotionClassifier) {
735 mMotionClassifier->dump(dump);
736 } else {
737 dump += INDENT2 "<nullptr>";
738 }
739 dump += "\n";
740}
741
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800742} // namespace android