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