1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "input_event_handler.h"
17
18 #include <cinttypes>
19 #include <cstdio>
20 #include <cstring>
21 #include <functional>
22 #include <vector>
23
24 #include <sys/stat.h>
25 #include <unistd.h>
26
27 #include "libinput.h"
28 #include "key_command_handler.h"
29 #include "timer_manager.h"
30 #include "util.h"
31
32 #undef MMI_LOG_DOMAIN
33 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
34 #undef MMI_LOG_TAG
35 #define MMI_LOG_TAG "InputEventHandler"
36
37 namespace OHOS {
38 namespace MMI {
39 namespace {
40 constexpr int32_t MT_TOOL_PALM { 2 };
41 constexpr uint32_t KEY_ESC { 1 };
42 constexpr uint32_t KEY_KPASTERISK { 55 };
43 constexpr uint32_t KEY_F1 { 59 };
44 constexpr uint32_t KEY_LEFTCTRL { 29 };
45 constexpr uint32_t KEY_RIGHTCTRL { 97 };
46 constexpr uint32_t KEY_LEFTALT { 56 };
47 constexpr uint32_t KEY_RIGHTALT { 100 };
48 constexpr uint32_t KEY_LEFTSHIFT { 42 };
49 constexpr uint32_t KEY_RIGHTSHIFT { 54 };
50 constexpr uint32_t KEY_FN { 0x1d0 };
51 constexpr uint32_t KEY_CAPSLOCK { 58 };
52 constexpr uint32_t KEY_TAB { 15 };
53 constexpr uint32_t KEY_COMPOSE { 127 };
54 constexpr uint32_t KEY_RIGHTMETA { 126 };
55 constexpr uint32_t KEY_LEFTMETA { 125 };
56 } // namespace
57
InputEventHandler()58 InputEventHandler::InputEventHandler()
59 {
60 lastEventBeginTime_ = GetSysClockTime();
61 udsServer_ = nullptr;
62 }
63
~InputEventHandler()64 InputEventHandler::~InputEventHandler() {}
65
Init(UDSServer& udsServer)66 void InputEventHandler::Init(UDSServer& udsServer)
67 {
68 udsServer_ = &udsServer;
69 BuildInputHandlerChain();
70 }
71
OnEvent(void *event, int64_t frameTime)72 void InputEventHandler::OnEvent(void *event, int64_t frameTime)
73 {
74 CHKPV(eventNormalizeHandler_);
75 if (event == nullptr) {
76 eventNormalizeHandler_->HandleEvent(nullptr, frameTime);
77 return;
78 }
79
80 idSeed_ += 1;
81 const uint64_t maxUInt64 = (std::numeric_limits<uint64_t>::max)() - 1;
82 if (idSeed_ >= maxUInt64) {
83 MMI_HILOGE("The value is flipped. id:%{public}" PRId64, idSeed_);
84 idSeed_ = 1;
85 }
86
87 auto *lpEvent = static_cast<libinput_event *>(event);
88 CHKPV(lpEvent);
89 int32_t eventType = libinput_event_get_type(lpEvent);
90 int64_t beginTime = GetSysClockTime();
91 lastEventBeginTime_ = beginTime;
92 MMI_HILOGD("Event reporting. id:%{public}" PRId64 ",tid:%{public}" PRId64 ",eventType:%{public}d,"
93 "beginTime:%{public}" PRId64, idSeed_, GetThisThreadId(), eventType, beginTime);
94
95 UpdateDwtRecord(lpEvent);
96 if (IsTouchpadMistouch(lpEvent)) {
97 return;
98 }
99
100 ResetLogTrace();
101 eventNormalizeHandler_->HandleEvent(lpEvent, frameTime);
102 int64_t endTime = GetSysClockTime();
103 int64_t lostTime = endTime - beginTime;
104 MMI_HILOGD("Event handling completed. id:%{public}" PRId64 ",endTime:%{public}" PRId64
105 ",lostTime:%{public}" PRId64, idSeed_, endTime, lostTime);
106 }
107
UpdateDwtRecord(libinput_event *event)108 void InputEventHandler::UpdateDwtRecord(libinput_event *event)
109 {
110 CHKPV(event);
111 auto type = libinput_event_get_type(event);
112 if (type == LIBINPUT_EVENT_TOUCHPAD_DOWN || type == LIBINPUT_EVENT_TOUCHPAD_MOTION) {
113 UpdateDwtTouchpadRecord(event);
114 }
115 if (type == LIBINPUT_EVENT_KEYBOARD_KEY) {
116 UpdateDwtKeyboardRecord(event);
117 }
118 }
119
UpdateDwtTouchpadRecord(libinput_event *event)120 void InputEventHandler::UpdateDwtTouchpadRecord(libinput_event *event)
121 {
122 auto touchpadEvent = libinput_event_get_touchpad_event(event);
123 CHKPV(touchpadEvent);
124 auto type = libinput_event_get_type(event);
125 if (type == LIBINPUT_EVENT_TOUCHPAD_DOWN) {
126 auto touchpadDevice = libinput_event_get_device(event); // guaranteed valid during event lifetime
127 CHKPV(touchpadDevice);
128 double touchpadSizeX;
129 double touchpadSizeY;
130 if (libinput_device_get_size(touchpadDevice, &touchpadSizeX, &touchpadSizeY) != 0) {
131 MMI_HILOGW("failed to get touchpad device size");
132 return;
133 }
134 touchpadEventDownAbsX_ = libinput_event_touchpad_get_x(touchpadEvent);
135 touchpadEventDownAbsY_ = libinput_event_touchpad_get_y(touchpadEvent);
136 touchpadEventAbsX_ = touchpadEventDownAbsX_;
137 touchpadEventAbsY_ = touchpadEventDownAbsY_;
138 if (touchpadEventDownAbsX_ > TOUCHPAD_EDGE_WIDTH &&
139 touchpadEventDownAbsX_ < touchpadSizeX - TOUCHPAD_EDGE_WIDTH) {
140 isDwtEdgeAreaForTouchpadMotionActing_ = false;
141 MMI_HILOGD("Pointer edge dwt unlocked, coordX = %{public}f", touchpadEventDownAbsX_);
142 }
143 if (touchpadEventDownAbsX_ > TOUCHPAD_EDGE_WIDTH_FOR_BUTTON &&
144 touchpadEventDownAbsX_ < touchpadSizeX - TOUCHPAD_EDGE_WIDTH_FOR_BUTTON) {
145 isDwtEdgeAreaForTouchpadButtonActing_ = false;
146 MMI_HILOGD("Button edge dwt unlocked, coordX = %{public}f", touchpadEventDownAbsX_);
147 }
148 if (touchpadEventDownAbsX_ > TOUCHPAD_EDGE_WIDTH_FOR_TAP &&
149 touchpadEventDownAbsX_ < touchpadSizeX - TOUCHPAD_EDGE_WIDTH_FOR_TAP) {
150 isDwtEdgeAreaForTouchpadTapActing_ = false;
151 MMI_HILOGD("Tap edge dwt unlocked, coordX = %{public}f", touchpadEventDownAbsX_);
152 }
153 }
154 if (type == LIBINPUT_EVENT_TOUCHPAD_MOTION) {
155 touchpadEventAbsX_ = libinput_event_touchpad_get_x(touchpadEvent);
156 touchpadEventAbsY_ = libinput_event_touchpad_get_y(touchpadEvent);
157 }
158 }
159
UpdateDwtKeyboardRecord(libinput_event *event)160 void InputEventHandler::UpdateDwtKeyboardRecord(libinput_event *event)
161 {
162 auto keyboardEvent = libinput_event_get_keyboard_event(event);
163 CHKPV(keyboardEvent);
164 uint32_t key = libinput_event_keyboard_get_key(keyboardEvent);
165 if (IsStandaloneFunctionKey(key)) {
166 return;
167 }
168
169 auto keyState = libinput_event_keyboard_get_key_state(keyboardEvent);
170 if (IsModifierKey(key)) {
171 modifierPressedCount_ += (keyState == LIBINPUT_KEY_STATE_PRESSED) ? 1 : -1;
172 }
173 if (keyState == LIBINPUT_KEY_STATE_PRESSED && modifierPressedCount_ > 0) {
174 isKeyPressedWithAnyModifiers_[key] = true; // set flag when key is pressed with modifiers
175 }
176 if (!IsModifierKey(key) && !isKeyPressedWithAnyModifiers_[key]) {
177 RefreshDwtActingState();
178 }
179 if (keyState == LIBINPUT_KEY_STATE_RELEASED) {
180 isKeyPressedWithAnyModifiers_[key] = false; // always reset flag when key is released
181 }
182 }
183
IsStandaloneFunctionKey(uint32_t keycode)184 bool InputEventHandler::IsStandaloneFunctionKey(uint32_t keycode)
185 {
186 if (IsModifierKey(keycode)) {
187 return false;
188 }
189 switch (keycode) {
190 case KEY_ESC:
191 case KEY_KPASTERISK:
192 return true;
193 default:
194 return keycode >= KEY_F1;
195 }
196 }
197
IsModifierKey(uint32_t keycode)198 bool InputEventHandler::IsModifierKey(uint32_t keycode)
199 {
200 switch (keycode) {
201 case KEY_LEFTCTRL:
202 case KEY_RIGHTCTRL:
203 case KEY_LEFTALT:
204 case KEY_RIGHTALT:
205 case KEY_LEFTSHIFT:
206 case KEY_RIGHTSHIFT:
207 case KEY_FN:
208 case KEY_CAPSLOCK:
209 case KEY_TAB:
210 case KEY_COMPOSE:
211 case KEY_RIGHTMETA:
212 case KEY_LEFTMETA:
213 return true;
214 default:
215 return false;
216 }
217 }
218
RefreshDwtActingState()219 void InputEventHandler::RefreshDwtActingState()
220 {
221 isDwtEdgeAreaForTouchpadMotionActing_ = true;
222 isDwtEdgeAreaForTouchpadButtonActing_ = true;
223 isDwtEdgeAreaForTouchpadTapActing_ = true;
224 }
225
IsTouchpadMistouch(libinput_event *event)226 bool InputEventHandler::IsTouchpadMistouch(libinput_event *event)
227 {
228 CHKPF(event);
229 auto type = libinput_event_get_type(event);
230 if (type >= LIBINPUT_EVENT_TOUCHPAD_DOWN && type <= LIBINPUT_EVENT_TOUCHPAD_MOTION) {
231 auto touchpadEvent = libinput_event_get_touchpad_event(event);
232 CHKPF(touchpadEvent);
233 int32_t toolType = libinput_event_touchpad_get_tool_type(touchpadEvent);
234 if (toolType == MT_TOOL_PALM) {
235 MMI_HILOGD("Touchpad event is palm");
236 return false;
237 }
238 }
239
240 if (type == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
241 return IsTouchpadButtonMistouch(event);
242 }
243 if (type == LIBINPUT_EVENT_POINTER_TAP) {
244 return IsTouchpadTapMistouch(event);
245 }
246 if (type == LIBINPUT_EVENT_TOUCHPAD_MOTION) {
247 return IsTouchpadMotionMistouch(event);
248 }
249 if (type == LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD) {
250 return IsTouchpadPointerMotionMistouch(event);
251 }
252
253 return false;
254 }
255
IsTouchpadButtonMistouch(libinput_event* event)256 bool InputEventHandler::IsTouchpadButtonMistouch(libinput_event* event)
257 {
258 CHKPF(event);
259 auto touchpadButtonEvent = libinput_event_get_pointer_event(event);
260 CHKPF(touchpadButtonEvent);
261 auto buttonState = libinput_event_pointer_get_button_state(touchpadButtonEvent);
262 if (buttonState == LIBINPUT_BUTTON_STATE_PRESSED) {
263 auto touchpadDevice = libinput_event_get_device(event); // guaranteed valid during event lifetime
264 CHKPF(touchpadDevice);
265 double touchpadSizeX;
266 double touchpadSizeY;
267 if (libinput_device_get_size(touchpadDevice, &touchpadSizeX, &touchpadSizeY) != 0) {
268 return false;
269 }
270 double coordX = touchpadEventAbsX_;
271 if (isDwtEdgeAreaForTouchpadButtonActing_ &&
272 (coordX <= TOUCHPAD_EDGE_WIDTH_FOR_BUTTON || coordX >= touchpadSizeX - TOUCHPAD_EDGE_WIDTH_FOR_BUTTON)) {
273 isButtonMistouch_ = true;
274 MMI_HILOGD("The buttonPressed event is mistouch");
275 return true;
276 }
277 }
278 if (buttonState == LIBINPUT_BUTTON_STATE_RELEASED) {
279 if (isButtonMistouch_) {
280 isButtonMistouch_ = false;
281 MMI_HILOGD("The buttonReleased event is mistouch");
282 return true;
283 }
284 }
285 return false;
286 }
287
IsTouchpadTapMistouch(libinput_event* event)288 bool InputEventHandler::IsTouchpadTapMistouch(libinput_event* event)
289 {
290 CHKPF(event);
291 auto data = libinput_event_get_pointer_event(event);
292 CHKPF(data);
293 auto state = libinput_event_pointer_get_button_state(data);
294 if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
295 auto touchpadDevice = libinput_event_get_device(event); // guaranteed valid during event lifetime
296 CHKPF(touchpadDevice);
297 double touchpadSizeX;
298 double touchpadSizeY;
299 if (libinput_device_get_size(touchpadDevice, &touchpadSizeX, &touchpadSizeY) != 0) {
300 return false;
301 }
302 double coordX = touchpadEventDownAbsX_;
303 if (isDwtEdgeAreaForTouchpadTapActing_ &&
304 (coordX <= TOUCHPAD_EDGE_WIDTH_FOR_TAP || coordX >= touchpadSizeX - TOUCHPAD_EDGE_WIDTH_FOR_TAP)) {
305 isTapMistouch_ = true;
306 MMI_HILOGD("Touchpad tap presse event is mistouch");
307 return true;
308 }
309 }
310 if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
311 if (isTapMistouch_) {
312 isTapMistouch_ = false;
313 MMI_HILOGD("Touchpad tap release event is mistouch");
314 return true;
315 }
316 }
317 return false;
318 }
319
IsTouchpadMotionMistouch(libinput_event *event)320 bool InputEventHandler::IsTouchpadMotionMistouch(libinput_event *event)
321 {
322 if (!isDwtEdgeAreaForTouchpadMotionActing_) {
323 return false;
324 }
325
326 CHKPF(event);
327 auto touchpadEvent = libinput_event_get_touchpad_event(event);
328 CHKPF(touchpadEvent);
329 auto touchpadDevice = libinput_event_get_device(event); // guaranteed valid during event lifetime
330 CHKPF(touchpadDevice);
331 double touchpadSizeX;
332 double touchpadSizeY;
333 if (libinput_device_get_size(touchpadDevice, &touchpadSizeX, &touchpadSizeY) != 0) {
334 return false;
335 }
336 auto coordX = touchpadEventDownAbsX_;
337 if (coordX <= TOUCHPAD_EDGE_WIDTH || coordX >= touchpadSizeX - TOUCHPAD_EDGE_WIDTH) {
338 MMI_HILOGD("Touchpad event is edge mistouch");
339 return true;
340 }
341 return false;
342 }
343
IsTouchpadPointerMotionMistouch(libinput_event *event)344 bool InputEventHandler::IsTouchpadPointerMotionMistouch(libinput_event *event)
345 {
346 if (!isDwtEdgeAreaForTouchpadMotionActing_) {
347 return false;
348 }
349
350 CHKPF(event);
351 auto pointerEvent = libinput_event_get_pointer_event(event);
352 CHKPF(pointerEvent);
353 auto touchpadDevice = libinput_event_get_device(event); // guaranteed valid during event lifetime
354 CHKPF(touchpadDevice);
355 double touchpadSizeX;
356 double touchpadSizeY;
357 if (libinput_device_get_size(touchpadDevice, &touchpadSizeX, &touchpadSizeY) != 0) {
358 return false;
359 }
360 double coordX = touchpadEventDownAbsX_;
361 if (coordX <= TOUCHPAD_EDGE_WIDTH || coordX >= touchpadSizeX - TOUCHPAD_EDGE_WIDTH) {
362 MMI_HILOGD("Touchpad pointer motion event is edge mistouch");
363 return true;
364 }
365 return false;
366 }
367
BuildInputHandlerChain()368 int32_t InputEventHandler::BuildInputHandlerChain()
369 {
370 eventNormalizeHandler_ = std::make_shared<EventNormalizeHandler>();
371 #if !defined(OHOS_BUILD_ENABLE_KEYBOARD) && !defined(OHOS_BUILD_ENABLE_POINTER) && !defined(OHOS_BUILD_ENABLE_TOUCH)
372 return RET_OK;
373 #endif // !OHOS_BUILD_ENABLE_KEYBOARD && !OHOS_BUILD_ENABLE_POINTER && !OHOS_BUILD_ENABLE_TOUCH
374
375 std::shared_ptr<IInputEventHandler> handler = eventNormalizeHandler_;
376 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
377 eventFilterHandler_ = std::make_shared<EventFilterHandler>();
378 handler->SetNext(eventFilterHandler_);
379 handler = eventFilterHandler_;
380 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
381
382 #ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
383 eventInterceptorHandler_ = std::make_shared<EventInterceptorHandler>();
384 handler->SetNext(eventInterceptorHandler_);
385 handler = eventInterceptorHandler_;
386 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR
387
388 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
389 #ifdef OHOS_BUILD_ENABLE_COMBINATION_KEY
390 eventKeyCommandHandler_ = std::make_shared<KeyCommandHandler>();
391 handler->SetNext(eventKeyCommandHandler_);
392 handler = eventKeyCommandHandler_;
393 #endif // OHOS_BUILD_ENABLE_COMBINATION_KEY
394 eventSubscriberHandler_ = std::make_shared<KeySubscriberHandler>();
395 handler->SetNext(eventSubscriberHandler_);
396 handler = eventSubscriberHandler_;
397 #endif // OHOS_BUILD_ENABLE_KEYBOARD
398 #ifdef OHOS_BUILD_ENABLE_SWITCH
399 switchEventSubscriberHandler_ = std::make_shared<SwitchSubscriberHandler>();
400 handler->SetNext(switchEventSubscriberHandler_);
401 handler = switchEventSubscriberHandler_;
402 #endif // OHOS_BUILD_ENABLE_SWITCH
403 #ifdef OHOS_BUILD_ENABLE_MONITOR
404 eventMonitorHandler_ = std::make_shared<EventMonitorHandler>();
405 handler->SetNext(eventMonitorHandler_);
406 handler = eventMonitorHandler_;
407 #endif // OHOS_BUILD_ENABLE_MONITOR
408 eventDispatchHandler_ = std::make_shared<EventDispatchHandler>();
409 handler->SetNext(eventDispatchHandler_);
410 return RET_OK;
411 }
412
GetIntervalSinceLastInput(int64_t &timeInterval)413 int32_t InputEventHandler::GetIntervalSinceLastInput(int64_t &timeInterval)
414 {
415 int64_t currentSystemTime = GetSysClockTime();
416 timeInterval = currentSystemTime - lastEventBeginTime_;
417 return RET_OK;
418 }
419
GetUDSServer() const420 UDSServer* InputEventHandler::GetUDSServer() const
421 {
422 return udsServer_;
423 }
424
GetEventNormalizeHandler() const425 std::shared_ptr<EventNormalizeHandler> InputEventHandler::GetEventNormalizeHandler() const
426 {
427 return eventNormalizeHandler_;
428 }
429
GetInterceptorHandler() const430 std::shared_ptr<EventInterceptorHandler> InputEventHandler::GetInterceptorHandler() const
431 {
432 return eventInterceptorHandler_;
433 }
434
GetSubscriberHandler() const435 std::shared_ptr<KeySubscriberHandler> InputEventHandler::GetSubscriberHandler() const
436 {
437 return eventSubscriberHandler_;
438 }
439
GetSwitchSubscriberHandler() const440 std::shared_ptr<SwitchSubscriberHandler> InputEventHandler::GetSwitchSubscriberHandler() const
441 {
442 return switchEventSubscriberHandler_;
443 }
444
GetKeyCommandHandler() const445 std::shared_ptr<KeyCommandHandler> InputEventHandler::GetKeyCommandHandler() const
446 {
447 return eventKeyCommandHandler_;
448 }
449
GetMonitorHandler() const450 std::shared_ptr<EventMonitorHandler> InputEventHandler::GetMonitorHandler() const
451 {
452 return eventMonitorHandler_;
453 }
454
GetFilterHandler() const455 std::shared_ptr<EventFilterHandler> InputEventHandler::GetFilterHandler() const
456 {
457 return eventFilterHandler_;
458 }
459
GetEventDispatchHandler() const460 std::shared_ptr<EventDispatchHandler> InputEventHandler::GetEventDispatchHandler() const
461 {
462 return eventDispatchHandler_;
463 }
464
SetMoveEventFilters(bool flag)465 int32_t InputEventHandler::SetMoveEventFilters(bool flag)
466 {
467 CALL_INFO_TRACE;
468 #ifdef OHOS_BUILD_ENABLE_MOVE_EVENT_FILTERS
469 CHKPR(eventNormalizeHandler_, INVALID_HANDLER_ID);
470 return eventNormalizeHandler_->SetMoveEventFilters(flag);
471 #else
472 MMI_HILOGW("Set move event filters does not support");
473 return ERROR_UNSUPPORT;
474 #endif // OHOS_BUILD_ENABLE_MOVE_EVENT_FILTERS
475 }
476 } // namespace MMI
477 } // namespace OHOS