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_register_module.h"
17
18 #include <algorithm>
19 #include <cinttypes>
20
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 size_t EVENT_NAME_LEN { 64 };
34 constexpr size_t PRE_KEYS_SIZE { 4 };
35 constexpr size_t INPUT_PARAMETER_MIDDLE { 2 };
36 constexpr size_t INPUT_PARAMETER_MAX { 3 };
37 constexpr int32_t OCCUPIED_BY_SYSTEM { -3 };
38 constexpr int32_t OCCUPIED_BY_OTHER { -4 };
39 } // namespace
40
41 static Callbacks callbacks = {};
42 static Callbacks hotkeyCallbacks = {};
43 std::mutex sCallBacksMutex;
44 static const std::vector<int32_t> pressKeyCodes = {
45 KeyEvent::KEYCODE_ALT_LEFT,
46 KeyEvent::KEYCODE_ALT_RIGHT,
47 KeyEvent::KEYCODE_SHIFT_LEFT,
48 KeyEvent::KEYCODE_SHIFT_RIGHT,
49 KeyEvent::KEYCODE_CTRL_LEFT,
50 KeyEvent::KEYCODE_CTRL_RIGHT
51 };
52 static const std::vector<int32_t> finalKeyCodes = {
53 KeyEvent::KEYCODE_ALT_LEFT,
54 KeyEvent::KEYCODE_ALT_RIGHT,
55 KeyEvent::KEYCODE_SHIFT_LEFT,
56 KeyEvent::KEYCODE_SHIFT_RIGHT,
57 KeyEvent::KEYCODE_CTRL_LEFT,
58 KeyEvent::KEYCODE_CTRL_RIGHT,
59 KeyEvent::KEYCODE_META_LEFT,
60 KeyEvent::KEYCODE_META_RIGHT
61 };
TypeOf(napi_env env, napi_value value, napi_valuetype type)62 bool JsCommon::TypeOf(napi_env env, napi_value value, napi_valuetype type)
63 {
64 napi_valuetype valueType = napi_undefined;
65 CHKRF(napi_typeof(env, value, &valueType), TYPEOF);
66 if (valueType != type) {
67 return false;
68 }
69 return true;
70 }
71
ThrowError(napi_env env, int32_t code)72 void JsCommon::ThrowError(napi_env env, int32_t code)
73 {
74 int32_t errorCode = std::abs(code);
75 if (errorCode == COMMON_USE_SYSAPI_ERROR) {
76 MMI_HILOGE("Non system applications use system API");
77 THROWERR_CUSTOM(env, COMMON_USE_SYSAPI_ERROR, "Non system applications use system API");
78 } else if (errorCode == COMMON_PERMISSION_CHECK_ERROR) {
79 MMI_HILOGE("Shield api need ohos.permission.INPUT_CONTROL_DISPATCHING");
80 THROWERR_API9(env, COMMON_PERMISSION_CHECK_ERROR, "shiled API", "ohos.permission.INPUT_CONTROL_DISPATCHING");
81 } else {
82 MMI_HILOGE("Dispatch control failed");
83 }
84 }
85
GetHotkeyEventInfo(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event, std::shared_ptr<KeyOption> keyOption)86 napi_value GetHotkeyEventInfo(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event,
87 std::shared_ptr<KeyOption> keyOption)
88 {
89 CALL_DEBUG_ENTER;
90 CHKPP(event);
91 CHKPP(keyOption);
92 size_t argc = 3;
93 napi_value argv[3] = { 0 };
94 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
95 napi_value receiveValue = nullptr;
96 CHKRP(napi_get_named_property(env, argv[1], "preKeys", &receiveValue), GET_NAMED_PROPERTY);
97 if (receiveValue == nullptr) {
98 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "PreKeys not found");
99 return nullptr;
100 }
101 std::set<int32_t> preKeys;
102 if (GetPreKeys(env, receiveValue, preKeys) == nullptr) {
103 MMI_HILOGE("Get preKeys failed");
104 return nullptr;
105 }
106 if (preKeys.size() > INPUT_PARAMETER_MIDDLE) {
107 MMI_HILOGE("PreKeys size invalid");
108 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "PreKeys size invalid");
109 return nullptr;
110 }
111 MMI_HILOGD("PreKeys size:%{public}zu", preKeys.size());
112 keyOption->SetPreKeys(preKeys);
113 std::string subKeyNames = "";
114 for (const auto &item : preKeys) {
115 auto it = std::find(pressKeyCodes.begin(), pressKeyCodes.end(), item);
116 if (it == pressKeyCodes.end()) {
117 MMI_HILOGE("PreKeys is not expect");
118 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "PreKeys size invalid");
119 return nullptr;
120 }
121 subKeyNames += std::to_string(item);
122 subKeyNames += ",";
123 MMI_HILOGD("PreKeys:%{private}d", item);
124 }
125 std::optional<int32_t> finalKeyOption = GetNamedPropertyInt32(env, argv[1], "finalKey");
126 if (!finalKeyOption) {
127 MMI_HILOGE("GetNamedPropertyInt32 failed");
128 return nullptr;
129 }
130 int32_t finalKey = finalKeyOption.value();
131 if (finalKey < 0) {
132 MMI_HILOGE("FinalKey:%{private}d is less 0, can not process", finalKey);
133 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "FinalKey must be greater than or equal to 0");
134 return nullptr;
135 }
136 auto it = std::find(finalKeyCodes.begin(), finalKeyCodes.end(), finalKey);
137 if (it != finalKeyCodes.end()) {
138 MMI_HILOGE("FinalKey is not expect");
139 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "FinalKey is not expect");
140 return nullptr;
141 }
142 subKeyNames += std::to_string(finalKey);
143 subKeyNames += ",";
144 keyOption->SetFinalKey(finalKey);
145 MMI_HILOGD("FinalKey:%{private}d", finalKey);
146
147 bool isFinalKeyDown = true;
148 subKeyNames += std::to_string(isFinalKeyDown);
149 subKeyNames += ",";
150 keyOption->SetFinalKeyDown(isFinalKeyDown);
151 MMI_HILOGD("IsFinalKeyDown:%{private}d,", (isFinalKeyDown == true ? 1 : 0));
152
153 int32_t finalKeyDownDuration = 0;
154 subKeyNames += std::to_string(finalKeyDownDuration);
155 subKeyNames += ",";
156 keyOption->SetFinalKeyDownDuration(finalKeyDownDuration);
157
158 bool isRepeat = true;
159 if (!GetNamedPropertyBool(env, argv[1], "isRepeat", isRepeat)) {
160 MMI_HILOGD("IsRepeat field is default");
161 }
162 subKeyNames += std::to_string(isRepeat);
163 keyOption->SetRepeat(isRepeat);
164 MMI_HILOGD("IsRepeat:%{public}s", (isRepeat ? "true" : "false"));
165 event->eventType = subKeyNames;
166
167 napi_value ret;
168 CHKRP(napi_create_int32(env, RET_OK, &ret), CREATE_INT32);
169 return ret;
170 }
171
GetEventInfoAPI9(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event, std::shared_ptr<KeyOption> keyOption)172 napi_value GetEventInfoAPI9(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event,
173 std::shared_ptr<KeyOption> keyOption)
174 {
175 CALL_DEBUG_ENTER;
176 CHKPP(event);
177 CHKPP(keyOption);
178 size_t argc = 3;
179 napi_value argv[3] = { 0 };
180 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
181 napi_value receiveValue = nullptr;
182 CHKRP(napi_get_named_property(env, argv[1], "preKeys", &receiveValue), GET_NAMED_PROPERTY);
183 if (receiveValue == nullptr) {
184 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "preKeys not found");
185 return nullptr;
186 }
187 std::set<int32_t> preKeys;
188 if (GetPreKeys(env, receiveValue, preKeys) == nullptr) {
189 MMI_HILOGE("Get preKeys failed");
190 return nullptr;
191 }
192 if (preKeys.size() > PRE_KEYS_SIZE) {
193 MMI_HILOGE("preKeys size invalid");
194 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "preKeys size invalid");
195 return nullptr;
196 }
197 MMI_HILOGD("PreKeys size:%{public}zu", preKeys.size());
198 keyOption->SetPreKeys(preKeys);
199 std::string subKeyNames = "";
200 for (const auto &item : preKeys) {
201 subKeyNames += std::to_string(item);
202 subKeyNames += ",";
203 MMI_HILOGD("preKeys:%{private}d", item);
204 }
205 std::optional<int32_t> tempFinalKey = GetNamedPropertyInt32(env, argv[1], "finalKey");
206 if (!tempFinalKey) {
207 MMI_HILOGE("GetNamedPropertyInt32 failed");
208 return nullptr;
209 }
210 int32_t finalKey = tempFinalKey.value();
211 if (finalKey < 0) {
212 MMI_HILOGE("finalKey:%{private}d is less 0, can not process", finalKey);
213 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "finalKey must be greater than or equal to 0");
214 return nullptr;
215 }
216 subKeyNames += std::to_string(finalKey);
217 subKeyNames += ",";
218 keyOption->SetFinalKey(finalKey);
219 MMI_HILOGD("FinalKey:%{private}d", finalKey);
220 bool isFinalKeyDown;
221 if (!GetNamedPropertyBool(env, argv[1], "isFinalKeyDown", isFinalKeyDown)) {
222 MMI_HILOGE("GetNamedPropertyBool failed");
223 return nullptr;
224 }
225 subKeyNames += std::to_string(isFinalKeyDown);
226 subKeyNames += ",";
227 keyOption->SetFinalKeyDown(isFinalKeyDown);
228 MMI_HILOGD("IsFinalKeyDown:%{private}d,map_key:%{private}s",
229 (isFinalKeyDown == true ? 1 : 0), subKeyNames.c_str());
230 std::optional<int32_t> tempKeyDownDuration = GetNamedPropertyInt32(env, argv[1], "finalKeyDownDuration");
231 if (!tempKeyDownDuration) {
232 MMI_HILOGE("GetNamedPropertyInt32 failed");
233 return nullptr;
234 }
235 int32_t finalKeyDownDuration = tempKeyDownDuration.value();
236 if (finalKeyDownDuration < 0) {
237 MMI_HILOGE("finalKeyDownDuration:%{public}d is less 0, can not process", finalKeyDownDuration);
238 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "finalKeyDownDuration must be greater than or equal to 0");
239 return nullptr;
240 }
241 subKeyNames += std::to_string(finalKeyDownDuration);
242 subKeyNames += ",";
243 keyOption->SetFinalKeyDownDuration(finalKeyDownDuration);
244 MMI_HILOGD("FinalKeyDownDuration:%{public}d", finalKeyDownDuration);
245 bool isRepeat = true;
246 if (!GetNamedPropertyBool(env, argv[1], "isRepeat", isRepeat)) {
247 MMI_HILOGD("IsRepeat field is default");
248 }
249 subKeyNames += std::to_string(isRepeat);
250 keyOption->SetRepeat(isRepeat);
251 MMI_HILOGD("IsRepeat:%{public}s", (isRepeat ? "true" : "false"));
252 event->eventType = subKeyNames;
253 napi_value ret;
254 CHKRP(napi_create_int32(env, RET_OK, &ret), CREATE_INT32);
255 return ret;
256 }
257
IsMatchKeyAction(bool isFinalKeydown, int32_t keyAction)258 static bool IsMatchKeyAction(bool isFinalKeydown, int32_t keyAction)
259 {
260 CALL_DEBUG_ENTER;
261 MMI_HILOGD("isFinalKeydown:%{public}d, keyAction:%{public}d", isFinalKeydown, keyAction);
262 if (isFinalKeydown && keyAction == KeyEvent::KEY_ACTION_DOWN) {
263 return true;
264 }
265 if (!isFinalKeydown && keyAction == KeyEvent::KEY_ACTION_UP) {
266 return true;
267 }
268 MMI_HILOGE("isFinalKeydown not matched with keyAction");
269 return false;
270 }
271
MatchCombinationKeys(sptr<KeyEventMonitorInfo> monitorInfo, std::shared_ptr<KeyEvent> keyEvent)272 static bool MatchCombinationKeys(sptr<KeyEventMonitorInfo> monitorInfo, std::shared_ptr<KeyEvent> keyEvent)
273 {
274 CALL_DEBUG_ENTER;
275 CHKPF(monitorInfo);
276 CHKPF(keyEvent);
277 auto keyOption = monitorInfo->keyOption;
278 CHKPF(keyOption);
279 std::vector<KeyEvent::KeyItem> items = keyEvent->GetKeyItems();
280 int32_t infoFinalKey = keyOption->GetFinalKey();
281 int32_t keyEventFinalKey = keyEvent->GetKeyCode();
282 bool isFinalKeydown = keyOption->IsFinalKeyDown();
283 MMI_HILOGD("InfoFinalKey:%{private}d,keyEventFinalKey:%{private}d", infoFinalKey, keyEventFinalKey);
284 if (infoFinalKey != keyEventFinalKey || items.size() > PRE_KEYS_SIZE ||
285 !IsMatchKeyAction(isFinalKeydown, keyEvent->GetKeyAction())) {
286 MMI_HILOGD("key Param invalid");
287 return false;
288 }
289 std::set<int32_t> infoPreKeys = keyOption->GetPreKeys();
290 int32_t infoSize = 0;
291 for (auto it = infoPreKeys.begin(); it != infoPreKeys.end(); ++it) {
292 if (*it >= 0) {
293 infoSize++;
294 }
295 }
296 int32_t count = 0;
297 for (const auto &item : items) {
298 if (item.GetKeyCode() == keyEventFinalKey) {
299 continue;
300 }
301 auto iter = find(infoPreKeys.begin(), infoPreKeys.end(), item.GetKeyCode());
302 if (iter == infoPreKeys.end()) {
303 MMI_HILOGW("No keyCode in preKeys");
304 return false;
305 }
306 count++;
307 }
308 MMI_HILOGD("kevEventSize:%{public}d, infoSize:%{public}d", count, infoSize);
309 std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem();
310 if (!keyItem) {
311 MMI_HILOGE("The keyItem is nullopt");
312 return false;
313 }
314 auto downTime = keyItem->GetDownTime();
315 auto upTime = keyEvent->GetActionTime();
316 auto curDurationTime = keyOption->GetFinalKeyDownDuration();
317 if (curDurationTime > 0 && (upTime - downTime >= (static_cast<int64_t>(curDurationTime) * 1000))) {
318 MMI_HILOGE("Skip, upTime - downTime >= duration");
319 return false;
320 }
321 return count == infoSize;
322 }
323
SubKeyEventCallback(std::shared_ptr<KeyEvent> keyEvent)324 static void SubKeyEventCallback(std::shared_ptr<KeyEvent> keyEvent)
325 {
326 CALL_DEBUG_ENTER;
327 CHKPV(keyEvent);
328 std::lock_guard guard(sCallBacksMutex);
329 auto iter = callbacks.begin();
330 while (iter != callbacks.end()) {
331 auto &list = iter->second;
332 ++iter;
333 MMI_HILOGD("list size:%{public}zu", list.size());
334 auto infoIter = list.begin();
335 while (infoIter != list.end()) {
336 auto monitorInfo = *infoIter;
337 if (MatchCombinationKeys(monitorInfo, keyEvent)) {
338 EmitAsyncCallbackWork(monitorInfo);
339 }
340 ++infoIter;
341 }
342 }
343 }
344
SubHotkeyEventCallback(std::shared_ptr<KeyEvent> keyEvent)345 static void SubHotkeyEventCallback(std::shared_ptr<KeyEvent> keyEvent)
346 {
347 CALL_DEBUG_ENTER;
348 CHKPV(keyEvent);
349 std::lock_guard guard(sCallBacksMutex);
350 auto iter = hotkeyCallbacks.begin();
351 while (iter != hotkeyCallbacks.end()) {
352 auto &list = iter->second;
353 ++iter;
354 MMI_HILOGD("Callback list size:%{public}zu", list.size());
355 auto infoIter = list.begin();
356 while (infoIter != list.end()) {
357 auto monitorInfo = *infoIter;
358 if (MatchCombinationKeys(monitorInfo, keyEvent)) {
359 EmitAsyncCallbackWork(monitorInfo);
360 }
361 ++infoIter;
362 }
363 }
364 }
365
SubscribeKey(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event, std::shared_ptr<KeyOption> keyOption)366 napi_value SubscribeKey(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event,
367 std::shared_ptr<KeyOption> keyOption)
368 {
369 CALL_DEBUG_ENTER;
370 CHKPP(event);
371 CHKPP(keyOption);
372 if (GetEventInfoAPI9(env, info, event, keyOption) == nullptr) {
373 MMI_HILOGE("GetEventInfoAPI9 failed");
374 return nullptr;
375 }
376 event->keyOption = keyOption;
377 int32_t preSubscribeId = GetPreSubscribeId(callbacks, event);
378 if (preSubscribeId < 0) {
379 MMI_HILOGD("EventType:%{private}s, eventName:%{public}s", event->eventType.c_str(), event->name.c_str());
380 int32_t subscribeId = -1;
381 subscribeId = InputManager::GetInstance()->SubscribeKeyEvent(keyOption, SubKeyEventCallback);
382 if (subscribeId < 0) {
383 MMI_HILOGE("SubscribeId invalid:%{public}d", subscribeId);
384 return nullptr;
385 }
386 MMI_HILOGD("SubscribeId:%{public}d", subscribeId);
387 event->subscribeId = subscribeId;
388 } else {
389 event->subscribeId = preSubscribeId;
390 }
391 if (AddEventCallback(env, callbacks, event) < 0) {
392 MMI_HILOGE("AddEventCallback failed");
393 return nullptr;
394 }
395 napi_value ret;
396 CHKRP(napi_create_int32(env, RET_OK, &ret), CREATE_INT32);
397 return ret;
398 }
399
SubscribeHotkey(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event, std::shared_ptr<KeyOption> keyOption)400 napi_value SubscribeHotkey(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event,
401 std::shared_ptr<KeyOption> keyOption)
402 {
403 CALL_DEBUG_ENTER;
404 CHKPP(event);
405 CHKPP(keyOption);
406 if (GetHotkeyEventInfo(env, info, event, keyOption) == nullptr) {
407 MMI_HILOGE("GetHotkeyEventInfo failed");
408 return nullptr;
409 }
410 event->keyOption = keyOption;
411 int32_t preSubscribeId = GetPreSubscribeId(hotkeyCallbacks, event);
412 if (preSubscribeId < 0) {
413 MMI_HILOGD("EventType:%{private}s, eventName:%{public}s", event->eventType.c_str(), event->name.c_str());
414 int32_t subscribeId = -1;
415 subscribeId = InputManager::GetInstance()->SubscribeHotkey(keyOption, SubHotkeyEventCallback);
416 if (subscribeId == OCCUPIED_BY_SYSTEM) {
417 MMI_HILOGE("SubscribeId invalid:%{public}d", subscribeId);
418 THROWERR_CUSTOM(env, INPUT_OCCUPIED_BY_SYSTEM, "Hotkey occupied by system");
419 return nullptr;
420 }
421 if (subscribeId == OCCUPIED_BY_OTHER) {
422 MMI_HILOGE("SubscribeId invalid:%{public}d", subscribeId);
423 THROWERR_CUSTOM(env, INPUT_OCCUPIED_BY_OTHER, "Hotkey occupied by other");
424 return nullptr;
425 }
426 MMI_HILOGD("SubscribeId:%{public}d", subscribeId);
427 event->subscribeId = subscribeId;
428 } else {
429 event->subscribeId = preSubscribeId;
430 }
431 if (AddEventCallback(env, hotkeyCallbacks, event) < 0) {
432 MMI_HILOGE("AddEventCallback failed");
433 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "AddEventCallback failed");
434 return nullptr;
435 }
436 napi_value ret;
437 CHKRP(napi_create_int32(env, RET_OK, &ret), CREATE_INT32);
438 return ret;
439 }
440
GetEventType(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event, std::string &keyType)441 bool GetEventType(napi_env env, napi_callback_info info, sptr<KeyEventMonitorInfo> event, std::string &keyType)
442 {
443 CALL_DEBUG_ENTER;
444 size_t argc = 3;
445 napi_value argv[3] = { 0 };
446 CHKRF(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
447 if (argc < INPUT_PARAMETER_MIDDLE) {
448 MMI_HILOGE("Parameter number error argc:%{public}zu", argc);
449 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
450 return false;
451 }
452 if (!UtilNapi::TypeOf(env, argv[0], napi_string)) {
453 MMI_HILOGE("The first parameter is not string");
454 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "type", "string");
455 return false;
456 }
457 if (!UtilNapi::TypeOf(env, argv[1], napi_object)) {
458 MMI_HILOGE("The second parameter is not napi_object");
459 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "keyOptions", "object");
460 return false;
461 }
462 if (argc == INPUT_PARAMETER_MAX) {
463 napi_valuetype valueType = napi_undefined;
464 CHKRF(napi_typeof(env, argv[INPUT_PARAMETER_MIDDLE], &valueType), TYPEOF);
465 if (valueType != napi_function) {
466 MMI_HILOGE("The third parameter is not napi_function");
467 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "callback", "function");
468 return false;
469 }
470 CHKRF(napi_create_reference(env, argv[INPUT_PARAMETER_MIDDLE], 1, &event->callback), REFERENCE_REF);
471 } else {
472 event->callback = nullptr;
473 }
474
475 char eventType[EVENT_NAME_LEN] = { 0 };
476 size_t typeLen = 0;
477 CHKRF(napi_get_value_string_utf8(env, argv[0], eventType, EVENT_NAME_LEN - 1, &typeLen), GET_VALUE_STRING_UTF8);
478 keyType = eventType;
479 if (keyType != SUBSCRIBE_TYPE && keyType != HOTKEY_SUBSCRIBE_TYPE) {
480 MMI_HILOGE("Type is not key or hotkey");
481 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Type must be key or hotkeyChange");
482 return false;
483 }
484 return true;
485 }
486
JsOn(napi_env env, napi_callback_info info)487 static napi_value JsOn(napi_env env, napi_callback_info info)
488 {
489 CALL_DEBUG_ENTER;
490 sptr<KeyEventMonitorInfo> event = new (std::nothrow) KeyEventMonitorInfo();
491 CHKPP(event);
492 event->env = env;
493 auto keyOption = std::make_shared<KeyOption>();
494 std::string keyType;
495 size_t argc = 3;
496 napi_value argv[3] = { 0 };
497 if (napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok) {
498 MMI_HILOGE("GET_CB_INFO failed");
499 return nullptr;
500 }
501 if (argc < INPUT_PARAMETER_MAX) {
502 MMI_HILOGE("Parameter number error argc:%{public}zu", argc);
503 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "parameter number error");
504 return nullptr;
505 }
506 if (!GetEventType(env, info, event, keyType)) {
507 MMI_HILOGE("GetEventType fail, type must be key or hotkeyChange");
508 return nullptr;
509 }
510 event->name = keyType;
511 if (keyType == HOTKEY_SUBSCRIBE_TYPE) {
512 if (SubscribeHotkey(env, info, event, keyOption) == nullptr) {
513 MMI_HILOGE("SubscribeHotkey failed");
514 return nullptr;
515 }
516 } else {
517 if (SubscribeKey(env, info, event, keyOption) == nullptr) {
518 MMI_HILOGE("SubscribeKey failed");
519 return nullptr;
520 }
521 }
522 return nullptr;
523 }
524
JsOff(napi_env env, napi_callback_info info)525 static napi_value JsOff(napi_env env, napi_callback_info info)
526 {
527 CALL_DEBUG_ENTER;
528 sptr<KeyEventMonitorInfo> event = new (std::nothrow) KeyEventMonitorInfo();
529 CHKPP(event);
530 event->env = env;
531 auto keyOption = std::make_shared<KeyOption>();
532 std::string keyType;
533 if (!GetEventType(env, info, event, keyType)) {
534 MMI_HILOGE("GetEventType fail, type must be key or hotkeyChange");
535 return nullptr;
536 }
537 event->name = keyType;
538 int32_t subscribeId = -1;
539 if (keyType == HOTKEY_SUBSCRIBE_TYPE) {
540 if (GetHotkeyEventInfo(env, info, event, keyOption) == nullptr) {
541 MMI_HILOGE("GetHotkeyEventInfo failed");
542 return nullptr;
543 }
544 if (DelEventCallback(env, hotkeyCallbacks, event, subscribeId) < 0) {
545 MMI_HILOGE("DelEventCallback failed");
546 return nullptr;
547 }
548 MMI_HILOGI("Unsubscribe hot key(%{public}d)", subscribeId);
549 InputManager::GetInstance()->UnsubscribeHotkey(subscribeId);
550 } else {
551 if (GetEventInfoAPI9(env, info, event, keyOption) == nullptr) {
552 MMI_HILOGE("GetEventInfoAPI9 failed");
553 return nullptr;
554 }
555 if (DelEventCallback(env, callbacks, event, subscribeId) < 0) {
556 MMI_HILOGE("DelEventCallback failed");
557 return nullptr;
558 }
559 MMI_HILOGI("Unsubscribe key event(%{public}d)", subscribeId);
560 InputManager::GetInstance()->UnsubscribeKeyEvent(subscribeId);
561 }
562 return nullptr;
563 }
564
SetShieldStatus(napi_env env, napi_callback_info info)565 static napi_value SetShieldStatus(napi_env env, napi_callback_info info)
566 {
567 CALL_DEBUG_ENTER;
568 size_t argc = 2;
569 napi_value argv[2] = { 0 };
570 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
571 if (argc < INPUT_PARAMETER_MIDDLE) {
572 MMI_HILOGE("At least two parameters is required");
573 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "shieldMode", "number");
574 return nullptr;
575 }
576 if (!JsCommon::TypeOf(env, argv[0], napi_number)) {
577 MMI_HILOGE("shieldMode parameter type is invalid");
578 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "shieldMode", "number");
579 return nullptr;
580 }
581 int32_t shieldMode = 0;
582 CHKRP(napi_get_value_int32(env, argv[0], &shieldMode), GET_VALUE_INT32);
583 if (shieldMode < FACTORY_MODE || shieldMode > OOBE_MODE) {
584 MMI_HILOGE("Undefined shield mode");
585 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Shield mode does not exist");
586 return nullptr;
587 }
588
589 if (!JsCommon::TypeOf(env, argv[1], napi_boolean)) {
590 MMI_HILOGE("isShield parameter type is invalid");
591 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "isShield", "boolean");
592 return nullptr;
593 }
594 bool isShield = true;
595 CHKRP(napi_get_value_bool(env, argv[1], &isShield), GET_VALUE_BOOL);
596
597 int32_t errCode = InputManager::GetInstance()->SetShieldStatus(shieldMode, isShield);
598 JsCommon::ThrowError(env, errCode);
599 napi_value result = nullptr;
600 if (napi_get_undefined(env, &result) != napi_ok) {
601 MMI_HILOGE("Get undefined result is failed");
602 return nullptr;
603 }
604 return result;
605 }
606
GetShieldStatus(napi_env env, napi_callback_info info)607 static napi_value GetShieldStatus(napi_env env, napi_callback_info info)
608 {
609 CALL_DEBUG_ENTER;
610 size_t argc = 1;
611 napi_value argv[1] = { 0 };
612 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
613 if (argc < 1) {
614 MMI_HILOGE("At least 1 parameter is required");
615 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "shieldMode", "number");
616 return nullptr;
617 }
618 if (!JsCommon::TypeOf(env, argv[0], napi_number)) {
619 MMI_HILOGE("shieldMode parameter type is invalid");
620 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "shieldMode", "number");
621 return nullptr;
622 }
623 int32_t shieldMode = 0;
624 CHKRP(napi_get_value_int32(env, argv[0], &shieldMode), GET_VALUE_INT32);
625 if (shieldMode < FACTORY_MODE || shieldMode > OOBE_MODE) {
626 MMI_HILOGE("Undefined shield mode");
627 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Shield mode does not exist");
628 return nullptr;
629 }
630 bool isShield { false };
631 auto errCode = InputManager::GetInstance()->GetShieldStatus(shieldMode, isShield);
632 JsCommon::ThrowError(env, errCode);
633 napi_value result = nullptr;
634 NAPI_CALL(env, napi_get_boolean(env, isShield, &result));
635 return result;
636 }
637
GetAllSystemHotkeys(napi_env env, napi_callback_info info)638 static napi_value GetAllSystemHotkeys(napi_env env, napi_callback_info info)
639 {
640 CALL_DEBUG_ENTER;
641 return GetSystemHotkey(env);
642 }
643
EnumConstructor(napi_env env, napi_callback_info info)644 static napi_value EnumConstructor(napi_env env, napi_callback_info info)
645 {
646 CALL_DEBUG_ENTER;
647 size_t argc = 0;
648 napi_value args[1] = { 0 };
649 napi_value ret = nullptr;
650 void *data = nullptr;
651 CHKRP(napi_get_cb_info(env, info, &argc, args, &ret, &data), GET_CB_INFO);
652 return ret;
653 }
654
CreateShieldMode(napi_env env, napi_value exports)655 static napi_value CreateShieldMode(napi_env env, napi_value exports)
656 {
657 CALL_DEBUG_ENTER;
658 napi_value factory_mode = nullptr;
659 CHKRP(napi_create_int32(env, SHIELD_MODE::FACTORY_MODE, &factory_mode), CREATE_INT32);
660 napi_value oobe_mode = nullptr;
661 CHKRP(napi_create_int32(env, SHIELD_MODE::OOBE_MODE, &oobe_mode), CREATE_INT32);
662
663 napi_property_descriptor desc[] = {
664 DECLARE_NAPI_STATIC_PROPERTY("FACTORY_MODE", factory_mode),
665 DECLARE_NAPI_STATIC_PROPERTY("OOBE_MODE", oobe_mode),
666 };
667 napi_value result = nullptr;
668 CHKRP(napi_define_class(env, "ShieldMode", NAPI_AUTO_LENGTH, EnumConstructor, nullptr,
669 sizeof(desc) / sizeof(*desc), desc, &result), DEFINE_CLASS);
670 CHKRP(napi_set_named_property(env, exports, "ShieldMode", result), SET_NAMED_PROPERTY);
671 return exports;
672 }
673
~KeyEventMonitorInfo()674 KeyEventMonitorInfo::~KeyEventMonitorInfo()
675 {}
676
677 EXTERN_C_START
MmiInit(napi_env env, napi_value exports)678 static napi_value MmiInit(napi_env env, napi_value exports)
679 {
680 CALL_DEBUG_ENTER;
681 napi_property_descriptor desc[] = {
682 DECLARE_NAPI_FUNCTION("on", JsOn),
683 DECLARE_NAPI_FUNCTION("off", JsOff),
684 DECLARE_NAPI_FUNCTION("setShieldStatus", SetShieldStatus),
685 DECLARE_NAPI_FUNCTION("getShieldStatus", GetShieldStatus),
686 DECLARE_NAPI_FUNCTION("getAllSystemHotkeys", GetAllSystemHotkeys)
687 };
688 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
689 if (CreateShieldMode(env, exports) == nullptr) {
690 THROWERR(env, "Failed to create shield mode");
691 return nullptr;
692 }
693 return exports;
694 }
695 EXTERN_C_END
696
697 static napi_module mmiModule = {
698 .nm_version = 1,
699 .nm_flags = 0,
700 .nm_filename = nullptr,
701 .nm_register_func = MmiInit,
702 .nm_modname = "multimodalInput.inputConsumer",
703 .nm_priv = ((void*)0),
704 .reserved = { 0 },
705 };
706
RegisterModule(void)707 extern "C" __attribute__((constructor)) void RegisterModule(void)
708 {
709 napi_module_register(&mmiModule);
710 }
711 } // namespace MMI
712 } // namespace OHOS
713