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