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 "js_input_monitor_module.h"
17
18 #include <unordered_set>
19
20 #include "define_multimodal.h"
21 #include "permission_helper.h"
22 #include "js_input_monitor_manager.h"
23 #include "napi_constants.h"
24 #include "util_napi_error.h"
25
26 #undef MMI_LOG_TAG
27 #define MMI_LOG_TAG "JsInputMonitorModule"
28
29 namespace OHOS {
30 namespace MMI {
31 namespace {
32 const std::unordered_set<std::string> ACTION_TYPE = {
33 "touch", "mouse", "pinch", "threeFingersSwipe", "fourFingersSwipe", "rotate", "threeFingersTap", "joystick",
34 "fingerprint", "swipeInward", TOUCH_SWIPE_GESTURE, TOUCH_PINCH_GESTURE, "keyPressed"
35 };
36 constexpr int32_t TWO_PARAMETERS { 2 };
37 constexpr int32_t THREE_PARAMETERS { 3 };
38 constexpr int32_t RECT_LIST_SIZE { 2 };
39 constexpr int32_t KEY_LIST_SIZE { 5 };
40 } // namespace
41
JsOnApi9(napi_env env,napi_callback_info info)42 static napi_value JsOnApi9(napi_env env, napi_callback_info info)
43 {
44 CALL_DEBUG_ENTER;
45 size_t argc = 2;
46 napi_value argv[2] = { 0 };
47
48 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
49 napi_valuetype valueType = napi_undefined;
50 CHKRP(napi_typeof(env, argv[0], &valueType), TYPEOF);
51 if (valueType != napi_string) {
52 MMI_HILOGE("First Parameter type error");
53 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "EventType", "string");
54 return nullptr;
55 }
56 char typeName[MAX_STRING_LEN] = { 0 };
57 size_t len = 0;
58 CHKRP(napi_get_value_string_utf8(env, argv[0], typeName, MAX_STRING_LEN - 1, &len), GET_VALUE_STRING_UTF8);
59 if (ACTION_TYPE.find(typeName) == ACTION_TYPE.end()) {
60 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "EventType is invalid");
61 return nullptr;
62 }
63 CHKRP(napi_typeof(env, argv[1], &valueType), TYPEOF);
64 if (valueType != napi_function) {
65 MMI_HILOGE("Second Parameter type error");
66 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Second Parameter type error");
67 return nullptr;
68 }
69 if (!JS_INPUT_MONITOR_MGR.AddEnv(env, info)) {
70 MMI_HILOGE("AddEnv failed");
71 return nullptr;
72 }
73 JS_INPUT_MONITOR_MGR.AddMonitor(env, typeName, argv[1]);
74 MMI_HILOGI("Add Monitor success, type:%{public}s", typeName);
75 return nullptr;
76 }
77
AddMouseMonitor(napi_env env,napi_callback_info info,napi_value napiRect,napi_value napiCallback)78 static void AddMouseMonitor(napi_env env, napi_callback_info info, napi_value napiRect, napi_value napiCallback)
79 {
80 std::vector<Rect> hotRectAreaList;
81 uint32_t rectArrayLength = 0;
82 CHKRV(napi_get_array_length(env, napiRect, &rectArrayLength), GET_ARRAY_LENGTH);
83 if (rectArrayLength <= 0 || rectArrayLength > RECT_LIST_SIZE) {
84 MMI_HILOGE("Hot Rect Area Parameter error");
85 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Hot Rect Area Parameter error");
86 return;
87 }
88 hotRectAreaList = JS_INPUT_MONITOR_MGR.GetHotRectAreaList(env, napiRect, rectArrayLength);
89 if (hotRectAreaList.size() != rectArrayLength) {
90 MMI_HILOGE("Hot Rect Area Parameter error");
91 return;
92 }
93 napi_valuetype valueType = napi_undefined;
94 CHKRV(napi_typeof(env, napiCallback, &valueType), TYPEOF);
95 if (valueType != napi_function) {
96 MMI_HILOGE("Third Parameter type error");
97 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Third Parameter type error");
98 return;
99 }
100 if (!JS_INPUT_MONITOR_MGR.AddEnv(env, info)) {
101 MMI_HILOGE("AddEnv failed");
102 return;
103 }
104 JS_INPUT_MONITOR_MGR.AddMonitor(env, "mouse", hotRectAreaList, rectArrayLength, napiCallback);
105 return;
106 }
107
AddPreMonitor(napi_env env,napi_callback_info info,napi_value napiKeys,napi_value napiCallback)108 static void AddPreMonitor(napi_env env, napi_callback_info info, napi_value napiKeys, napi_value napiCallback)
109 {
110 std::vector<int32_t> keys;
111 uint32_t keysLength = 0;
112 CHKRV(napi_get_array_length(env, napiKeys, &keysLength), GET_ARRAY_LENGTH);
113 if (keysLength <= 0 || keysLength > KEY_LIST_SIZE) {
114 MMI_HILOGE("keys Parameter error");
115 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "keys Parameter error");
116 return;
117 }
118 if (!JS_INPUT_MONITOR_MGR.GetKeysArray(env, napiKeys, keysLength, keys)) {
119 THROWERR_CUSTOM(env, PRE_KEY_NOT_SUPPORTED, "Event listening not supported for the key");
120 return;
121 }
122 if (keys.size() != keysLength) {
123 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "keys Parameter error");
124 MMI_HILOGE("keys Parameter error");
125 return;
126 }
127 napi_valuetype valueType = napi_undefined;
128 CHKRV(napi_typeof(env, napiCallback, &valueType), TYPEOF);
129 if (valueType != napi_function) {
130 MMI_HILOGE("Third Parameter type error");
131 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Third Parameter type error");
132 return;
133 }
134 if (!JS_INPUT_MONITOR_MGR.AddEnv(env, info)) {
135 MMI_HILOGE("AddEnv failed");
136 return;
137 }
138 JS_INPUT_MONITOR_MGR.AddPreMonitor(env, "keyPressed", napiCallback, keys);
139 }
140
AddMonitor(napi_env env,napi_callback_info info)141 static napi_value AddMonitor(napi_env env, napi_callback_info info)
142 {
143 CALL_DEBUG_ENTER;
144 size_t argc = 3;
145 napi_value argv[3] = { 0 };
146 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
147 napi_valuetype valueType = napi_undefined;
148 CHKRP(napi_typeof(env, argv[0], &valueType), TYPEOF);
149 if (valueType != napi_string) {
150 MMI_HILOGE("First Parameter type error");
151 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "EventType", "string");
152 return nullptr;
153 }
154 char typeName[MAX_STRING_LEN] = { 0 };
155 size_t len = 0;
156 CHKRP(napi_get_value_string_utf8(env, argv[0], typeName, MAX_STRING_LEN - 1, &len), GET_VALUE_STRING_UTF8);
157 if (ACTION_TYPE.find(typeName) == ACTION_TYPE.end()) {
158 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "EventType is invalid");
159 return nullptr;
160 }
161 if (strcmp(typeName, "mouse") == 0) {
162 AddMouseMonitor(env, info, argv[1], argv[TWO_PARAMETERS]);
163 } else if (strcmp(typeName, "keyPressed") == 0) {
164 AddPreMonitor(env, info, argv[1], argv[TWO_PARAMETERS]);
165 } else {
166 CHKRP(napi_typeof(env, argv[1], &valueType), TYPEOF);
167 if (valueType != napi_number) {
168 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Second Parameter type error");
169 return nullptr;
170 }
171 int32_t fingers = 0;
172 CHKRP(napi_get_value_int32(env, argv[1], &fingers), GET_VALUE_INT32);
173 if (fingers < 0) {
174 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "fingers is invalid");
175 return nullptr;
176 }
177
178 CHKRP(napi_typeof(env, argv[TWO_PARAMETERS], &valueType), TYPEOF);
179 if (valueType != napi_function) {
180 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Third Parameter type error");
181 return nullptr;
182 }
183 if (!JS_INPUT_MONITOR_MGR.AddEnv(env, info)) {
184 MMI_HILOGE("AddEnv failed");
185 return nullptr;
186 }
187 JS_INPUT_MONITOR_MGR.AddMonitor(env, typeName, argv[TWO_PARAMETERS], fingers);
188 }
189 MMI_HILOGI("Add Monitor success, type:%{public}s", typeName);
190 return nullptr;
191 }
192
JsOn(napi_env env,napi_callback_info info)193 static napi_value JsOn(napi_env env, napi_callback_info info)
194 {
195 CALL_DEBUG_ENTER;
196 if (!PER_HELPER->VerifySystemApp()) {
197 THROWERR_API9(env, COMMON_USE_SYSAPI_ERROR, "", "");
198 return nullptr;
199 }
200 size_t argc = 3;
201 napi_value argv[3] = { 0 };
202 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
203 if (argc < TWO_PARAMETERS) {
204 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
205 return nullptr;
206 }
207 if (argc == TWO_PARAMETERS) {
208 JsOnApi9(env, info);
209 } else if (argc == THREE_PARAMETERS) {
210 AddMonitor(env, info);
211 }
212 return nullptr;
213 }
214
JsOffApi9(napi_env env,napi_callback_info info)215 static napi_value JsOffApi9(napi_env env, napi_callback_info info)
216 {
217 CALL_DEBUG_ENTER;
218 size_t argc = 2;
219 napi_value argv[2] = { 0 };
220 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
221 napi_valuetype valueType = napi_undefined;
222 CHKRP(napi_typeof(env, argv[0], &valueType), TYPEOF);
223 if (valueType != napi_string) {
224 MMI_HILOGE("First Parameter type error");
225 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "EventType", "string");
226 return nullptr;
227 }
228 char typeName[MAX_STRING_LEN] = { 0 };
229 size_t len = 0;
230 CHKRP(napi_get_value_string_utf8(env, argv[0], typeName, MAX_STRING_LEN - 1, &len), GET_VALUE_STRING_UTF8);
231 if (ACTION_TYPE.find(typeName) == ACTION_TYPE.end()) {
232 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "EventType is invalid");
233 return nullptr;
234 }
235 if (argc < TWO_PARAMETERS) {
236 JS_INPUT_MONITOR_MGR.RemoveMonitor(env, typeName);
237 MMI_HILOGD("Remove all monitor");
238 return nullptr;
239 }
240
241 CHKRP(napi_typeof(env, argv[1], &valueType), TYPEOF);
242 if (valueType != napi_function) {
243 MMI_HILOGE("Second Parameter type error");
244 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Second Parameter type error");
245 return nullptr;
246 }
247
248 if (!JS_INPUT_MONITOR_MGR.AddEnv(env, info)) {
249 JS_INPUT_MONITOR_MGR.RemoveMonitor(env, typeName);
250 return nullptr;
251 }
252
253 JS_INPUT_MONITOR_MGR.RemoveMonitor(env, typeName, argv[1]);
254 return nullptr;
255 }
256
RemoveMonitor(napi_env env,napi_callback_info info)257 static napi_value RemoveMonitor(napi_env env, napi_callback_info info)
258 {
259 CALL_DEBUG_ENTER;
260 size_t argc = 3;
261 napi_value argv[3] = { 0 };
262 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
263 napi_valuetype valueType = napi_undefined;
264 CHKRP(napi_typeof(env, argv[0], &valueType), TYPEOF);
265 if (valueType != napi_string) {
266 MMI_HILOGE("First Parameter type error");
267 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "EventType", "string");
268 return nullptr;
269 }
270 char typeName[MAX_STRING_LEN] = { 0 };
271 size_t len = 0;
272 CHKRP(napi_get_value_string_utf8(env, argv[0], typeName, MAX_STRING_LEN - 1, &len), GET_VALUE_STRING_UTF8);
273 if (ACTION_TYPE.find(typeName) == ACTION_TYPE.end()) {
274 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "EventType is invalid");
275 return nullptr;
276 }
277 CHKRP(napi_typeof(env, argv[1], &valueType), TYPEOF);
278 if (valueType != napi_number) {
279 MMI_HILOGE("Second Parameter type error");
280 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Second Parameter type error");
281 return nullptr;
282 }
283 int32_t fingers = 0;
284 CHKRP(napi_get_value_int32(env, argv[1], &fingers), GET_VALUE_INT32);
285 if (fingers < 0) {
286 MMI_HILOGE("Invalid fingers");
287 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "fingers is invalid");
288 return nullptr;
289 }
290 if (argc < THREE_PARAMETERS) {
291 JS_INPUT_MONITOR_MGR.RemoveMonitor(env, typeName, fingers);
292 MMI_HILOGD("Remove all monitor");
293 return nullptr;
294 }
295 CHKRP(napi_typeof(env, argv[TWO_PARAMETERS], &valueType), TYPEOF);
296 if (valueType != napi_function) {
297 MMI_HILOGE("Second Parameter type error");
298 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Second Parameter type error");
299 return nullptr;
300 }
301 if (!JS_INPUT_MONITOR_MGR.AddEnv(env, info)) {
302 JS_INPUT_MONITOR_MGR.RemoveMonitor(env, typeName, fingers);
303 return nullptr;
304 }
305
306 JS_INPUT_MONITOR_MGR.RemoveMonitor(env, typeName, argv[TWO_PARAMETERS], fingers);
307 return nullptr;
308 }
309
JsOff(napi_env env,napi_callback_info info)310 static napi_value JsOff(napi_env env, napi_callback_info info)
311 {
312 CALL_DEBUG_ENTER;
313 if (!PER_HELPER->VerifySystemApp()) {
314 THROWERR_API9(env, COMMON_USE_SYSAPI_ERROR, "", "");
315 return nullptr;
316 }
317 size_t argc = 2;
318 napi_value argv[2] = { 0 };
319
320 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
321 if (argc < 1) {
322 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
323 return nullptr;
324 }
325 napi_valuetype valueType = napi_undefined;
326 napi_typeof(env, argv[1], &valueType);
327
328 if (argc == 1 || napi_function == valueType) {
329 JsOffApi9(env, info);
330 } else {
331 RemoveMonitor(env, info);
332 }
333 return nullptr;
334 }
335
336 EXTERN_C_START
MmiInputMonitorInit(napi_env env,napi_value exports)337 static napi_value MmiInputMonitorInit(napi_env env, napi_value exports)
338 {
339 CALL_DEBUG_ENTER;
340 napi_property_descriptor desc[] = {
341 DECLARE_NAPI_FUNCTION("on", JsOn),
342 DECLARE_NAPI_FUNCTION("off", JsOff),
343 };
344 CHKRP(napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc), DEFINE_PROPERTIES);
345 return exports;
346 }
347 EXTERN_C_END
348
349 static napi_module mmiInputMonitorModule = {
350 .nm_version = 1,
351 .nm_flags = 0,
352 .nm_filename = nullptr,
353 .nm_register_func = MmiInputMonitorInit,
354 .nm_modname = "multimodalInput.inputMonitor",
355 .nm_priv = ((void*)0),
356 .reserved = { 0 },
357 };
358
RegisterModule(void)359 extern "C" __attribute__((constructor)) void RegisterModule(void)
360 {
361 napi_module_register(&mmiInputMonitorModule);
362 }
363 } // namespace MMI
364 } // namespace OHOS
365