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("Received.");
148 BytraceAdapter::StartBytrace(key, BytraceAdapter::TRACE_START, BytraceAdapter::KEY_DISPATCH_EVENT);
149 key->SetProcessedCallback(dispatchCallback_);
150 InputMgrImpl.OnKeyEvent(key);
151 key->MarkProcessed();
152 return RET_OK;
153 }
154 #endif // OHOS_BUILD_ENABLE_KEYBOARD
155
NotifyBundleName(const UDSClient & client,NetPacket & pkt)156 int32_t ClientMsgHandler::NotifyBundleName(const UDSClient& client, NetPacket& pkt)
157 {
158 CALL_DEBUG_ENTER;
159 int32_t pid = 0;
160 int32_t uid = 0;
161 int32_t syncStatus = 0;
162 std::string bundleName;
163 pkt >> pid >> uid >> bundleName >> syncStatus;
164 InputMgrImpl.NotifyBundleName(pid, uid, bundleName, syncStatus);
165 MMI_HILOGD("NotifyBundleName pid:%{public}d, uid:%{public}d, bundleName:%{public}s, syncStatus:%{public}d",
166 pid, uid, bundleName.c_str(), syncStatus);
167 return RET_OK;
168 }
169
170 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
OnPointerEvent(const UDSClient & client,NetPacket & pkt)171 int32_t ClientMsgHandler::OnPointerEvent(const UDSClient& client, NetPacket& pkt)
172 {
173 CALL_DEBUG_ENTER;
174 auto pointerEvent = PointerEvent::Create();
175 CHKPR(pointerEvent, ERROR_NULL_POINTER);
176 if (InputEventDataTransformation::Unmarshalling(pkt, pointerEvent) != ERR_OK) {
177 MMI_HILOG_DISPATCHE("Failed to deserialize pointer event");
178 return RET_ERR;
179 }
180 #ifdef OHOS_BUILD_ENABLE_SECURITY_COMPONENT
181 if (InputEventDataTransformation::UnmarshallingEnhanceData(pkt, pointerEvent) != ERR_OK) {
182 MMI_HILOG_DISPATCHE("Failed to deserialize enhance data pointer event");
183 return RET_ERR;
184 }
185 #endif // OHOS_BUILD_ENABLE_SECURITY_COMPONENT
186 LogTracer lt(pointerEvent->GetId(), pointerEvent->GetEventType(), pointerEvent->GetPointerAction());
187 if (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_UPDATE &&
188 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_UPDATE) {
189 std::string logInfo = std::string("ac: ") + pointerEvent->DumpPointerAction();
190 aggregator_.Record({MMI_LOG_DISPATCH, INPUT_KEY_FLOW, __FUNCTION__, __LINE__}, logInfo.c_str(),
191 std::to_string(pointerEvent->GetId()));
192 }
193 if (PointerEvent::POINTER_ACTION_CANCEL == pointerEvent->GetPointerAction() ||
194 PointerEvent::POINTER_ACTION_HOVER_CANCEL == pointerEvent->GetPointerAction() ||
195 PointerEvent::POINTER_ACTION_FINGERPRINT_CANCEL == pointerEvent->GetPointerAction()) {
196 MMI_HILOG_DISPATCHI("Operation canceled");
197 }
198 pointerEvent->SetProcessedCallback(dispatchCallback_);
199 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START, BytraceAdapter::POINT_DISPATCH_EVENT);
200 processedCount_++;
201 if (processedCount_ == PRINT_INTERVAL_COUNT) {
202 MMI_HILOG_FREEZEI("Last eventId:%{public}d, current eventId:%{public}d", lastEventId_, pointerEvent->GetId());
203 processedCount_ = 0;
204 lastEventId_ = pointerEvent->GetId();
205 }
206 InputMgrImpl.OnPointerEvent(pointerEvent);
207 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_JOYSTICK) {
208 pointerEvent->MarkProcessed();
209 }
210 return RET_OK;
211 }
212 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
213
214 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnSubscribeKeyEventCallback(const UDSClient & client,NetPacket & pkt)215 int32_t ClientMsgHandler::OnSubscribeKeyEventCallback(const UDSClient &client, NetPacket &pkt)
216 {
217 std::shared_ptr<KeyEvent> keyEvent = KeyEvent::Create();
218 CHKPR(keyEvent, ERROR_NULL_POINTER);
219 int32_t ret = InputEventDataTransformation::NetPacketToKeyEvent(pkt, keyEvent);
220 if (ret != RET_OK) {
221 MMI_HILOGE("Read net packet failed");
222 return RET_ERR;
223 }
224 LogTracer lt(keyEvent->GetId(), keyEvent->GetEventType(), keyEvent->GetKeyAction());
225 int32_t fd = -1;
226 int32_t subscribeId = -1;
227 pkt >> fd >> subscribeId;
228 if (pkt.ChkRWError()) {
229 MMI_HILOGE("Packet read fd failed");
230 return PACKET_READ_FAIL;
231 }
232 if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER) {
233 if (!EventLogHelper::IsBetaVersion()) {
234 MMI_HILOGI("Subscribe:%{public}d,Fd:%{public}d,KeyEvent:%{public}d, "
235 "Action:%{public}d, KeyAction:%{public}d, EventType:%{public}d,Flag:%{public}u",
236 subscribeId, fd, keyEvent->GetId(), keyEvent->GetAction(), keyEvent->GetKeyAction(),
237 keyEvent->GetEventType(), keyEvent->GetFlag());
238 } else {
239 MMI_HILOGI("Subscribe:%{public}d,Fd:%{public}d,KeyEvent:%{public}d, "
240 "Action:%{public}d, KeyAction:%{public}d, EventType:%{public}d,Flag:%{public}u",
241 subscribeId, fd, keyEvent->GetId(), keyEvent->GetAction(), keyEvent->GetKeyAction(),
242 keyEvent->GetEventType(), keyEvent->GetFlag());
243 }
244 } else {
245 MMI_HILOGD("Subscribe:%{public}d,Fd:%{public}d,KeyEvent:%{public}d,"
246 "KeyCode:%{private}d,ActionTime:%{public}" PRId64 ",ActionStartTime:%{public}" PRId64 ","
247 "Action:%{public}d,KeyAction:%{public}d,EventType:%{public}d,Flag:%{public}u",
248 subscribeId, fd, keyEvent->GetId(), keyEvent->GetKeyCode(), keyEvent->GetActionTime(),
249 keyEvent->GetActionStartTime(), keyEvent->GetAction(), keyEvent->GetKeyAction(),
250 keyEvent->GetEventType(), keyEvent->GetFlag());
251 }
252
253 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::TRACE_START, BytraceAdapter::KEY_SUBSCRIBE_EVENT);
254 return KeyEventInputSubscribeMgr.OnSubscribeKeyEventCallback(keyEvent, subscribeId);
255 }
256 #endif // OHOS_BUILD_ENABLE_KEYBOARD
257
258 #ifdef OHOS_BUILD_ENABLE_SWITCH
OnSubscribeSwitchEventCallback(const UDSClient & client,NetPacket & pkt)259 int32_t ClientMsgHandler::OnSubscribeSwitchEventCallback(const UDSClient &client, NetPacket &pkt)
260 {
261 std::shared_ptr<SwitchEvent> switchEvent = std::make_shared<SwitchEvent>(0);
262 int32_t ret = InputEventDataTransformation::NetPacketToSwitchEvent(pkt, switchEvent);
263 if (ret != RET_OK) {
264 MMI_HILOGE("Read net packet failed");
265 return RET_ERR;
266 }
267 LogTracer lt(switchEvent->GetId(), switchEvent->GetEventType(), switchEvent->GetAction());
268 int32_t fd = -1;
269 int32_t subscribeId = -1;
270 pkt >> fd >> subscribeId;
271 if (pkt.ChkRWError()) {
272 MMI_HILOGE("Packet read fd failed");
273 return PACKET_READ_FAIL;
274 }
275 return SWITCH_EVENT_INPUT_SUBSCRIBE_MGR.OnSubscribeSwitchEventCallback(switchEvent, subscribeId);
276 }
277 #endif
278
OnDevListener(const UDSClient & client,NetPacket & pkt)279 int32_t ClientMsgHandler::OnDevListener(const UDSClient& client, NetPacket& pkt)
280 {
281 CALL_DEBUG_ENTER;
282 std::string type;
283 int32_t deviceId = 0;
284 pkt >> type >> deviceId;
285 if (pkt.ChkRWError()) {
286 MMI_HILOGE("Packet read type failed");
287 return RET_ERR;
288 }
289 INPUT_DEVICE_IMPL.OnDevListener(deviceId, type);
290 return RET_OK;
291 }
292
293 #if defined(OHOS_BUILD_ENABLE_KEYBOARD) && (defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || \
294 defined(OHOS_BUILD_ENABLE_MONITOR))
ReportKeyEvent(const UDSClient & client,NetPacket & pkt)295 int32_t ClientMsgHandler::ReportKeyEvent(const UDSClient& client, NetPacket& pkt)
296 {
297 CALL_DEBUG_ENTER;
298 InputHandlerType handlerType;
299 uint32_t deviceTags = 0;
300 pkt >> handlerType >> deviceTags;
301 if (pkt.ChkRWError()) {
302 MMI_HILOG_DISPATCHE("Packet read handler failed");
303 return RET_ERR;
304 }
305 auto keyEvent = KeyEvent::Create();
306 CHKPR(keyEvent, ERROR_NULL_POINTER);
307 if (InputEventDataTransformation::NetPacketToKeyEvent(pkt, keyEvent) != ERR_OK) {
308 MMI_HILOG_DISPATCHE("Failed to deserialize key event");
309 return RET_ERR;
310 }
311 LogTracer lt(keyEvent->GetId(), keyEvent->GetEventType(), keyEvent->GetKeyAction());
312 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::TRACE_START, BytraceAdapter::KEY_INTERCEPT_EVENT);
313 switch (handlerType) {
314 case INTERCEPTOR: {
315 #ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
316 InputInterMgr->OnInputEvent(keyEvent, deviceTags);
317 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR
318 break;
319 }
320 case MONITOR: {
321 #ifdef OHOS_BUILD_ENABLE_MONITOR
322 IMonitorMgr->OnInputEvent(keyEvent, deviceTags);
323 #endif // OHOS_BUILD_ENABLE_MONITOR
324 break;
325 }
326 default: {
327 MMI_HILOG_DISPATCHW("Failed to intercept or monitor on the event");
328 break;
329 }
330 }
331 return RET_OK;
332 }
333 #endif // OHOS_BUILD_ENABLE_KEYBOARD && OHOS_BUILD_ENABLE_INTERCEPTOR || OHOS_BUILD_ENABLE_MONITOR
334
335 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && \
336 (defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR))
ReportPointerEvent(const UDSClient & client,NetPacket & pkt)337 int32_t ClientMsgHandler::ReportPointerEvent(const UDSClient& client, NetPacket& pkt)
338 {
339 InputHandlerType handlerType;
340 uint32_t deviceTags = 0;
341 pkt >> handlerType >> deviceTags;
342 if (pkt.ChkRWError()) {
343 MMI_HILOG_DISPATCHE("Packet read Pointer data failed");
344 return RET_ERR;
345 }
346 MMI_HILOG_DISPATCHD("Client handlerType:%{public}d", handlerType);
347 auto pointerEvent = PointerEvent::Create();
348 CHKPR(pointerEvent, ERROR_NULL_POINTER);
349 if (InputEventDataTransformation::Unmarshalling(pkt, pointerEvent) != ERR_OK) {
350 MMI_HILOG_DISPATCHW("Failed to deserialize pointer event");
351 return RET_ERR;
352 }
353 LogTracer lt(pointerEvent->GetId(), pointerEvent->GetEventType(), pointerEvent->GetPointerAction());
354 BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_START, BytraceAdapter::POINT_INTERCEPT_EVENT);
355 switch (handlerType) {
356 case INTERCEPTOR: {
357 #ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
358 InputInterMgr->OnInputEvent(pointerEvent, deviceTags);
359 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR
360 break;
361 }
362 case MONITOR: {
363 #ifdef OHOS_BUILD_ENABLE_MONITOR
364 IMonitorMgr->OnInputEvent(pointerEvent, deviceTags);
365 #endif // OHOS_BUILD_ENABLE_MONITOR
366 break;
367 }
368 default: {
369 MMI_HILOG_DISPATCHW("Failed to intercept or monitor on the event");
370 break;
371 }
372 }
373 return RET_OK;
374 }
375 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
376
OnDispatchEventProcessed(int32_t eventId,int64_t actionTime)377 void ClientMsgHandler::OnDispatchEventProcessed(int32_t eventId, int64_t actionTime)
378 {
379 CALL_DEBUG_ENTER;
380 ANRHDL->SetLastProcessedEventId(ANR_DISPATCH, eventId, actionTime);
381 }
382
OnAnr(const UDSClient & client,NetPacket & pkt)383 int32_t ClientMsgHandler::OnAnr(const UDSClient& client, NetPacket& pkt)
384 {
385 CALL_DEBUG_ENTER;
386 int32_t pid = 0;
387 int32_t eventId = 0;
388 pkt >> pid;
389 pkt >> eventId;
390 if (pkt.ChkRWError()) {
391 MMI_HILOG_ANRDETECTE("Packet read data failed");
392 return RET_ERR;
393 }
394 MMI_HILOG_ANRDETECTI("Client pid:%{public}d eventId:%{public}d", pid, eventId);
395 InputMgrImpl.OnAnr(pid, eventId);
396 return RET_OK;
397 }
398
NotifyWindowStateError(const UDSClient & client,NetPacket & pkt)399 int32_t ClientMsgHandler::NotifyWindowStateError(const UDSClient& client, NetPacket& pkt)
400 {
401 CALL_DEBUG_ENTER;
402 int32_t pid = 0;
403 int32_t windowId = 0;
404 pkt >> pid;
405 pkt >> windowId;
406 if (pkt.ChkRWError()) {
407 MMI_HILOG_ANRDETECTE("Packet read data failed");
408 return RET_ERR;
409 }
410 MMI_HILOG_ANRDETECTI("Client pid:%{public}d windowId:%{public}d", pid, windowId);
411 InputMgrImpl.OnWindowStateError(pid, windowId);
412 return RET_OK;
413 }
414
415 } // namespace MMI
416 } // namespace OHOS
417