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_monitor_handler.h"
17
18 #include "anr_manager.h"
19 #include "bytrace_adapter.h"
20 #include "define_multimodal.h"
21 #include "input_event_data_transformation.h"
22 #include "input_event_handler.h"
23 #include "mmi_log.h"
24 #include "napi_constants.h"
25 #include "net_packet.h"
26 #include "proto.h"
27 #include "util_ex.h"
28
29 namespace OHOS {
30 namespace MMI {
31 namespace {
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "EventMonitorHandler" };
33 #ifdef OHOS_BUILD_ENABLE_TOUCH
34 constexpr size_t MAX_EVENTIDS_SIZE = 1000;
35 #endif // OHOS_BUILD_ENABLE_TOUCH
36 constexpr int32_t SYS_PINCH_FINGER_CNT { 2 };
37 } // namespace
38
39 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)40 void EventMonitorHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
41 {
42 CHKPV(keyEvent);
43 OnHandleEvent(keyEvent);
44 CHKPV(nextHandler_);
45 nextHandler_->HandleKeyEvent(keyEvent);
46 }
47 #endif // OHOS_BUILD_ENABLE_KEYBOARD
48
49 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)50 void EventMonitorHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
51 {
52 CHKPV(pointerEvent);
53 if (OnHandleEvent(pointerEvent)) {
54 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
55 MMI_HILOGD("Monitor is succeeded");
56 return;
57 }
58 CHKPV(nextHandler_);
59 nextHandler_->HandlePointerEvent(pointerEvent);
60 }
61 #endif // OHOS_BUILD_ENABLE_POINTER
62
63 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)64 void EventMonitorHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
65 {
66 CHKPV(pointerEvent);
67 if (OnHandleEvent(pointerEvent)) {
68 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
69 MMI_HILOGD("Monitor is succeeded");
70 return;
71 }
72 CHKPV(nextHandler_);
73 nextHandler_->HandleTouchEvent(pointerEvent);
74 }
75 #endif // OHOS_BUILD_ENABLE_TOUCH
76
AddInputHandler(InputHandlerType handlerType,HandleEventType eventType,SessionPtr session)77 int32_t EventMonitorHandler::AddInputHandler(InputHandlerType handlerType,
78 HandleEventType eventType, SessionPtr session)
79 {
80 CALL_INFO_TRACE;
81 CHKPR(session, RET_ERR);
82 if ((eventType & HANDLE_EVENT_TYPE_ALL) == HANDLE_EVENT_TYPE_NONE) {
83 MMI_HILOGE("Invalid event type");
84 return RET_ERR;
85 }
86 InitSessionLostCallback();
87 SessionHandler mon { handlerType, eventType, session };
88 return monitors_.AddMonitor(mon);
89 }
90
RemoveInputHandler(InputHandlerType handlerType,HandleEventType eventType,SessionPtr session)91 void EventMonitorHandler::RemoveInputHandler(InputHandlerType handlerType, HandleEventType eventType,
92 SessionPtr session)
93 {
94 CALL_INFO_TRACE;
95 if (handlerType == InputHandlerType::MONITOR) {
96 SessionHandler monitor { handlerType, eventType, session };
97 monitors_.RemoveMonitor(monitor);
98 }
99 }
100
MarkConsumed(int32_t eventId,SessionPtr session)101 void EventMonitorHandler::MarkConsumed(int32_t eventId, SessionPtr session)
102 {
103 monitors_.MarkConsumed(eventId, session);
104 }
105
106 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)107 bool EventMonitorHandler::OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)
108 {
109 MMI_HILOGD("Handle KeyEvent");
110 CHKPF(keyEvent);
111 if (keyEvent->HasFlag(InputEvent::EVENT_FLAG_NO_MONITOR)) {
112 MMI_HILOGD("This event has been tagged as not to be monitored");
113 } else {
114 if (monitors_.HandleEvent(keyEvent)) {
115 MMI_HILOGD("Key event was consumed");
116 return true;
117 }
118 }
119 return false;
120 }
121 #endif // OHOS_BUILD_ENABLE_KEYBOARD
122
123 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
OnHandleEvent(std::shared_ptr<PointerEvent> pointerEvent)124 bool EventMonitorHandler::OnHandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
125 {
126 CHKPF(pointerEvent);
127 if (pointerEvent->HasFlag(InputEvent::EVENT_FLAG_NO_MONITOR)) {
128 MMI_HILOGD("This event has been tagged as not to be monitored");
129 } else {
130 if (monitors_.HandleEvent(pointerEvent)) {
131 MMI_HILOGD("Pointer event was monitor");
132 return true;
133 }
134 }
135 MMI_HILOGD("Interception and monitor failed");
136 return false;
137 }
138 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
139
InitSessionLostCallback()140 void EventMonitorHandler::InitSessionLostCallback()
141 {
142 if (sessionLostCallbackInitialized_) {
143 return;
144 }
145 auto udsServerPtr = InputHandler->GetUDSServer();
146 CHKPV(udsServerPtr);
147 udsServerPtr->AddSessionDeletedCallback(std::bind(
148 &EventMonitorHandler::OnSessionLost, this, std::placeholders::_1));
149 sessionLostCallbackInitialized_ = true;
150 MMI_HILOGD("The callback on session deleted is registered successfully");
151 }
152
OnSessionLost(SessionPtr session)153 void EventMonitorHandler::OnSessionLost(SessionPtr session)
154 {
155 monitors_.OnSessionLost(session);
156 }
157
SendToClient(std::shared_ptr<KeyEvent> keyEvent) const158 void EventMonitorHandler::SessionHandler::SendToClient(std::shared_ptr<KeyEvent> keyEvent) const
159 {
160 CHKPV(keyEvent);
161 NetPacket pkt(MmiMessageId::REPORT_KEY_EVENT);
162 pkt << handlerType_ << static_cast<uint32_t>(evdev_device_udev_tags::EVDEV_UDEV_TAG_INPUT);
163 if (pkt.ChkRWError()) {
164 MMI_HILOGE("Packet write key event failed");
165 return;
166 }
167 if (InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt) != RET_OK) {
168 MMI_HILOGE("Packet key event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
169 return;
170 }
171 if (!session_->SendMsg(pkt)) {
172 MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
173 return;
174 }
175 }
176
SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const177 void EventMonitorHandler::SessionHandler::SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const
178 {
179 CHKPV(pointerEvent);
180 CHKPV(session_);
181 NetPacket pkt(MmiMessageId::REPORT_POINTER_EVENT);
182 MMI_HILOGD("Service SendToClient InputHandlerType:%{public}d,TokenType:%{public}d, pid:%{public}d",
183 handlerType_, session_->GetTokenType(), session_->GetPid());
184 auto currentTime = GetSysClockTime();
185 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
186 if (ANRMgr->TriggerANR(ANR_MONITOR, currentTime, session_)) {
187 MMI_HILOGW("The pointer event does not report normally, application not response");
188 return;
189 }
190 }
191 pkt << handlerType_ << static_cast<uint32_t>(evdev_device_udev_tags::EVDEV_UDEV_TAG_INPUT);
192 if (pkt.ChkRWError()) {
193 MMI_HILOGE("Packet write pointer event failed");
194 return;
195 }
196 if (InputEventDataTransformation::Marshalling(pointerEvent, pkt) != RET_OK) {
197 MMI_HILOGE("Marshalling pointer event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
198 return;
199 }
200 if (!session_->SendMsg(pkt)) {
201 MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
202 return;
203 }
204 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
205 ANRMgr->AddTimer(ANR_MONITOR, pointerEvent->GetId(), currentTime, session_);
206 }
207 }
208
AddMonitor(const SessionHandler & monitor)209 int32_t EventMonitorHandler::MonitorCollection::AddMonitor(const SessionHandler& monitor)
210 {
211 if (monitors_.size() >= MAX_N_INPUT_MONITORS) {
212 MMI_HILOGE("The number of monitors exceeds the maximum:%{public}zu,monitors,errCode:%{public}d",
213 monitors_.size(), INVALID_MONITOR_MON);
214 return RET_ERR;
215 }
216 bool isFound = false;
217 auto iter = monitors_.find(monitor);
218 if (iter != monitors_.end()) {
219 if (iter->eventType_ == monitor.eventType_) {
220 MMI_HILOGD("Monitor with event type (%{public}u) already exists", monitor.eventType_);
221 return RET_OK;
222 }
223 isFound = true;
224 monitors_.erase(iter);
225 }
226
227 auto [sIter, isOk] = monitors_.insert(monitor);
228 if (!isOk) {
229 if (isFound) {
230 MMI_HILOGE("Internal error: monitor has been removed");
231 } else {
232 MMI_HILOGE("Failed to add monitor");
233 }
234 return RET_ERR;
235 }
236
237 if (isFound) {
238 MMI_HILOGD("Event type is updated:%{public}u", monitor.eventType_);
239 } else {
240 MMI_HILOGD("Service Add Monitor Success");
241 }
242 return RET_OK;
243 }
244
RemoveMonitor(const SessionHandler & monitor)245 void EventMonitorHandler::MonitorCollection::RemoveMonitor(const SessionHandler& monitor)
246 {
247 auto iter = monitors_.find(monitor);
248 if (iter == monitors_.cend()) {
249 MMI_HILOGE("Monitor does not exist");
250 return;
251 }
252
253 monitors_.erase(iter);
254 if (monitor.eventType_ == HANDLE_EVENT_TYPE_NONE) {
255 MMI_HILOGD("Unregister monitor successfully");
256 return;
257 }
258
259 auto [sIter, isOk] = monitors_.insert(monitor);
260 if (!isOk) {
261 MMI_HILOGE("Internal error, monitor has been removed");
262 return;
263 }
264 MMI_HILOGD("Event type is updated:%{public}u", monitor.eventType_);
265 }
266
MarkConsumed(int32_t eventId,SessionPtr session)267 void EventMonitorHandler::MonitorCollection::MarkConsumed(int32_t eventId, SessionPtr session)
268 {
269 if (!HasMonitor(session)) {
270 MMI_HILOGW("Specified monitor does not exist");
271 return;
272 }
273 auto tIter = states_.begin();
274 for (; tIter != states_.end(); ++tIter) {
275 const auto &eventIds = tIter->second.eventIds_;
276 if (eventIds.find(eventId) != eventIds.cend()) {
277 break;
278 }
279 }
280 if (tIter == states_.end()) {
281 MMI_HILOGE("No operation corresponding to this event");
282 return;
283 }
284 ConsumptionState &state = tIter->second;
285
286 if (state.isMonitorConsumed_) {
287 MMI_HILOGE("Corresponding operation has been marked as consumed");
288 return;
289 }
290 state.isMonitorConsumed_ = true;
291 if (state.lastPointerEvent_ == nullptr) {
292 MMI_HILOGE("No former touch event");
293 return;
294 }
295 #ifdef OHOS_BUILD_ENABLE_TOUCH
296 MMI_HILOGD("Cancel operation");
297 auto pointerEvent = std::make_shared<PointerEvent>(*state.lastPointerEvent_);
298 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
299 pointerEvent->SetActionTime(GetSysClockTime());
300 pointerEvent->UpdateId();
301 pointerEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT | InputEvent::EVENT_FLAG_NO_MONITOR);
302 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
303 CHKPV(inputEventNormalizeHandler);
304 inputEventNormalizeHandler->HandleTouchEvent(pointerEvent);
305 #endif // OHOS_BUILD_ENABLE_TOUCH
306 }
307
308 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)309 bool EventMonitorHandler::MonitorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
310 {
311 CHKPF(keyEvent);
312 MMI_HILOGD("There are currently %{public}zu monitors", monitors_.size());
313 for (const auto &mon : monitors_) {
314 if ((mon.eventType_ & HANDLE_EVENT_TYPE_KEY) == HANDLE_EVENT_TYPE_KEY) {
315 mon.SendToClient(keyEvent);
316 }
317 }
318 return false;
319 }
320 #endif // OHOS_BUILD_ENABLE_KEYBOARD
321
322 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)323 bool EventMonitorHandler::MonitorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
324 {
325 CHKPF(pointerEvent);
326
327 // if is 2 finger pinch,then return false
328 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE &&
329 (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_BEGIN ||
330 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_UPDATE ||
331 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_END) &&
332 pointerEvent->GetFingerCount() == SYS_PINCH_FINGER_CNT) {
333 MMI_HILOGD("Source type = %{public}d, pointer action = %{public}d finger count = %{public}d",
334 pointerEvent->GetSourceType(), pointerEvent->GetPointerAction(), pointerEvent->GetFingerCount());
335 return false;
336 }
337 #ifdef OHOS_BUILD_ENABLE_TOUCH
338 UpdateConsumptionState(pointerEvent);
339 #endif // OHOS_BUILD_ENABLE_TOUCH
340 Monitor(pointerEvent);
341 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN ||
342 pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) {
343 auto iter = states_.find(pointerEvent->GetDeviceId());
344 return (iter != states_.end() ? iter->second.isMonitorConsumed_ : false);
345 }
346 MMI_HILOGD("This is not a touch-screen event");
347 return false;
348 }
349 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
350
HasMonitor(SessionPtr session)351 bool EventMonitorHandler::MonitorCollection::HasMonitor(SessionPtr session)
352 {
353 SessionHandler monitor { InputHandlerType::MONITOR, HANDLE_EVENT_TYPE_ALL, session };
354 return (monitors_.find(monitor) != monitors_.end());
355 }
356
357 #ifdef OHOS_BUILD_ENABLE_TOUCH
UpdateConsumptionState(std::shared_ptr<PointerEvent> pointerEvent)358 void EventMonitorHandler::MonitorCollection::UpdateConsumptionState(std::shared_ptr<PointerEvent> pointerEvent)
359 {
360 CALL_DEBUG_ENTER;
361 CHKPV(pointerEvent);
362 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHSCREEN &&
363 pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD) {
364 return;
365 }
366 auto sIter = states_.find(pointerEvent->GetDeviceId());
367 if (sIter == states_.end()) {
368 auto [tIter, isOk] = states_.emplace(pointerEvent->GetDeviceId(), ConsumptionState());
369 if (!isOk) {
370 MMI_HILOGE("Failed to emplace consumption state");
371 return;
372 }
373 sIter = tIter;
374 }
375 ConsumptionState &state = sIter->second;
376 if (state.eventIds_.size() >= MAX_EVENTIDS_SIZE) {
377 auto iter = state.eventIds_.begin();
378 state.eventIds_.erase(iter);
379 }
380 auto [tIter, isOk] = state.eventIds_.emplace(pointerEvent->GetId());
381 if (!isOk) {
382 MMI_HILOGW("Failed to stash event");
383 }
384 state.lastPointerEvent_ = pointerEvent;
385
386 if (pointerEvent->GetPointerIds().size() != 1) {
387 MMI_HILOGD("In intermediate process");
388 return;
389 }
390 if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN ||
391 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_BEGIN ||
392 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_BEGIN) {
393 MMI_HILOGD("First press down");
394 state.eventIds_.clear();
395 auto [tIter, isOk] = state.eventIds_.emplace(pointerEvent->GetId());
396 if (!isOk) {
397 MMI_HILOGW("Event number is duplicated");
398 }
399 state.isMonitorConsumed_ = false;
400 } else if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP ||
401 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_END ||
402 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_END) {
403 MMI_HILOGD("Last lift up");
404 state.eventIds_.clear();
405 }
406 }
407 #endif // OHOS_BUILD_ENABLE_TOUCH
408
409 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
Monitor(std::shared_ptr<PointerEvent> pointerEvent)410 void EventMonitorHandler::MonitorCollection::Monitor(std::shared_ptr<PointerEvent> pointerEvent)
411 {
412 CHKPV(pointerEvent);
413 MMI_HILOGD("There are currently %{public}zu monitors", monitors_.size());
414 for (const auto &monitor : monitors_) {
415 if ((monitor.eventType_ & HANDLE_EVENT_TYPE_POINTER) == HANDLE_EVENT_TYPE_POINTER) {
416 monitor.SendToClient(pointerEvent);
417 }
418 }
419 }
420 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
421
OnSessionLost(SessionPtr session)422 void EventMonitorHandler::MonitorCollection::OnSessionLost(SessionPtr session)
423 {
424 CALL_INFO_TRACE;
425 std::set<SessionHandler>::const_iterator cItr = monitors_.cbegin();
426 while (cItr != monitors_.cend()) {
427 if (cItr->session_ != session) {
428 ++cItr;
429 } else {
430 cItr = monitors_.erase(cItr);
431 }
432 }
433 }
434
Dump(int32_t fd,const std::vector<std::string> & args)435 void EventMonitorHandler::Dump(int32_t fd, const std::vector<std::string> &args)
436 {
437 return monitors_.Dump(fd, args);
438 }
439
Dump(int32_t fd,const std::vector<std::string> & args)440 void EventMonitorHandler::MonitorCollection::Dump(int32_t fd, const std::vector<std::string> &args)
441 {
442 CALL_DEBUG_ENTER;
443 mprintf(fd, "Monitor information:\t");
444 mprintf(fd, "monitors: count=%d", monitors_.size());
445 for (const auto &item : monitors_) {
446 SessionPtr session = item.session_;
447 CHKPV(session);
448 mprintf(fd,
449 "handlerType:%d | Pid:%d | Uid:%d | Fd:%d "
450 "| EarliestEventTime:%" PRId64 " | Descript:%s \t",
451 item.handlerType_, session->GetPid(),
452 session->GetUid(), session->GetFd(),
453 session->GetEarliestEventTime(), session->GetDescript().c_str());
454 }
455 }
456 } // namespace MMI
457 } // namespace OHOS
458