1 /*
2 * Copyright (c) 2022 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_event_data_transformation.h"
22 #include "input_event_handler.h"
23 #include "mmi_log.h"
24 #include "net_packet.h"
25 #include "proto.h"
26 #include "util_ex.h"
27
28 namespace OHOS {
29 namespace MMI {
30 namespace {
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "EventInterceptorHandler" };
32 } // namespace
33
34 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)35 void EventInterceptorHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
36 {
37 CHKPV(keyEvent);
38 #ifdef OHOS_BUILD_ENABLE_COOPERATE
39 if (!InputHandler->GetJumpInterceptState() && OnHandleEvent(keyEvent)) {
40 MMI_HILOGD("KeyEvent filter find a keyEvent from Original event keyCode:%{puiblic}d",
41 keyEvent->GetKeyCode());
42 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_INTERCEPT_EVENT);
43 return;
44 }
45 #else
46 if (OnHandleEvent(keyEvent)) {
47 MMI_HILOGD("KeyEvent filter find a keyEvent from Original event keyCode:%{puiblic}d",
48 keyEvent->GetKeyCode());
49 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_INTERCEPT_EVENT);
50 return;
51 }
52 #endif // OHOS_BUILD_ENABLE_COOPERATE
53 CHKPV(nextHandler_);
54 nextHandler_->HandleKeyEvent(keyEvent);
55 }
56 #endif // OHOS_BUILD_ENABLE_KEYBOARD
57
58 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)59 void EventInterceptorHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
60 {
61 CHKPV(pointerEvent);
62 if (OnHandleEvent(pointerEvent)) {
63 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
64 MMI_HILOGD("Interception is succeeded");
65 return;
66 }
67 CHKPV(nextHandler_);
68 nextHandler_->HandlePointerEvent(pointerEvent);
69 }
70 #endif // OHOS_BUILD_ENABLE_POINTER
71
72 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)73 void EventInterceptorHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
74 {
75 CHKPV(pointerEvent);
76 if (OnHandleEvent(pointerEvent)) {
77 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP);
78 MMI_HILOGD("Interception is succeeded");
79 return;
80 }
81 CHKPV(nextHandler_);
82 nextHandler_->HandleTouchEvent(pointerEvent);
83 }
84 #endif // OHOS_BUILD_ENABLE_TOUCH
85
AddInputHandler(InputHandlerType handlerType,HandleEventType eventType,SessionPtr session)86 int32_t EventInterceptorHandler::AddInputHandler(InputHandlerType handlerType,
87 HandleEventType eventType, SessionPtr session)
88 {
89 CALL_INFO_TRACE;
90 CHKPR(session, RET_ERR);
91 if ((eventType & HANDLE_EVENT_TYPE_ALL) == HANDLE_EVENT_TYPE_NONE) {
92 MMI_HILOGE("Invalid event type");
93 return RET_ERR;
94 }
95 InitSessionLostCallback();
96 SessionHandler interceptor { handlerType, eventType, session };
97 return interceptors_.AddInterceptor(interceptor);
98 }
99
RemoveInputHandler(InputHandlerType handlerType,HandleEventType eventType,SessionPtr session)100 void EventInterceptorHandler::RemoveInputHandler(InputHandlerType handlerType,
101 HandleEventType eventType, SessionPtr session)
102 {
103 CALL_INFO_TRACE;
104 CHKPV(session);
105 if (handlerType == InputHandlerType::INTERCEPTOR) {
106 SessionHandler interceptor { handlerType, eventType, session };
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(std::bind(
144 &EventInterceptorHandler::OnSessionLost, this, std::placeholders::_1));
145 sessionLostCallbackInitialized_ = true;
146 MMI_HILOGD("The callback on session deleted is registered successfully");
147 }
148
OnSessionLost(SessionPtr session)149 void EventInterceptorHandler::OnSessionLost(SessionPtr session)
150 {
151 interceptors_.OnSessionLost(session);
152 }
153
SendToClient(std::shared_ptr<KeyEvent> keyEvent) const154 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<KeyEvent> keyEvent) const
155 {
156 CHKPV(keyEvent);
157 NetPacket pkt(MmiMessageId::REPORT_KEY_EVENT);
158 pkt << handlerType_;
159 if (pkt.ChkRWError()) {
160 MMI_HILOGE("Packet write key event failed");
161 return;
162 }
163 if (InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt) != RET_OK) {
164 MMI_HILOGE("Packet key event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
165 return;
166 }
167 if (!session_->SendMsg(pkt)) {
168 MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
169 return;
170 }
171 }
172
SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const173 void EventInterceptorHandler::SessionHandler::SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const
174 {
175 CHKPV(pointerEvent);
176 NetPacket pkt(MmiMessageId::REPORT_POINTER_EVENT);
177 MMI_HILOGD("Service send to client InputHandlerType:%{public}d", handlerType_);
178 pkt << handlerType_;
179 if (pkt.ChkRWError()) {
180 MMI_HILOGE("Packet write pointer event failed");
181 return;
182 }
183 if (InputEventDataTransformation::Marshalling(pointerEvent, pkt) != RET_OK) {
184 MMI_HILOGE("Marshalling pointer event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
185 return;
186 }
187 if (!session_->SendMsg(pkt)) {
188 MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
189 return;
190 }
191 }
192
193 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)194 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
195 {
196 CHKPF(keyEvent);
197 if (interceptors_.empty()) {
198 MMI_HILOGW("Key interceptors is empty");
199 return false;
200 }
201 MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
202 bool isInterceptor = false;
203 for (const auto &interceptor : interceptors_) {
204 if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_KEY) == HANDLE_EVENT_TYPE_KEY) {
205 interceptor.SendToClient(keyEvent);
206 MMI_HILOGD("Key event was intercepted");
207 isInterceptor = true;
208 }
209 }
210 return isInterceptor;
211 }
212 #endif // OHOS_BUILD_ENABLE_KEYBOARD
213
214 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)215 bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
216 {
217 CHKPF(pointerEvent);
218 if (interceptors_.empty()) {
219 MMI_HILOGI("Interceptors is empty");
220 return false;
221 }
222 MMI_HILOGD("There are currently:%{public}zu interceptors", interceptors_.size());
223 bool isInterceptor = false;
224 for (const auto &interceptor : interceptors_) {
225 if ((interceptor.eventType_ & HANDLE_EVENT_TYPE_POINTER) == HANDLE_EVENT_TYPE_POINTER) {
226 interceptor.SendToClient(pointerEvent);
227 MMI_HILOGD("Pointer event was intercepted");
228 isInterceptor = true;
229 }
230 }
231 return isInterceptor;
232 }
233 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
234
AddInterceptor(const SessionHandler & interceptor)235 int32_t EventInterceptorHandler::InterceptorCollection::AddInterceptor(const SessionHandler& interceptor)
236 {
237 if (interceptors_.size() >= MAX_N_INPUT_INTERCEPTORS) {
238 MMI_HILOGE("The number of interceptors exceeds limit");
239 return RET_ERR;
240 }
241 bool isFound = false;
242 auto iter = interceptors_.find(interceptor);
243 if (iter != interceptors_.end()) {
244 if (iter->eventType_ == interceptor.eventType_) {
245 MMI_HILOGD("Interceptor with event type (%{public}u) already exists", interceptor.eventType_);
246 return RET_OK;
247 }
248 isFound = true;
249 interceptors_.erase(iter);
250 }
251
252 auto [sIter, isOk] = interceptors_.insert(interceptor);
253 if (!isOk) {
254 if (isFound) {
255 MMI_HILOGE("Internal error: interceptor has been removed");
256 } else {
257 MMI_HILOGE("Failed to add interceptor");
258 }
259 return RET_ERR;
260 }
261
262 if (isFound) {
263 MMI_HILOGD("Event type is updated:%{public}u", interceptor.eventType_);
264 } else {
265 MMI_HILOGD("Service AddInterceptor Success");
266 }
267 return RET_OK;
268 }
269
RemoveInterceptor(const SessionHandler & interceptor)270 void EventInterceptorHandler::InterceptorCollection::RemoveInterceptor(const SessionHandler& interceptor)
271 {
272 std::set<SessionHandler>::const_iterator iter = interceptors_.find(interceptor);
273 if (iter == interceptors_.cend()) {
274 MMI_HILOGE("Interceptor does not exist");
275 return;
276 }
277
278 interceptors_.erase(iter);
279 if (interceptor.eventType_ == HANDLE_EVENT_TYPE_NONE) {
280 MMI_HILOGD("Unregister interceptor successfully");
281 return;
282 }
283
284 auto [sIter, isOk] = interceptors_.insert(interceptor);
285 if (!isOk) {
286 MMI_HILOGE("Internal error, interceptor has been removed");
287 return;
288 }
289 MMI_HILOGD("Event type is updated:%{public}u", interceptor.eventType_);
290 }
291
OnSessionLost(SessionPtr session)292 void EventInterceptorHandler::InterceptorCollection::OnSessionLost(SessionPtr session)
293 {
294 CALL_INFO_TRACE;
295 std::set<SessionHandler>::const_iterator cItr = interceptors_.cbegin();
296 while (cItr != interceptors_.cend()) {
297 if (cItr->session_ != session) {
298 ++cItr;
299 } else {
300 cItr = interceptors_.erase(cItr);
301 }
302 }
303 }
Dump(int32_t fd,const std::vector<std::string> & args)304 void EventInterceptorHandler::Dump(int32_t fd, const std::vector<std::string> &args)
305 {
306 return interceptors_.Dump(fd, args);
307 }
308
Dump(int32_t fd,const std::vector<std::string> & args)309 void EventInterceptorHandler::InterceptorCollection::Dump(int32_t fd, const std::vector<std::string> &args)
310 {
311 CALL_DEBUG_ENTER;
312 mprintf(fd, "Interceptor information:\t");
313 mprintf(fd, "interceptors: count=%d", interceptors_.size());
314 for (const auto &item : interceptors_) {
315 SessionPtr session = item.session_;
316 CHKPV(session);
317 mprintf(fd,
318 "handlerType:%d | eventType:%d | Pid:%d | Uid:%d | Fd:%d "
319 "| EarliestEventTime:%" PRId64 " | Descript:%s \t",
320 item.handlerType_, item.eventType_,
321 session->GetPid(), session->GetUid(),
322 session->GetFd(),
323 session->GetEarliestEventTime(), session->GetDescript().c_str());
324 }
325 }
326 } // namespace MMI
327 } // namespace OHOS
328