• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_event_target.h"
17 
18 #include "bytrace_adapter.h"
19 #include "napi_constants.h"
20 #include "util_napi_error.h"
21 
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "JsEventTarget"
24 
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr int32_t INPUT_PARAMETER_MIDDLE { 2 };
29 
30 std::mutex mutex_;
31 const std::string ADD_EVENT = "add";
32 const std::string REMOVE_EVENT = "remove";
33 
34 struct DeviceItem {
35     int32_t deviceId;
36     void *item;
37 };
38 
39 } // namespace
40 
JsEventTarget()41 JsEventTarget::JsEventTarget()
42 {
43     CALL_DEBUG_ENTER;
44     std::lock_guard<std::mutex> lock(mutex_);
45     auto ret = devListener_.insert({ CHANGED_TYPE, std::vector<std::unique_ptr<JsUtil::CallbackInfo>>() });
46     CK(ret.second, VAL_NOT_EXP);
47 }
48 
EmitAddedDeviceEvent(sptr<JsUtil::ReportData> reportData)49 void JsEventTarget::EmitAddedDeviceEvent(sptr<JsUtil::ReportData> reportData)
50 {
51     CALL_DEBUG_ENTER;
52     std::lock_guard<std::mutex> guard(mutex_);
53     reportData->DecStrongRef(nullptr);
54     auto addEvent = devListener_.find(CHANGED_TYPE);
55     if (addEvent == devListener_.end()) {
56         MMI_HILOGE("Find change event failed");
57         return;
58     }
59     for (const auto &item : addEvent->second) {
60         CHKPC(item->env);
61         if (item->ref != reportData->ref) {
62             continue;
63         }
64         napi_handle_scope scope = nullptr;
65         napi_open_handle_scope(item->env, &scope);
66         CHKPV(scope);
67         napi_value eventType = nullptr;
68         CHKRV_SCOPE_DEL(item->env, napi_create_string_utf8(item->env, ADD_EVENT.c_str(), NAPI_AUTO_LENGTH, &eventType),
69             CREATE_STRING_UTF8, scope);
70         napi_value object = nullptr;
71         CHKRV_SCOPE_DEL(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
72         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
73             scope);
74         napi_value handler = nullptr;
75         CHKRV_SCOPE_DEL(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE,
76             scope);
77         napi_value deviceId = nullptr;
78         CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope);
79         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
80             scope);
81         napi_value ret = nullptr;
82         CHKRV_SCOPE_DEL(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
83             scope);
84         napi_close_handle_scope(item->env, scope);
85         BytraceAdapter::StartDevListener(ADD_EVENT, reportData->deviceId);
86         MMI_HILOGI("Report device change task, event type:%{public}s, deviceid:%{public}d",
87             ADD_EVENT.c_str(), reportData->deviceId);
88         BytraceAdapter::StopDevListener();
89     }
90 }
91 
EmitRemoveDeviceEvent(sptr<JsUtil::ReportData> reportData)92 void JsEventTarget::EmitRemoveDeviceEvent(sptr<JsUtil::ReportData> reportData)
93 {
94     CALL_DEBUG_ENTER;
95     std::lock_guard<std::mutex> guard(mutex_);
96     reportData->DecStrongRef(nullptr);
97     auto removeEvent = devListener_.find(CHANGED_TYPE);
98     if (removeEvent == devListener_.end()) {
99         MMI_HILOGE("Find change event failed");
100         return;
101     }
102     for (const auto &item : removeEvent->second) {
103         CHKPC(item->env);
104         if (item->ref != reportData->ref) {
105             continue;
106         }
107         napi_handle_scope scope = nullptr;
108         napi_open_handle_scope(item->env, &scope);
109         CHKPV(scope);
110         napi_value eventType = nullptr;
111         CHKRV_SCOPE_DEL(item->env, napi_create_string_utf8(item->env, REMOVE_EVENT.c_str(), NAPI_AUTO_LENGTH,
112             &eventType), CREATE_STRING_UTF8, scope);
113         napi_value deviceId = nullptr;
114         CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope);
115         napi_value object = nullptr;
116         CHKRV_SCOPE_DEL(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
117         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
118             scope);
119         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
120             scope);
121         napi_value handler = nullptr;
122         CHKRV_SCOPE_DEL(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE,
123             scope);
124         napi_value ret = nullptr;
125         CHKRV_SCOPE_DEL(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
126             scope);
127         napi_close_handle_scope(item->env, scope);
128         BytraceAdapter::StartDevListener(REMOVE_EVENT, reportData->deviceId);
129         MMI_HILOGI("Report device change task, event type:%{public}s, deviceid:%{public}d",
130             REMOVE_EVENT.c_str(), reportData->deviceId);
131         BytraceAdapter::StopDevListener();
132     }
133 }
134 
OnDeviceAdded(int32_t deviceId,const std::string & type)135 void JsEventTarget::OnDeviceAdded(int32_t deviceId, const std::string &type)
136 {
137     CALL_DEBUG_ENTER;
138     std::lock_guard<std::mutex> guard(mutex_);
139     auto changeEvent = devListener_.find(CHANGED_TYPE);
140     if (changeEvent == devListener_.end()) {
141         MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
142         return;
143     }
144 
145     for (auto &item : changeEvent->second) {
146         CHKPC(item);
147         CHKPC(item->env);
148         sptr<JsUtil::ReportData> reportData = new (std::nothrow) JsUtil::ReportData;
149         if (reportData == nullptr) {
150             MMI_HILOGE("Memory allocation failed");
151             return;
152         }
153         reportData->deviceId = deviceId;
154         reportData->ref = item->ref;
155         reportData->IncStrongRef(nullptr);
156         auto task = [reportData, this] () { EmitAddedDeviceEvent(reportData); };
157         int32_t ret = napi_send_event(item->env, task, napi_eprio_vip);
158         if (ret != 0) {
159             MMI_HILOGE("napi_send_event failed");
160             return;
161         }
162     }
163 }
164 
OnDeviceRemoved(int32_t deviceId,const std::string & type)165 void JsEventTarget::OnDeviceRemoved(int32_t deviceId, const std::string &type)
166 {
167     CALL_DEBUG_ENTER;
168     std::lock_guard<std::mutex> guard(mutex_);
169     auto changeEvent = devListener_.find(CHANGED_TYPE);
170     if (changeEvent == devListener_.end()) {
171         MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
172         return;
173     }
174     for (auto &item : changeEvent->second) {
175         CHKPC(item);
176         CHKPC(item->env);
177         sptr<JsUtil::ReportData> reportData = new (std::nothrow) JsUtil::ReportData;
178         if (reportData == nullptr) {
179             MMI_HILOGE("Memory allocation failed");
180             return;
181         }
182         reportData->deviceId = deviceId;
183         reportData->ref = item->ref;
184         reportData->IncStrongRef(nullptr);
185         auto task = [reportData, this] () { EmitRemoveDeviceEvent(reportData); };
186         int32_t ret = napi_send_event(item->env, task, napi_eprio_vip);
187         if (ret != 0) {
188             MMI_HILOGE("napi_send_event failed");
189             return;
190         }
191     }
192 }
193 
CallIdsAsyncWork(uv_work_t * work,int32_t status)194 void JsEventTarget::CallIdsAsyncWork(uv_work_t *work, int32_t status)
195 {
196     CALL_DEBUG_ENTER;
197     CHKPV(work);
198     if (work->data == nullptr) {
199         JsUtil::DeletePtr<uv_work_t *>(work);
200         MMI_HILOGE("Check data is nullptr");
201         return;
202     }
203     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
204     JsUtil::DeletePtr<uv_work_t *>(work);
205     cb->DecStrongRef(nullptr);
206     CHKPV(cb->env);
207     napi_handle_scope scope = nullptr;
208     napi_open_handle_scope(cb->env, &scope);
209     CHKPV(scope);
210     napi_value arr[2];
211     CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &arr[0]), GET_UNDEFINED, scope);
212     CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr[1]), CREATE_ARRAY, scope);
213     uint32_t index = 0;
214     napi_value value = nullptr;
215     for (const auto &item : cb->data.ids) {
216         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
217         CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr[1], index, value), SET_ELEMENT, scope);
218         ++index;
219     }
220 
221     napi_value handler = nullptr;
222     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
223     napi_value result = nullptr;
224     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, arr, &result),
225         CALL_FUNCTION, scope);
226     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
227     napi_close_handle_scope(cb->env, scope);
228 }
229 
CallIdsPromiseWork(uv_work_t * work,int32_t status)230 void JsEventTarget::CallIdsPromiseWork(uv_work_t *work, int32_t status)
231 {
232     CALL_DEBUG_ENTER;
233     CHKPV(work);
234     if (work->data == nullptr) {
235         JsUtil::DeletePtr<uv_work_t *>(work);
236         MMI_HILOGE("Check data is nullptr");
237         return;
238     }
239     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
240     JsUtil::DeletePtr<uv_work_t *>(work);
241     cb->DecStrongRef(nullptr);
242     CHKPV(cb->env);
243     napi_handle_scope scope = nullptr;
244     napi_open_handle_scope(cb->env, &scope);
245     CHKPV(scope);
246     napi_value arr = nullptr;
247     CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr), CREATE_ARRAY, scope);
248     uint32_t index = 0;
249     napi_value value = nullptr;
250     for (const auto &item : cb->data.ids) {
251         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
252         CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr, index, value), SET_ELEMENT, scope);
253         ++index;
254     }
255     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, arr), RESOLVE_DEFERRED, scope);
256     napi_close_handle_scope(cb->env, scope);
257 }
258 
EmitJsIds(sptr<JsUtil::CallbackInfo> cb,std::vector<int32_t> & ids)259 void JsEventTarget::EmitJsIds(sptr<JsUtil::CallbackInfo> cb, std::vector<int32_t> &ids)
260 {
261     CALL_DEBUG_ENTER;
262     CHKPV(cb);
263     CHKPV(cb->env);
264     cb->data.ids = ids;
265     cb->errCode = RET_OK;
266     EmitJsIdsInternal(cb);
267 }
268 
EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)269 void JsEventTarget::EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)
270 {
271     uv_loop_s *loop = nullptr;
272     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
273     uv_work_t *work = new (std::nothrow) uv_work_t;
274     CHKPV(work);
275     cb->IncStrongRef(nullptr);
276     work->data = cb.GetRefPtr();
277     int32_t ret = -1;
278     if (cb->isApi9) {
279         if (cb->ref == nullptr) {
280             ret = uv_queue_work_with_qos(
281                 loop, work,
282                 [](uv_work_t *work) {
283                     MMI_HILOGD("uv_queue_work callback function is called");
284                     CallJsIdsTask(work);
285                 }, CallDevListPromiseWork, uv_qos_user_initiated);
286         } else {
287             ret = uv_queue_work_with_qos(
288                 loop, work,
289                 [](uv_work_t *work) {
290                     MMI_HILOGD("uv_queue_work callback function is called");
291                     CallJsIdsTask(work);
292                 }, CallDevListAsyncWork, uv_qos_user_initiated);
293         }
294     } else {
295         if (cb->ref == nullptr) {
296             ret = uv_queue_work_with_qos(
297                 loop, work,
298                 [](uv_work_t *work) {
299                     MMI_HILOGD("uv_queue_work callback function is called");
300                     CallJsIdsTask(work);
301                 }, CallIdsPromiseWork, uv_qos_user_initiated);
302         } else {
303             ret = uv_queue_work_with_qos(
304                 loop, work,
305                 [](uv_work_t *work) {
306                     MMI_HILOGD("uv_queue_work callback function is called");
307                     CallJsIdsTask(work);
308                 }, CallIdsAsyncWork, uv_qos_user_initiated);
309         }
310     }
311     if (ret != 0) {
312         MMI_HILOGE("uv_queue_work_with_qos failed");
313         JsUtil::DeletePtr<uv_work_t *>(work);
314     }
315 }
316 
CallDevAsyncWork(uv_work_t * work,int32_t status)317 void JsEventTarget::CallDevAsyncWork(uv_work_t *work, int32_t status)
318 {
319     CALL_DEBUG_ENTER;
320     CHKPV(work);
321     if (work->data == nullptr) {
322         JsUtil::DeletePtr<uv_work_t *>(work);
323         MMI_HILOGE("Check data is nullptr");
324         return;
325     }
326     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
327     JsUtil::DeletePtr<uv_work_t *>(work);
328     cb->DecStrongRef(nullptr);
329     CHKPV(cb->env);
330     napi_handle_scope scope = nullptr;
331     napi_open_handle_scope(cb->env, &scope);
332     CHKPV(scope);
333     napi_value object[2];
334     CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &object[0]), GET_UNDEFINED, scope);
335     object[1] = JsUtil::GetDeviceInfo(cb);
336     napi_value handler = nullptr;
337     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
338     napi_value result = nullptr;
339     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, object, &result),
340         CALL_FUNCTION, scope);
341     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
342     napi_close_handle_scope(cb->env, scope);
343 }
344 
CallDevPromiseWork(uv_work_t * work,int32_t status)345 void JsEventTarget::CallDevPromiseWork(uv_work_t *work, int32_t status)
346 {
347     CALL_DEBUG_ENTER;
348     CHKPV(work);
349     if (work->data == nullptr) {
350         JsUtil::DeletePtr<uv_work_t *>(work);
351         MMI_HILOGE("Check data is nullptr");
352         return;
353     }
354     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
355     JsUtil::DeletePtr<uv_work_t *>(work);
356     cb->DecStrongRef(nullptr);
357     CHKPV(cb->env);
358     napi_handle_scope scope = nullptr;
359     napi_open_handle_scope(cb->env, &scope);
360     CHKPV(scope);
361     napi_value object = JsUtil::GetDeviceInfo(cb);
362     if (object == nullptr) {
363         MMI_HILOGE("Check object is nullptr");
364         napi_close_handle_scope(cb->env, scope);
365         return;
366     }
367     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
368     napi_close_handle_scope(cb->env, scope);
369 }
370 
EmitJsDev(sptr<JsUtil::CallbackInfo> cb,int32_t deviceid)371 void JsEventTarget::EmitJsDev(sptr<JsUtil::CallbackInfo> cb, int32_t deviceid)
372 {
373     CALL_DEBUG_ENTER;
374     CHKPV(cb);
375     CHKPV(cb->env);
376     cb->data.deviceId = deviceid;
377     cb->errCode = RET_OK;
378     EmitJsDevInternal(cb);
379 }
380 
EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)381 void JsEventTarget::EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)
382 {
383     uv_loop_s *loop = nullptr;
384     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
385     uv_work_t *work = new (std::nothrow) uv_work_t;
386     CHKPV(work);
387     cb->IncStrongRef(nullptr);
388     work->data = cb.GetRefPtr();
389     int32_t ret = -1;
390     if (cb->isApi9) {
391         if (cb->ref == nullptr) {
392             ret = uv_queue_work_with_qos(
393                 loop, work,
394                 [](uv_work_t *work) {
395                     MMI_HILOGD("uv_queue_work callback function is called");
396                     CallJsDevTask(work);
397                 }, CallDevInfoPromiseWork, uv_qos_user_initiated);
398         } else {
399             ret = uv_queue_work_with_qos(
400                 loop, work,
401                 [](uv_work_t *work) {
402                     MMI_HILOGD("uv_queue_work callback function is called");
403                     CallJsDevTask(work);
404                 }, CallDevInfoAsyncWork, uv_qos_user_initiated);
405         }
406     } else {
407         if (cb->ref == nullptr) {
408             ret = uv_queue_work_with_qos(
409                 loop, work,
410                 [](uv_work_t *work) {
411                     MMI_HILOGD("uv_queue_work callback function is called");
412                     CallJsDevTask(work);
413                 }, CallDevPromiseWork, uv_qos_user_initiated);
414         } else {
415             ret = uv_queue_work_with_qos(
416                 loop, work,
417                 [](uv_work_t *work) {
418                     MMI_HILOGD("uv_queue_work callback function is called");
419                     CallJsDevTask(work);
420                 }, CallDevAsyncWork, uv_qos_user_initiated);
421         }
422     }
423     if (ret != 0) {
424         MMI_HILOGE("uv_queue_work_with_qos failed");
425         JsUtil::DeletePtr<uv_work_t *>(work);
426     }
427 }
428 
CallKeystrokeAbilityPromise(uv_work_t * work,int32_t status)429 void JsEventTarget::CallKeystrokeAbilityPromise(uv_work_t *work, int32_t status)
430 {
431     CALL_DEBUG_ENTER;
432     CHKPV(work);
433     if (work->data == nullptr) {
434         JsUtil::DeletePtr<uv_work_t *>(work);
435         MMI_HILOGE("Check data is nullptr");
436         return;
437     }
438     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
439     JsUtil::DeletePtr<uv_work_t *>(work);
440     cb->DecStrongRef(nullptr);
441     CHKPV(cb->env);
442     napi_handle_scope scope = nullptr;
443     napi_open_handle_scope(cb->env, &scope);
444     CHKPV(scope);
445     napi_value callResult = nullptr;
446     if (cb->errCode != RET_OK) {
447         if (cb->errCode == RET_ERR) {
448             napi_close_handle_scope(cb->env, scope);
449             MMI_HILOGE("Other errors");
450             return;
451         }
452         NapiError codeMsg;
453         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
454             napi_close_handle_scope(cb->env, scope);
455             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
456             return;
457         }
458         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
459         if (callResult == nullptr) {
460             MMI_HILOGE("The callResult is nullptr");
461             napi_close_handle_scope(cb->env, scope);
462             return;
463         }
464         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
465     } else {
466         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult), CREATE_ARRAY, scope);
467         for (size_t i = 0; i < cb->data.keystrokeAbility.size(); ++i) {
468             napi_value ret = nullptr;
469             napi_value isSupport = nullptr;
470             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keystrokeAbility[i] ? 1 : 0, &ret), CREATE_INT32,
471                 scope);
472             CHKRV_SCOPE(cb->env, napi_coerce_to_bool(cb->env, ret, &isSupport), COERCE_TO_BOOL, scope);
473             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult, static_cast<uint32_t>(i), isSupport),
474                 SET_ELEMENT, scope);
475         }
476         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
477     }
478     napi_close_handle_scope(cb->env, scope);
479 }
480 
CallKeystrokeAbilityAsync(uv_work_t * work,int32_t status)481 void JsEventTarget::CallKeystrokeAbilityAsync(uv_work_t *work, int32_t status)
482 {
483     CALL_DEBUG_ENTER;
484     CHKPV(work);
485     if (work->data == nullptr) {
486         JsUtil::DeletePtr<uv_work_t *>(work);
487         MMI_HILOGE("Check data is nullptr");
488         return;
489     }
490     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
491     JsUtil::DeletePtr<uv_work_t *>(work);
492     cb->DecStrongRef(nullptr);
493     CHKPV(cb->env);
494     napi_handle_scope scope = nullptr;
495     napi_open_handle_scope(cb->env, &scope);
496     CHKPV(scope);
497     napi_value callResult[2] = { 0 };
498     if (cb->errCode != RET_OK) {
499         if (cb->errCode == RET_ERR) {
500             napi_close_handle_scope(cb->env, scope);
501             MMI_HILOGE("Other errors");
502             return;
503         }
504         NapiError codeMsg;
505         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
506             napi_close_handle_scope(cb->env, scope);
507             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
508             return;
509         }
510         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
511         if (callResult[0] == nullptr) {
512             MMI_HILOGE("The callResult[0] is nullptr");
513             napi_close_handle_scope(cb->env, scope);
514             return;
515         }
516         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
517     } else {
518         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult[1]), CREATE_ARRAY, scope);
519         for (size_t i = 0; i < cb->data.keystrokeAbility.size(); ++i) {
520             napi_value ret = nullptr;
521             napi_value isSupport = nullptr;
522             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keystrokeAbility[i] ? 1 : 0, &ret), CREATE_INT32,
523                 scope);
524             CHKRV_SCOPE(cb->env, napi_coerce_to_bool(cb->env, ret, &isSupport), COERCE_TO_BOOL, scope);
525             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult[1], static_cast<uint32_t>(i), isSupport),
526                 SET_ELEMENT, scope);
527         }
528         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
529     }
530     napi_value handler = nullptr;
531     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
532     napi_value result = nullptr;
533     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
534         CALL_FUNCTION, scope);
535     napi_close_handle_scope(cb->env, scope);
536 }
537 
EmitSupportKeys(sptr<JsUtil::CallbackInfo> cb,std::vector<int32_t> & keycode,int32_t id)538 void JsEventTarget::EmitSupportKeys(sptr<JsUtil::CallbackInfo> cb, std::vector<int32_t> &keycode, int32_t id)
539 {
540     CALL_DEBUG_ENTER;
541     CHKPV(cb);
542     CHKPV(cb->env);
543     cb->data.ids = keycode;
544     cb->data.deviceId = id;
545     cb->errCode = RET_OK;
546     uv_loop_s *loop = nullptr;
547     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
548     uv_work_t *work = new (std::nothrow) uv_work_t;
549     CHKPV(work);
550     cb->IncStrongRef(nullptr);
551     work->data = cb.GetRefPtr();
552     int32_t ret = -1;
553     if (cb->ref == nullptr) {
554         ret = uv_queue_work_with_qos(
555             loop, work,
556             [](uv_work_t *work) {
557                 MMI_HILOGD("uv_queue_work callback function is called");
558                 CallSupportKeysTask(work);
559             },
560             CallKeystrokeAbilityPromise, uv_qos_user_initiated);
561     } else {
562         ret = uv_queue_work_with_qos(
563             loop, work,
564             [](uv_work_t *work) {
565                 MMI_HILOGD("uv_queue_work callback function is called");
566                 CallSupportKeysTask(work);
567             },
568             CallKeystrokeAbilityAsync, uv_qos_user_initiated);
569     }
570     if (ret != 0) {
571         MMI_HILOGE("uv_queue_work_with_qos failed");
572         JsUtil::DeletePtr<uv_work_t *>(work);
573     }
574 }
575 
EmitJsKeyboardType(sptr<JsUtil::CallbackInfo> cb,int32_t deviceid)576 void JsEventTarget::EmitJsKeyboardType(sptr<JsUtil::CallbackInfo> cb, int32_t deviceid)
577 {
578     CALL_DEBUG_ENTER;
579     CHKPV(cb);
580     CHKPV(cb->env);
581     cb->data.deviceId = deviceid;
582     cb->errCode = RET_OK;
583     uv_loop_s *loop = nullptr;
584     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
585 
586     uv_work_t *work = new (std::nothrow) uv_work_t;
587     CHKPV(work);
588     cb->IncStrongRef(nullptr);
589     work->data = cb.GetRefPtr();
590     int32_t ret = -1;
591     if (cb->ref == nullptr) {
592         ret = uv_queue_work_with_qos(
593             loop, work,
594             [](uv_work_t *work) {
595                 MMI_HILOGD("uv_queue_work callback function is called");
596                 CallGetKeyboardTypeTask(work);
597             },
598             CallKeyboardTypePromise, uv_qos_user_initiated);
599     } else {
600         ret = uv_queue_work_with_qos(
601             loop, work,
602             [](uv_work_t *work) {
603                 MMI_HILOGD("uv_queue_work callback function is called");
604                 CallGetKeyboardTypeTask(work);
605             },
606             CallKeyboardTypeAsync, uv_qos_user_initiated);
607     }
608     if (ret != 0) {
609         MMI_HILOGE("uv_queue_work_with_qos failed");
610         JsUtil::DeletePtr<uv_work_t *>(work);
611     }
612 }
613 
CallKeyboardTypeAsync(uv_work_t * work,int32_t status)614 void JsEventTarget::CallKeyboardTypeAsync(uv_work_t *work, int32_t status)
615 {
616     CALL_DEBUG_ENTER;
617     CHKPV(work);
618     if (work->data == nullptr) {
619         JsUtil::DeletePtr<uv_work_t *>(work);
620         MMI_HILOGE("Check data is nullptr");
621         return;
622     }
623     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
624     JsUtil::DeletePtr<uv_work_t *>(work);
625     cb->DecStrongRef(nullptr);
626     CHKPV(cb->env);
627 
628     napi_handle_scope scope = nullptr;
629     napi_open_handle_scope(cb->env, &scope);
630     CHKPV(scope);
631 
632     napi_value callResult[2] = { 0 };
633     if (cb->errCode != RET_OK) {
634         if (cb->errCode == RET_ERR) {
635             napi_close_handle_scope(cb->env, scope);
636             MMI_HILOGE("Other errors");
637             return;
638         }
639         NapiError codeMsg;
640         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
641             napi_close_handle_scope(cb->env, scope);
642             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
643             return;
644         }
645         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
646         if (callResult[0] == nullptr) {
647             MMI_HILOGE("The callResult[0] is nullptr");
648             napi_close_handle_scope(cb->env, scope);
649             return;
650         }
651         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
652     } else {
653         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keyboardType, &callResult[1]), CREATE_INT32, scope);
654         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
655     }
656     napi_value handler = nullptr;
657     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
658     napi_value result = nullptr;
659     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
660         CALL_FUNCTION, scope);
661     napi_close_handle_scope(cb->env, scope);
662 }
663 
CallKeyboardTypePromise(uv_work_t * work,int32_t status)664 void JsEventTarget::CallKeyboardTypePromise(uv_work_t *work, int32_t status)
665 {
666     CALL_DEBUG_ENTER;
667     CHKPV(work);
668     if (work->data == nullptr) {
669         JsUtil::DeletePtr<uv_work_t *>(work);
670         MMI_HILOGE("Check data is nullptr");
671         return;
672     }
673     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
674     JsUtil::DeletePtr<uv_work_t *>(work);
675     cb->DecStrongRef(nullptr);
676     CHKPV(cb->env);
677 
678     napi_handle_scope scope = nullptr;
679     napi_open_handle_scope(cb->env, &scope);
680     CHKPV(scope);
681 
682     napi_value callResult;
683     if (cb->errCode != RET_OK) {
684         if (cb->errCode == RET_ERR) {
685             napi_close_handle_scope(cb->env, scope);
686             MMI_HILOGE("Other errors");
687             return;
688         }
689         NapiError codeMsg;
690         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
691             napi_close_handle_scope(cb->env, scope);
692             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
693             return;
694         }
695         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
696         if (callResult == nullptr) {
697             MMI_HILOGE("The callResult is nullptr");
698             napi_close_handle_scope(cb->env, scope);
699             return;
700         }
701         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
702     } else {
703         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keyboardType, &callResult), CREATE_INT32, scope);
704         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
705     }
706     napi_close_handle_scope(cb->env, scope);
707 }
708 
CallDevListAsyncWork(uv_work_t * work,int32_t status)709 void JsEventTarget::CallDevListAsyncWork(uv_work_t *work, int32_t status)
710 {
711     CALL_DEBUG_ENTER;
712     CHKPV(work);
713     if (work->data == nullptr) {
714         JsUtil::DeletePtr<uv_work_t *>(work);
715         MMI_HILOGE("Check data is nullptr");
716         return;
717     }
718     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
719     JsUtil::DeletePtr<uv_work_t *>(work);
720     cb->DecStrongRef(nullptr);
721     CHKPV(cb->env);
722     napi_handle_scope scope = nullptr;
723     napi_open_handle_scope(cb->env, &scope);
724     CHKPV(scope);
725 
726     napi_value callResult[2] = { 0 };
727     if (cb->errCode != RET_OK) {
728         if (cb->errCode == RET_ERR) {
729             napi_close_handle_scope(cb->env, scope);
730             MMI_HILOGE("Other errors");
731             return;
732         }
733         NapiError codeMsg;
734         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
735             napi_close_handle_scope(cb->env, scope);
736             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
737             return;
738         }
739         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
740         CHKNRV_SCOPE(cb->env, callResult[0], "callResult[0]", scope);
741         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
742     } else {
743         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult[1]), CREATE_ARRAY, scope);
744         uint32_t index = 0;
745         napi_value value = nullptr;
746         for (const auto &item : cb->data.ids) {
747             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
748             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult[1], index, value), SET_ELEMENT, scope);
749             ++index;
750         }
751         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
752     }
753     napi_value handler = nullptr;
754     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
755     napi_value result = nullptr;
756     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
757         CALL_FUNCTION, scope);
758     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
759     napi_close_handle_scope(cb->env, scope);
760 }
761 
CallDevListPromiseWork(uv_work_t * work,int32_t status)762 void JsEventTarget::CallDevListPromiseWork(uv_work_t *work, int32_t status)
763 {
764     CALL_DEBUG_ENTER;
765     CHKPV(work);
766     if (work->data == nullptr) {
767         JsUtil::DeletePtr<uv_work_t *>(work);
768         MMI_HILOGE("Check data is nullptr");
769         return;
770     }
771     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
772     JsUtil::DeletePtr<uv_work_t *>(work);
773     cb->DecStrongRef(nullptr);
774     CHKPV(cb->env);
775     napi_handle_scope scope = nullptr;
776     napi_open_handle_scope(cb->env, &scope);
777     CHKPV(scope);
778     napi_value callResult = nullptr;
779     if (cb->errCode != RET_OK) {
780         if (cb->errCode == RET_ERR) {
781             napi_close_handle_scope(cb->env, scope);
782             MMI_HILOGE("Other errors");
783             return;
784         }
785         NapiError codeMsg;
786         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
787             napi_close_handle_scope(cb->env, scope);
788             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
789             return;
790         }
791         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
792         if (callResult == nullptr) {
793             MMI_HILOGE("The callResult is nullptr");
794             napi_close_handle_scope(cb->env, scope);
795             return;
796         }
797         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
798     } else {
799         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult), CREATE_ARRAY, scope);
800         uint32_t index = 0;
801         napi_value value = nullptr;
802         for (const auto &item : cb->data.ids) {
803             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
804             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult, index, value), SET_ELEMENT, scope);
805             ++index;
806         }
807         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
808     }
809     napi_close_handle_scope(cb->env, scope);
810 }
811 
CallDevInfoPromiseWork(uv_work_t * work,int32_t status)812 void JsEventTarget::CallDevInfoPromiseWork(uv_work_t *work, int32_t status)
813 {
814     CALL_DEBUG_ENTER;
815     CHKPV(work);
816     if (work->data == nullptr) {
817         JsUtil::DeletePtr<uv_work_t *>(work);
818         MMI_HILOGE("Check data is nullptr");
819         return;
820     }
821     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
822     JsUtil::DeletePtr<uv_work_t *>(work);
823     cb->DecStrongRef(nullptr);
824     CHKPV(cb->env);
825     napi_handle_scope scope = nullptr;
826     napi_open_handle_scope(cb->env, &scope);
827     CHKPV(scope);
828     napi_value callResult = nullptr;
829     if (cb->errCode != RET_OK) {
830         if (cb->errCode == RET_ERR) {
831             napi_close_handle_scope(cb->env, scope);
832             MMI_HILOGE("Other errors");
833             return;
834         }
835         NapiError codeMsg;
836         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
837             napi_close_handle_scope(cb->env, scope);
838             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
839             return;
840         }
841         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
842         if (callResult == nullptr) {
843             MMI_HILOGE("The callResult is nullptr");
844             napi_close_handle_scope(cb->env, scope);
845             return;
846         }
847         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
848     } else {
849         callResult = JsUtil::GetDeviceInfo(cb);
850         if (callResult == nullptr) {
851             MMI_HILOGE("Check callResult is nullptr");
852             napi_close_handle_scope(cb->env, scope);
853             return;
854         }
855         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
856     }
857     napi_close_handle_scope(cb->env, scope);
858 }
859 
CallDevInfoAsyncWork(uv_work_t * work,int32_t status)860 void JsEventTarget::CallDevInfoAsyncWork(uv_work_t *work, int32_t status)
861 {
862     CALL_DEBUG_ENTER;
863     CHKPV(work);
864     if (work->data == nullptr) {
865         JsUtil::DeletePtr<uv_work_t *>(work);
866         MMI_HILOGE("Check data is nullptr");
867         return;
868     }
869     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
870     JsUtil::DeletePtr<uv_work_t *>(work);
871     cb->DecStrongRef(nullptr);
872     CHKPV(cb->env);
873     napi_handle_scope scope = nullptr;
874     napi_open_handle_scope(cb->env, &scope);
875     CHKPV(scope);
876     napi_value callResult[2] = { 0 };
877     if (cb->errCode != RET_OK) {
878         if (cb->errCode == RET_ERR) {
879             napi_close_handle_scope(cb->env, scope);
880             MMI_HILOGE("Other errors");
881             return;
882         }
883         NapiError codeMsg;
884         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
885             napi_close_handle_scope(cb->env, scope);
886             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
887             return;
888         }
889         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
890         if (callResult[0] == nullptr) {
891             MMI_HILOGE("The callResult[0] is nullptr");
892             napi_close_handle_scope(cb->env, scope);
893             return;
894         }
895         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
896     } else {
897         callResult[1] = JsUtil::GetDeviceInfo(cb);
898         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
899     }
900     napi_value handler = nullptr;
901     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
902     napi_value result = nullptr;
903     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
904         CALL_FUNCTION, scope);
905     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
906     napi_close_handle_scope(cb->env, scope);
907 }
908 
EmitJsSetKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb,int32_t delay)909 void JsEventTarget::EmitJsSetKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb, int32_t delay)
910 {
911     CALL_DEBUG_ENTER;
912     CHKPV(cb);
913     CHKPV(cb->env);
914     cb->data.keyboardRepeatDelay = delay;
915     cb->errCode = RET_OK;
916     uv_loop_s *loop = nullptr;
917     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
918 
919     uv_work_t *work = new (std::nothrow) uv_work_t;
920     CHKPV(work);
921     cb->IncStrongRef(nullptr);
922     work->data = cb.GetRefPtr();
923     int32_t ret = -1;
924     if (cb->ref == nullptr) {
925         ret = uv_queue_work_with_qos(
926             loop, work,
927             [](uv_work_t *work) {
928                 MMI_HILOGD("uv_queue_work callback function is called");
929                 CallKeyboardRepeatDelayTask(work, "set");
930             },
931             CallKeyboardRepeatDelayPromise, uv_qos_user_initiated);
932     } else {
933         ret = uv_queue_work_with_qos(
934             loop, work,
935             [](uv_work_t *work) {
936                 MMI_HILOGD("uv_queue_work callback function is called");
937                 CallKeyboardRepeatDelayTask(work, "set");
938             },
939             CallKeyboardRepeatDelayAsync, uv_qos_user_initiated);
940     }
941     if (ret != 0) {
942         MMI_HILOGE("uv_queue_work_with_qos failed");
943         JsUtil::DeletePtr<uv_work_t *>(work);
944     }
945 }
946 
EmitJsKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb,int32_t delay)947 void JsEventTarget::EmitJsKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb, int32_t delay)
948 {
949     CALL_DEBUG_ENTER;
950     CHKPV(cb);
951     CHKPV(cb->env);
952     cb->data.keyboardRepeatDelay = delay;
953     cb->errCode = RET_OK;
954     uv_loop_s *loop = nullptr;
955     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
956 
957     uv_work_t *work = new (std::nothrow) uv_work_t;
958     CHKPV(work);
959     cb->IncStrongRef(nullptr);
960     work->data = cb.GetRefPtr();
961     int32_t ret = -1;
962     if (cb->ref == nullptr) {
963         ret = uv_queue_work_with_qos(
964             loop, work,
965             [](uv_work_t *work) {
966                 MMI_HILOGD("uv_queue_work callback function is called");
967                 CallKeyboardRepeatDelayTask(work, "get");
968             },
969             CallKeyboardRepeatDelayPromise, uv_qos_user_initiated);
970     } else {
971         ret = uv_queue_work_with_qos(
972             loop, work,
973             [](uv_work_t *work) {
974                 MMI_HILOGD("uv_queue_work callback function is called");
975                 CallKeyboardRepeatDelayTask(work, "get");
976             },
977             CallKeyboardRepeatDelayAsync, uv_qos_user_initiated);
978     }
979     if (ret != 0) {
980         MMI_HILOGE("uv_queue_work_with_qos failed");
981         JsUtil::DeletePtr<uv_work_t *>(work);
982     }
983 }
984 
CallKeyboardRepeatDelayAsync(uv_work_t * work,int32_t status)985 void JsEventTarget::CallKeyboardRepeatDelayAsync(uv_work_t *work, int32_t status)
986 {
987     CALL_DEBUG_ENTER;
988     CHKPV(work);
989     if (work->data == nullptr) {
990         JsUtil::DeletePtr<uv_work_t *>(work);
991         MMI_HILOGE("Check data is nullptr");
992         return;
993     }
994     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
995     JsUtil::DeletePtr<uv_work_t *>(work);
996     cb->DecStrongRef(nullptr);
997     CHKPV(cb->env);
998 
999     napi_handle_scope scope = nullptr;
1000     napi_open_handle_scope(cb->env, &scope);
1001     CHKPV(scope);
1002 
1003     napi_value callResult[2] = {0};
1004     if (cb->errCode != RET_OK) {
1005         if (cb->errCode == RET_ERR) {
1006             napi_close_handle_scope(cb->env, scope);
1007             MMI_HILOGE("Other errors");
1008             return;
1009         }
1010         NapiError codeMsg;
1011         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1012             napi_close_handle_scope(cb->env, scope);
1013             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1014             return;
1015         }
1016         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1017         if (callResult[0] == nullptr) {
1018             MMI_HILOGE("callResult[0] is nullptr");
1019             napi_close_handle_scope(cb->env, scope);
1020             return;
1021         }
1022         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
1023     } else {
1024         CHKRV_SCOPE(
1025             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatDelay, &callResult[1]), CREATE_INT32, scope);
1026         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
1027     }
1028     napi_value handler = nullptr;
1029     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
1030     napi_value result = nullptr;
1031     CHKRV_SCOPE(cb->env,
1032         napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
1033         CALL_FUNCTION,
1034         scope);
1035     napi_close_handle_scope(cb->env, scope);
1036 }
1037 
CallKeyboardRepeatDelayPromise(uv_work_t * work,int32_t status)1038 void JsEventTarget::CallKeyboardRepeatDelayPromise(uv_work_t *work, int32_t status)
1039 {
1040     CALL_DEBUG_ENTER;
1041     CHKPV(work);
1042     if (work->data == nullptr) {
1043         JsUtil::DeletePtr<uv_work_t *>(work);
1044         MMI_HILOGE("Check data is nullptr");
1045         return;
1046     }
1047     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1048     JsUtil::DeletePtr<uv_work_t *>(work);
1049     cb->DecStrongRef(nullptr);
1050     CHKPV(cb->env);
1051 
1052     napi_handle_scope scope = nullptr;
1053     napi_open_handle_scope(cb->env, &scope);
1054     CHKPV(scope);
1055 
1056     napi_value callResult;
1057     if (cb->errCode != RET_OK) {
1058         if (cb->errCode == RET_ERR) {
1059             napi_close_handle_scope(cb->env, scope);
1060             MMI_HILOGE("Other errors");
1061             return;
1062         }
1063         NapiError codeMsg;
1064         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1065             napi_close_handle_scope(cb->env, scope);
1066             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1067             return;
1068         }
1069         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1070         if (callResult == nullptr) {
1071             MMI_HILOGE("The callResult is nullptr");
1072             napi_close_handle_scope(cb->env, scope);
1073             return;
1074         }
1075         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1076     } else {
1077         CHKRV_SCOPE(
1078             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatDelay, &callResult), CREATE_INT32, scope);
1079         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1080     }
1081     napi_close_handle_scope(cb->env, scope);
1082 }
1083 
EmitJsSetKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb,int32_t rate)1084 void JsEventTarget::EmitJsSetKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb, int32_t rate)
1085 {
1086     CALL_DEBUG_ENTER;
1087     CHKPV(cb);
1088     CHKPV(cb->env);
1089     cb->data.keyboardRepeatRate = rate;
1090     cb->errCode = RET_OK;
1091     uv_loop_s *loop = nullptr;
1092     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1093 
1094     uv_work_t *work = new (std::nothrow) uv_work_t;
1095     CHKPV(work);
1096     cb->IncStrongRef(nullptr);
1097     work->data = cb.GetRefPtr();
1098     int32_t ret = -1;
1099     if (cb->ref == nullptr) {
1100         ret = uv_queue_work_with_qos(
1101             loop, work,
1102             [](uv_work_t *work) {
1103                 MMI_HILOGD("uv_queue_work callback function is called");
1104                 CallKeyboardRepeatRateTask(work, "set");
1105             },
1106             CallKeyboardRepeatRatePromise, uv_qos_user_initiated);
1107     } else {
1108         ret = uv_queue_work_with_qos(
1109             loop, work,
1110             [](uv_work_t *work) {
1111                 MMI_HILOGD("uv_queue_work callback function is called");
1112                 CallKeyboardRepeatRateTask(work, "set");
1113             },
1114             CallKeyboardRepeatRateAsync, uv_qos_user_initiated);
1115     }
1116     if (ret != 0) {
1117         MMI_HILOGE("uv_queue_work_with_qos failed");
1118         JsUtil::DeletePtr<uv_work_t *>(work);
1119     }
1120 }
1121 
EmitJsKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb,int32_t rate)1122 void JsEventTarget::EmitJsKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb, int32_t rate)
1123 {
1124     CALL_DEBUG_ENTER;
1125     CHKPV(cb);
1126     CHKPV(cb->env);
1127     cb->data.keyboardRepeatRate = rate;
1128     cb->errCode = RET_OK;
1129     uv_loop_s *loop = nullptr;
1130     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1131 
1132     uv_work_t *work = new (std::nothrow) uv_work_t;
1133     CHKPV(work);
1134     cb->IncStrongRef(nullptr);
1135     work->data = cb.GetRefPtr();
1136     int32_t ret = -1;
1137     if (cb->ref == nullptr) {
1138         ret = uv_queue_work_with_qos(
1139             loop, work,
1140             [](uv_work_t *work) {
1141                 MMI_HILOGD("uv_queue_work callback function is called");
1142                 CallKeyboardRepeatRateTask(work, "get");
1143             },
1144             CallKeyboardRepeatRatePromise, uv_qos_user_initiated);
1145     } else {
1146         ret = uv_queue_work_with_qos(
1147             loop, work,
1148             [](uv_work_t *work) {
1149                 MMI_HILOGD("uv_queue_work callback function is called");
1150                 CallKeyboardRepeatRateTask(work, "get");
1151             },
1152             CallKeyboardRepeatRateAsync, uv_qos_user_initiated);
1153     }
1154     if (ret != 0) {
1155         MMI_HILOGE("uv_queue_work_with_qos failed");
1156         JsUtil::DeletePtr<uv_work_t *>(work);
1157     }
1158 }
1159 
CallKeyboardRepeatRateAsync(uv_work_t * work,int32_t status)1160 void JsEventTarget::CallKeyboardRepeatRateAsync(uv_work_t *work, int32_t status)
1161 {
1162     CALL_DEBUG_ENTER;
1163     CHKPV(work);
1164     if (work->data == nullptr) {
1165         JsUtil::DeletePtr<uv_work_t *>(work);
1166         MMI_HILOGE("Check data is nullptr");
1167         return;
1168     }
1169     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1170     JsUtil::DeletePtr<uv_work_t *>(work);
1171     cb->DecStrongRef(nullptr);
1172     CHKPV(cb->env);
1173 
1174     napi_handle_scope scope = nullptr;
1175     napi_open_handle_scope(cb->env, &scope);
1176     CHKPV(scope);
1177 
1178     napi_value callResult[2] = {0};
1179     if (cb->errCode != RET_OK) {
1180         if (cb->errCode == RET_ERR) {
1181             napi_close_handle_scope(cb->env, scope);
1182             MMI_HILOGE("Other errors");
1183             return;
1184         }
1185         NapiError codeMsg;
1186         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1187             napi_close_handle_scope(cb->env, scope);
1188             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1189             return;
1190         }
1191         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1192         if (callResult[0] == nullptr) {
1193             MMI_HILOGE("The callResult[0] is nullptr");
1194             napi_close_handle_scope(cb->env, scope);
1195             return;
1196         }
1197         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
1198     } else {
1199         CHKRV_SCOPE(
1200             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatRate, &callResult[1]), CREATE_INT32, scope);
1201         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
1202     }
1203     napi_value handler = nullptr;
1204     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
1205     napi_value result = nullptr;
1206     CHKRV_SCOPE(cb->env,
1207         napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
1208         CALL_FUNCTION,
1209         scope);
1210     napi_close_handle_scope(cb->env, scope);
1211 }
1212 
CallKeyboardRepeatRatePromise(uv_work_t * work,int32_t status)1213 void JsEventTarget::CallKeyboardRepeatRatePromise(uv_work_t *work, int32_t status)
1214 {
1215     CALL_DEBUG_ENTER;
1216     CHKPV(work);
1217     if (work->data == nullptr) {
1218         JsUtil::DeletePtr<uv_work_t *>(work);
1219         MMI_HILOGE("Check data is nullptr");
1220         return;
1221     }
1222     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1223     JsUtil::DeletePtr<uv_work_t *>(work);
1224     cb->DecStrongRef(nullptr);
1225     CHKPV(cb->env);
1226 
1227     napi_handle_scope scope = nullptr;
1228     napi_open_handle_scope(cb->env, &scope);
1229     CHKPV(scope);
1230 
1231     napi_value callResult;
1232     if (cb->errCode != RET_OK) {
1233         if (cb->errCode == RET_ERR) {
1234             napi_close_handle_scope(cb->env, scope);
1235             MMI_HILOGE("Other errors");
1236             return;
1237         }
1238         NapiError codeMsg;
1239         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1240             napi_close_handle_scope(cb->env, scope);
1241             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1242             return;
1243         }
1244         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1245         if (callResult == nullptr) {
1246             MMI_HILOGE("The callResult is nullptr");
1247             napi_close_handle_scope(cb->env, scope);
1248             return;
1249         }
1250         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1251     } else {
1252         CHKRV_SCOPE(
1253             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatRate, &callResult), CREATE_INT32, scope);
1254         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1255     }
1256     napi_close_handle_scope(cb->env, scope);
1257 }
1258 
AddListener(napi_env env,const std::string & type,napi_value handle)1259 void JsEventTarget::AddListener(napi_env env, const std::string &type, napi_value handle)
1260 {
1261     CALL_DEBUG_ENTER;
1262     std::lock_guard<std::mutex> guard(mutex_);
1263     auto iter = devListener_.find(type);
1264     if (iter == devListener_.end()) {
1265         MMI_HILOGE("Find %{public}s failed", type.c_str());
1266         return;
1267     }
1268 
1269     for (const auto &temp : iter->second) {
1270         CHKPC(temp);
1271         if (temp->env != env) {
1272             continue;
1273         }
1274         if (JsUtil::IsSameHandle(env, handle, temp->ref)) {
1275             MMI_HILOGW("The handle already exists");
1276             return;
1277         }
1278     }
1279     napi_ref ref = nullptr;
1280     CHKRV(napi_create_reference(env, handle, 1, &ref), CREATE_REFERENCE);
1281     auto monitor = std::make_unique<JsUtil::CallbackInfo>();
1282     monitor->env = env;
1283     monitor->ref = ref;
1284     iter->second.push_back(std::move(monitor));
1285     if (!isListeningProcess_) {
1286         isListeningProcess_ = true;
1287         InputManager::GetInstance()->RegisterDevListener("change", shared_from_this());
1288     }
1289 }
1290 
RemoveListener(napi_env env,const std::string & type,napi_value handle)1291 void JsEventTarget::RemoveListener(napi_env env, const std::string &type, napi_value handle)
1292 {
1293     CALL_DEBUG_ENTER;
1294     std::lock_guard<std::mutex> guard(mutex_);
1295     auto iter = devListener_.find(type);
1296     if (iter == devListener_.end()) {
1297         MMI_HILOGE("Find %{public}s failed", type.c_str());
1298         return;
1299     }
1300     if (handle == nullptr) {
1301         iter->second.clear();
1302         goto monitorLabel;
1303     }
1304     for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
1305         if ((*it)->env != env) {
1306             continue;
1307         }
1308         if (JsUtil::IsSameHandle(env, handle, (*it)->ref)) {
1309             MMI_HILOGD("Succeeded in removing monitor");
1310             JsUtil::DeleteCallbackInfo(std::move(*it));
1311             iter->second.erase(it);
1312             goto monitorLabel;
1313         }
1314     }
1315 
1316 monitorLabel:
1317     if (isListeningProcess_ && iter->second.empty()) {
1318         isListeningProcess_ = false;
1319         InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1320     }
1321 }
1322 
GreateBusinessError(napi_env env,int32_t errCode,std::string errMessage)1323 napi_value JsEventTarget::GreateBusinessError(napi_env env, int32_t errCode, std::string errMessage)
1324 {
1325     CALL_DEBUG_ENTER;
1326     napi_value result = nullptr;
1327     napi_value resultCode = nullptr;
1328     napi_value resultMessage = nullptr;
1329     CHKRP(napi_create_int32(env, errCode, &resultCode), CREATE_INT32);
1330     CHKRP(napi_create_string_utf8(env, errMessage.data(), NAPI_AUTO_LENGTH, &resultMessage), CREATE_STRING_UTF8);
1331     CHKRP(napi_create_error(env, nullptr, resultMessage, &result), CREATE_ERROR);
1332     CHKRP(napi_set_named_property(env, result, ERR_CODE.c_str(), resultCode), SET_NAMED_PROPERTY);
1333     return result;
1334 }
1335 
CreateCallbackInfo(napi_env env,napi_value handle,sptr<JsUtil::CallbackInfo> cb)1336 napi_value JsEventTarget::CreateCallbackInfo(napi_env env, napi_value handle, sptr<JsUtil::CallbackInfo> cb)
1337 {
1338     CALL_DEBUG_ENTER;
1339     CHKPP(cb);
1340     cb->env = env;
1341     napi_value promise = nullptr;
1342     if (handle == nullptr) {
1343         CHKRP(napi_create_promise(env, &cb->deferred, &promise), CREATE_PROMISE);
1344     } else {
1345         CHKRP(napi_create_reference(env, handle, 1, &cb->ref), CREATE_REFERENCE);
1346     }
1347     return promise;
1348 }
1349 
EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)1350 void JsEventTarget::EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)
1351 {
1352     CALL_DEBUG_ENTER;
1353     CHKPV(cb);
1354     CHKPV(cb->env);
1355     uv_loop_s *loop = nullptr;
1356     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1357     uv_work_t *work = new (std::nothrow) uv_work_t;
1358     CHKPV(work);
1359     cb->IncStrongRef(nullptr);
1360     work->data = cb.GetRefPtr();
1361     int32_t ret = 0;
1362     ret = uv_queue_work_with_qos(
1363         loop, work,
1364         [](uv_work_t *work) {
1365             MMI_HILOGD("uv_queue_work callback function is called");
1366             CallIntervalSinceLastInputTask(work);
1367         },
1368         CallIntervalSinceLastInputPromise, uv_qos_user_initiated);
1369     if (ret != 0) {
1370         MMI_HILOGE("uv_queue_work_with_qos failed");
1371         cb->DecStrongRef(nullptr);
1372         JsUtil::DeletePtr<uv_work_t *>(work);
1373     }
1374 }
1375 
CallIntervalSinceLastInputPromise(uv_work_t * work,int32_t status)1376 void JsEventTarget::CallIntervalSinceLastInputPromise(uv_work_t *work, int32_t status)
1377 {
1378     CALL_DEBUG_ENTER;
1379     CHKPV(work);
1380     if (work->data == nullptr) {
1381         JsUtil::DeletePtr<uv_work_t *>(work);
1382         MMI_HILOGE("Check data is nullptr");
1383         return;
1384     }
1385     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1386     JsUtil::DeletePtr<uv_work_t *>(work);
1387     cb->DecStrongRef(nullptr);
1388     CHKPV(cb->env);
1389 
1390     napi_handle_scope scope = nullptr;
1391     napi_open_handle_scope(cb->env, &scope);
1392     CHKPV(scope);
1393     napi_value callResult;
1394     CHKRV_SCOPE(cb->env, napi_create_int64(cb->env, cb->data.IntervalSinceLastInput, &callResult),
1395         CREATE_INT64, scope);
1396     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1397     napi_close_handle_scope(cb->env, scope);
1398 }
1399 
ResetEnv()1400 void JsEventTarget::ResetEnv()
1401 {
1402     CALL_DEBUG_ENTER;
1403     std::lock_guard<std::mutex> guard(mutex_);
1404     devListener_.clear();
1405     InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1406 }
1407 
CallSetInputDeviceEnabledPromise(uv_work_t * work,int32_t status)1408 void JsEventTarget::CallSetInputDeviceEnabledPromise(uv_work_t *work, int32_t status)
1409 {
1410     CALL_DEBUG_ENTER;
1411     CHKPV(work);
1412     if (work->data == nullptr) {
1413         JsUtil::DeletePtr<uv_work_t *>(work);
1414         MMI_HILOGE("Check data is nullptr");
1415         return;
1416     }
1417     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1418     JsUtil::DeletePtr<uv_work_t *>(work);
1419     cb->DecStrongRef(nullptr);
1420     CHKPV(cb->env);
1421 
1422     napi_handle_scope scope = nullptr;
1423     napi_open_handle_scope(cb->env, &scope);
1424     CHKPV(scope);
1425 
1426     napi_value callResult;
1427     if (cb->errCode != RET_OK) {
1428         if (cb->errCode == RET_ERR) {
1429             napi_close_handle_scope(cb->env, scope);
1430             MMI_HILOGE("Other errors");
1431             return;
1432         }
1433         NapiError codeMsg;
1434         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1435             napi_close_handle_scope(cb->env, scope);
1436             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1437             return;
1438         }
1439         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1440         if (callResult == nullptr) {
1441             MMI_HILOGE("The callResult is nullptr");
1442             napi_close_handle_scope(cb->env, scope);
1443             return;
1444         }
1445         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1446     } else {
1447         CHKRV_SCOPE(
1448             cb->env, napi_create_int32(cb->env, cb->errCode, &callResult), CREATE_INT32, scope);
1449         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1450     }
1451     napi_close_handle_scope(cb->env, scope);
1452 }
1453 
EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb,int32_t errCode)1454 void JsEventTarget::EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb, int32_t errCode)
1455 {
1456     CALL_DEBUG_ENTER;
1457     CHKPV(cb);
1458     CHKPV(cb->env);
1459     cb->errCode = errCode;
1460     uv_loop_s *loop = nullptr;
1461     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1462 
1463     uv_work_t *work = new (std::nothrow) uv_work_t;
1464     CHKPV(work);
1465     cb->IncStrongRef(nullptr);
1466     work->data = cb.GetRefPtr();
1467     int32_t ret = -1;
1468     if (cb->ref == nullptr) {
1469         ret = uv_queue_work_with_qos(
1470             loop, work,
1471             [](uv_work_t *work) {
1472                 MMI_HILOGD("uv_queue_work callback function is called");
1473             },
1474             CallSetInputDeviceEnabledPromise, uv_qos_user_initiated);
1475     }
1476     if (ret != 0) {
1477         MMI_HILOGE("uv_queue_work_with_qos failed");
1478         JsUtil::DeletePtr<uv_work_t *>(work);
1479     }
1480 }
1481 
EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey,bool state)1482 void JsEventTarget::EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey, bool state)
1483 {
1484     CALL_DEBUG_ENTER;
1485     CHKPV(cb);
1486     int32_t keyState = state ? 1 : 0;
1487     cb->uData.keys.push_back(funcKey);
1488     cb->uData.keys.push_back(keyState);
1489     cb->setFuncKeyType = true;
1490     cb->errCode = -1;
1491     uv_loop_s *loop = nullptr;
1492     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1493     uv_work_t *work = new (std::nothrow) uv_work_t;
1494     CHKPV(work);
1495     cb->IncStrongRef(nullptr);
1496     // data heap point cb pointer
1497     work->data = cb.GetRefPtr();
1498     int32_t ret = -1;
1499     ret = uv_queue_work_with_qos(
1500         loop, work,
1501         [](uv_work_t *work) {
1502             MMI_HILOGD("uv_queue_work callback function is called");
1503             CallFunctionKeyStateTask(work);
1504         },
1505         CallFunctionKeyState, uv_qos_user_initiated);
1506     if (ret != 0) {
1507         MMI_HILOGE("uv_queue_work_with_qos failed");
1508         cb->DecStrongRef(nullptr);
1509         JsUtil::DeletePtr<uv_work_t *>(work);
1510     }
1511 }
1512 
EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey)1513 void JsEventTarget::EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey)
1514 {
1515     CALL_DEBUG_ENTER;
1516     CHKPV(cb);
1517     cb->uData.keys.push_back(funcKey);
1518     cb->getFuncKeyType = true;
1519     uv_loop_s *loop = nullptr;
1520     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1521     uv_work_t *work = new (std::nothrow) uv_work_t;
1522     CHKPV(work);
1523     cb->IncStrongRef(nullptr);
1524     work->data = cb.GetRefPtr();
1525     int32_t ret = -1;
1526     ret = uv_queue_work_with_qos(
1527         loop, work,
1528         [](uv_work_t *work) {
1529             MMI_HILOGD("uv_queue_work callback function is called");
1530             CallFunctionKeyStateTask(work);
1531         },
1532         CallFunctionKeyState, uv_qos_user_initiated);
1533     if (ret != 0) {
1534         MMI_HILOGE("uv_queue_work_with_qos failed");
1535         cb->DecStrongRef(nullptr);
1536         JsUtil::DeletePtr<uv_work_t *>(work);
1537     }
1538 }
1539 
CallFunctionKeyStateTask(uv_work_t * work)1540 void JsEventTarget::CallFunctionKeyStateTask(uv_work_t *work)
1541 {
1542     CHKPV(work);
1543     if (work->data == nullptr) {
1544         JsUtil::DeletePtr<uv_work_t *>(work);
1545         MMI_HILOGE("Check data is nullptr");
1546         return;
1547     }
1548     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1549     CHKPV(cb->env);
1550     if (cb->getFuncKeyType) {
1551         bool resultState = false;
1552         auto funcKey = cb->uData.keys.front();
1553         int32_t napiCode = InputManager::GetInstance()->GetFunctionKeyState(funcKey, resultState);
1554         int32_t keyState = resultState ? 1 : 0;
1555         cb->errCode = napiCode;
1556         cb->uData.keys.push_back(keyState);
1557     }
1558     if (cb->setFuncKeyType) {
1559         auto funcKey = cb->uData.keys.front();
1560         auto state = cb->uData.keys.back();
1561         int32_t napiCode = InputManager::GetInstance()->SetFunctionKeyState(funcKey, state);
1562         cb->errCode = napiCode;
1563     }
1564 }
1565 
GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb,napi_handle_scope scope,napi_value & callResult)1566 bool JsEventTarget::GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb, napi_handle_scope scope,
1567     napi_value &callResult)
1568 {
1569     CALL_DEBUG_ENTER;
1570     CHKPF(cb);
1571     if (cb->errCode == RET_ERR) {
1572         napi_close_handle_scope(cb->env, scope);
1573         MMI_HILOGE("return value errors");
1574         return false;
1575     }
1576     NapiError codeMsg;
1577     if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1578         napi_close_handle_scope(cb->env, scope);
1579         MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1580         return false;
1581     }
1582     callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1583     if (callResult == nullptr) {
1584         MMI_HILOGE("The callResult is nullptr");
1585         napi_close_handle_scope(cb->env, scope);
1586         return false;
1587     }
1588     return true;
1589 }
1590 
CallFunctionKeyState(uv_work_t * work,int32_t status)1591 void JsEventTarget::CallFunctionKeyState(uv_work_t *work, int32_t status)
1592 {
1593     CALL_DEBUG_ENTER;
1594     CHKPV(work);
1595     if (work->data == nullptr) {
1596         JsUtil::DeletePtr<uv_work_t *>(work);
1597         return;
1598     }
1599     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1600     JsUtil::DeletePtr<uv_work_t *>(work);
1601     cb->DecStrongRef(nullptr);
1602     CHKPV(cb->env);
1603     napi_handle_scope scope = nullptr;
1604     napi_open_handle_scope(cb->env, &scope);
1605     CHKPV(scope);
1606     napi_value callResult = nullptr;
1607     if (cb->errCode != RET_OK) {
1608         if (!GetFunctionKeyStateErrCode(cb, scope, callResult)) {
1609             MMI_HILOGE("promise get function key state error");
1610             return;
1611         }
1612         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1613     } else {
1614         if (cb->getFuncKeyType) {
1615             auto state = cb->uData.keys.back();
1616             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, state, &callResult), CREATE_INT32, scope);
1617         } else {
1618             CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult), GET_UNDEFINED, scope);
1619         }
1620         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1621     }
1622     napi_close_handle_scope(cb->env, scope);
1623 }
1624 
CallKeyboardRepeatDelayTask(uv_work_t * work,const std::string & operateType)1625 void JsEventTarget::CallKeyboardRepeatDelayTask(uv_work_t *work, const std::string& operateType)
1626 {
1627     CHKPV(work);
1628     if (work->data == nullptr) {
1629         JsUtil::DeletePtr<uv_work_t *>(work);
1630         MMI_HILOGE("Check data is nullptr");
1631         return;
1632     }
1633     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1634     CHKPV(cb->env);
1635 
1636     if (operateType == "get") {
1637         int32_t _delay = -1;
1638         auto callback = [&_delay] (int32_t delay) { _delay = delay; };
1639         int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatDelay(callback);
1640         cb->errCode = napiCode;
1641         cb->data.keyboardRepeatDelay = _delay;
1642     } else {
1643         int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatDelay(cb->data.keyboardRepeatDelay);
1644         cb->errCode = napiCode;
1645     }
1646 }
1647 
CallKeyboardRepeatRateTask(uv_work_t * work,const std::string & operateType)1648 void JsEventTarget::CallKeyboardRepeatRateTask(uv_work_t *work, const std::string& operateType)
1649 {
1650     CHKPV(work);
1651     if (work->data == nullptr) {
1652         JsUtil::DeletePtr<uv_work_t *>(work);
1653         MMI_HILOGE("Check data is nullptr");
1654         return;
1655     }
1656     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1657     CHKPV(cb->env);
1658 
1659     if (operateType == "get") {
1660         int32_t _rate = -1;
1661         auto callback = [&_rate] (int32_t rate) { _rate = rate; };
1662         int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatRate(callback);
1663         cb->errCode = napiCode;
1664         cb->data.keyboardRepeatRate = _rate;
1665     } else {
1666         int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatRate(cb->data.keyboardRepeatRate);
1667         cb->errCode = napiCode;
1668     }
1669 }
1670 
CallGetKeyboardTypeTask(uv_work_t * work)1671 void JsEventTarget::CallGetKeyboardTypeTask(uv_work_t *work)
1672 {
1673     CHKPV(work);
1674     if (work->data == nullptr) {
1675         JsUtil::DeletePtr<uv_work_t *>(work);
1676         MMI_HILOGE("Check data is nullptr");
1677         return;
1678     }
1679     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1680     CHKPV(cb->env);
1681 
1682     int32_t _keyboardtype = -1;
1683     auto callback = [&_keyboardtype] (int32_t keyboardtype) { _keyboardtype = keyboardtype; };
1684     int32_t napiCode = InputManager::GetInstance()->GetKeyboardType(cb->data.deviceId, callback);
1685     cb->errCode = napiCode;
1686     cb->data.keyboardType = _keyboardtype;
1687 }
1688 
CallJsIdsTask(uv_work_t * work)1689 void JsEventTarget::CallJsIdsTask(uv_work_t *work)
1690 {
1691     CHKPV(work);
1692     if (work->data == nullptr) {
1693         JsUtil::DeletePtr<uv_work_t *>(work);
1694         MMI_HILOGE("Check data is nullptr");
1695         return;
1696     }
1697     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1698     CHKPV(cb->env);
1699     std::vector<int32_t> _ids;
1700     auto callback = [&_ids] (std::vector<int32_t>& ids) { _ids = ids; };
1701     int32_t napiCode = InputManager::GetInstance()->GetDeviceIds(callback);
1702     cb->errCode = napiCode;
1703     cb->data.ids = _ids;
1704 }
1705 
CallJsDevTask(uv_work_t * work)1706 void JsEventTarget::CallJsDevTask(uv_work_t *work)
1707 {
1708     CHKPV(work);
1709     if (work->data == nullptr) {
1710         JsUtil::DeletePtr<uv_work_t *>(work);
1711         MMI_HILOGE("Check data is nullptr");
1712         return;
1713     }
1714     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1715     CHKPV(cb->env);
1716     std::shared_ptr<InputDevice> _device = std::make_shared<InputDevice>();
1717     auto callback = [&_device] (std::shared_ptr<InputDevice> device) { _device = device; };
1718     int32_t napiCode = InputManager::GetInstance()->GetDevice(cb->data.deviceId, callback);
1719     CHKPV(_device);
1720     cb->errCode = napiCode;
1721     cb->data.device = _device;
1722 }
1723 
CallSupportKeysTask(uv_work_t * work)1724 void JsEventTarget::CallSupportKeysTask(uv_work_t *work)
1725 {
1726     CHKPV(work);
1727     if (work->data == nullptr) {
1728         JsUtil::DeletePtr<uv_work_t *>(work);
1729         MMI_HILOGE("Check data is nullptr");
1730         return;
1731     }
1732     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1733     CHKPV(cb->env);
1734     auto callback = [&] (std::vector<bool>& keystrokeAbility) {
1735         cb->data.keystrokeAbility = keystrokeAbility;
1736     };
1737     int32_t napiCode = InputManager::GetInstance()->SupportKeys(cb->data.deviceId, cb->data.ids, callback);
1738     cb->errCode = napiCode;
1739 }
CallIntervalSinceLastInputTask(uv_work_t * work)1740 void JsEventTarget::CallIntervalSinceLastInputTask(uv_work_t *work)
1741 {
1742     CHKPV(work);
1743     if (work->data == nullptr) {
1744         JsUtil::DeletePtr<uv_work_t *>(work);
1745         MMI_HILOGE("Check data is nullptr");
1746         return;
1747     }
1748     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1749     CHKPV(cb->env);
1750     int32_t napiCode = InputManager::GetInstance()->GetIntervalSinceLastInput(cb->data.IntervalSinceLastInput);
1751     cb->errCode = napiCode;
1752 }
1753 } // namespace MMI
1754 } // namespace OHOS
1755