• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 "dfx_hisysevent.h"
21 #include "event_dispatch_handler.h"
22 #include "input_device_manager.h"
23 #include "input_event_data_transformation.h"
24 #include "input_event_handler.h"
25 #include "mmi_log.h"
26 #include "net_packet.h"
27 #include "proto.h"
28 #include "util_ex.h"
29 #include "init_param.h"
30 
31 #undef MMI_LOG_DOMAIN
32 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
33 #undef MMI_LOG_TAG
34 #define MMI_LOG_TAG "EventInterceptorHandler"
35 
36 namespace OHOS {
37 namespace MMI {
38 namespace {
39 constexpr int32_t ACCESSIBILITY_UID { 1103 };
40 
41 const std::string DEFAULT_KEYEVENT_INTERCEPT_WHITELIST = "2722;41;40;0;22;17;16;23;2841;9;2089;2083;";
42 } // namespace
43 
44 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)45 void EventInterceptorHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
46 {
47     CHKPV(keyEvent);
48     if (TouchPadKnuckleDoubleClickHandle(keyEvent)) {
49         return;
50     }
51     bool isIntercept = this->KeyInterceptByHostOSWhiteList(keyEvent->GetKeyCode());
52     if (!isIntercept && OnHandleEvent(keyEvent)) {
53         MMI_HILOGD("KeyEvent filter find a keyEvent from Original event:%{private}d",
54             keyEvent->GetKeyCode());
55         BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_INTERCEPT_EVENT);
56         DfxHisysevent::ReportKeyEvent("intercept");
57         return;
58     }
59     CHKPV(nextHandler_);
60     nextHandler_->HandleKeyEvent(keyEvent);
61 }
62 
KeyInterceptByHostOSWhiteList(int32_t keyCode)63 bool EventInterceptorHandler::KeyInterceptByHostOSWhiteList(int32_t keyCode)
64 {
65     if (keyevent_intercept_whitelist != nullptr && keyevent_intercept_whitelist->empty()) {
66         return false;
67     }
68     if (keyevent_intercept_whitelist == nullptr) {
69         uint32_t size = 0;
70         int ret = SystemReadParam("const.multimodalinput.keyevent_intercept_whitelist", nullptr, &size);
71         std::string intercept_whitelist = "";
72         if (ret == 0) {
73             std::vector<char> value(size + 1);
74             ret = SystemReadParam("const.multimodalinput.keyevent_intercept_whitelist", value.data(), &size);
75             if (ret == 0) {
76                 intercept_whitelist = std::string(value.data());
77             } else {
78                 intercept_whitelist = DEFAULT_KEYEVENT_INTERCEPT_WHITELIST;
79             }
80         }
81         keyevent_intercept_whitelist = std::make_unique<std::string>(intercept_whitelist);
82     }
83     std::string keyString = std::to_string(keyCode);
84     keyString += ";";
85     bool isIntercept = keyevent_intercept_whitelist->find(keyString) != std::string::npos;
86     MMI_HILOGD("Received key event is %{private}d isIntercept is %{public}d", keyCode, isIntercept);
87     return isIntercept;
88 }
89 #endif // OHOS_BUILD_ENABLE_KEYBOARD
90 
91 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)92 void EventInterceptorHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
93 {
94     CHKPV(pointerEvent);
95     if (OnHandleEvent(pointerEvent)) {
96         BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
97         MMI_HILOGD("Interception is succeeded");
98         return;
99     }
100     CHKPV(nextHandler_);
101     nextHandler_->HandlePointerEvent(pointerEvent);
102 }
103 #endif // OHOS_BUILD_ENABLE_POINTER
104 
105 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)106 void EventInterceptorHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
107 {
108     CHKPV(pointerEvent);
109     if (OnHandleEvent(pointerEvent)) {
110         BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
111         MMI_HILOGD("Interception is succeeded");
112         return;
113     }
114     CHKPV(nextHandler_);
115     nextHandler_->HandleTouchEvent(pointerEvent);
116 }
117 #endif // OHOS_BUILD_ENABLE_TOUCH
118 
AddInputHandler(InputHandlerType handlerType,HandleEventType eventType,int32_t priority,uint32_t deviceTags,SessionPtr session)119 int32_t EventInterceptorHandler::AddInputHandler(InputHandlerType handlerType,
120     HandleEventType eventType, int32_t priority, uint32_t deviceTags, SessionPtr session)
121 {
122     CALL_INFO_TRACE;
123     CHKPR(session, RET_ERR);
124     if ((eventType & HANDLE_EVENT_TYPE_ALL) == HANDLE_EVENT_TYPE_NONE) {
125         MMI_HILOGE("Invalid event type");
126         return RET_ERR;
127     }
128     InitSessionLostCallback();
129     SessionHandler interceptor { handlerType, eventType, priority, deviceTags, session };
130     MMI_HILOGD("The handlerType:%{public}d, eventType:%{public}d, deviceTags:%{public}d, priority:%{public}d",
131         handlerType, eventType, deviceTags, priority);
132     return interceptors_.AddInterceptor(interceptor);
133 }
134 
RemoveInputHandler(InputHandlerType handlerType,HandleEventType eventType,int32_t priority,uint32_t deviceTags,SessionPtr session)135 void EventInterceptorHandler::RemoveInputHandler(InputHandlerType handlerType,
136     HandleEventType eventType, int32_t priority, uint32_t deviceTags, SessionPtr session)
137 {
138     CALL_INFO_TRACE;
139     CHKPV(session);
140     if (handlerType == InputHandlerType::INTERCEPTOR) {
141         SessionHandler interceptor { handlerType, eventType, priority, deviceTags, session };
142         MMI_HILOGD("The handlerType:%{public}d, eventType:%{public}d, deviceTags:%{public}d, priority:%{public}d",
143             handlerType, eventType, deviceTags, priority);
144         interceptors_.RemoveInterceptor(interceptor);
145     }
146 }
147 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)148 bool EventInterceptorHandler::OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)
149 {
150     MMI_HILOGD("Handle KeyEvent");
151     CHKPF(keyEvent);
152     if (keyEvent->HasFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT)) {
153         MMI_HILOGW("This event has been tagged as not to be intercepted");
154         return false;
155     }
156     return interceptors_.HandleEvent(keyEvent);
157 }
158 #endif // OHOS_BUILD_ENABLE_KEYBOARD
159 
160 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
OnHandleEvent(std::shared_ptr<PointerEvent> pointerEvent)161 bool EventInterceptorHandler::OnHandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
162 {
163     CHKPF(pointerEvent);
164     if (pointerEvent->HasFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT)) {
165         MMI_HILOGW("This event has been tagged as not to be intercepted");
166         return false;
167     }
168     return interceptors_.HandleEvent(pointerEvent);
169 }
170 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
171 
InitSessionLostCallback()172 void EventInterceptorHandler::InitSessionLostCallback()
173 {
174     if (sessionLostCallbackInitialized_) {
175         MMI_HILOGE("Init session is failed");
176         return;
177     }
178     auto udsServerPtr = InputHandler->GetUDSServer();
179     CHKPV(udsServerPtr);
180     udsServerPtr->AddSessionDeletedCallback([this] (SessionPtr session) { this->OnSessionLost(session); });
181     sessionLostCallbackInitialized_ = true;
182     MMI_HILOGD("The callback on session deleted is registered successfully");
183 }
184 
OnSessionLost(SessionPtr session)185 void EventInterceptorHandler::OnSessionLost(SessionPtr session)
186 {
187     interceptors_.OnSessionLost(session);
188 }
189 
CheckInputDeviceSource(const std::shared_ptr<PointerEvent> pointerEvent,uint32_t deviceTags)190 bool EventInterceptorHandler::CheckInputDeviceSource(
191     const std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags)
192 {
193     if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
194         ((deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH)) ||
195         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL)))) {
196         return true;
197     } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) &&
198         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
199         return true;
200     } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) &&
201         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
202         return true;
203     }
204     return false;
205 }
206 
SendToClient(std::shared_ptr<KeyEvent> keyEvent) const207 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<KeyEvent> keyEvent) const
208 {
209     CHKPV(keyEvent);
210     CHKPV(session_);
211     if (session_->GetUid() == ACCESSIBILITY_UID) {
212         keyEvent->AddFlag(InputEvent::EVENT_FLAG_ACCESSIBILITY);
213     }
214     NetPacket pkt(MmiMessageId::REPORT_KEY_EVENT);
215     pkt << handlerType_ << deviceTags_;
216     if (pkt.ChkRWError()) {
217         MMI_HILOGE("Packet write key event failed");
218         return;
219     }
220     if (InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt) != RET_OK) {
221         MMI_HILOGE("Packet key event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
222         return;
223     }
224     if (!session_->SendMsg(pkt)) {
225         MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
226         return;
227     }
228 }
229 
SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const230 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const
231 {
232     CHKPV(pointerEvent);
233     CHKPV(session_);
234     if (session_->GetUid() == ACCESSIBILITY_UID) {
235         pointerEvent->AddFlag(InputEvent::EVENT_FLAG_ACCESSIBILITY);
236     }
237     NetPacket pkt(MmiMessageId::REPORT_POINTER_EVENT);
238     MMI_HILOGD("Service send to client InputHandlerType:%{public}d", handlerType_);
239     pkt << handlerType_ << deviceTags_;
240     if (pkt.ChkRWError()) {
241         MMI_HILOGE("Packet write pointer event failed");
242         return;
243     }
244     if (InputEventDataTransformation::Marshalling(pointerEvent, pkt) != RET_OK) {
245         MMI_HILOGE("Marshalling pointer event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
246         return;
247     }
248     if (!session_->SendMsg(pkt)) {
249         MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
250         return;
251     }
252 }
253 
254 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)255 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
256 {
257     CHKPF(keyEvent);
258     if (interceptors_.empty()) {
259         MMI_HILOGD("Key interceptors is empty");
260         return false;
261     }
262     MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
263     bool isInterceptor = false;
264     std::vector<KeyEvent::KeyItem> keyItems = keyEvent->GetKeyItems();
265     if (keyItems.empty()) {
266         MMI_HILOGE("keyItems is empty");
267         DfxHisysevent::ReportFailHandleKey("InterceptorCollection::HandleEvent", keyEvent->GetKeyCode(),
268             DfxHisysevent::KEY_ERROR_CODE::INVALID_PARAMETER);
269         return false;
270     }
271     std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(keyItems.front().GetDeviceId());
272     CHKPF(inputDevice);
273     uint32_t capKeyboard = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
274     for (const auto &interceptor : interceptors_) {
275         MMI_HILOGD("The eventType:%{public}d, deviceTags:%{public}d",
276             interceptor.eventType_, interceptor.deviceTags_);
277         if ((capKeyboard & interceptor.deviceTags_) == 0) {
278             MMI_HILOGD("Interceptor cap does not have keyboard");
279             continue;
280         }
281         if (!inputDevice->HasCapability(interceptor.deviceTags_)) {
282             continue;
283         }
284         auto session = interceptor.session_;
285         if (session != nullptr) {
286             int32_t tokenType = session->GetTokenType();
287             int32_t pid = session->GetPid();
288             if (tokenType == TokenType::TOKEN_HAP && !IInputWindowsManager::GetInstance()->CheckAppFocused(pid)) {
289                 MMI_HILOGD("Token hap is not focus, no need interceptor key");
290                 continue;
291             }
292         }
293         if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_KEY) == HANDLE_EVENT_TYPE_KEY) {
294             interceptor.SendToClient(keyEvent);
295             MMI_HILOGD("Key event was intercepted");
296             isInterceptor = true;
297             break;
298         }
299     }
300     return isInterceptor;
301 }
302 #endif // OHOS_BUILD_ENABLE_KEYBOARD
303 
304 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)305 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
306 {
307     CHKPF(pointerEvent);
308     if (interceptors_.empty()) {
309         MMI_HILOGD("Interceptors are empty");
310         return false;
311     }
312     MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
313     bool isInterceptor = false;
314     PointerEvent::PointerItem pointerItem;
315     int32_t pointerId = pointerEvent->GetPointerId();
316     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
317         MMI_HILOGE("GetPointerItem:%{public}d fail", pointerId);
318         return false;
319     }
320     std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(pointerItem.GetDeviceId(), false);
321     CHKPF(inputDevice);
322     uint32_t capPointer = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
323     uint32_t capTouch = CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH);
324     for (const auto &interceptor : interceptors_) {
325         MMI_HILOGD("The eventType:%{public}d, deviceTags:%{public}d",
326             interceptor.eventType_, interceptor.deviceTags_);
327         if (((capPointer | capTouch) & interceptor.deviceTags_) == 0) {
328             MMI_HILOGD("Interceptor cap does not have pointer or touch");
329             continue;
330         }
331         if (!EventInterceptorHandler::CheckInputDeviceSource(pointerEvent, interceptor.deviceTags_)) {
332             continue;
333         }
334 #ifndef OHOS_BUILD_EMULATOR
335         if (!inputDevice->HasCapability(interceptor.deviceTags_)) {
336             continue;
337         }
338 #endif // OHOS_BUILD_EMULATOR
339         auto session = interceptor.session_;
340         if (session != nullptr) {
341             int32_t tokenType = session->GetTokenType();
342             if ((tokenType == TokenType::TOKEN_HAP) &&
343                 (IInputWindowsManager::GetInstance()->GetWindowPid(pointerEvent->GetTargetWindowId()) !=
344                 session->GetPid())) {
345                 MMI_HILOGD("Token hap is not hit, no need interceptor pointer");
346                 continue;
347             }
348         }
349         if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_POINTER) == HANDLE_EVENT_TYPE_POINTER) {
350             interceptor.SendToClient(pointerEvent);
351             if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_PULL_UP ||
352                 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_BUTTON_UP) {
353                     MMI_HILOGI("Action:%{public}d event was intercepted", pointerEvent->GetPointerAction());
354             }
355             MMI_HILOGD("Pointer event was intercepted");
356             isInterceptor = true;
357             break;
358         }
359     }
360     return isInterceptor;
361 }
362 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
363 
AddInterceptor(const SessionHandler & interceptor)364 int32_t EventInterceptorHandler::InterceptorCollection::AddInterceptor(const SessionHandler& interceptor)
365 {
366     for (auto iter = interceptors_.begin(); iter != interceptors_.end(); ++iter) {
367         if (iter->session_ == interceptor.session_) {
368             interceptors_.erase(iter);
369             break;
370         }
371     }
372 
373     if (interceptors_.size() >= MAX_N_INPUT_INTERCEPTORS) {
374         MMI_HILOGE("The number of interceptors exceeds limit");
375         return RET_ERR;
376     }
377 
378     auto iterIndex = interceptors_.cbegin();
379     for (; iterIndex != interceptors_.cend(); ++iterIndex) {
380         if (interceptor.priority_ < iterIndex->priority_) {
381             break;
382         }
383     }
384     auto sIter = interceptors_.emplace(iterIndex, interceptor);
385     if (sIter == interceptors_.end()) {
386         MMI_HILOGE("Failed to add interceptor");
387         return RET_ERR;
388     }
389     return RET_OK;
390 }
391 
RemoveInterceptor(const SessionHandler & interceptor)392 void EventInterceptorHandler::InterceptorCollection::RemoveInterceptor(const SessionHandler& interceptor)
393 {
394     for (auto iter = interceptors_.begin(); iter != interceptors_.end(); ++iter) {
395         if (iter->session_ == interceptor.session_) {
396             interceptors_.erase(iter);
397             break;
398         }
399     }
400     if (interceptor.eventType_ == HANDLE_EVENT_TYPE_NONE) {
401         MMI_HILOGD("Unregister interceptor successfully");
402         return;
403     }
404 
405     auto iterIndex = interceptors_.cbegin();
406     for (; iterIndex != interceptors_.cend(); ++iterIndex) {
407         if (interceptor.priority_ < iterIndex->priority_) {
408             break;
409         }
410     }
411     auto sIter = interceptors_.emplace(iterIndex, interceptor);
412     if (sIter == interceptors_.end()) {
413         MMI_HILOGE("Internal error, interceptor has been removed");
414         return;
415     }
416     MMI_HILOGD("Event type is updated:%{public}u", interceptor.eventType_);
417 }
418 
OnSessionLost(SessionPtr session)419 void EventInterceptorHandler::InterceptorCollection::OnSessionLost(SessionPtr session)
420 {
421     CALL_INFO_TRACE;
422     auto iter = interceptors_.cbegin();
423     while (iter != interceptors_.cend()) {
424         if (iter->session_ != session) {
425             ++iter;
426         } else {
427             iter = interceptors_.erase(iter);
428         }
429     }
430 }
431 
Dump(int32_t fd,const std::vector<std::string> & args)432 void EventInterceptorHandler::Dump(int32_t fd, const std::vector<std::string> &args)
433 {
434     return interceptors_.Dump(fd, args);
435 }
436 
Dump(int32_t fd,const std::vector<std::string> & args)437 void EventInterceptorHandler::InterceptorCollection::Dump(int32_t fd, const std::vector<std::string> &args)
438 {
439     CALL_DEBUG_ENTER;
440     mprintf(fd, "Interceptor information:\t");
441     mprintf(fd, "interceptors: count=%zu", interceptors_.size());
442     for (const auto &item : interceptors_) {
443         SessionPtr session = item.session_;
444         CHKPV(session);
445         mprintf(fd,
446                 "handlerType:%d | eventType:%u | Pid:%d | Uid:%d | Fd:%d "
447                 "| EarliestEventTime:%" PRId64 " | Descript:%s | ProgramName:%s \t",
448                 item.handlerType_, item.eventType_,
449                 session->GetPid(), session->GetUid(),
450                 session->GetFd(),
451                 session->GetEarliestEventTime(), session->GetDescript().c_str(),
452                 session->GetProgramName().c_str());
453     }
454 }
455 
456 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)457 bool EventInterceptorHandler::TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)
458 {
459     CHKPF(event);
460     CHKPF(nextHandler_);
461     if (event->GetKeyAction() != KNUCKLE_1F_DOUBLE_CLICK &&
462         event->GetKeyAction() != KNUCKLE_2F_DOUBLE_CLICK) {
463         return false;
464     }
465     MMI_HILOGI("Current is touchPad knuckle double click action");
466     nextHandler_->HandleKeyEvent(event);
467     return true;
468 }
469 #endif // OHOS_BUILD_ENABLE_KEYBOARD
470 } // namespace MMI
471 } // namespace OHOS
472