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 "event_dispatch_handler.h"
17
18 #include <cinttypes>
19
20 #include "dfx_hisysevent.h"
21 #include "hitrace_meter.h"
22
23 #include "anr_manager.h"
24 #include "bytrace_adapter.h"
25 #ifdef OHOS_BUILD_ENABLE_COOPERATE
26 #include "distributed_input_adapter.h"
27 #endif // OHOS_BUILD_ENABLE_COOPERATE
28 #include "error_multimodal.h"
29 #include "input_event_data_transformation.h"
30 #include "input_event_handler.h"
31 #include "input_windows_manager.h"
32 #include "input-event-codes.h"
33 #include "mouse_device_state.h"
34 #include "napi_constants.h"
35 #include "proto.h"
36 #include "util.h"
37
38 namespace OHOS {
39 namespace MMI {
40 namespace {
41 #if defined(OHOS_BUILD_ENABLE_KEYBOARD) || defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
42 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "EventDispatchHandler" };
43 #endif // OHOS_BUILD_ENABLE_KEYBOARD || OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
44 constexpr int32_t INTERVAL_TIME = 3000; // log time interval is 3 seconds.
45 } // namespace
46
EventDispatchHandler()47 EventDispatchHandler::EventDispatchHandler()
48 {
49 #ifdef OHOS_BUILD_ENABLE_COOPERATE
50 DistributedAdapter->RegisterEventCallback(std::bind(&EventDispatchHandler::OnDinputSimulateEvent, this,
51 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
52 #endif // OHOS_BUILD_ENABLE_COOPERATE
53 }
54
~EventDispatchHandler()55 EventDispatchHandler::~EventDispatchHandler() {}
56
57 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)58 void EventDispatchHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
59 {
60 CHKPV(keyEvent);
61 auto udsServer = InputHandler->GetUDSServer();
62 CHKPV(udsServer);
63 DispatchKeyEventPid(*udsServer, keyEvent);
64 }
65 #endif // OHOS_BUILD_ENABLE_KEYBOARD
66
67 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)68 void EventDispatchHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
69 {
70 CHKPV(pointerEvent);
71 HandlePointerEventInner(pointerEvent);
72 }
73 #endif // OHOS_BUILD_ENABLE_POINTER
74
75 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)76 void EventDispatchHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
77 {
78 CHKPV(pointerEvent);
79 HandlePointerEventInner(pointerEvent);
80 }
81 #endif // OHOS_BUILD_ENABLE_TOUCH
82
83 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
HandlePointerEventInner(const std::shared_ptr<PointerEvent> point)84 void EventDispatchHandler::HandlePointerEventInner(const std::shared_ptr<PointerEvent> point)
85 {
86 CALL_DEBUG_ENTER;
87 CHKPV(point);
88 auto fd = WinMgr->GetClientFd(point);
89 currentTime_ = point->GetActionTime();
90 if (fd < 0 && currentTime_ - eventTime_ > INTERVAL_TIME) {
91 eventTime_ = currentTime_;
92 MMI_HILOGE("The fd less than 0, fd:%{public}d", fd);
93 DfxHisysevent::OnUpdateTargetPointer(point, fd, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
94 return;
95 }
96 #ifdef OHOS_BUILD_ENABLE_COOPERATE
97 if (CheckPointerEvent(point)) {
98 MMI_HILOGE("Check pointer event return true,filter out this pointer event");
99 return;
100 }
101 #endif // OHOS_BUILD_ENABLE_COOPERATE
102 auto udsServer = InputHandler->GetUDSServer();
103 CHKPV(udsServer);
104 auto session = udsServer->GetSession(fd);
105 CHKPV(session);
106 auto currentTime = GetSysClockTime();
107 if (ANRMgr->TriggerANR(ANR_DISPATCH, currentTime, session)) {
108 MMI_HILOGW("The pointer event does not report normally, application not response");
109 return;
110 }
111 auto pointerEvent = std::make_shared<PointerEvent>(*point);
112 auto pointerIdList = pointerEvent->GetPointerIds();
113 if (pointerIdList.size() > 1) {
114 for (const auto& id : pointerIdList) {
115 PointerEvent::PointerItem pointeritem;
116 if (!pointerEvent->GetPointerItem(id, pointeritem)) {
117 MMI_HILOGW("Can't find this poinerItem");
118 continue;
119 }
120 auto itemPid = WinMgr->GetWindowPid(pointeritem.GetTargetWindowId());
121 if ((itemPid >= 0) && (itemPid != udsServer->GetClientPid(fd))) {
122 pointerEvent->RemovePointerItem(id);
123 MMI_HILOGD("pointerIdList size:%{public}zu", pointerEvent->GetPointerIds().size());
124 }
125 }
126 }
127 NetPacket pkt(MmiMessageId::ON_POINTER_EVENT);
128 InputEventDataTransformation::Marshalling(pointerEvent, pkt);
129 BytraceAdapter::StartBytrace(point, BytraceAdapter::TRACE_STOP);
130 if (!udsServer->SendMsg(fd, pkt)) {
131 MMI_HILOGE("Sending structure of EventTouch failed! errCode:%{public}d", MSG_SEND_FAIL);
132 return;
133 }
134 ANRMgr->AddTimer(ANR_DISPATCH, point->GetId(), currentTime, session);
135 }
136 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_POINTER
137
138 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
DispatchKeyEventPid(UDSServer & udsServer,std::shared_ptr<KeyEvent> key)139 int32_t EventDispatchHandler::DispatchKeyEventPid(UDSServer& udsServer, std::shared_ptr<KeyEvent> key)
140 {
141 CALL_DEBUG_ENTER;
142 CHKPR(key, PARAM_INPUT_INVALID);
143 auto fd = WinMgr->UpdateTarget(key);
144 currentTime_ = key->GetActionTime();
145 if (fd < 0 && currentTime_ - eventTime_ > INTERVAL_TIME) {
146 eventTime_ = currentTime_;
147 MMI_HILOGE("Invalid fd, fd:%{public}d", fd);
148 DfxHisysevent::OnUpdateTargetKey(key, fd, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
149 return RET_ERR;
150 }
151 MMI_HILOGD("Event dispatcher of server:KeyEvent:KeyCode:%{public}d,Action:%{public}d,EventType:%{public}d,"
152 "Fd:%{public}d", key->GetKeyCode(), key->GetAction(), key->GetEventType(), fd);
153 auto session = udsServer.GetSession(fd);
154 CHKPR(session, RET_ERR);
155 auto currentTime = GetSysClockTime();
156 if (ANRMgr->TriggerANR(ANR_DISPATCH, currentTime, session)) {
157 MMI_HILOGW("The key event does not report normally, application not response");
158 return RET_OK;
159 }
160
161 NetPacket pkt(MmiMessageId::ON_KEY_EVENT);
162 InputEventDataTransformation::KeyEventToNetPacket(key, pkt);
163 BytraceAdapter::StartBytrace(key, BytraceAdapter::KEY_DISPATCH_EVENT);
164 pkt << fd;
165 if (pkt.ChkRWError()) {
166 MMI_HILOGE("Packet write structure of EventKeyboard failed");
167 return RET_ERR;
168 }
169 if (!udsServer.SendMsg(fd, pkt)) {
170 MMI_HILOGE("Sending structure of EventKeyboard failed! errCode:%{public}d", MSG_SEND_FAIL);
171 return MSG_SEND_FAIL;
172 }
173 ANRMgr->AddTimer(ANR_DISPATCH, key->GetId(), currentTime, session);
174 return RET_OK;
175 }
176 #endif // OHOS_BUILD_ENABLE_KEYBOARD
177
178 #ifdef OHOS_BUILD_ENABLE_COOPERATE
CheckPointerEvent(std::shared_ptr<PointerEvent> pointerEvent)179 bool EventDispatchHandler::CheckPointerEvent(std::shared_ptr<PointerEvent> pointerEvent)
180 {
181 CHKPF(pointerEvent);
182 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_MOUSE) {
183 return false;
184 }
185 std::lock_guard<std::mutex> guard(lock_);
186 if (dinputSimulateEvent_.empty()) {
187 return false;
188 }
189 int32_t pointerAction = PointerEvent::POINTER_ACTION_BUTTON_DOWN;
190 if (dinputSimulateEvent_[0].value == BUTTON_STATE_RELEASED) {
191 pointerAction = PointerEvent::POINTER_ACTION_BUTTON_UP;
192 }
193 if ((dinputSimulateEvent_[0].type == EV_KEY) &&
194 (pointerAction == pointerEvent->GetPointerAction()) &&
195 (MouseState->LibinputChangeToPointer(dinputSimulateEvent_[0].code) == pointerEvent->GetButtonId())) {
196 dinputSimulateEvent_.clear();
197 return true;
198 }
199 return false;
200 }
201
OnDinputSimulateEvent(uint32_t type,uint32_t code,int32_t value)202 void EventDispatchHandler::OnDinputSimulateEvent(uint32_t type, uint32_t code, int32_t value)
203 {
204 std::lock_guard<std::mutex> guard(lock_);
205 dinputSimulateEvent_.clear();
206 dinputSimulateEvent_.push_back({type, code, value});
207 }
208 #endif // OHOS_BUILD_ENABLE_COOPERATE
209 } // namespace MMI
210 } // namespace OHOS
211