• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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