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