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