1 /*
2  * Copyright (c) 2021-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 "js_register_module.h"
17 
18 #include <cinttypes>
19 
20 #include "event_log_helper.h"
21 #include "input_manager.h"
22 #include "js_register_util.h"
23 #include "napi_constants.h"
24 #include "util_napi.h"
25 #include "util_napi_error.h"
26 
27 #undef MMI_LOG_TAG
28 #define MMI_LOG_TAG "JSRegisterModule"
29 
30 namespace OHOS {
31 namespace MMI {
32 namespace {
33 constexpr int32_t JS_CALLBACK_MOUSE_BUTTON_MIDDLE { 1 };
34 constexpr int32_t JS_CALLBACK_MOUSE_BUTTON_RIGHT { 2 };
35 } // namespace
36 
GetInjectionEventData(napi_env env,std::shared_ptr<KeyEvent> keyEvent,napi_value keyHandle)37 static void GetInjectionEventData(napi_env env, std::shared_ptr<KeyEvent> keyEvent, napi_value keyHandle)
38 {
39     CHKPV(keyEvent);
40     keyEvent->SetRepeat(true);
41     bool isPressed = false;
42     if (GetNamedPropertyBool(env, keyHandle, "isPressed", isPressed) != RET_OK) {
43         MMI_HILOGE("Get isPressed failed");
44     }
45     bool isIntercepted = false;
46     if (GetNamedPropertyBool(env, keyHandle, "isIntercepted", isIntercepted) != RET_OK) {
47         MMI_HILOGE("Get isIntercepted failed");
48     }
49     keyEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT);
50     int32_t keyDownDuration = 0;
51     if (GetNamedPropertyInt32(env, keyHandle, "keyDownDuration", keyDownDuration) != RET_OK) {
52         MMI_HILOGE("Get keyDownDuration failed");
53     }
54     if (keyDownDuration < 0) {
55         MMI_HILOGE("keyDownDuration:%{public}d is less 0, can not process", keyDownDuration);
56         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "keyDownDuration must be greater than or equal to 0");
57     }
58     int32_t keyCode = 0;
59     if (GetNamedPropertyInt32(env, keyHandle, "keyCode", keyCode) != RET_OK) {
60         MMI_HILOGE("Get keyCode failed");
61     }
62     if (keyCode < 0) {
63         if (!EventLogHelper::IsBetaVersion()) {
64             MMI_HILOGE("keyCode is less 0, can not process");
65         } else {
66             MMI_HILOGE("keyCode is less 0, can not process");
67         }
68         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "keyCode must be greater than or equal to 0");
69     }
70     keyEvent->SetKeyCode(keyCode);
71     auto keyAction = isPressed ? KeyEvent::KEY_ACTION_DOWN : KeyEvent::KEY_ACTION_UP;
72     keyEvent->SetKeyAction(keyAction);
73     KeyEvent::KeyItem item;
74     item.SetKeyCode(keyCode);
75     item.SetPressed(isPressed);
76     item.SetDownTime(static_cast<int64_t>(keyDownDuration));
77     keyEvent->AddKeyItem(item);
78     InputManager::GetInstance()->SimulateInputEvent(keyEvent);
79     std::this_thread::sleep_for(std::chrono::milliseconds(keyDownDuration));
80 }
81 
InjectEvent(napi_env env,napi_callback_info info)82 static napi_value InjectEvent(napi_env env, napi_callback_info info)
83 {
84     CALL_DEBUG_ENTER;
85     napi_value result = nullptr;
86     size_t argc = 1;
87     napi_value argv[1] = { 0 };
88     CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
89     if (argc < 1) {
90         MMI_HILOGE("Parameter number error");
91         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
92         return nullptr;
93     }
94     napi_valuetype tmpType = napi_undefined;
95     CHKRP(napi_typeof(env, argv[0], &tmpType), TYPEOF);
96     if (tmpType != napi_object) {
97         MMI_HILOGE("KeyEvent is not napi_object");
98         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "KeyEvent", "object");
99         return nullptr;
100     }
101     napi_value keyHandle = nullptr;
102     CHKRP(napi_get_named_property(env, argv[0], "KeyEvent", &keyHandle), GET_NAMED_PROPERTY);
103     if (keyHandle == nullptr) {
104         MMI_HILOGE("KeyEvent is nullptr");
105         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "KeyEvent not found");
106         return nullptr;
107     }
108     CHKRP(napi_typeof(env, keyHandle, &tmpType), TYPEOF);
109     if (tmpType != napi_object) {
110         MMI_HILOGE("KeyEvent is not napi_object");
111         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "KeyEvent", "object");
112         return nullptr;
113     }
114     auto keyEvent = KeyEvent::Create();
115     CHKPP(keyEvent);
116     GetInjectionEventData(env, keyEvent, keyHandle);
117     CHKRP(napi_create_int32(env, 0, &result), CREATE_INT32);
118     return result;
119 }
120 
InjectKeyEvent(napi_env env,napi_callback_info info)121 static napi_value InjectKeyEvent(napi_env env, napi_callback_info info)
122 {
123     CALL_DEBUG_ENTER;
124     napi_value result = nullptr;
125     size_t argc = 1;
126     napi_value argv[1] = { 0 };
127     CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
128     if (argc < 1) {
129         MMI_HILOGE("Parameter number error");
130         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
131         return nullptr;
132     }
133     napi_valuetype tmpType = napi_undefined;
134     CHKRP(napi_typeof(env, argv[0], &tmpType), TYPEOF);
135     if (tmpType != napi_object) {
136         MMI_HILOGE("keyEvent is not napi_object");
137         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "keyEvent", "object");
138         return nullptr;
139     }
140     napi_value keyHandle = nullptr;
141     CHKRP(napi_get_named_property(env, argv[0], "keyEvent", &keyHandle), GET_NAMED_PROPERTY);
142     if (keyHandle == nullptr) {
143         MMI_HILOGE("keyEvent is nullptr");
144         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "keyEvent not found");
145         return nullptr;
146     }
147     CHKRP(napi_typeof(env, keyHandle, &tmpType), TYPEOF);
148     if (tmpType != napi_object) {
149         MMI_HILOGE("keyEvent is not napi_object");
150         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "keyEvent", "object");
151         return nullptr;
152     }
153     auto keyEvent = KeyEvent::Create();
154     CHKPP(keyEvent);
155     GetInjectionEventData(env, keyEvent, keyHandle);
156     CHKRP(napi_create_int32(env, 0, &result), CREATE_INT32);
157     return result;
158 }
159 
HandleMouseButton(napi_env env,napi_value mouseHandle,std::shared_ptr<PointerEvent> pointerEvent)160 static void HandleMouseButton(napi_env env, napi_value mouseHandle, std::shared_ptr<PointerEvent> pointerEvent)
161 {
162     int32_t button = 0;
163     if (GetNamedPropertyInt32(env, mouseHandle, "button", button) != RET_OK) {
164         MMI_HILOGE("Get button failed");
165     }
166     if (button < 0) {
167         MMI_HILOGE("button:%{public}d is less 0, can not process", button);
168         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "button must be greater than or equal to 0");
169     }
170 
171     switch (button) {
172         case JS_CALLBACK_MOUSE_BUTTON_MIDDLE:
173             button = PointerEvent::MOUSE_BUTTON_MIDDLE;
174             break;
175         case JS_CALLBACK_MOUSE_BUTTON_RIGHT:
176             button = PointerEvent::MOUSE_BUTTON_RIGHT;
177             break;
178         default:
179             MMI_HILOGE("button:%{public}d is unknown", button);
180             break;
181     }
182     pointerEvent->SetButtonId(button);
183     pointerEvent->SetButtonPressed(button);
184 }
185 
HandleMouseAction(napi_env env,napi_value mouseHandle,std::shared_ptr<PointerEvent> pointerEvent,PointerEvent::PointerItem & item)186 static void HandleMouseAction(napi_env env, napi_value mouseHandle,
187     std::shared_ptr<PointerEvent> pointerEvent, PointerEvent::PointerItem &item)
188 {
189     int32_t action = 0;
190     if (GetNamedPropertyInt32(env, mouseHandle, "action", action) != RET_OK) {
191         MMI_HILOGE("Get action failed");
192         return;
193     }
194     switch (action) {
195         case JS_CALLBACK_MOUSE_ACTION_MOVE:
196             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
197             break;
198         case JS_CALLBACK_MOUSE_ACTION_BUTTON_DOWN:
199             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN);
200             item.SetPressed(true);
201             break;
202         case JS_CALLBACK_MOUSE_ACTION_BUTTON_UP:
203             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP);
204             item.SetPressed(false);
205             break;
206         case JS_CALLBACK_POINTER_ACTION_DOWN:
207             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
208             item.SetPressed(true);
209             break;
210         case JS_CALLBACK_POINTER_ACTION_UP:
211             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
212             item.SetPressed(false);
213             break;
214         default:
215             MMI_HILOGE("action:%{public}d is unknown", action);
216             break;
217     }
218     if (action == JS_CALLBACK_MOUSE_ACTION_BUTTON_DOWN || action == JS_CALLBACK_MOUSE_ACTION_BUTTON_UP) {
219         HandleMouseButton(env, mouseHandle, pointerEvent);
220     }
221 }
222 
HandleMousePropertyInt32(napi_env env,napi_value mouseHandle,std::shared_ptr<PointerEvent> pointerEvent,PointerEvent::PointerItem & item)223 static void HandleMousePropertyInt32(napi_env env, napi_value mouseHandle,
224     std::shared_ptr<PointerEvent> pointerEvent, PointerEvent::PointerItem &item)
225 {
226     int32_t screenX = 0;
227     if (GetNamedPropertyInt32(env, mouseHandle, "screenX", screenX) != RET_OK) {
228         MMI_HILOGE("Get screenX failed");
229     }
230     int32_t screenY = 0;
231     if (GetNamedPropertyInt32(env, mouseHandle, "screenY", screenY) != RET_OK) {
232         MMI_HILOGE("Get screenY failed");
233     }
234     int32_t toolType = 0;
235     if (GetNamedPropertyInt32(env, mouseHandle, "toolType", toolType) != RET_OK) {
236         MMI_HILOGE("Get toolType failed");
237     }
238     if (toolType < 0) {
239         MMI_HILOGE("toolType:%{public}d is less 0, can not process", toolType);
240         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "toolType must be greater than or equal to 0");
241     }
242     pointerEvent->SetSourceType(toolType);
243     item.SetPointerId(0);
244     item.SetDisplayX(screenX);
245     item.SetDisplayY(screenY);
246     pointerEvent->SetPointerId(0);
247     pointerEvent->AddPointerItem(item);
248 }
249 
InjectMouseEvent(napi_env env,napi_callback_info info)250 static napi_value InjectMouseEvent(napi_env env, napi_callback_info info)
251 {
252     CALL_DEBUG_ENTER;
253     napi_value result = nullptr;
254     size_t argc = 1;
255     napi_value argv[1] = { 0 };
256     CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
257     if (argc < 1) {
258         MMI_HILOGE("Parameter number error");
259         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
260         return nullptr;
261     }
262     napi_valuetype tmpType = napi_undefined;
263     CHKRP(napi_typeof(env, argv[0], &tmpType), TYPEOF);
264     if (tmpType != napi_object) {
265         MMI_HILOGE("MouseEvent is not napi_object");
266         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "mouseEvent", "object");
267         return nullptr;
268     }
269     napi_value mouseHandle = nullptr;
270     CHKRP(napi_get_named_property(env, argv[0], "mouseEvent", &mouseHandle), GET_NAMED_PROPERTY);
271     if (mouseHandle == nullptr) {
272         MMI_HILOGE("MouseEvent is nullptr");
273         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "MouseEvent not found");
274         return nullptr;
275     }
276     CHKRP(napi_typeof(env, mouseHandle, &tmpType), TYPEOF);
277     if (tmpType != napi_object) {
278         MMI_HILOGE("MouseEvent is not napi_object");
279         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "mouseEvent", "object");
280         return nullptr;
281     }
282     auto pointerEvent = PointerEvent::Create();
283     PointerEvent::PointerItem item;
284     CHKPP(pointerEvent);
285 
286     HandleMouseAction(env, mouseHandle, pointerEvent, item);
287     HandleMousePropertyInt32(env, mouseHandle, pointerEvent, item);
288     InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
289     CHKRP(napi_create_int32(env, 0, &result), CREATE_INT32);
290     return result;
291 }
292 
HandleTouchAction(napi_env env,napi_value touchHandle,std::shared_ptr<PointerEvent> pointerEvent,PointerEvent::PointerItem & item)293 static int32_t HandleTouchAction(napi_env env, napi_value touchHandle,
294     std::shared_ptr<PointerEvent> pointerEvent, PointerEvent::PointerItem &item)
295 {
296     int32_t action = 0;
297     if (GetNamedPropertyInt32(env, touchHandle, "action", action) != RET_OK) {
298         MMI_HILOGE("Get action failed");
299         return RET_ERR;
300     }
301     switch (action) {
302         case JS_CALLBACK_TOUCH_ACTION_DOWN:
303             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
304             item.SetPressed(true);
305             break;
306         case JS_CALLBACK_TOUCH_ACTION_MOVE:
307             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
308             break;
309         case JS_CALLBACK_TOUCH_ACTION_UP:
310             pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
311             item.SetPressed(false);
312             break;
313         default:
314             MMI_HILOGE("action:%{public}d is unknown", action);
315             break;
316     }
317     return action;
318 }
319 
HandleTouchProperty(napi_env env,napi_value touchHandle)320 static napi_value HandleTouchProperty(napi_env env, napi_value touchHandle)
321 {
322     napi_value touchProperty = nullptr;
323     if (napi_get_named_property(env, touchHandle, "touch", &touchProperty) != RET_OK) {
324         MMI_HILOGE("Get touch failed");
325         return nullptr;
326     }
327     if (touchProperty == nullptr) {
328         MMI_HILOGE("Touch value is null");
329         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Invalid touch");
330         return nullptr;
331     }
332     napi_valuetype tmpType = napi_undefined;
333     if (napi_typeof(env, touchProperty, &tmpType) != napi_ok) {
334         MMI_HILOGE("Call napi_typeof failed");
335         return nullptr;
336     }
337     if (tmpType != napi_object) {
338         MMI_HILOGE("touch is not napi_object");
339         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "touch", "object");
340         return nullptr;
341     }
342     return touchProperty;
343 }
344 
HandleTouchPropertyInt32(napi_env env,napi_value touchHandle,std::shared_ptr<PointerEvent> pointerEvent,PointerEvent::PointerItem & item,int32_t action)345 static void HandleTouchPropertyInt32(napi_env env, napi_value touchHandle,
346     std::shared_ptr<PointerEvent> pointerEvent, PointerEvent::PointerItem &item, int32_t action)
347 {
348     int32_t sourceType = 0;
349     if (GetNamedPropertyInt32(env, touchHandle, "sourceType", sourceType) != RET_OK) {
350         MMI_HILOGE("Get sourceType failed");
351     }
352     if (sourceType < 0) {
353         MMI_HILOGE("sourceType:%{public}d is less 0, can not process", sourceType);
354         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "sourceType must be greater than or equal to 0");
355     }
356     if (sourceType == TOUCH_SCREEN || sourceType == PEN) {
357         sourceType = PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
358     }
359     int32_t screenId = -1;
360     if (GetNamedPropertyInt32(env, touchHandle, "screenId", screenId, false) != RET_OK) {
361         MMI_HILOGE("Get screenId failed");
362     }
363     napi_value touchProperty = HandleTouchProperty(env, touchHandle);
364     CHKPV(touchProperty);
365     int32_t screenX = 0;
366     if (GetNamedPropertyInt32(env, touchProperty, "screenX", screenX) != RET_OK) {
367         MMI_HILOGE("Get screenX failed");
368     }
369     int32_t screenY = 0;
370     if (GetNamedPropertyInt32(env, touchProperty, "screenY", screenY) != RET_OK) {
371         MMI_HILOGE("Get screenY failed");
372     }
373     int64_t pressedTime;
374     if (GetNamedPropertyInt64(env, touchProperty, "pressedTime", pressedTime) != RET_OK) {
375         MMI_HILOGE("Get pressed time failed");
376     }
377     int32_t toolType = 0;
378     if (GetNamedPropertyInt32(env, touchProperty, "toolType", toolType) != RET_OK) {
379         MMI_HILOGE("Get toolType failed");
380     }
381     double pressure;
382     if (GetNamedPropertyDouble(env, touchProperty, "pressure", pressure) != RET_OK) {
383         MMI_HILOGE("Get pressure failed");
384     }
385     item.SetDisplayX(screenX);
386     item.SetDisplayY(screenY);
387     item.SetPointerId(0);
388     item.SetToolType(toolType);
389     item.SetPressure(pressure);
390     pointerEvent->SetPointerId(0);
391     pointerEvent->AddPointerItem(item);
392     pointerEvent->SetSourceType(sourceType);
393     pointerEvent->SetActionTime(pressedTime);
394     pointerEvent->SetTargetDisplayId(screenId);
395     if ((action == JS_CALLBACK_TOUCH_ACTION_MOVE) || (action == JS_CALLBACK_TOUCH_ACTION_UP)) {
396         pointerEvent->UpdatePointerItem(0, item);
397     }
398 }
399 
InjectTouchEvent(napi_env env,napi_callback_info info)400 static napi_value InjectTouchEvent(napi_env env, napi_callback_info info)
401 {
402     CALL_DEBUG_ENTER;
403     napi_value result = nullptr;
404     size_t argc = 1;
405     napi_value argv[1] = { 0 };
406     CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
407     if (argc < 1) {
408         MMI_HILOGE("Parameter number error");
409         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
410         return nullptr;
411     }
412     napi_valuetype tmpType = napi_undefined;
413     CHKRP(napi_typeof(env, argv[0], &tmpType), TYPEOF);
414     if (tmpType != napi_object) {
415         MMI_HILOGE("TouchEvent is not napi_object");
416         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "touchEvent", "object");
417         return nullptr;
418     }
419     napi_value touchHandle = nullptr;
420     CHKRP(napi_get_named_property(env, argv[0], "touchEvent", &touchHandle), GET_NAMED_PROPERTY);
421     if (touchHandle == nullptr) {
422         MMI_HILOGE("TouchEvent is nullptr");
423         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "TouchEvent not found");
424         return nullptr;
425     }
426     CHKRP(napi_typeof(env, touchHandle, &tmpType), TYPEOF);
427     if (tmpType != napi_object) {
428         MMI_HILOGE("TouchEvent is not napi_object");
429         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "touchEvent", "object");
430         return nullptr;
431     }
432     auto pointerEvent = PointerEvent::Create();
433     PointerEvent::PointerItem item;
434     CHKPP(pointerEvent);
435 
436     int32_t action = HandleTouchAction(env, touchHandle, pointerEvent, item);
437     HandleTouchPropertyInt32(env, touchHandle, pointerEvent, item, action);
438     InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
439     CHKRP(napi_create_int32(env, 0, &result), CREATE_INT32);
440     return result;
441 }
442 
PermitInjection(napi_env env,napi_callback_info info)443 static napi_value PermitInjection(napi_env env, napi_callback_info info)
444 {
445     CALL_DEBUG_ENTER;
446     napi_value result = nullptr;
447     size_t argc = 1;
448     napi_value argv[1] = { 0 };
449     CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
450     if (argc < 1) {
451         MMI_HILOGE("Parameter number error");
452         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
453         return nullptr;
454     }
455 
456     bool bResult = false;
457     if (!UtilNapi::TypeOf(env, argv[0], napi_boolean)) {
458         THROWERR_API9(env, COMMON_PARAMETER_ERROR, "type", "boolean");
459         MMI_HILOGE("The first parameter is not boolean");
460         return nullptr;
461     }
462 
463     CHKRP(napi_get_value_bool(env, argv[0], &bResult), GET_VALUE_BOOL);
464     MMI_HILOGI("Parameter bResult:%{public}d ok", bResult);
465 
466     InputManager::GetInstance()->Authorize(bResult);
467     CHKRP(napi_create_int32(env, 0, &result), CREATE_INT32);
468     return result;
469 }
470 
471 EXTERN_C_START
MmiInit(napi_env env,napi_value exports)472 static napi_value MmiInit(napi_env env, napi_value exports)
473 {
474     napi_property_descriptor desc[] = {
475         DECLARE_NAPI_FUNCTION("injectEvent", InjectEvent),
476         DECLARE_NAPI_FUNCTION("injectKeyEvent", InjectKeyEvent),
477         DECLARE_NAPI_FUNCTION("injectMouseEvent", InjectMouseEvent),
478         DECLARE_NAPI_FUNCTION("injectTouchEvent", InjectTouchEvent),
479         DECLARE_NAPI_FUNCTION("permitInjection", PermitInjection),
480     };
481     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
482     return exports;
483 }
484 EXTERN_C_END
485 
486 static napi_module mmiModule = {
487     .nm_version = 1,
488     .nm_flags = 0,
489     .nm_filename = nullptr,
490     .nm_register_func = MmiInit,
491     .nm_modname = "multimodalInput.inputEventClient",
492     .nm_priv = ((void*)0),
493     .reserved = { 0 },
494 };
495 
RegisterModule(void)496 extern "C" __attribute__((constructor)) void RegisterModule(void)
497 {
498     napi_module_register(&mmiModule);
499 }
500 } // namespace MMI
501 } // namespace OHOS