• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_interceptor_handler.h"
17 
18 #include "bytrace_adapter.h"
19 #include "define_multimodal.h"
20 #include "event_dispatch_handler.h"
21 #include "input_device_manager.h"
22 #include "input_event_data_transformation.h"
23 #include "input_event_handler.h"
24 #include "mmi_log.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, "EventInterceptorHandler" };
33 } // namespace
34 
35 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)36 void EventInterceptorHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
37 {
38     CHKPV(keyEvent);
39     if (OnHandleEvent(keyEvent)) {
40         MMI_HILOGD("KeyEvent filter find a keyEvent from Original event keyCode:%{public}d",
41             keyEvent->GetKeyCode());
42         BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_INTERCEPT_EVENT);
43         return;
44     }
45     CHKPV(nextHandler_);
46     nextHandler_->HandleKeyEvent(keyEvent);
47 }
48 #endif // OHOS_BUILD_ENABLE_KEYBOARD
49 
50 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)51 void EventInterceptorHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
52 {
53     CHKPV(pointerEvent);
54     if (OnHandleEvent(pointerEvent)) {
55         BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
56         MMI_HILOGD("Interception is succeeded");
57         return;
58     }
59     CHKPV(nextHandler_);
60     nextHandler_->HandlePointerEvent(pointerEvent);
61 }
62 #endif // OHOS_BUILD_ENABLE_POINTER
63 
64 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)65 void EventInterceptorHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
66 {
67     CHKPV(pointerEvent);
68     if (OnHandleEvent(pointerEvent)) {
69         BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
70         MMI_HILOGD("Interception is succeeded");
71         return;
72     }
73     CHKPV(nextHandler_);
74     nextHandler_->HandleTouchEvent(pointerEvent);
75 }
76 #endif // OHOS_BUILD_ENABLE_TOUCH
77 
AddInputHandler(InputHandlerType handlerType,HandleEventType eventType,int32_t priority,uint32_t deviceTags,SessionPtr session)78 int32_t EventInterceptorHandler::AddInputHandler(InputHandlerType handlerType,
79     HandleEventType eventType, int32_t priority, uint32_t deviceTags, SessionPtr session)
80 {
81     CALL_INFO_TRACE;
82     CHKPR(session, RET_ERR);
83     if ((eventType & HANDLE_EVENT_TYPE_ALL) == HANDLE_EVENT_TYPE_NONE) {
84         MMI_HILOGE("Invalid event type");
85         return RET_ERR;
86     }
87     InitSessionLostCallback();
88     SessionHandler interceptor { handlerType, eventType, priority, deviceTags, session };
89     MMI_HILOGD("handlerType:%{public}d, eventType:%{public}d, deviceTags:%{public}d, priority:%{public}d",
90         handlerType, eventType, deviceTags, priority);
91     return interceptors_.AddInterceptor(interceptor);
92 }
93 
RemoveInputHandler(InputHandlerType handlerType,HandleEventType eventType,int32_t priority,uint32_t deviceTags,SessionPtr session)94 void EventInterceptorHandler::RemoveInputHandler(InputHandlerType handlerType,
95     HandleEventType eventType, int32_t priority, uint32_t deviceTags, SessionPtr session)
96 {
97     CALL_INFO_TRACE;
98     CHKPV(session);
99     if (handlerType == InputHandlerType::INTERCEPTOR) {
100         SessionHandler interceptor { handlerType, eventType, priority, deviceTags, session };
101         MMI_HILOGD("handlerType:%{public}d, eventType:%{public}d, deviceTags:%{public}d, priority:%{public}d",
102             handlerType, eventType, deviceTags, priority);
103         interceptors_.RemoveInterceptor(interceptor);
104     }
105 }
106 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)107 bool EventInterceptorHandler::OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)
108 {
109     MMI_HILOGD("Handle KeyEvent");
110     CHKPF(keyEvent);
111     if (keyEvent->HasFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT)) {
112         MMI_HILOGW("This event has been tagged as not to be intercepted");
113         return false;
114     }
115     return interceptors_.HandleEvent(keyEvent);
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 EventInterceptorHandler::OnHandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
121 {
122     CHKPF(pointerEvent);
123     if (pointerEvent->HasFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT)) {
124         MMI_HILOGW("This event has been tagged as not to be intercepted");
125         return false;
126     }
127     return interceptors_.HandleEvent(pointerEvent);
128 }
129 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
130 
InitSessionLostCallback()131 void EventInterceptorHandler::InitSessionLostCallback()
132 {
133     if (sessionLostCallbackInitialized_)  {
134         MMI_HILOGE("Init session is failed");
135         return;
136     }
137     auto udsServerPtr = InputHandler->GetUDSServer();
138     CHKPV(udsServerPtr);
139     udsServerPtr->AddSessionDeletedCallback(std::bind(
140         &EventInterceptorHandler::OnSessionLost, this, std::placeholders::_1));
141     sessionLostCallbackInitialized_ = true;
142     MMI_HILOGD("The callback on session deleted is registered successfully");
143 }
144 
OnSessionLost(SessionPtr session)145 void EventInterceptorHandler::OnSessionLost(SessionPtr session)
146 {
147     interceptors_.OnSessionLost(session);
148 }
149 
SendToClient(std::shared_ptr<KeyEvent> keyEvent) const150 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<KeyEvent> keyEvent) const
151 {
152     CHKPV(keyEvent);
153     NetPacket pkt(MmiMessageId::REPORT_KEY_EVENT);
154     pkt << handlerType_ << deviceTags_;
155     if (pkt.ChkRWError()) {
156         MMI_HILOGE("Packet write key event failed");
157         return;
158     }
159     if (InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt) != RET_OK) {
160         MMI_HILOGE("Packet key event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
161         return;
162     }
163     if (!session_->SendMsg(pkt)) {
164         MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
165         return;
166     }
167 }
168 
SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const169 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const
170 {
171     CHKPV(pointerEvent);
172     NetPacket pkt(MmiMessageId::REPORT_POINTER_EVENT);
173     MMI_HILOGD("Service send to client InputHandlerType:%{public}d", handlerType_);
174     pkt << handlerType_ << deviceTags_;
175     if (pkt.ChkRWError()) {
176         MMI_HILOGE("Packet write pointer event failed");
177         return;
178     }
179     if (InputEventDataTransformation::Marshalling(pointerEvent, pkt) != RET_OK) {
180         MMI_HILOGE("Marshalling pointer event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
181         return;
182     }
183     if (!session_->SendMsg(pkt)) {
184         MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
185         return;
186     }
187 }
188 
189 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)190 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
191 {
192     CHKPF(keyEvent);
193     if (interceptors_.empty()) {
194         MMI_HILOGD("Key interceptors is empty");
195         return false;
196     }
197     MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
198     bool isInterceptor = false;
199     std::vector<KeyEvent::KeyItem> keyItems = keyEvent->GetKeyItems();
200     if (keyItems.empty()) {
201         MMI_HILOGE("keyItems is empty");
202         return false;
203     }
204     std::shared_ptr<InputDevice> inputDevice = InputDevMgr->GetInputDevice(keyItems.front().GetDeviceId());
205     CHKPF(inputDevice);
206     uint32_t capKeyboard = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
207     for (const auto &interceptor : interceptors_) {
208         MMI_HILOGD("eventType:%{public}d, deviceTags:%{public}d",
209             interceptor.eventType_, interceptor.deviceTags_);
210         if ((capKeyboard & interceptor.deviceTags_) == 0) {
211             MMI_HILOGD("Interceptor cap does not have keyboard");
212             continue;
213         }
214         if (!inputDevice->HasCapability(interceptor.deviceTags_)) {
215             continue;
216         }
217         if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_KEY) == HANDLE_EVENT_TYPE_KEY) {
218             interceptor.SendToClient(keyEvent);
219             MMI_HILOGD("Key event was intercepted");
220             isInterceptor = true;
221             break;
222         }
223     }
224     return isInterceptor;
225 }
226 #endif // OHOS_BUILD_ENABLE_KEYBOARD
227 
CheckInputDeviceSource(const std::shared_ptr<PointerEvent> pointerEvent,uint32_t deviceTags) const228 bool EventInterceptorHandler::InterceptorCollection::CheckInputDeviceSource(
229     const std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags) const
230 {
231     if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
232         ((deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH)) ||
233         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL)))) {
234         return true;
235     } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) &&
236         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
237         return true;
238     } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) &&
239         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
240         return true;
241     }
242     return false;
243 }
244 
245 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)246 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
247 {
248     CHKPF(pointerEvent);
249     if (interceptors_.empty()) {
250         MMI_HILOGD("Interceptors are empty");
251         return false;
252     }
253     MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
254     bool isInterceptor = false;
255     PointerEvent::PointerItem pointerItem;
256     int32_t pointerId = pointerEvent->GetPointerId();
257     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
258         MMI_HILOGE("GetPointerItem:%{public}d fail", pointerId);
259         return false;
260     }
261     std::shared_ptr<InputDevice> inputDevice = InputDevMgr->GetInputDevice(pointerItem.GetDeviceId());
262     CHKPF(inputDevice);
263     uint32_t capPointer = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
264     uint32_t capTouch = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH);
265     for (const auto &interceptor : interceptors_) {
266         MMI_HILOGD("eventType:%{public}d, deviceTags:%{public}d",
267             interceptor.eventType_, interceptor.deviceTags_);
268         if (((capPointer | capTouch) & interceptor.deviceTags_) == 0) {
269             MMI_HILOGD("Interceptor cap does not have pointer or touch");
270             continue;
271         }
272         if (!CheckInputDeviceSource(pointerEvent, interceptor.deviceTags_)) {
273             continue;
274         }
275         if (!inputDevice->HasCapability(interceptor.deviceTags_)) {
276             continue;
277         }
278         if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_POINTER) == HANDLE_EVENT_TYPE_POINTER) {
279             interceptor.SendToClient(pointerEvent);
280             MMI_HILOGD("Pointer event was intercepted");
281             isInterceptor = true;
282             break;
283         }
284     }
285     return isInterceptor;
286 }
287 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
288 
AddInterceptor(const SessionHandler & interceptor)289 int32_t EventInterceptorHandler::InterceptorCollection::AddInterceptor(const SessionHandler& interceptor)
290 {
291     for (auto iter = interceptors_.begin(); iter != interceptors_.end(); ++iter) {
292         if (iter->session_ == interceptor.session_) {
293             interceptors_.erase(iter);
294             break;
295         }
296     }
297 
298     if (interceptors_.size() >= MAX_N_INPUT_INTERCEPTORS) {
299         MMI_HILOGE("The number of interceptors exceeds limit");
300         return RET_ERR;
301     }
302 
303     auto iterIndex = interceptors_.cbegin();
304     for (; iterIndex != interceptors_.cend(); ++iterIndex) {
305         if (interceptor.priority_ < iterIndex->priority_) {
306             break;
307         }
308     }
309     auto sIter = interceptors_.emplace(iterIndex, interceptor);
310     if (sIter == interceptors_.end()) {
311         MMI_HILOGE("Failed to add interceptor");
312         return RET_ERR;
313     }
314     return RET_OK;
315 }
316 
RemoveInterceptor(const SessionHandler & interceptor)317 void EventInterceptorHandler::InterceptorCollection::RemoveInterceptor(const SessionHandler& interceptor)
318 {
319     for (auto iter = interceptors_.begin(); iter != interceptors_.end(); ++iter) {
320         if (iter->session_ == interceptor.session_) {
321             interceptors_.erase(iter);
322             break;
323         }
324     }
325     if (interceptor.eventType_ == HANDLE_EVENT_TYPE_NONE) {
326         MMI_HILOGD("Unregister interceptor successfully");
327         return;
328     }
329 
330     auto iterIndex = interceptors_.cbegin();
331     for (; iterIndex != interceptors_.cend(); ++iterIndex) {
332         if (interceptor.priority_ < iterIndex->priority_) {
333             break;
334         }
335     }
336     auto sIter = interceptors_.emplace(iterIndex, interceptor);
337     if (sIter == interceptors_.end()) {
338         MMI_HILOGE("Internal error, interceptor has been removed");
339         return;
340     }
341     MMI_HILOGD("Event type is updated:%{public}u", interceptor.eventType_);
342 }
343 
OnSessionLost(SessionPtr session)344 void EventInterceptorHandler::InterceptorCollection::OnSessionLost(SessionPtr session)
345 {
346     CALL_INFO_TRACE;
347     auto iter = interceptors_.cbegin();
348     while (iter != interceptors_.cend()) {
349         if (iter->session_ != session) {
350             ++iter;
351         } else {
352             iter = interceptors_.erase(iter);
353         }
354     }
355 }
356 
Dump(int32_t fd,const std::vector<std::string> & args)357 void EventInterceptorHandler::Dump(int32_t fd, const std::vector<std::string> &args)
358 {
359     return interceptors_.Dump(fd, args);
360 }
361 
Dump(int32_t fd,const std::vector<std::string> & args)362 void EventInterceptorHandler::InterceptorCollection::Dump(int32_t fd, const std::vector<std::string> &args)
363 {
364     CALL_DEBUG_ENTER;
365     mprintf(fd, "Interceptor information:\t");
366     mprintf(fd, "interceptors: count=%d", interceptors_.size());
367     for (const auto &item : interceptors_) {
368         SessionPtr session = item.session_;
369         CHKPV(session);
370         mprintf(fd,
371                 "handlerType:%d | eventType:%d | Pid:%d | Uid:%d | Fd:%d "
372                 "| EarliestEventTime:%" PRId64 " | Descript:%s \t",
373                 item.handlerType_, item.eventType_,
374                 session->GetPid(), session->GetUid(),
375                 session->GetFd(),
376                 session->GetEarliestEventTime(), session->GetDescript().c_str());
377     }
378 }
379 } // namespace MMI
380 } // namespace OHOS
381