1 /*
2 * Copyright (c) 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 "event_normalize_handler.h"
17
18 #include "bytrace_adapter.h"
19 #include "define_multimodal.h"
20 #include "dfx_hisysevent.h"
21
22 #include "error_multimodal.h"
23 #include "event_log_helper.h"
24 #include "input_device_manager.h"
25 #include "input_event_handler.h"
26 #include "key_auto_repeat.h"
27 #include "key_event_normalize.h"
28 #include "key_event_value_transformation.h"
29 #include "libinput_adapter.h"
30 #include "mmi_log.h"
31 #include "time_cost_chk.h"
32 #include "timer_manager.h"
33 #include "touch_event_normalize.h"
34
35 namespace OHOS {
36 namespace MMI {
37 namespace {
38 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "EventNormalizeHandler" };
39 constexpr int32_t FINGER_NUM = 2;
40 constexpr int32_t MT_TOOL_PALM = 2;
41 }
42
HandleEvent(libinput_event * event)43 void EventNormalizeHandler::HandleEvent(libinput_event* event)
44 {
45 CALL_DEBUG_ENTER;
46 CHKPV(event);
47 DfxHisysevent::GetDispStartTime();
48 auto type = libinput_event_get_type(event);
49 TimeCostChk chk("HandleLibinputEvent", "overtime 1000(us)", MAX_INPUT_EVENT_TIME, type);
50 if (type == LIBINPUT_EVENT_TOUCH_CANCEL || type == LIBINPUT_EVENT_TOUCH_FRAME) {
51 MMI_HILOGD("This touch event is canceled type:%{public}d", type);
52 return;
53 }
54 switch (type) {
55 case LIBINPUT_EVENT_DEVICE_ADDED: {
56 OnEventDeviceAdded(event);
57 break;
58 }
59 case LIBINPUT_EVENT_DEVICE_REMOVED: {
60 OnEventDeviceRemoved(event);
61 break;
62 }
63 case LIBINPUT_EVENT_KEYBOARD_KEY: {
64 HandleKeyboardEvent(event);
65 DfxHisysevent::CalcKeyDispTimes();
66 break;
67 }
68 case LIBINPUT_EVENT_POINTER_MOTION:
69 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
70 case LIBINPUT_EVENT_POINTER_BUTTON:
71 case LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD:
72 case LIBINPUT_EVENT_POINTER_AXIS:
73 case LIBINPUT_EVENT_POINTER_TAP:
74 case LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD: {
75 HandleMouseEvent(event);
76 DfxHisysevent::CalcPointerDispTimes();
77 break;
78 }
79 case LIBINPUT_EVENT_TOUCHPAD_DOWN:
80 case LIBINPUT_EVENT_TOUCHPAD_UP:
81 case LIBINPUT_EVENT_TOUCHPAD_MOTION: {
82 HandleTouchPadEvent(event);
83 DfxHisysevent::CalcPointerDispTimes();
84 break;
85 }
86 case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
87 case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
88 case LIBINPUT_EVENT_GESTURE_SWIPE_END:
89 case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
90 case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
91 case LIBINPUT_EVENT_GESTURE_PINCH_END: {
92 HandleGestureEvent(event);
93 DfxHisysevent::CalcPointerDispTimes();
94 break;
95 }
96 case LIBINPUT_EVENT_TOUCH_DOWN:
97 case LIBINPUT_EVENT_TOUCH_UP:
98 case LIBINPUT_EVENT_TOUCH_MOTION: {
99 HandleTouchEvent(event);
100 DfxHisysevent::CalcPointerDispTimes();
101 break;
102 }
103 case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
104 case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
105 case LIBINPUT_EVENT_TABLET_TOOL_TIP: {
106 HandleTableToolEvent(event);
107 break;
108 }
109 case LIBINPUT_EVENT_JOYSTICK_BUTTON:
110 case LIBINPUT_EVENT_JOYSTICK_AXIS: {
111 HandleJoystickEvent(event);
112 DfxHisysevent::CalcPointerDispTimes();
113 break;
114 }
115 case LIBINPUT_EVENT_SWITCH_TOGGLE: {
116 HandleSwitchInputEvent(event);
117 break;
118 }
119 default: {
120 MMI_HILOGW("This device does not support :%d", type);
121 break;
122 }
123 }
124 DfxHisysevent::ReportDispTimes();
125 }
126
OnEventDeviceAdded(libinput_event * event)127 int32_t EventNormalizeHandler::OnEventDeviceAdded(libinput_event *event)
128 {
129 CHKPR(event, ERROR_NULL_POINTER);
130 auto device = libinput_event_get_device(event);
131 CHKPR(device, ERROR_NULL_POINTER);
132 InputDevMgr->OnInputDeviceAdded(device);
133 KeyMapMgr->ParseDeviceConfigFile(device);
134 KeyRepeat->AddDeviceConfig(device);
135 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
136 KeyEventHdr->ResetKeyEvent(device);
137 #endif // OHOS_BUILD_ENABLE_KEYBOARD
138 return RET_OK;
139 }
140
OnEventDeviceRemoved(libinput_event * event)141 int32_t EventNormalizeHandler::OnEventDeviceRemoved(libinput_event *event)
142 {
143 CHKPR(event, ERROR_NULL_POINTER);
144 auto device = libinput_event_get_device(event);
145 CHKPR(device, ERROR_NULL_POINTER);
146 KeyMapMgr->RemoveKeyValue(device);
147 KeyRepeat->RemoveDeviceConfig(device);
148 InputDevMgr->OnInputDeviceRemoved(device);
149 return RET_OK;
150 }
151
152 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)153 void EventNormalizeHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
154 {
155 if (nextHandler_ == nullptr) {
156 MMI_HILOGW("Keyboard device does not support");
157 return;
158 }
159 DfxHisysevent::GetDispStartTime();
160 CHKPV(keyEvent);
161 EventLogHelper::PrintEventData(keyEvent);
162 nextHandler_->HandleKeyEvent(keyEvent);
163 DfxHisysevent::CalcKeyDispTimes();
164 DfxHisysevent::ReportDispTimes();
165 }
166 #endif // OHOS_BUILD_ENABLE_KEYBOARD
167
168 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)169 void EventNormalizeHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
170 {
171 if (nextHandler_ == nullptr) {
172 MMI_HILOGW("Pointer device does not support");
173 return;
174 }
175 DfxHisysevent::GetDispStartTime();
176 CHKPV(pointerEvent);
177 if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_END) {
178 MMI_HILOGI("MouseEvent Normalization Results, PointerAction:%{public}d,PointerId:%{public}d,"
179 "SourceType:%{public}d,ButtonId:%{public}d,"
180 "VerticalAxisValue:%{public}lf,HorizontalAxisValue:%{public}lf",
181 pointerEvent->GetPointerAction(), pointerEvent->GetPointerId(), pointerEvent->GetSourceType(),
182 pointerEvent->GetButtonId(), pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL),
183 pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL));
184 PointerEvent::PointerItem item;
185 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), item)) {
186 MMI_HILOGE("Get pointer item failed. pointer:%{public}d", pointerEvent->GetPointerId());
187 return;
188 }
189 MMI_HILOGI("MouseEvent Item Normalization Results, DownTime:%{public}" PRId64 ",IsPressed:%{public}d,"
190 "DisplayX:%{public}d,DisplayY:%{public}d,WindowX:%{public}d,WindowY:%{public}d,"
191 "Width:%{public}d,Height:%{public}d,Pressure:%{public}f,Device:%{public}d",
192 item.GetDownTime(), static_cast<int32_t>(item.IsPressed()), item.GetDisplayX(), item.GetDisplayY(),
193 item.GetWindowX(), item.GetWindowY(), item.GetWidth(), item.GetHeight(), item.GetPressure(),
194 item.GetDeviceId());
195 }
196 WinMgr->UpdateTargetPointer(pointerEvent);
197 nextHandler_->HandlePointerEvent(pointerEvent);
198 DfxHisysevent::CalcPointerDispTimes();
199 DfxHisysevent::ReportDispTimes();
200 }
201 #endif // OHOS_BUILD_ENABLE_POINTER
202
203 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)204 void EventNormalizeHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
205 {
206 if (nextHandler_ == nullptr) {
207 MMI_HILOGW("Touchscreen device does not support");
208 return;
209 }
210 DfxHisysevent::GetDispStartTime();
211 CHKPV(pointerEvent);
212 WinMgr->UpdateTargetPointer(pointerEvent);
213 nextHandler_->HandleTouchEvent(pointerEvent);
214 DfxHisysevent::CalcPointerDispTimes();
215 DfxHisysevent::ReportDispTimes();
216 }
217 #endif // OHOS_BUILD_ENABLE_TOUCH
218
HandleKeyboardEvent(libinput_event * event)219 int32_t EventNormalizeHandler::HandleKeyboardEvent(libinput_event* event)
220 {
221 if (nextHandler_ == nullptr) {
222 MMI_HILOGW("Keyboard device does not support");
223 return ERROR_UNSUPPORT;
224 }
225 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
226 auto keyEvent = KeyEventHdr->GetKeyEvent();
227 CHKPR(keyEvent, ERROR_NULL_POINTER);
228 CHKPR(event, ERROR_NULL_POINTER);
229 std::vector<int32_t> pressedKeys = keyEvent->GetPressedKeys();
230 int32_t lastPressedKey = -1;
231 if (!pressedKeys.empty()) {
232 lastPressedKey = pressedKeys.back();
233 MMI_HILOGD("The last repeat button, keyCode:%{public}d", lastPressedKey);
234 }
235 auto packageResult = KeyEventHdr->Normalize(event, keyEvent);
236 if (packageResult == MULTIDEVICE_SAME_EVENT_MARK) {
237 MMI_HILOGD("The same event reported by multi_device should be discarded");
238 return RET_OK;
239 }
240 if (packageResult != RET_OK) {
241 MMI_HILOGE("KeyEvent package failed, ret:%{public}d,errCode:%{public}d", packageResult, KEY_EVENT_PKG_FAIL);
242 return KEY_EVENT_PKG_FAIL;
243 }
244
245 BytraceAdapter::StartBytrace(keyEvent);
246 EventLogHelper::PrintEventData(keyEvent);
247 nextHandler_->HandleKeyEvent(keyEvent);
248 KeyRepeat->SelectAutoRepeat(keyEvent);
249 MMI_HILOGD("keyCode:%{public}d, action:%{public}d", keyEvent->GetKeyCode(), keyEvent->GetKeyAction());
250 #else
251 MMI_HILOGW("Keyboard device does not support");
252 #endif // OHOS_BUILD_ENABLE_KEYBOARD
253 return RET_OK;
254 }
255
HandleMouseEvent(libinput_event * event)256 int32_t EventNormalizeHandler::HandleMouseEvent(libinput_event* event)
257 {
258 if (nextHandler_ == nullptr) {
259 MMI_HILOGW("Pointer device does not support");
260 return ERROR_UNSUPPORT;
261 }
262 #ifdef OHOS_BUILD_ENABLE_POINTER
263 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
264 const auto &keyEvent = KeyEventHdr->GetKeyEvent();
265 CHKPR(keyEvent, ERROR_NULL_POINTER);
266 #endif // OHOS_BUILD_ENABLE_KEYBOARD
267 if (MouseEventHdr->OnEvent(event) == RET_ERR) {
268 MMI_HILOGE("OnEvent is failed");
269 return RET_ERR;
270 }
271 auto pointerEvent = MouseEventHdr->GetPointerEvent();
272 CHKPR(pointerEvent, ERROR_NULL_POINTER);
273 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
274 std::vector<int32_t> pressedKeys = keyEvent->GetPressedKeys();
275 for (const int32_t& keyCode : pressedKeys) {
276 MMI_HILOGI("Pressed keyCode:%{public}d", keyCode);
277 }
278 pointerEvent->SetPressedKeys(pressedKeys);
279 #endif // OHOS_BUILD_ENABLE_KEYBOARD
280 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START);
281 HandlePalmEvent(event, pointerEvent);
282 nextHandler_->HandlePointerEvent(pointerEvent);
283 #else
284 MMI_HILOGW("Pointer device does not support");
285 #endif // OHOS_BUILD_ENABLE_POINTER
286 return RET_OK;
287 }
288
HandlePalmEvent(libinput_event * event,std::shared_ptr<PointerEvent> pointerEvent)289 void EventNormalizeHandler::HandlePalmEvent(libinput_event* event, std::shared_ptr<PointerEvent> pointerEvent)
290 {
291 auto touchpad = libinput_event_get_touchpad_event(event);
292 CHKPV(touchpad);
293 int32_t toolType = libinput_event_touchpad_get_tool_type(touchpad);
294 if (toolType == MT_TOOL_PALM) {
295 MMI_HILOGD("ToolType is MT_TOOL_PALM");
296 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
297 }
298 }
299
HandleTouchPadEvent(libinput_event * event)300 int32_t EventNormalizeHandler::HandleTouchPadEvent(libinput_event* event)
301 {
302 if (nextHandler_ == nullptr) {
303 MMI_HILOGW("Pointer device does not support");
304 return ERROR_UNSUPPORT;
305 }
306 #ifdef OHOS_BUILD_ENABLE_POINTER
307 CHKPR(event, ERROR_NULL_POINTER);
308 auto touchpad = libinput_event_get_touchpad_event(event);
309 CHKPR(touchpad, ERROR_NULL_POINTER);
310 int32_t seatSlot = libinput_event_touchpad_get_seat_slot(touchpad);
311 buttonIds_.insert(seatSlot);
312 auto type = libinput_event_get_type(event);
313 if (buttonIds_.size() == FINGER_NUM &&
314 (type == LIBINPUT_EVENT_TOUCHPAD_DOWN || type == LIBINPUT_EVENT_TOUCHPAD_UP)) {
315 MMI_HILOGD("Handle mouse axis event");
316 HandleMouseEvent(event);
317 }
318 return RET_OK;
319 #else
320 MMI_HILOGW("Pointer device does not support");
321 #endif // OHOS_BUILD_ENABLE_POINTER
322 return RET_OK;
323 }
324
HandleGestureEvent(libinput_event * event)325 int32_t EventNormalizeHandler::HandleGestureEvent(libinput_event* event)
326 {
327 if (nextHandler_ == nullptr) {
328 MMI_HILOGW("Pointer device does not support");
329 return ERROR_UNSUPPORT;
330 }
331 #ifdef OHOS_BUILD_ENABLE_POINTER
332 CHKPR(event, ERROR_NULL_POINTER);
333 auto pointerEvent = TouchEventHdr->OnLibInput(event, TouchEventNormalize::DeviceType::TOUCH_PAD);
334 CHKPR(pointerEvent, ERROR_NULL_POINTER);
335 nextHandler_->HandlePointerEvent(pointerEvent);
336 auto type = libinput_event_get_type(event);
337 if (type == LIBINPUT_EVENT_GESTURE_SWIPE_END || type == LIBINPUT_EVENT_GESTURE_PINCH_END) {
338 pointerEvent->RemovePointerItem(pointerEvent->GetPointerId());
339 MMI_HILOGD("This touch pad event is up remove this finger");
340 if (pointerEvent->GetPointerIds().empty()) {
341 MMI_HILOGD("This touch pad event is final finger up remove this finger");
342 pointerEvent->Reset();
343 }
344 }
345 #else
346 MMI_HILOGW("Pointer device does not support");
347 #endif // OHOS_BUILD_ENABLE_POINTER
348 return RET_OK;
349 }
350
HandleTouchEvent(libinput_event * event)351 int32_t EventNormalizeHandler::HandleTouchEvent(libinput_event* event)
352 {
353 if (nextHandler_ == nullptr) {
354 MMI_HILOGW("Touchscreen device does not support");
355 return ERROR_UNSUPPORT;
356 }
357 #ifdef OHOS_BUILD_ENABLE_TOUCH
358 CHKPR(event, ERROR_NULL_POINTER);
359 auto pointerEvent = TouchEventHdr->OnLibInput(event, TouchEventNormalize::DeviceType::TOUCH);
360 CHKPR(pointerEvent, ERROR_NULL_POINTER);
361 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START);
362 nextHandler_->HandleTouchEvent(pointerEvent);
363 ResetTouchUpEvent(pointerEvent, event);
364 #else
365 MMI_HILOGW("Touchscreen device does not support");
366 #endif // OHOS_BUILD_ENABLE_TOUCH
367 return RET_OK;
368 }
369
ResetTouchUpEvent(std::shared_ptr<PointerEvent> pointerEvent,struct libinput_event * event)370 void EventNormalizeHandler::ResetTouchUpEvent(std::shared_ptr<PointerEvent> pointerEvent,
371 struct libinput_event *event)
372 {
373 CHKPV(pointerEvent);
374 CHKPV(event);
375 auto type = libinput_event_get_type(event);
376 if (type == LIBINPUT_EVENT_TOUCH_UP) {
377 pointerEvent->RemovePointerItem(pointerEvent->GetPointerId());
378 MMI_HILOGD("This touch event is up remove this finger");
379 if (pointerEvent->GetPointerIds().empty()) {
380 MMI_HILOGD("This touch event is final finger up remove this finger");
381 pointerEvent->Reset();
382 }
383 }
384 }
385
HandleTableToolEvent(libinput_event * event)386 int32_t EventNormalizeHandler::HandleTableToolEvent(libinput_event* event)
387 {
388 if (nextHandler_ == nullptr) {
389 MMI_HILOGW("TableTool device does not support");
390 return ERROR_UNSUPPORT;
391 }
392 #ifdef OHOS_BUILD_ENABLE_TOUCH
393 CHKPR(event, ERROR_NULL_POINTER);
394 auto pointerEvent = TouchEventHdr->OnLibInput(event, TouchEventNormalize::DeviceType::TABLET_TOOL);
395 CHKPR(pointerEvent, ERROR_NULL_POINTER);
396 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START);
397 nextHandler_->HandleTouchEvent(pointerEvent);
398 if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP) {
399 pointerEvent->Reset();
400 }
401 #else
402 MMI_HILOGW("TableTool device does not support");
403 #endif // OHOS_BUILD_ENABLE_TOUCH
404 return RET_OK;
405 }
406
HandleJoystickEvent(libinput_event * event)407 int32_t EventNormalizeHandler::HandleJoystickEvent(libinput_event* event)
408 {
409 CALL_DEBUG_ENTER;
410 if (nextHandler_ == nullptr) {
411 MMI_HILOGW("Joystick device does not support");
412 return ERROR_UNSUPPORT;
413 }
414 #ifdef OHOS_BUILD_ENABLE_JOYSTICK
415 CHKPR(event, ERROR_NULL_POINTER);
416 auto pointerEvent = TouchEventHdr->OnLibInput(event, TouchEventNormalize::DeviceType::JOYSTICK);
417 CHKPR(pointerEvent, ERROR_NULL_POINTER);
418 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START);
419 nextHandler_->HandlePointerEvent(pointerEvent);
420 #else
421 MMI_HILOGW("Joystick device does not support");
422 #endif // OHOS_BUILD_ENABLE_JOYSTICK
423 return RET_OK;
424 }
425
HandleSwitchInputEvent(libinput_event * event)426 int32_t EventNormalizeHandler::HandleSwitchInputEvent(libinput_event* event)
427 {
428 if (nextHandler_ == nullptr) {
429 MMI_HILOGW("switch device does not support");
430 return ERROR_UNSUPPORT;
431 }
432 #ifdef OHOS_BUILD_ENABLE_SWITCH
433 CHKPR(event, ERROR_NULL_POINTER);
434 struct libinput_event_switch *swev = libinput_event_get_switch_event(event);
435 CHKPR(swev, ERROR_NULL_POINTER);
436
437 enum libinput_switch_state state = libinput_event_switch_get_switch_state(swev);
438 auto swEvent = std::make_unique<SwitchEvent>(static_cast<int>(state));
439 nextHandler_->HandleSwitchEvent(std::move(swEvent));
440 #else
441 MMI_HILOGW("switch device does not support");
442 #endif // OHOS_BUILD_ENABLE_SWITCH
443 return RET_OK;
444 }
445
AddHandleTimer(int32_t timeout)446 int32_t EventNormalizeHandler::AddHandleTimer(int32_t timeout)
447 {
448 CALL_DEBUG_ENTER;
449 timerId_ = TimerMgr->AddTimer(timeout, 1, [this]() {
450 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
451 auto keyEvent = KeyEventHdr->GetKeyEvent();
452 CHKPV(keyEvent);
453 CHKPV(nextHandler_);
454 nextHandler_->HandleKeyEvent(keyEvent);
455 int32_t triggerTime = KeyRepeat->GetIntervalTime(keyEvent->GetDeviceId());
456 this->AddHandleTimer(triggerTime);
457 #endif // OHOS_BUILD_ENABLE_KEYBOARD
458 });
459 return timerId_;
460 }
461 } // namespace MMI
462 } // namespace OHOS
463