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