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