1 /*
2 * Copyright (c) 2021-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 "client_msg_handler.h"
17
18 #include <cinttypes>
19 #include <iostream>
20 #include <sstream>
21
22 #include "anr_handler.h"
23 #include "bytrace_adapter.h"
24 #include "event_log_helper.h"
25 #include "input_device.h"
26 #include "input_device_impl.h"
27 #include "input_event_data_transformation.h"
28 #include "input_handler_manager.h"
29 #include "input_manager_impl.h"
30 #ifdef OHOS_BUILD_ENABLE_MONITOR
31 #include "input_monitor_manager.h"
32 #endif // OHOS_BUILD_ENABLE_MONITOR
33 #include "mmi_client.h"
34 #include "multimodal_event_handler.h"
35 #include "multimodal_input_connect_manager.h"
36 #include "napi_constants.h"
37 #include "proto.h"
38 #include "time_cost_chk.h"
39 #include "util.h"
40
41 #undef MMI_LOG_TAG
42 #define MMI_LOG_TAG "ClientMsgHandler"
43
44 namespace OHOS {
45 namespace MMI {
46 namespace {
47 constexpr int32_t PRINT_INTERVAL_COUNT { 50 };
48 } // namespace
Init()49 void ClientMsgHandler::Init()
50 {
51 MsgCallback funs[] = {
52 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
53 { MmiMessageId::ON_KEY_EVENT, [this] (const UDSClient& client, NetPacket& pkt) {
54 return this->OnKeyEvent(client, pkt); }},
55 { MmiMessageId::ON_SUBSCRIBE_KEY, [this] (const UDSClient &client, NetPacket &pkt) {
56 return this->OnSubscribeKeyEventCallback(client, pkt); }},
57 #endif // OHOS_BUILD_ENABLE_KEYBOARD
58 #ifdef OHOS_BUILD_ENABLE_SWITCH
59 { MmiMessageId::ON_SUBSCRIBE_SWITCH, [this] (const UDSClient &client, NetPacket &pkt) {
60 return this->OnSubscribeSwitchEventCallback(client, pkt); }},
61 #endif // OHOS_BUILD_ENABLE_SWITCH
62 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
63 { MmiMessageId::ON_POINTER_EVENT, [this] (const UDSClient& client, NetPacket& pkt) {
64 return this->OnPointerEvent(client, pkt); }},
65 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
66 { MmiMessageId::ADD_INPUT_DEVICE_LISTENER, [this] (const UDSClient& client, NetPacket& pkt) {
67 return this->OnDevListener(client, pkt); }},
68 { MmiMessageId::NOTICE_ANR, [this] (const UDSClient& client, NetPacket& pkt) {
69 return this->OnAnr(client, pkt); }},
70 #if defined(OHOS_BUILD_ENABLE_KEYBOARD) && (defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || \
71 defined(OHOS_BUILD_ENABLE_MONITOR))
72 { MmiMessageId::REPORT_KEY_EVENT, [this] (const UDSClient& client, NetPacket& pkt) {
73 return this->ReportKeyEvent(client, pkt); }},
74 #endif // OHOS_BUILD_ENABLE_KEYBOARD
75 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && \
76 (defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR))
77 { MmiMessageId::REPORT_POINTER_EVENT, [this] (const UDSClient& client, NetPacket& pkt) {
78 return this->ReportPointerEvent(client, pkt); }},
79 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
80 { MmiMessageId::NOTIFY_BUNDLE_NAME, [this] (const UDSClient& client, NetPacket& pkt) {
81 return this->NotifyBundleName(client, pkt); }},
82 { MmiMessageId::WINDOW_STATE_ERROR_NOTIFY, [this] (const UDSClient& client, NetPacket& pkt) {
83 return this->NotifyWindowStateError(client, pkt); }},
84 };
85 for (auto &it : funs) {
86 if (!RegistrationEvent(it)) {
87 MMI_HILOGW("Failed to register event errCode:%{public}d", EVENT_REG_FAIL);
88 continue;
89 }
90 }
91 }
92
InitProcessedCallback()93 void ClientMsgHandler::InitProcessedCallback()
94 {
95 CALL_DEBUG_ENTER;
96 int32_t tokenType = MULTIMODAL_INPUT_CONNECT_MGR->GetTokenType();
97 if (tokenType == TokenType::TOKEN_HAP || tokenType == TokenType::TOKEN_SYSTEM_HAP) {
98 MMI_HILOGD("Current session is hap");
99 dispatchCallback_ = [] (int32_t eventId, int64_t actionTime) {
100 return ClientMsgHandler::OnDispatchEventProcessed(eventId, actionTime);
101 };
102 } else if (tokenType == static_cast<int32_t>(TokenType::TOKEN_NATIVE)) {
103 MMI_HILOGD("Current session is native");
104 } else {
105 MMI_HILOGE("Current session is unknown tokenType:%{public}d", tokenType);
106 }
107 }
108
OnMsgHandler(const UDSClient& client, NetPacket& pkt)109 void ClientMsgHandler::OnMsgHandler(const UDSClient& client, NetPacket& pkt)
110 {
111 auto id = pkt.GetMsgId();
112 TimeCostChk chk("ClientMsgHandler::OnMsgHandler", "overtime 300(us)", MAX_OVER_TIME, id);
113 auto callback = GetMsgCallback(id);
114 CHKPV(callback);
115 ResetLogTrace();
116 auto ret = (*callback)(client, pkt);
117 if (ret < 0) {
118 MMI_HILOGE("Msg handling failed. id:%{public}d, ret:%{public}d", id, ret);
119 return;
120 }
121 }
122
123 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnKeyEvent(const UDSClient& client, NetPacket& pkt)124 int32_t ClientMsgHandler::OnKeyEvent(const UDSClient& client, NetPacket& pkt)
125 {
126 auto key = KeyEvent::Create();
127 CHKPR(key, ERROR_NULL_POINTER);
128 int32_t ret = InputEventDataTransformation::NetPacketToKeyEvent(pkt, key);
129 if (ret != RET_OK) {
130 MMI_HILOG_DISPATCHE("Read netPacket failed");
131 return RET_ERR;
132 }
133 LogTracer lt(key->GetId(), key->GetEventType(), key->GetKeyAction());
134 int32_t fd = 0;
135 pkt >> fd;
136 #ifdef OHOS_BUILD_ENABLE_SECURITY_COMPONENT
137 if (InputEventDataTransformation::UnmarshallingEnhanceData(pkt, key) != ERR_OK) {
138 MMI_HILOG_DISPATCHE("Failed to deserialize enhance data key event");
139 return RET_ERR;
140 }
141 #endif // OHOS_BUILD_ENABLE_SECURITY_COMPONENT
142 if (pkt.ChkRWError()) {
143 MMI_HILOG_DISPATCHE("Packet read fd failed");
144 return PACKET_READ_FAIL;
145 }
146 MMI_HILOG_DISPATCHD("Key event dispatcher of client, Fd:%{public}d", fd);
147 MMI_HILOG_DISPATCHI("InputTracking id:%{public}d KeyEvent ReceivedMsg", key->GetId());
148 EventLogHelper::PrintEventData(key, MMI_LOG_HEADER);
149 BytraceAdapter::StartBytrace(key, BytraceAdapter::TRACE_START, BytraceAdapter::KEY_DISPATCH_EVENT);
150 key->SetProcessedCallback(dispatchCallback_);
151 InputMgrImpl.OnKeyEvent(key);
152 key->MarkProcessed();
153 return RET_OK;
154 }
155 #endif // OHOS_BUILD_ENABLE_KEYBOARD
156
NotifyBundleName(const UDSClient& client, NetPacket& pkt)157 int32_t ClientMsgHandler::NotifyBundleName(const UDSClient& client, NetPacket& pkt)
158 {
159 CALL_DEBUG_ENTER;
160 int32_t pid = 0;
161 int32_t uid = 0;
162 int32_t syncStatus = 0;
163 std::string bundleName;
164 pkt >> pid >> uid >> bundleName >> syncStatus;
165 InputMgrImpl.NotifyBundleName(pid, uid, bundleName, syncStatus);
166 MMI_HILOGD("NotifyBundleName pid:%{public}d, uid:%{public}d, bundleName:%{public}s, syncStatus:%{public}d",
167 pid, uid, bundleName.c_str(), syncStatus);
168 return RET_OK;
169 }
170
171 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
OnPointerEvent(const UDSClient& client, NetPacket& pkt)172 int32_t ClientMsgHandler::OnPointerEvent(const UDSClient& client, NetPacket& pkt)
173 {
174 CALL_DEBUG_ENTER;
175 auto pointerEvent = PointerEvent::Create();
176 CHKPR(pointerEvent, ERROR_NULL_POINTER);
177 if (InputEventDataTransformation::Unmarshalling(pkt, pointerEvent) != ERR_OK) {
178 MMI_HILOG_DISPATCHE("Failed to deserialize pointer event");
179 return RET_ERR;
180 }
181 #ifdef OHOS_BUILD_ENABLE_SECURITY_COMPONENT
182 if (InputEventDataTransformation::UnmarshallingEnhanceData(pkt, pointerEvent) != ERR_OK) {
183 MMI_HILOG_DISPATCHE("Failed to deserialize enhance data pointer event");
184 return RET_ERR;
185 }
186 #endif // OHOS_BUILD_ENABLE_SECURITY_COMPONENT
187 LogTracer lt(pointerEvent->GetId(), pointerEvent->GetEventType(), pointerEvent->GetPointerAction());
188 MMI_HILOG_FREEZEI("id:%{public}d ac:%{public}d recv", pointerEvent->GetId(), pointerEvent->GetPointerAction());
189 if (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_UPDATE &&
190 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_UPDATE) {
191 std::string logInfo = std::string("ac: ") + pointerEvent->DumpPointerAction();
192 aggregator_.Record({MMI_LOG_DISPATCH, INPUT_KEY_FLOW, __FUNCTION__, __LINE__}, logInfo.c_str(),
193 std::to_string(pointerEvent->GetId()));
194 }
195 EventLogHelper::PrintEventData(pointerEvent, {MMI_LOG_DISPATCH, INPUT_KEY_FLOW, __FUNCTION__, __LINE__});
196 if (PointerEvent::POINTER_ACTION_CANCEL == pointerEvent->GetPointerAction() ||
197 PointerEvent::POINTER_ACTION_HOVER_CANCEL == pointerEvent->GetPointerAction() ||
198 PointerEvent::POINTER_ACTION_FINGERPRINT_CANCEL == pointerEvent->GetPointerAction()) {
199 MMI_HILOG_DISPATCHI("Operation canceled");
200 }
201 pointerEvent->SetProcessedCallback(dispatchCallback_);
202 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START, BytraceAdapter::POINT_DISPATCH_EVENT);
203 processedCount_++;
204 if (processedCount_ == PRINT_INTERVAL_COUNT) {
205 MMI_HILOG_FREEZEI("Last eventId:%{public}d, current eventId:%{public}d", lastEventId_, pointerEvent->GetId());
206 processedCount_ = 0;
207 lastEventId_ = pointerEvent->GetId();
208 }
209 InputMgrImpl.OnPointerEvent(pointerEvent);
210 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_JOYSTICK) {
211 pointerEvent->MarkProcessed();
212 }
213 return RET_OK;
214 }
215 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
216
217 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnSubscribeKeyEventCallback(const UDSClient &client, NetPacket &pkt)218 int32_t ClientMsgHandler::OnSubscribeKeyEventCallback(const UDSClient &client, NetPacket &pkt)
219 {
220 std::shared_ptr<KeyEvent> keyEvent = KeyEvent::Create();
221 CHKPR(keyEvent, ERROR_NULL_POINTER);
222 int32_t ret = InputEventDataTransformation::NetPacketToKeyEvent(pkt, keyEvent);
223 if (ret != RET_OK) {
224 MMI_HILOGE("Read net packet failed");
225 return RET_ERR;
226 }
227 LogTracer lt(keyEvent->GetId(), keyEvent->GetEventType(), keyEvent->GetKeyAction());
228 int32_t fd = -1;
229 int32_t subscribeId = -1;
230 pkt >> fd >> subscribeId;
231 if (pkt.ChkRWError()) {
232 MMI_HILOGE("Packet read fd failed");
233 return PACKET_READ_FAIL;
234 }
235 if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER) {
236 if (!EventLogHelper::IsBetaVersion()) {
237 MMI_HILOGI("Subscribe:%{public}d,Fd:%{public}d,KeyEvent:%{public}d, "
238 "Action:%{public}d, KeyAction:%{public}d, EventType:%{public}d,Flag:%{public}u",
239 subscribeId, fd, keyEvent->GetId(), keyEvent->GetAction(), keyEvent->GetKeyAction(),
240 keyEvent->GetEventType(), keyEvent->GetFlag());
241 } else {
242 MMI_HILOGI("Subscribe:%{public}d,Fd:%{public}d,KeyEvent:%{public}d,"
243 "KeyCode:%{private}d,ActionTime:%{public}" PRId64 ",ActionStartTime:%{public}" PRId64 ","
244 "Action:%{public}d,KeyAction:%{public}d,EventType:%{public}d,Flag:%{public}u",
245 subscribeId, fd, keyEvent->GetId(), keyEvent->GetKeyCode(), keyEvent->GetActionTime(),
246 keyEvent->GetActionStartTime(), keyEvent->GetAction(), keyEvent->GetKeyAction(),
247 keyEvent->GetEventType(), keyEvent->GetFlag());
248 }
249 } else {
250 MMI_HILOGD("Subscribe:%{public}d,Fd:%{public}d,KeyEvent:%{public}d,"
251 "KeyCode:%{private}d,ActionTime:%{public}" PRId64 ",ActionStartTime:%{public}" PRId64 ","
252 "Action:%{public}d,KeyAction:%{public}d,EventType:%{public}d,Flag:%{public}u",
253 subscribeId, fd, keyEvent->GetId(), keyEvent->GetKeyCode(), keyEvent->GetActionTime(),
254 keyEvent->GetActionStartTime(), keyEvent->GetAction(), keyEvent->GetKeyAction(),
255 keyEvent->GetEventType(), keyEvent->GetFlag());
256 }
257
258 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::TRACE_START, BytraceAdapter::KEY_SUBSCRIBE_EVENT);
259 return KeyEventInputSubscribeMgr.OnSubscribeKeyEventCallback(keyEvent, subscribeId);
260 }
261 #endif // OHOS_BUILD_ENABLE_KEYBOARD
262
263 #ifdef OHOS_BUILD_ENABLE_SWITCH
OnSubscribeSwitchEventCallback(const UDSClient &client, NetPacket &pkt)264 int32_t ClientMsgHandler::OnSubscribeSwitchEventCallback(const UDSClient &client, NetPacket &pkt)
265 {
266 std::shared_ptr<SwitchEvent> switchEvent = std::make_shared<SwitchEvent>(0);
267 int32_t ret = InputEventDataTransformation::NetPacketToSwitchEvent(pkt, switchEvent);
268 if (ret != RET_OK) {
269 MMI_HILOGE("Read net packet failed");
270 return RET_ERR;
271 }
272 LogTracer lt(switchEvent->GetId(), switchEvent->GetEventType(), switchEvent->GetAction());
273 int32_t fd = -1;
274 int32_t subscribeId = -1;
275 pkt >> fd >> subscribeId;
276 if (pkt.ChkRWError()) {
277 MMI_HILOGE("Packet read fd failed");
278 return PACKET_READ_FAIL;
279 }
280 return SWITCH_EVENT_INPUT_SUBSCRIBE_MGR.OnSubscribeSwitchEventCallback(switchEvent, subscribeId);
281 }
282 #endif // OHOS_BUILD_ENABLE_SWITCH
283
OnDevListener(const UDSClient& client, NetPacket& pkt)284 int32_t ClientMsgHandler::OnDevListener(const UDSClient& client, NetPacket& pkt)
285 {
286 CALL_DEBUG_ENTER;
287 std::string type;
288 int32_t deviceId = 0;
289 pkt >> type >> deviceId;
290 if (pkt.ChkRWError()) {
291 MMI_HILOGE("Packet read type failed");
292 return RET_ERR;
293 }
294 INPUT_DEVICE_IMPL.OnDevListener(deviceId, type);
295 return RET_OK;
296 }
297
298 #if defined(OHOS_BUILD_ENABLE_KEYBOARD) && (defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || \
299 defined(OHOS_BUILD_ENABLE_MONITOR))
ReportKeyEvent(const UDSClient& client, NetPacket& pkt)300 int32_t ClientMsgHandler::ReportKeyEvent(const UDSClient& client, NetPacket& pkt)
301 {
302 CALL_DEBUG_ENTER;
303 InputHandlerType handlerType;
304 uint32_t deviceTags = 0;
305 pkt >> handlerType >> deviceTags;
306 if (pkt.ChkRWError()) {
307 MMI_HILOG_DISPATCHE("Packet read handler failed");
308 return RET_ERR;
309 }
310 auto keyEvent = KeyEvent::Create();
311 CHKPR(keyEvent, ERROR_NULL_POINTER);
312 if (InputEventDataTransformation::NetPacketToKeyEvent(pkt, keyEvent) != ERR_OK) {
313 MMI_HILOG_DISPATCHE("Failed to deserialize key event");
314 return RET_ERR;
315 }
316 LogTracer lt(keyEvent->GetId(), keyEvent->GetEventType(), keyEvent->GetKeyAction());
317 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::TRACE_START, BytraceAdapter::KEY_INTERCEPT_EVENT);
318 switch (handlerType) {
319 case INTERCEPTOR: {
320 #ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
321 InputInterMgr->OnInputEvent(keyEvent, deviceTags);
322 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR
323 break;
324 }
325 case MONITOR: {
326 #ifdef OHOS_BUILD_ENABLE_MONITOR
327 IMonitorMgr->OnInputEvent(keyEvent, deviceTags);
328 #endif // OHOS_BUILD_ENABLE_MONITOR
329 break;
330 }
331 default: {
332 MMI_HILOG_DISPATCHW("Failed to intercept or monitor on the event");
333 break;
334 }
335 }
336 return RET_OK;
337 }
338 #endif // OHOS_BUILD_ENABLE_KEYBOARD && OHOS_BUILD_ENABLE_INTERCEPTOR || OHOS_BUILD_ENABLE_MONITOR
339
340 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && \
341 (defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR))
ReportPointerEvent(const UDSClient& client, NetPacket& pkt)342 int32_t ClientMsgHandler::ReportPointerEvent(const UDSClient& client, NetPacket& pkt)
343 {
344 InputHandlerType handlerType;
345 uint32_t deviceTags = 0;
346 pkt >> handlerType >> deviceTags;
347 if (pkt.ChkRWError()) {
348 MMI_HILOG_DISPATCHE("Packet read Pointer data failed");
349 return RET_ERR;
350 }
351 MMI_HILOG_DISPATCHD("Client handlerType:%{public}d", handlerType);
352 auto pointerEvent = PointerEvent::Create();
353 CHKPR(pointerEvent, ERROR_NULL_POINTER);
354 if (InputEventDataTransformation::Unmarshalling(pkt, pointerEvent) != ERR_OK) {
355 MMI_HILOG_DISPATCHW("Failed to deserialize pointer event");
356 return RET_ERR;
357 }
358 LogTracer lt(pointerEvent->GetId(), pointerEvent->GetEventType(), pointerEvent->GetPointerAction());
359 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START, BytraceAdapter::POINT_INTERCEPT_EVENT);
360 switch (handlerType) {
361 case INTERCEPTOR: {
362 #ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
363 InputInterMgr->OnInputEvent(pointerEvent, deviceTags);
364 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR
365 break;
366 }
367 case MONITOR: {
368 #ifdef OHOS_BUILD_ENABLE_MONITOR
369 IMonitorMgr->OnInputEvent(pointerEvent, deviceTags);
370 #endif // OHOS_BUILD_ENABLE_MONITOR
371 break;
372 }
373 default: {
374 MMI_HILOG_DISPATCHW("Failed to intercept or monitor on the event");
375 break;
376 }
377 }
378 return RET_OK;
379 }
380 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
381
OnDispatchEventProcessed(int32_t eventId, int64_t actionTime)382 void ClientMsgHandler::OnDispatchEventProcessed(int32_t eventId, int64_t actionTime)
383 {
384 CALL_DEBUG_ENTER;
385 ANRHDL->SetLastProcessedEventId(ANR_DISPATCH, eventId, actionTime);
386 }
387
OnAnr(const UDSClient& client, NetPacket& pkt)388 int32_t ClientMsgHandler::OnAnr(const UDSClient& client, NetPacket& pkt)
389 {
390 CALL_DEBUG_ENTER;
391 int32_t pid = 0;
392 int32_t eventId = 0;
393 pkt >> pid;
394 pkt >> eventId;
395 if (pkt.ChkRWError()) {
396 MMI_HILOG_ANRDETECTE("Packet read data failed");
397 return RET_ERR;
398 }
399 MMI_HILOG_ANRDETECTI("Client pid:%{public}d eventId:%{public}d", pid, eventId);
400 InputMgrImpl.OnAnr(pid, eventId);
401 return RET_OK;
402 }
403
NotifyWindowStateError(const UDSClient& client, NetPacket& pkt)404 int32_t ClientMsgHandler::NotifyWindowStateError(const UDSClient& client, NetPacket& pkt)
405 {
406 CALL_DEBUG_ENTER;
407 int32_t pid = 0;
408 int32_t windowId = 0;
409 pkt >> pid;
410 pkt >> windowId;
411 if (pkt.ChkRWError()) {
412 MMI_HILOG_ANRDETECTE("Packet read data failed");
413 return RET_ERR;
414 }
415 MMI_HILOG_ANRDETECTI("Client pid:%{public}d windowId:%{public}d", pid, windowId);
416 InputMgrImpl.OnWindowStateError(pid, windowId);
417 return RET_OK;
418 }
419
420 } // namespace MMI
421 } // namespace OHOS
422