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