• 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 "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