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 if (pointerEvent->HasFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT)) {
128 MMI_HILOGW("This event has been tagged as not to be intercepted");
129 return false;
130 }
131 return interceptors_.HandleEvent(pointerEvent);
132 }
133 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
134
InitSessionLostCallback()135 void EventInterceptorHandler::InitSessionLostCallback()
136 {
137 if (sessionLostCallbackInitialized_) {
138 MMI_HILOGE("Init session is failed");
139 return;
140 }
141 auto udsServerPtr = InputHandler->GetUDSServer();
142 CHKPV(udsServerPtr);
143 udsServerPtr->AddSessionDeletedCallback([this] (SessionPtr session) { this->OnSessionLost(session); });
144 sessionLostCallbackInitialized_ = true;
145 MMI_HILOGD("The callback on session deleted is registered successfully");
146 }
147
OnSessionLost(SessionPtr session)148 void EventInterceptorHandler::OnSessionLost(SessionPtr session)
149 {
150 interceptors_.OnSessionLost(session);
151 }
152
CheckInputDeviceSource(const std::shared_ptr<PointerEvent> pointerEvent,uint32_t deviceTags)153 bool EventInterceptorHandler::CheckInputDeviceSource(
154 const std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags)
155 {
156 if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
157 ((deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH)) ||
158 (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL)))) {
159 return true;
160 } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) &&
161 (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
162 return true;
163 } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) &&
164 (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
165 return true;
166 }
167 return false;
168 }
169
SendToClient(std::shared_ptr<KeyEvent> keyEvent) const170 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<KeyEvent> keyEvent) const
171 {
172 CHKPV(keyEvent);
173 NetPacket pkt(MmiMessageId::REPORT_KEY_EVENT);
174 pkt << handlerType_ << deviceTags_;
175 if (pkt.ChkRWError()) {
176 MMI_HILOGE("Packet write key event failed");
177 return;
178 }
179 if (InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt) != RET_OK) {
180 MMI_HILOGE("Packet key 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
SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const189 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const
190 {
191 CHKPV(pointerEvent);
192 CHKPV(session_);
193 if (session_->GetUid() == ACCESSIBILITY_UID) {
194 pointerEvent->AddFlag(InputEvent::EVENT_FLAG_ACCESSIBILITY);
195 if (PointerEvent::POINTER_ACTION_CANCEL == pointerEvent->GetPointerAction()) {
196 pointerEvent->SetPointerAction(pointerEvent->GetOriginPointerAction());
197 MMI_HILOGD("OriginPointerAction:%{public}d", pointerEvent->GetPointerAction());
198 }
199 }
200 NetPacket pkt(MmiMessageId::REPORT_POINTER_EVENT);
201 MMI_HILOGD("Service send to client InputHandlerType:%{public}d", handlerType_);
202 pkt << handlerType_ << deviceTags_;
203 if (pkt.ChkRWError()) {
204 MMI_HILOGE("Packet write pointer event failed");
205 return;
206 }
207 if (InputEventDataTransformation::Marshalling(pointerEvent, pkt) != RET_OK) {
208 MMI_HILOGE("Marshalling pointer event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
209 return;
210 }
211 if (!session_->SendMsg(pkt)) {
212 MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
213 return;
214 }
215 }
216
217 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)218 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
219 {
220 CHKPF(keyEvent);
221 if (interceptors_.empty()) {
222 MMI_HILOGD("Key interceptors is empty");
223 return false;
224 }
225 MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
226 bool isInterceptor = false;
227 std::vector<KeyEvent::KeyItem> keyItems = keyEvent->GetKeyItems();
228 if (keyItems.empty()) {
229 MMI_HILOGE("keyItems is empty");
230 return false;
231 }
232 std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(keyItems.front().GetDeviceId());
233 CHKPF(inputDevice);
234 uint32_t capKeyboard = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
235 for (const auto &interceptor : interceptors_) {
236 MMI_HILOGD("eventType:%{public}d, deviceTags:%{public}d",
237 interceptor.eventType_, interceptor.deviceTags_);
238 if ((capKeyboard & interceptor.deviceTags_) == 0) {
239 MMI_HILOGD("Interceptor cap does not have keyboard");
240 continue;
241 }
242 if (!inputDevice->HasCapability(interceptor.deviceTags_)) {
243 continue;
244 }
245 if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_KEY) == HANDLE_EVENT_TYPE_KEY) {
246 interceptor.SendToClient(keyEvent);
247 MMI_HILOGD("Key event was intercepted");
248 isInterceptor = true;
249 break;
250 }
251 }
252 return isInterceptor;
253 }
254 #endif // OHOS_BUILD_ENABLE_KEYBOARD
255
256 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)257 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
258 {
259 CHKPF(pointerEvent);
260 if (interceptors_.empty()) {
261 MMI_HILOGD("Interceptors are empty");
262 return false;
263 }
264 MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
265 bool isInterceptor = false;
266 PointerEvent::PointerItem pointerItem;
267 int32_t pointerId = pointerEvent->GetPointerId();
268 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
269 MMI_HILOGE("GetPointerItem:%{public}d fail", pointerId);
270 return false;
271 }
272 std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(pointerItem.GetDeviceId(), false);
273 CHKPF(inputDevice);
274 uint32_t capPointer = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
275 uint32_t capTouch = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH);
276 for (const auto &interceptor : interceptors_) {
277 MMI_HILOGD("eventType:%{public}d, deviceTags:%{public}d",
278 interceptor.eventType_, interceptor.deviceTags_);
279 if (((capPointer | capTouch) & interceptor.deviceTags_) == 0) {
280 MMI_HILOGD("Interceptor cap does not have pointer or touch");
281 continue;
282 }
283 if (!EventInterceptorHandler::CheckInputDeviceSource(pointerEvent, interceptor.deviceTags_)) {
284 continue;
285 }
286 #ifndef OHOS_BUILD_EMULATOR
287 if (!inputDevice->HasCapability(interceptor.deviceTags_)) {
288 continue;
289 }
290 #endif // OHOS_BUILD_EMULATOR
291 if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_POINTER) == HANDLE_EVENT_TYPE_POINTER) {
292 interceptor.SendToClient(pointerEvent);
293 MMI_HILOGD("Pointer event was intercepted");
294 isInterceptor = true;
295 break;
296 }
297 }
298 return isInterceptor;
299 }
300 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
301
AddInterceptor(const SessionHandler & interceptor)302 int32_t EventInterceptorHandler::InterceptorCollection::AddInterceptor(const SessionHandler& interceptor)
303 {
304 for (auto iter = interceptors_.begin(); iter != interceptors_.end(); ++iter) {
305 if (iter->session_ == interceptor.session_) {
306 interceptors_.erase(iter);
307 break;
308 }
309 }
310
311 if (interceptors_.size() >= MAX_N_INPUT_INTERCEPTORS) {
312 MMI_HILOGE("The number of interceptors exceeds limit");
313 return RET_ERR;
314 }
315
316 auto iterIndex = interceptors_.cbegin();
317 for (; iterIndex != interceptors_.cend(); ++iterIndex) {
318 if (interceptor.priority_ < iterIndex->priority_) {
319 break;
320 }
321 }
322 auto sIter = interceptors_.emplace(iterIndex, interceptor);
323 if (sIter == interceptors_.end()) {
324 MMI_HILOGE("Failed to add interceptor");
325 return RET_ERR;
326 }
327 return RET_OK;
328 }
329
RemoveInterceptor(const SessionHandler & interceptor)330 void EventInterceptorHandler::InterceptorCollection::RemoveInterceptor(const SessionHandler& interceptor)
331 {
332 for (auto iter = interceptors_.begin(); iter != interceptors_.end(); ++iter) {
333 if (iter->session_ == interceptor.session_) {
334 interceptors_.erase(iter);
335 break;
336 }
337 }
338 if (interceptor.eventType_ == HANDLE_EVENT_TYPE_NONE) {
339 MMI_HILOGD("Unregister interceptor successfully");
340 return;
341 }
342
343 auto iterIndex = interceptors_.cbegin();
344 for (; iterIndex != interceptors_.cend(); ++iterIndex) {
345 if (interceptor.priority_ < iterIndex->priority_) {
346 break;
347 }
348 }
349 auto sIter = interceptors_.emplace(iterIndex, interceptor);
350 if (sIter == interceptors_.end()) {
351 MMI_HILOGE("Internal error, interceptor has been removed");
352 return;
353 }
354 MMI_HILOGD("Event type is updated:%{public}u", interceptor.eventType_);
355 }
356
OnSessionLost(SessionPtr session)357 void EventInterceptorHandler::InterceptorCollection::OnSessionLost(SessionPtr session)
358 {
359 CALL_INFO_TRACE;
360 auto iter = interceptors_.cbegin();
361 while (iter != interceptors_.cend()) {
362 if (iter->session_ != session) {
363 ++iter;
364 } else {
365 iter = interceptors_.erase(iter);
366 }
367 }
368 }
369
Dump(int32_t fd,const std::vector<std::string> & args)370 void EventInterceptorHandler::Dump(int32_t fd, const std::vector<std::string> &args)
371 {
372 return interceptors_.Dump(fd, args);
373 }
374
Dump(int32_t fd,const std::vector<std::string> & args)375 void EventInterceptorHandler::InterceptorCollection::Dump(int32_t fd, const std::vector<std::string> &args)
376 {
377 CALL_DEBUG_ENTER;
378 mprintf(fd, "Interceptor information:\t");
379 mprintf(fd, "interceptors: count=%zu", interceptors_.size());
380 for (const auto &item : interceptors_) {
381 SessionPtr session = item.session_;
382 CHKPV(session);
383 mprintf(fd,
384 "handlerType:%d | eventType:%u | Pid:%d | Uid:%d | Fd:%d "
385 "| EarliestEventTime:%" PRId64 " | Descript:%s | ProgramName:%s \t",
386 item.handlerType_, item.eventType_,
387 session->GetPid(), session->GetUid(),
388 session->GetFd(),
389 session->GetEarliestEventTime(), session->GetDescript().c_str(),
390 session->GetProgramName().c_str());
391 }
392 }
393 } // namespace MMI
394 } // namespace OHOS
395