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 #include <cstdio>
18 #include <cstring>
19 #include <functional>
20 #include <vector>
21 #include <cinttypes>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include "bytrace.h"
25 #include "input_device_manager.h"
26 #include "interceptor_manager_global.h"
27 #include "mmi_func_callback.h"
28 #include "mouse_event_handler.h"
29 #include "s_input.h"
30 #include "time_cost_chk.h"
31 #include "timer_manager.h"
32 #include "touch_transform_point_manager.h"
33 #include "util.h"
34
35 namespace OHOS {
36 namespace MMI {
37 namespace {
38 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "InputEventHandler" };
39 }
40
InputEventHandler()41 InputEventHandler::InputEventHandler()
42 {
43 udsServer_ = nullptr;
44 notifyDeviceChange_ = nullptr;
45 }
46
~InputEventHandler()47 InputEventHandler::~InputEventHandler() {}
48
Init(UDSServer & udsServer)49 void InputEventHandler::Init(UDSServer& udsServer)
50 {
51 udsServer_ = &udsServer;
52 MsgCallback funs[] = {
53 {
54 MmiMessageId::LIBINPUT_EVENT_DEVICE_ADDED,
55 MsgCallbackBind1(&InputEventHandler::OnEventDeviceAdded, this)
56 },
57 {
58 MmiMessageId::LIBINPUT_EVENT_DEVICE_REMOVED,
59 MsgCallbackBind1(&InputEventHandler::OnEventDeviceRemoved, this)
60 },
61 {
62 MmiMessageId::LIBINPUT_EVENT_KEYBOARD_KEY,
63 MsgCallbackBind1(&InputEventHandler::OnEventKey, this)
64 },
65 {
66 MmiMessageId::LIBINPUT_EVENT_POINTER_MOTION,
67 MsgCallbackBind1(&InputEventHandler::OnEventPointer, this)
68 },
69 {
70 MmiMessageId::LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
71 MsgCallbackBind1(&InputEventHandler::OnEventPointer, this)
72 },
73 {
74 MmiMessageId::LIBINPUT_EVENT_POINTER_BUTTON,
75 MsgCallbackBind1(&InputEventHandler::OnEventPointer, this)
76 },
77 {
78 MmiMessageId::LIBINPUT_EVENT_POINTER_AXIS,
79 MsgCallbackBind1(&InputEventHandler::OnEventPointer, this)
80 },
81 {
82 MmiMessageId::LIBINPUT_EVENT_TOUCH_DOWN,
83 MsgCallbackBind1(&InputEventHandler::OnEventTouch, this)
84 },
85 {
86 MmiMessageId::LIBINPUT_EVENT_TOUCH_UP,
87 MsgCallbackBind1(&InputEventHandler::OnEventTouch, this)
88 },
89 {
90 MmiMessageId::LIBINPUT_EVENT_TOUCH_MOTION,
91 MsgCallbackBind1(&InputEventHandler::OnEventTouch, this)
92 },
93 {
94 MmiMessageId::LIBINPUT_EVENT_TOUCH_CANCEL,
95 MsgCallbackBind1(&InputEventHandler::OnEventTouch, this)
96 },
97 {
98 MmiMessageId::LIBINPUT_EVENT_TOUCH_FRAME,
99 MsgCallbackBind1(&InputEventHandler::OnEventTouch, this)
100 },
101 {
102 MmiMessageId::LIBINPUT_EVENT_TOUCHPAD_DOWN,
103 MsgCallbackBind1(&InputEventHandler::OnEventTouchpad, this)
104 },
105 {
106 MmiMessageId::LIBINPUT_EVENT_TOUCHPAD_UP,
107 MsgCallbackBind1(&InputEventHandler::OnEventTouchpad, this)
108 },
109 {
110 MmiMessageId::LIBINPUT_EVENT_TOUCHPAD_MOTION,
111 MsgCallbackBind1(&InputEventHandler::OnEventTouchpad, this)
112 },
113 {
114 MmiMessageId::LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
115 MsgCallbackBind1(&InputEventHandler::OnEventGesture, this)
116 },
117 {
118 MmiMessageId::LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
119 MsgCallbackBind1(&InputEventHandler::OnEventGesture, this)
120 },
121 {
122 MmiMessageId::LIBINPUT_EVENT_GESTURE_SWIPE_END,
123 MsgCallbackBind1(&InputEventHandler::OnEventGesture, this)
124 },
125 {
126 MmiMessageId::LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
127 MsgCallbackBind1(&InputEventHandler::OnEventGesture, this)
128 },
129 {
130 MmiMessageId::LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
131 MsgCallbackBind1(&InputEventHandler::OnEventGesture, this)
132 },
133 {
134 MmiMessageId::LIBINPUT_EVENT_GESTURE_PINCH_END,
135 MsgCallbackBind1(&InputEventHandler::OnEventGesture, this)
136 },
137 };
138 for (auto &item : funs) {
139 CHKC(RegistrationEvent(item), EVENT_REG_FAIL);
140 }
141 return;
142 }
143
OnEvent(void * event)144 void InputEventHandler::OnEvent(void *event)
145 {
146 CHKPV(event);
147 std::lock_guard<std::mutex> lock(mu_);
148 auto *lpMmiEvent = static_cast<multimodal_libinput_event *>(event);
149 CHKPV(lpMmiEvent);
150 auto *lpEvent = lpMmiEvent->event;
151 CHKPV(lpEvent);
152 if (initSysClock_ != 0 && lastSysClock_ == 0) {
153 MMI_LOGE("Event not handled. id:%{public}" PRId64 ",eventType:%{public}d,initSysClock:%{public}" PRId64,
154 idSeed_, eventType_, initSysClock_);
155 }
156
157 eventType_ = libinput_event_get_type(lpEvent);
158 auto tid = GetThisThreadIdOfLL();
159 initSysClock_ = GetSysClockTime();
160 lastSysClock_ = 0;
161 idSeed_ += 1;
162 const uint64_t maxUInt64 = (std::numeric_limits<uint64_t>::max)() - 1;
163 if (idSeed_ >= maxUInt64) {
164 MMI_LOGE("Invaild value. id:%{public}" PRId64, idSeed_);
165 idSeed_ = 1;
166 return;
167 }
168
169 MMI_LOGD("Event reporting. id:%{public}" PRId64 ",tid:%{public}" PRId64 ",eventType:%{public}d,"
170 "initSysClock:%{public}" PRId64, idSeed_, tid, eventType_, initSysClock_);
171
172 OnEventHandler(*lpMmiEvent);
173 lastSysClock_ = GetSysClockTime();
174 int64_t lostTime = lastSysClock_ - initSysClock_;
175 MMI_LOGD("Event handling completed. id:%{public}" PRId64 ",lastSynClock:%{public}" PRId64
176 ",lostTime:%{public}" PRId64, idSeed_, lastSysClock_, lostTime);
177 }
178
OnEventHandler(const multimodal_libinput_event & ev)179 int32_t InputEventHandler::OnEventHandler(const multimodal_libinput_event& ev)
180 {
181 CHKPR(ev.event, ERROR_NULL_POINTER);
182 auto type = libinput_event_get_type(ev.event);
183 TimeCostChk chk("InputEventHandler::OnEventHandler", "overtime 1000(us)", MAX_INPUT_EVENT_TIME, type);
184 auto callback = GetMsgCallback(static_cast<MmiMessageId>(type));
185 if (callback == nullptr) {
186 MMI_LOGE("Unknown event type:%{public}d,errCode:%{public}d", type, UNKNOWN_EVENT);
187 return UNKNOWN_EVENT;
188 }
189 auto ret = (*callback)(ev);
190 if (ret != 0) {
191 MMI_LOGE("Event handling failed. type:%{public}d,ret:%{public}d,errCode:%{public}d",
192 type, ret, EVENT_CONSUM_FAIL);
193 return ret;
194 }
195 return ret;
196 }
197
OnCheckEventReport()198 void InputEventHandler::OnCheckEventReport()
199 {
200 std::lock_guard<std::mutex> lock(mu_);
201 if (initSysClock_ == 0 || lastSysClock_ != 0) {
202 return;
203 }
204 constexpr uint64_t MAX_DID_TIME = 1000 * 1000 * 3;
205 auto curSysClock = GetSysClockTime();
206 auto lostTime = curSysClock - initSysClock_;
207 if (lostTime < MAX_DID_TIME) {
208 return;
209 }
210 MMI_LOGE("Event not responding. id:%{public}" PRId64 ",eventType:%{public}d,initSysClock:%{public}" PRId64 ","
211 "lostTime:%{public}" PRId64, idSeed_, eventType_, initSysClock_, lostTime);
212 }
213
GetUDSServer()214 UDSServer* InputEventHandler::GetUDSServer()
215 {
216 return udsServer_;
217 }
218
AddInputEventFilter(sptr<IEventFilter> filter)219 int32_t InputEventHandler::AddInputEventFilter(sptr<IEventFilter> filter)
220 {
221 return eventDispatch_.AddInputEventFilter(filter);
222 }
223
OnEventDeviceAdded(const multimodal_libinput_event & ev)224 int32_t InputEventHandler::OnEventDeviceAdded(const multimodal_libinput_event& ev)
225 {
226 CHKPR(ev.event, ERROR_NULL_POINTER);
227 auto device = libinput_event_get_device(ev.event);
228 InputDevMgr->OnInputDeviceAdded(device);
229 return RET_OK;
230 }
OnEventDeviceRemoved(const multimodal_libinput_event & ev)231 int32_t InputEventHandler::OnEventDeviceRemoved(const multimodal_libinput_event& ev)
232 {
233 CHKPR(ev.event, ERROR_NULL_POINTER);
234 auto device = libinput_event_get_device(ev.event);
235 InputDevMgr->OnInputDeviceRemoved(device);
236 return RET_OK;
237 }
238
AddHandleTimer(int32_t timeout)239 void InputEventHandler::AddHandleTimer(int32_t timeout)
240 {
241 timerId_ = TimerMgr->AddTimer(timeout, 1, [this]() {
242 MMI_LOGD("enter");
243 if (this->keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
244 MMI_LOGD("key up");
245 return;
246 }
247 int64_t sysStartProcessTime = GetSysClockTime();
248 auto ret = eventDispatch_.DispatchKeyEventPid(*(this->udsServer_), this->keyEvent_, sysStartProcessTime);
249 if (ret != RET_OK) {
250 MMI_LOGE("KeyEvent dispatch failed. ret:%{public}d,errCode:%{public}d", ret, KEY_EVENT_DISP_FAIL);
251 }
252 constexpr int32_t triggerTime = 100;
253 this->AddHandleTimer(triggerTime);
254 MMI_LOGD("leave");
255 });
256 }
257
OnEventKey(const multimodal_libinput_event & ev)258 int32_t InputEventHandler::OnEventKey(const multimodal_libinput_event& ev)
259 {
260 CHKPR(ev.event, ERROR_NULL_POINTER);
261 CHKPR(udsServer_, ERROR_NULL_POINTER);
262 int64_t sysStartProcessTime = GetSysClockTime();
263 if (keyEvent_ == nullptr) {
264 keyEvent_ = KeyEvent::Create();
265 }
266
267 auto packageResult = eventPackage_.PackageKeyEvent(ev.event, keyEvent_);
268 if (packageResult == MULTIDEVICE_SAME_EVENT_MARK) {
269 MMI_LOGD("The same event reported by multi_device should be discarded");
270 return RET_OK;
271 }
272 if (packageResult != RET_OK) {
273 MMI_LOGE("KeyEvent package failed. ret:%{public}d,errCode:%{public}d", packageResult, KEY_EVENT_PKG_FAIL);
274 return KEY_EVENT_PKG_FAIL;
275 }
276
277 int32_t keyId = keyEvent_->GetId();
278 std::string keyEventString = "OnKeyEvent";
279 StartAsyncTrace(BYTRACE_TAG_MULTIMODALINPUT, keyEventString, keyId);
280 keyEventString = "service report keyId=" + std::to_string(keyId);
281 BYTRACE_NAME(BYTRACE_TAG_MULTIMODALINPUT, keyEventString);
282
283 auto ret = eventDispatch_.DispatchKeyEventPid(*udsServer_, keyEvent_, sysStartProcessTime);
284 if (ret != RET_OK) {
285 MMI_LOGE("KeyEvent dispatch failed. ret:%{public}d,errCode:%{public}d", ret, KEY_EVENT_DISP_FAIL);
286 return KEY_EVENT_DISP_FAIL;
287 }
288 if (keyEvent_->GetKeyCode() == KeyEvent::KEYCODE_VOLUME_UP ||
289 keyEvent_->GetKeyCode() == KeyEvent::KEYCODE_VOLUME_DOWN) {
290 if (!TimerMgr->IsExist(timerId_) && keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
291 AddHandleTimer();
292 MMI_LOGD("add a timer");
293 }
294 if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_UP && TimerMgr->IsExist(timerId_)) {
295 TimerMgr->RemoveTimer(timerId_);
296 timerId_ = -1;
297 }
298 }
299
300 MMI_LOGD("keyCode:%{public}d,action:%{public}d", keyEvent_->GetKeyCode(), keyEvent_->GetKeyAction());
301 return RET_OK;
302 }
303
OnEventPointer(const multimodal_libinput_event & ev)304 int32_t InputEventHandler::OnEventPointer(const multimodal_libinput_event& ev)
305 {
306 CHKPR(ev.event, ERROR_NULL_POINTER);
307 return OnMouseEventHandler(ev.event);
308 }
309
OnEventTouchSecond(struct libinput_event * event)310 int32_t InputEventHandler::OnEventTouchSecond(struct libinput_event *event)
311 {
312 MMI_LOGD("Enter");
313 CHKPR(event, ERROR_NULL_POINTER);
314 auto type = libinput_event_get_type(event);
315 if (type == LIBINPUT_EVENT_TOUCH_CANCEL || type == LIBINPUT_EVENT_TOUCH_FRAME) {
316 MMI_LOGI("This touch event is canceled type:%{public}d", type);
317 return RET_OK;
318 }
319 auto point = TouchTransformPointManger->OnLibinputTouchEvent(event);
320 CHKPR(point, ERROR_NULL_POINTER);
321 int32_t pointerId = point->GetId();
322 std::string touchEvent = "OnEventTouch";
323 StartAsyncTrace(BYTRACE_TAG_MULTIMODALINPUT, touchEvent, pointerId);
324 eventDispatch_.HandlePointerEvent(point);
325 if (type == LIBINPUT_EVENT_TOUCH_UP) {
326 point->RemovePointerItem(point->GetPointerId());
327 MMI_LOGD("This touch event is up remove this finger");
328 if (point->GetPointersIdList().empty()) {
329 MMI_LOGD("This touch event is final finger up remove this finger");
330 point->Reset();
331 }
332 return RET_OK;
333 }
334 MMI_LOGD("Leave");
335 return RET_OK;
336 }
337
OnEventTouchPadSecond(struct libinput_event * event)338 int32_t InputEventHandler::OnEventTouchPadSecond(struct libinput_event *event)
339 {
340 MMI_LOGD("Enter");
341 CHKPR(event, ERROR_NULL_POINTER);
342
343 auto point = TouchTransformPointManger->OnLibinputTouchPadEvent(event);
344 if (point == nullptr) {
345 MMI_LOGW("PointerEvent is null");
346 return RET_OK;
347 }
348 eventDispatch_.HandlePointerEvent(point);
349 auto type = libinput_event_get_type(event);
350 if (type == LIBINPUT_EVENT_TOUCHPAD_UP) {
351 point->RemovePointerItem(point->GetPointerId());
352 MMI_LOGD("This touch pad event is up remove this finger");
353 if (point->GetPointersIdList().empty()) {
354 MMI_LOGD("This touch pad event is final finger up remove this finger");
355 point->Reset();
356 }
357 return RET_OK;
358 }
359 MMI_LOGD("Leave");
360 return RET_OK;
361 }
362
OnEventTouch(const multimodal_libinput_event & ev)363 int32_t InputEventHandler::OnEventTouch(const multimodal_libinput_event& ev)
364 {
365 CHKPR(ev.event, ERROR_NULL_POINTER);
366 SInput::LoginfoPackagingTool(ev.event);
367 return OnEventTouchSecond(ev.event);
368 }
369
OnEventTouchpad(const multimodal_libinput_event & ev)370 int32_t InputEventHandler::OnEventTouchpad(const multimodal_libinput_event& ev)
371 {
372 OnEventTouchPadSecond(ev.event);
373 return RET_OK;
374 }
375
OnGestureEvent(struct libinput_event * event)376 int32_t InputEventHandler::OnGestureEvent(struct libinput_event *event)
377 {
378 CHKPR(event, ERROR_NULL_POINTER);
379 auto pointer = TouchTransformPointManger->OnTouchPadGestrueEvent(event);
380 if (pointer == nullptr) {
381 MMI_LOGE("Gesture event package failed, errCode:%{public}d", GESTURE_EVENT_PKG_FAIL);
382 return GESTURE_EVENT_PKG_FAIL;
383 }
384 MMI_LOGD("GestrueEvent package, eventType:%{public}d,actionTime:%{public}" PRId64 ","
385 "action:%{public}d,actionStartTime:%{public}" PRId64 ","
386 "pointerAction:%{public}d,sourceType:%{public}d,"
387 "PinchAxisValue:%{public}.2f",
388 pointer->GetEventType(), pointer->GetActionTime(),
389 pointer->GetAction(), pointer->GetActionStartTime(),
390 pointer->GetPointerAction(), pointer->GetSourceType(),
391 pointer->GetAxisValue(PointerEvent::AXIS_TYPE_PINCH));
392
393 PointerEvent::PointerItem item;
394 pointer->GetPointerItem(pointer->GetPointerId(), item);
395 MMI_LOGD("Item:DownTime:%{public}" PRId64 ",IsPressed:%{public}s,"
396 "GlobalX:%{public}d,GlobalY:%{public}d,LocalX:%{public}d,LocalY:%{public}d,"
397 "Width:%{public}d,Height:%{public}d",
398 item.GetDownTime(), (item.IsPressed() ? "true" : "false"),
399 item.GetGlobalX(), item.GetGlobalY(), item.GetLocalX(), item.GetLocalY(),
400 item.GetWidth(), item.GetHeight());
401
402 int32_t ret = eventDispatch_.HandlePointerEvent(pointer);
403 if (ret != RET_OK) {
404 MMI_LOGE("Gesture event dispatch failed, errCode:%{public}d", GESTURE_EVENT_DISP_FAIL);
405 return GESTURE_EVENT_DISP_FAIL;
406 }
407 return RET_OK;
408 }
409
OnEventGesture(const multimodal_libinput_event & ev)410 int32_t InputEventHandler::OnEventGesture(const multimodal_libinput_event& ev)
411 {
412 CHKPR(ev.event, ERROR_NULL_POINTER);
413 OnGestureEvent(ev.event);
414 return RET_OK;
415 }
416
OnMouseEventHandler(struct libinput_event * event)417 int32_t InputEventHandler::OnMouseEventHandler(struct libinput_event *event)
418 {
419 CHKPR(event, ERROR_NULL_POINTER);
420
421 // 更新 全局 鼠标事件 数据
422 MouseEventHdr->Normalize(event);
423
424 auto pointerEvent = MouseEventHdr->GetPointerEvent();
425 if (pointerEvent == nullptr) {
426 MMI_LOGE("MouseEvent is NULL");
427 return RET_ERR;
428 }
429
430 // 处理 按键 + 鼠标
431 if (keyEvent_ == nullptr) {
432 keyEvent_ = KeyEvent::Create();
433 }
434 CHKPR(keyEvent_, ERROR_NULL_POINTER);
435 if (keyEvent_ != nullptr) {
436 std::vector<int32_t> pressedKeys = keyEvent_->GetPressedKeys();
437 if (pressedKeys.empty()) {
438 MMI_LOGI("Pressed keys is empty");
439 } else {
440 for (int32_t keyCode : pressedKeys) {
441 MMI_LOGI("Pressed keyCode:%{public}d", keyCode);
442 }
443 }
444 pointerEvent->SetPressedKeys(pressedKeys);
445 }
446 int32_t pointerId = keyEvent_->GetId();
447 const std::string pointerEventstring = "OnEventPointer";
448 StartAsyncTrace(BYTRACE_TAG_MULTIMODALINPUT, pointerEventstring, pointerId);
449 // 派发
450 eventDispatch_.HandlePointerEvent(pointerEvent);
451 // 返回值 代表是 鼠标事件有没有处理过, 不关心成功与失败
452 return RET_OK;
453 }
454
OnMouseEventEndTimerHandler(std::shared_ptr<PointerEvent> pointerEvent)455 int32_t InputEventHandler::OnMouseEventEndTimerHandler(std::shared_ptr<PointerEvent> pointerEvent)
456 {
457 CHKPR(pointerEvent, ERROR_NULL_POINTER);
458 // Mouse Axis Data
459 MMI_LOGI("MouseEvent Normalization Results, PointerAction:%{public}d,PointerId:%{public}d,"
460 "SourceType:%{public}d,ButtonId:%{public}d,"
461 "VerticalAxisValue:%{public}lf,HorizontalAxisValue:%{public}lf",
462 pointerEvent->GetPointerAction(), pointerEvent->GetPointerId(), pointerEvent->GetSourceType(),
463 pointerEvent->GetButtonId(), pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL),
464 pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL));
465 PointerEvent::PointerItem item;
466 CHKR(pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), item), PARAM_INPUT_FAIL, RET_ERR);
467 MMI_LOGI("MouseEvent Item Normalization Results, DownTime:%{public}" PRId64 ",IsPressed:%{public}d,"
468 "GlobalX:%{public}d,GlobalY:%{public}d,LocalX:%{public}d,LocalY:%{public}d,"
469 "Width:%{public}d,Height:%{public}d,Pressure:%{public}d",
470 item.GetDownTime(), static_cast<int32_t>(item.IsPressed()), item.GetGlobalX(), item.GetGlobalY(),
471 item.GetLocalX(), item.GetLocalY(), item.GetWidth(), item.GetHeight(), item.GetPressure());
472
473 eventDispatch_.HandlePointerEvent(pointerEvent);
474 return RET_OK;
475 }
476
SendMsg(const int32_t fd,NetPacket & pkt) const477 bool InputEventHandler::SendMsg(const int32_t fd, NetPacket& pkt) const
478 {
479 CHKPF(udsServer_);
480 return udsServer_->SendMsg(fd, pkt);
481 }
482 } // namespace MMI
483 } // namespace OHOS
484