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