• 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     reportData->DecStrongRef(nullptr);
53     auto addEvent = devListener_.find(CHANGED_TYPE);
54     if (addEvent == devListener_.end()) {
55         MMI_HILOGE("Find change event failed");
56         return;
57     }
58     for (const auto &item : addEvent->second) {
59         CHKPC(item->env);
60         if (item->ref != reportData->ref) {
61             continue;
62         }
63         napi_handle_scope scope = nullptr;
64         napi_open_handle_scope(item->env, &scope);
65         CHKPV(scope);
66         napi_value eventType = nullptr;
67         CHKRV_SCOPE_DEL(item->env, napi_create_string_utf8(item->env, ADD_EVENT.c_str(), NAPI_AUTO_LENGTH, &eventType),
68             CREATE_STRING_UTF8, scope);
69         napi_value object = nullptr;
70         CHKRV_SCOPE_DEL(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
71         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
72             scope);
73         napi_value handler = nullptr;
74         CHKRV_SCOPE_DEL(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE,
75             scope);
76         napi_value deviceId = nullptr;
77         CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope);
78         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
79             scope);
80         napi_value ret = nullptr;
81         CHKRV_SCOPE_DEL(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
82             scope);
83         napi_close_handle_scope(item->env, scope);
84         BytraceAdapter::StartDevListener(ADD_EVENT, reportData->deviceId);
85         MMI_HILOGI("Report device change task, event type:%{public}s, deviceid:%{public}d",
86             ADD_EVENT.c_str(), reportData->deviceId);
87         BytraceAdapter::StopDevListener();
88     }
89 }
90 
EmitRemoveDeviceEvent(sptr<JsUtil::ReportData> reportData)91 void JsEventTarget::EmitRemoveDeviceEvent(sptr<JsUtil::ReportData> reportData)
92 {
93     CALL_DEBUG_ENTER;
94     reportData->DecStrongRef(nullptr);
95     auto removeEvent = devListener_.find(CHANGED_TYPE);
96     if (removeEvent == devListener_.end()) {
97         MMI_HILOGE("Find change event failed");
98         return;
99     }
100     for (const auto &item : removeEvent->second) {
101         CHKPC(item->env);
102         if (item->ref != reportData->ref) {
103             continue;
104         }
105         napi_handle_scope scope = nullptr;
106         napi_open_handle_scope(item->env, &scope);
107         CHKPV(scope);
108         napi_value eventType = nullptr;
109         CHKRV_SCOPE_DEL(item->env, napi_create_string_utf8(item->env, REMOVE_EVENT.c_str(), NAPI_AUTO_LENGTH,
110             &eventType), CREATE_STRING_UTF8, scope);
111         napi_value deviceId = nullptr;
112         CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope);
113         napi_value object = nullptr;
114         CHKRV_SCOPE_DEL(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
115         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
116             scope);
117         CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
118             scope);
119         napi_value handler = nullptr;
120         CHKRV_SCOPE_DEL(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE,
121             scope);
122         napi_value ret = nullptr;
123         CHKRV_SCOPE_DEL(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
124             scope);
125         napi_close_handle_scope(item->env, scope);
126         BytraceAdapter::StartDevListener(REMOVE_EVENT, reportData->deviceId);
127         MMI_HILOGI("Report device change task, event type:%{public}s, deviceid:%{public}d",
128             REMOVE_EVENT.c_str(), reportData->deviceId);
129         BytraceAdapter::StopDevListener();
130     }
131 }
132 
OnDeviceAdded(int32_t deviceId,const std::string & type)133 void JsEventTarget::OnDeviceAdded(int32_t deviceId, const std::string &type)
134 {
135     CALL_DEBUG_ENTER;
136     std::lock_guard<std::mutex> guard(mutex_);
137     auto changeEvent = devListener_.find(CHANGED_TYPE);
138     if (changeEvent == devListener_.end()) {
139         MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
140         return;
141     }
142 
143     for (auto &item : changeEvent->second) {
144         CHKPC(item);
145         CHKPC(item->env);
146         sptr<JsUtil::ReportData> reportData = new (std::nothrow) JsUtil::ReportData;
147         if (reportData == nullptr) {
148             MMI_HILOGE("Memory allocation failed");
149             return;
150         }
151         reportData->deviceId = deviceId;
152         reportData->ref = item->ref;
153         reportData->IncStrongRef(nullptr);
154         auto task = [reportData, this] () { EmitAddedDeviceEvent(reportData); };
155         int32_t ret = napi_send_event(item->env, task, napi_eprio_vip);
156         if (ret != 0) {
157             MMI_HILOGE("napi_send_event failed");
158             return;
159         }
160     }
161 }
162 
OnDeviceRemoved(int32_t deviceId,const std::string & type)163 void JsEventTarget::OnDeviceRemoved(int32_t deviceId, const std::string &type)
164 {
165     CALL_DEBUG_ENTER;
166     std::lock_guard<std::mutex> guard(mutex_);
167     auto changeEvent = devListener_.find(CHANGED_TYPE);
168     if (changeEvent == devListener_.end()) {
169         MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
170         return;
171     }
172     for (auto &item : changeEvent->second) {
173         CHKPC(item);
174         CHKPC(item->env);
175         sptr<JsUtil::ReportData> reportData = new (std::nothrow) JsUtil::ReportData;
176         if (reportData == nullptr) {
177             MMI_HILOGE("Memory allocation failed");
178             return;
179         }
180         reportData->deviceId = deviceId;
181         reportData->ref = item->ref;
182         reportData->IncStrongRef(nullptr);
183         auto task = [reportData, this] () { EmitRemoveDeviceEvent(reportData); };
184         int32_t ret = napi_send_event(item->env, task, napi_eprio_vip);
185         if (ret != 0) {
186             MMI_HILOGE("napi_send_event failed");
187             return;
188         }
189     }
190 }
191 
CallIdsAsyncWork(uv_work_t * work,int32_t status)192 void JsEventTarget::CallIdsAsyncWork(uv_work_t *work, int32_t status)
193 {
194     CALL_DEBUG_ENTER;
195     CHKPV(work);
196     if (work->data == nullptr) {
197         JsUtil::DeletePtr<uv_work_t *>(work);
198         MMI_HILOGE("Check data is nullptr");
199         return;
200     }
201     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
202     JsUtil::DeletePtr<uv_work_t *>(work);
203     cb->DecStrongRef(nullptr);
204     CHKPV(cb->env);
205     napi_handle_scope scope = nullptr;
206     napi_open_handle_scope(cb->env, &scope);
207     CHKPV(scope);
208     napi_value arr[2];
209     CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &arr[0]), GET_UNDEFINED, scope);
210     CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr[1]), CREATE_ARRAY, scope);
211     uint32_t index = 0;
212     napi_value value = nullptr;
213     for (const auto &item : cb->data.ids) {
214         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
215         CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr[1], index, value), SET_ELEMENT, scope);
216         ++index;
217     }
218 
219     napi_value handler = nullptr;
220     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
221     napi_value result = nullptr;
222     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, arr, &result),
223         CALL_FUNCTION, scope);
224     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
225     napi_close_handle_scope(cb->env, scope);
226 }
227 
CallIdsPromiseWork(uv_work_t * work,int32_t status)228 void JsEventTarget::CallIdsPromiseWork(uv_work_t *work, int32_t status)
229 {
230     CALL_DEBUG_ENTER;
231     CHKPV(work);
232     if (work->data == nullptr) {
233         JsUtil::DeletePtr<uv_work_t *>(work);
234         MMI_HILOGE("Check data is nullptr");
235         return;
236     }
237     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
238     JsUtil::DeletePtr<uv_work_t *>(work);
239     cb->DecStrongRef(nullptr);
240     CHKPV(cb->env);
241     napi_handle_scope scope = nullptr;
242     napi_open_handle_scope(cb->env, &scope);
243     CHKPV(scope);
244     napi_value arr = nullptr;
245     CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr), CREATE_ARRAY, scope);
246     uint32_t index = 0;
247     napi_value value = nullptr;
248     for (const auto &item : cb->data.ids) {
249         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
250         CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr, index, value), SET_ELEMENT, scope);
251         ++index;
252     }
253     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, arr), RESOLVE_DEFERRED, scope);
254     napi_close_handle_scope(cb->env, scope);
255 }
256 
EmitJsIds(sptr<JsUtil::CallbackInfo> cb,std::vector<int32_t> & ids)257 void JsEventTarget::EmitJsIds(sptr<JsUtil::CallbackInfo> cb, std::vector<int32_t> &ids)
258 {
259     CALL_DEBUG_ENTER;
260     CHKPV(cb);
261     CHKPV(cb->env);
262     cb->data.ids = ids;
263     cb->errCode = RET_OK;
264     EmitJsIdsInternal(cb);
265 }
266 
EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)267 void JsEventTarget::EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)
268 {
269     uv_loop_s *loop = nullptr;
270     CHKPV(cb);
271     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
272     uv_work_t *work = new (std::nothrow) uv_work_t;
273     CHKPV(work);
274     cb->IncStrongRef(nullptr);
275     work->data = cb.GetRefPtr();
276     int32_t ret = -1;
277     if (cb->isApi9) {
278         if (cb->ref == nullptr) {
279             ret = uv_queue_work_with_qos(
280                 loop, work,
281                 [](uv_work_t *work) {
282                     MMI_HILOGD("uv_queue_work callback function is called");
283                     CallJsIdsTask(work);
284                 }, CallDevListPromiseWork, uv_qos_user_initiated);
285         } else {
286             ret = uv_queue_work_with_qos(
287                 loop, work,
288                 [](uv_work_t *work) {
289                     MMI_HILOGD("uv_queue_work callback function is called");
290                     CallJsIdsTask(work);
291                 }, CallDevListAsyncWork, uv_qos_user_initiated);
292         }
293     } else {
294         if (cb->ref == nullptr) {
295             ret = uv_queue_work_with_qos(
296                 loop, work,
297                 [](uv_work_t *work) {
298                     MMI_HILOGD("uv_queue_work callback function is called");
299                     CallJsIdsTask(work);
300                 }, CallIdsPromiseWork, uv_qos_user_initiated);
301         } else {
302             ret = uv_queue_work_with_qos(
303                 loop, work,
304                 [](uv_work_t *work) {
305                     MMI_HILOGD("uv_queue_work callback function is called");
306                     CallJsIdsTask(work);
307                 }, CallIdsAsyncWork, uv_qos_user_initiated);
308         }
309     }
310     if (ret != 0) {
311         MMI_HILOGE("uv_queue_work_with_qos failed");
312         JsUtil::DeletePtr<uv_work_t *>(work);
313     }
314 }
315 
CallDevAsyncWork(uv_work_t * work,int32_t status)316 void JsEventTarget::CallDevAsyncWork(uv_work_t *work, int32_t status)
317 {
318     CALL_DEBUG_ENTER;
319     CHKPV(work);
320     if (work->data == nullptr) {
321         JsUtil::DeletePtr<uv_work_t *>(work);
322         MMI_HILOGE("Check data is nullptr");
323         return;
324     }
325     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
326     JsUtil::DeletePtr<uv_work_t *>(work);
327     cb->DecStrongRef(nullptr);
328     CHKPV(cb->env);
329     napi_handle_scope scope = nullptr;
330     napi_open_handle_scope(cb->env, &scope);
331     CHKPV(scope);
332     napi_value object[2];
333     CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &object[0]), GET_UNDEFINED, scope);
334     object[1] = JsUtil::GetDeviceInfo(cb);
335     napi_value handler = nullptr;
336     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
337     napi_value result = nullptr;
338     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, object, &result),
339         CALL_FUNCTION, scope);
340     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
341     napi_close_handle_scope(cb->env, scope);
342 }
343 
CallDevPromiseWork(uv_work_t * work,int32_t status)344 void JsEventTarget::CallDevPromiseWork(uv_work_t *work, int32_t status)
345 {
346     CALL_DEBUG_ENTER;
347     CHKPV(work);
348     if (work->data == nullptr) {
349         JsUtil::DeletePtr<uv_work_t *>(work);
350         MMI_HILOGE("Check data is nullptr");
351         return;
352     }
353     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
354     JsUtil::DeletePtr<uv_work_t *>(work);
355     cb->DecStrongRef(nullptr);
356     CHKPV(cb->env);
357     napi_handle_scope scope = nullptr;
358     napi_open_handle_scope(cb->env, &scope);
359     CHKPV(scope);
360     napi_value object = JsUtil::GetDeviceInfo(cb);
361     if (object == nullptr) {
362         MMI_HILOGE("Check object is nullptr");
363         napi_close_handle_scope(cb->env, scope);
364         return;
365     }
366     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
367     napi_close_handle_scope(cb->env, scope);
368 }
369 
EmitJsDev(sptr<JsUtil::CallbackInfo> cb,int32_t deviceid)370 void JsEventTarget::EmitJsDev(sptr<JsUtil::CallbackInfo> cb, int32_t deviceid)
371 {
372     CALL_DEBUG_ENTER;
373     CHKPV(cb);
374     CHKPV(cb->env);
375     cb->data.deviceId = deviceid;
376     cb->errCode = RET_OK;
377     EmitJsDevInternal(cb);
378 }
379 
EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)380 void JsEventTarget::EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)
381 {
382     uv_loop_s *loop = nullptr;
383     CHKPV(cb);
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     bool isListening { false };
1263     {
1264         std::lock_guard<std::mutex> guard(mutex_);
1265         auto iter = devListener_.find(type);
1266         if (iter == devListener_.end()) {
1267             MMI_HILOGE("Find %{public}s failed", type.c_str());
1268             return;
1269         }
1270         for (const auto &temp : iter->second) {
1271             CHKPC(temp);
1272             if (temp->env != env) {
1273                 continue;
1274             }
1275             if (JsUtil::IsSameHandle(env, handle, temp->ref)) {
1276                 MMI_HILOGW("The handle already exists");
1277                 return;
1278             }
1279         }
1280         napi_ref ref = nullptr;
1281         CHKRV(napi_create_reference(env, handle, 1, &ref), CREATE_REFERENCE);
1282         auto monitor = std::make_unique<JsUtil::CallbackInfo>();
1283         monitor->env = env;
1284         monitor->ref = ref;
1285         iter->second.push_back(std::move(monitor));
1286         isListening = isListeningProcess_;
1287     }
1288     if (!isListening) {
1289         auto ret = InputManager::GetInstance()->RegisterDevListener("change", shared_from_this());
1290         if (ret != RET_OK) {
1291             MMI_HILOGE("RegisterDevListener fail, error:%{public}d", ret);
1292         } else {
1293             std::lock_guard<std::mutex> guard(mutex_);
1294             isListeningProcess_ = true;
1295         }
1296     }
1297 }
1298 
RemoveListener(napi_env env,const std::string & type,napi_value handle)1299 void JsEventTarget::RemoveListener(napi_env env, const std::string &type, napi_value handle)
1300 {
1301     CALL_DEBUG_ENTER;
1302     bool needStopListening { false };
1303     {
1304         std::lock_guard<std::mutex> guard(mutex_);
1305         auto iter = devListener_.find(type);
1306         if (iter == devListener_.end()) {
1307             MMI_HILOGE("Find %{public}s failed", type.c_str());
1308             return;
1309         }
1310         if (handle == nullptr) {
1311             iter->second.clear();
1312             goto monitorLabel;
1313         }
1314         for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
1315             if ((*it)->env != env) {
1316                 continue;
1317             }
1318             if (JsUtil::IsSameHandle(env, handle, (*it)->ref)) {
1319                 MMI_HILOGD("Succeeded in removing monitor");
1320                 JsUtil::DeleteCallbackInfo(std::move(*it));
1321                 iter->second.erase(it);
1322                 goto monitorLabel;
1323             }
1324         }
1325 
1326     monitorLabel:
1327         if (isListeningProcess_ && iter->second.empty()) {
1328             needStopListening = true;
1329             isListeningProcess_ = false;
1330         }
1331     }
1332     if (needStopListening) {
1333         auto ret = InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1334         if (ret != RET_OK) {
1335             MMI_HILOGE("UnregisterDevListener fail, error:%{public}d", ret);
1336         }
1337     }
1338 }
1339 
GreateBusinessError(napi_env env,int32_t errCode,std::string errMessage)1340 napi_value JsEventTarget::GreateBusinessError(napi_env env, int32_t errCode, std::string errMessage)
1341 {
1342     CALL_DEBUG_ENTER;
1343     napi_value result = nullptr;
1344     napi_value resultCode = nullptr;
1345     napi_value resultMessage = nullptr;
1346     CHKRP(napi_create_int32(env, errCode, &resultCode), CREATE_INT32);
1347     CHKRP(napi_create_string_utf8(env, errMessage.data(), NAPI_AUTO_LENGTH, &resultMessage), CREATE_STRING_UTF8);
1348     CHKRP(napi_create_error(env, nullptr, resultMessage, &result), CREATE_ERROR);
1349     CHKRP(napi_set_named_property(env, result, ERR_CODE.c_str(), resultCode), SET_NAMED_PROPERTY);
1350     return result;
1351 }
1352 
CreateCallbackInfo(napi_env env,napi_value handle,sptr<JsUtil::CallbackInfo> cb)1353 napi_value JsEventTarget::CreateCallbackInfo(napi_env env, napi_value handle, sptr<JsUtil::CallbackInfo> cb)
1354 {
1355     CALL_DEBUG_ENTER;
1356     CHKPP(cb);
1357     cb->env = env;
1358     napi_value promise = nullptr;
1359     if (handle == nullptr) {
1360         CHKRP(napi_create_promise(env, &cb->deferred, &promise), CREATE_PROMISE);
1361     } else {
1362         CHKRP(napi_create_reference(env, handle, 1, &cb->ref), CREATE_REFERENCE);
1363     }
1364     return promise;
1365 }
1366 
EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)1367 void JsEventTarget::EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)
1368 {
1369     CALL_DEBUG_ENTER;
1370     CHKPV(cb);
1371     CHKPV(cb->env);
1372     uv_loop_s *loop = nullptr;
1373     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1374     uv_work_t *work = new (std::nothrow) uv_work_t;
1375     CHKPV(work);
1376     cb->IncStrongRef(nullptr);
1377     work->data = cb.GetRefPtr();
1378     int32_t ret = 0;
1379     ret = uv_queue_work_with_qos(
1380         loop, work,
1381         [](uv_work_t *work) {
1382             MMI_HILOGD("uv_queue_work callback function is called");
1383             CallIntervalSinceLastInputTask(work);
1384         },
1385         CallIntervalSinceLastInputPromise, uv_qos_user_initiated);
1386     if (ret != 0) {
1387         MMI_HILOGE("uv_queue_work_with_qos failed");
1388         cb->DecStrongRef(nullptr);
1389         JsUtil::DeletePtr<uv_work_t *>(work);
1390     }
1391 }
1392 
CallIntervalSinceLastInputPromise(uv_work_t * work,int32_t status)1393 void JsEventTarget::CallIntervalSinceLastInputPromise(uv_work_t *work, int32_t status)
1394 {
1395     CALL_DEBUG_ENTER;
1396     CHKPV(work);
1397     if (work->data == nullptr) {
1398         JsUtil::DeletePtr<uv_work_t *>(work);
1399         MMI_HILOGE("Check data is nullptr");
1400         return;
1401     }
1402     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1403     JsUtil::DeletePtr<uv_work_t *>(work);
1404     cb->DecStrongRef(nullptr);
1405     CHKPV(cb->env);
1406 
1407     napi_handle_scope scope = nullptr;
1408     napi_open_handle_scope(cb->env, &scope);
1409     CHKPV(scope);
1410     napi_value callResult;
1411     CHKRV_SCOPE(cb->env, napi_create_int64(cb->env, cb->data.IntervalSinceLastInput, &callResult),
1412         CREATE_INT64, scope);
1413     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1414     napi_close_handle_scope(cb->env, scope);
1415 }
1416 
ResetEnv()1417 void JsEventTarget::ResetEnv()
1418 {
1419     CALL_DEBUG_ENTER;
1420     {
1421         std::lock_guard<std::mutex> guard(mutex_);
1422         devListener_.clear();
1423     }
1424     auto ret = InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1425     if (ret != RET_OK) {
1426         MMI_HILOGE("UnregisterDevListener fail, error:%{public}d", ret);
1427     }
1428 }
1429 
CallSetInputDeviceEnabledPromise(uv_work_t * work,int32_t status)1430 void JsEventTarget::CallSetInputDeviceEnabledPromise(uv_work_t *work, int32_t status)
1431 {
1432     CALL_DEBUG_ENTER;
1433     CHKPV(work);
1434     if (work->data == nullptr) {
1435         JsUtil::DeletePtr<uv_work_t *>(work);
1436         MMI_HILOGE("Check data is nullptr");
1437         return;
1438     }
1439     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1440     JsUtil::DeletePtr<uv_work_t *>(work);
1441     cb->DecStrongRef(nullptr);
1442     CHKPV(cb->env);
1443 
1444     napi_handle_scope scope = nullptr;
1445     napi_open_handle_scope(cb->env, &scope);
1446     CHKPV(scope);
1447 
1448     napi_value callResult;
1449     if (cb->errCode != RET_OK) {
1450         if (cb->errCode == RET_ERR) {
1451             napi_close_handle_scope(cb->env, scope);
1452             MMI_HILOGE("Other errors");
1453             return;
1454         }
1455         NapiError codeMsg;
1456         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1457             napi_close_handle_scope(cb->env, scope);
1458             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1459             return;
1460         }
1461         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1462         if (callResult == nullptr) {
1463             MMI_HILOGE("The callResult is nullptr");
1464             napi_close_handle_scope(cb->env, scope);
1465             return;
1466         }
1467         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1468     } else {
1469         CHKRV_SCOPE(
1470             cb->env, napi_create_int32(cb->env, cb->errCode, &callResult), CREATE_INT32, scope);
1471         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1472     }
1473     napi_close_handle_scope(cb->env, scope);
1474 }
1475 
EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb,int32_t errCode)1476 void JsEventTarget::EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb, int32_t errCode)
1477 {
1478     CALL_DEBUG_ENTER;
1479     CHKPV(cb);
1480     CHKPV(cb->env);
1481     cb->errCode = errCode;
1482     uv_loop_s *loop = nullptr;
1483     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1484 
1485     uv_work_t *work = new (std::nothrow) uv_work_t;
1486     CHKPV(work);
1487     cb->IncStrongRef(nullptr);
1488     work->data = cb.GetRefPtr();
1489     int32_t ret = -1;
1490     if (cb->ref == nullptr) {
1491         ret = uv_queue_work_with_qos(
1492             loop, work,
1493             [](uv_work_t *work) {
1494                 MMI_HILOGD("uv_queue_work callback function is called");
1495             },
1496             CallSetInputDeviceEnabledPromise, uv_qos_user_initiated);
1497     }
1498     if (ret != 0) {
1499         MMI_HILOGE("uv_queue_work_with_qos failed");
1500         JsUtil::DeletePtr<uv_work_t *>(work);
1501     }
1502 }
1503 
EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey,bool state)1504 void JsEventTarget::EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey, bool state)
1505 {
1506     CALL_DEBUG_ENTER;
1507     CHKPV(cb);
1508     int32_t keyState = state ? 1 : 0;
1509     cb->uData.keys.push_back(funcKey);
1510     cb->uData.keys.push_back(keyState);
1511     cb->setFuncKeyType = true;
1512     cb->errCode = -1;
1513     uv_loop_s *loop = nullptr;
1514     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1515     uv_work_t *work = new (std::nothrow) uv_work_t;
1516     CHKPV(work);
1517     cb->IncStrongRef(nullptr);
1518     // data heap point cb pointer
1519     work->data = cb.GetRefPtr();
1520     int32_t ret = -1;
1521     ret = uv_queue_work_with_qos(
1522         loop, work,
1523         [](uv_work_t *work) {
1524             MMI_HILOGD("uv_queue_work callback function is called");
1525             CallFunctionKeyStateTask(work);
1526         },
1527         CallFunctionKeyState, uv_qos_user_initiated);
1528     if (ret != 0) {
1529         MMI_HILOGE("uv_queue_work_with_qos failed");
1530         cb->DecStrongRef(nullptr);
1531         JsUtil::DeletePtr<uv_work_t *>(work);
1532     }
1533 }
1534 
EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey)1535 void JsEventTarget::EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey)
1536 {
1537     CALL_DEBUG_ENTER;
1538     CHKPV(cb);
1539     cb->uData.keys.push_back(funcKey);
1540     cb->getFuncKeyType = true;
1541     uv_loop_s *loop = nullptr;
1542     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1543     uv_work_t *work = new (std::nothrow) uv_work_t;
1544     CHKPV(work);
1545     cb->IncStrongRef(nullptr);
1546     work->data = cb.GetRefPtr();
1547     int32_t ret = -1;
1548     ret = uv_queue_work_with_qos(
1549         loop, work,
1550         [](uv_work_t *work) {
1551             MMI_HILOGD("uv_queue_work callback function is called");
1552             CallFunctionKeyStateTask(work);
1553         },
1554         CallFunctionKeyState, uv_qos_user_initiated);
1555     if (ret != 0) {
1556         MMI_HILOGE("uv_queue_work_with_qos failed");
1557         cb->DecStrongRef(nullptr);
1558         JsUtil::DeletePtr<uv_work_t *>(work);
1559     }
1560 }
1561 
CallFunctionKeyStateTask(uv_work_t * work)1562 void JsEventTarget::CallFunctionKeyStateTask(uv_work_t *work)
1563 {
1564     CHKPV(work);
1565     if (work->data == nullptr) {
1566         JsUtil::DeletePtr<uv_work_t *>(work);
1567         MMI_HILOGE("Check data is nullptr");
1568         return;
1569     }
1570     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1571     CHKPV(cb->env);
1572     if (cb->getFuncKeyType) {
1573         bool resultState = false;
1574         auto funcKey = cb->uData.keys.front();
1575         int32_t napiCode = InputManager::GetInstance()->GetFunctionKeyState(funcKey, resultState);
1576         int32_t keyState = resultState ? 1 : 0;
1577         cb->errCode = napiCode;
1578         cb->uData.keys.push_back(keyState);
1579     }
1580     if (cb->setFuncKeyType) {
1581         auto funcKey = cb->uData.keys.front();
1582         auto state = cb->uData.keys.back();
1583         int32_t napiCode = InputManager::GetInstance()->SetFunctionKeyState(funcKey, state);
1584         cb->errCode = napiCode;
1585     }
1586 }
1587 
GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb,napi_handle_scope scope,napi_value & callResult)1588 bool JsEventTarget::GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb, napi_handle_scope scope,
1589     napi_value &callResult)
1590 {
1591     CALL_DEBUG_ENTER;
1592     CHKPF(cb);
1593     if (cb->errCode == RET_ERR) {
1594         napi_close_handle_scope(cb->env, scope);
1595         MMI_HILOGE("return value errors");
1596         return false;
1597     }
1598     NapiError codeMsg;
1599     if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1600         napi_close_handle_scope(cb->env, scope);
1601         MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1602         return false;
1603     }
1604     callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1605     if (callResult == nullptr) {
1606         MMI_HILOGE("The callResult is nullptr");
1607         napi_close_handle_scope(cb->env, scope);
1608         return false;
1609     }
1610     return true;
1611 }
1612 
CallFunctionKeyState(uv_work_t * work,int32_t status)1613 void JsEventTarget::CallFunctionKeyState(uv_work_t *work, int32_t status)
1614 {
1615     CALL_DEBUG_ENTER;
1616     CHKPV(work);
1617     if (work->data == nullptr) {
1618         JsUtil::DeletePtr<uv_work_t *>(work);
1619         return;
1620     }
1621     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1622     JsUtil::DeletePtr<uv_work_t *>(work);
1623     cb->DecStrongRef(nullptr);
1624     CHKPV(cb->env);
1625     napi_handle_scope scope = nullptr;
1626     napi_open_handle_scope(cb->env, &scope);
1627     CHKPV(scope);
1628     napi_value callResult = nullptr;
1629     if (cb->errCode != RET_OK) {
1630         if (!GetFunctionKeyStateErrCode(cb, scope, callResult)) {
1631             MMI_HILOGE("promise get function key state error");
1632             return;
1633         }
1634         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1635     } else {
1636         if (cb->getFuncKeyType) {
1637             auto state = cb->uData.keys.back();
1638             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, state, &callResult), CREATE_INT32, scope);
1639         } else {
1640             CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult), GET_UNDEFINED, scope);
1641         }
1642         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1643     }
1644     napi_close_handle_scope(cb->env, scope);
1645 }
1646 
CallKeyboardRepeatDelayTask(uv_work_t * work,const std::string & operateType)1647 void JsEventTarget::CallKeyboardRepeatDelayTask(uv_work_t *work, const std::string& operateType)
1648 {
1649     CHKPV(work);
1650     if (work->data == nullptr) {
1651         JsUtil::DeletePtr<uv_work_t *>(work);
1652         MMI_HILOGE("Check data is nullptr");
1653         return;
1654     }
1655     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1656     CHKPV(cb->env);
1657 
1658     if (operateType == "get") {
1659         int32_t _delay = -1;
1660         auto callback = [&_delay] (int32_t delay) { _delay = delay; };
1661         int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatDelay(callback);
1662         cb->errCode = napiCode;
1663         cb->data.keyboardRepeatDelay = _delay;
1664     } else {
1665         int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatDelay(cb->data.keyboardRepeatDelay);
1666         cb->errCode = napiCode;
1667     }
1668 }
1669 
CallKeyboardRepeatRateTask(uv_work_t * work,const std::string & operateType)1670 void JsEventTarget::CallKeyboardRepeatRateTask(uv_work_t *work, const std::string& operateType)
1671 {
1672     CHKPV(work);
1673     if (work->data == nullptr) {
1674         JsUtil::DeletePtr<uv_work_t *>(work);
1675         MMI_HILOGE("Check data is nullptr");
1676         return;
1677     }
1678     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1679     CHKPV(cb->env);
1680 
1681     if (operateType == "get") {
1682         int32_t _rate = -1;
1683         auto callback = [&_rate] (int32_t rate) { _rate = rate; };
1684         int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatRate(callback);
1685         cb->errCode = napiCode;
1686         cb->data.keyboardRepeatRate = _rate;
1687     } else {
1688         int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatRate(cb->data.keyboardRepeatRate);
1689         cb->errCode = napiCode;
1690     }
1691 }
1692 
CallGetKeyboardTypeTask(uv_work_t * work)1693 void JsEventTarget::CallGetKeyboardTypeTask(uv_work_t *work)
1694 {
1695     CHKPV(work);
1696     if (work->data == nullptr) {
1697         JsUtil::DeletePtr<uv_work_t *>(work);
1698         MMI_HILOGE("Check data is nullptr");
1699         return;
1700     }
1701     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1702     CHKPV(cb->env);
1703 
1704     int32_t _keyboardtype = -1;
1705     auto callback = [&_keyboardtype] (int32_t keyboardtype) { _keyboardtype = keyboardtype; };
1706     int32_t napiCode = InputManager::GetInstance()->GetKeyboardType(cb->data.deviceId, callback);
1707     cb->errCode = napiCode;
1708     cb->data.keyboardType = _keyboardtype;
1709 }
1710 
CallJsIdsTask(uv_work_t * work)1711 void JsEventTarget::CallJsIdsTask(uv_work_t *work)
1712 {
1713     CHKPV(work);
1714     if (work->data == nullptr) {
1715         JsUtil::DeletePtr<uv_work_t *>(work);
1716         MMI_HILOGE("Check data is nullptr");
1717         return;
1718     }
1719     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1720     CHKPV(cb->env);
1721     std::vector<int32_t> _ids;
1722     auto callback = [&_ids] (std::vector<int32_t>& ids) { _ids = ids; };
1723     int32_t napiCode = InputManager::GetInstance()->GetDeviceIds(callback);
1724     cb->errCode = napiCode;
1725     cb->data.ids = _ids;
1726 }
1727 
CallJsDevTask(uv_work_t * work)1728 void JsEventTarget::CallJsDevTask(uv_work_t *work)
1729 {
1730     CHKPV(work);
1731     if (work->data == nullptr) {
1732         JsUtil::DeletePtr<uv_work_t *>(work);
1733         MMI_HILOGE("Check data is nullptr");
1734         return;
1735     }
1736     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1737     CHKPV(cb->env);
1738     std::shared_ptr<InputDevice> _device = std::make_shared<InputDevice>();
1739     auto callback = [&_device] (std::shared_ptr<InputDevice> device) { _device = device; };
1740     int32_t napiCode = InputManager::GetInstance()->GetDevice(cb->data.deviceId, callback);
1741     CHKPV(_device);
1742     cb->errCode = napiCode;
1743     cb->data.device = _device;
1744 }
1745 
CallSupportKeysTask(uv_work_t * work)1746 void JsEventTarget::CallSupportKeysTask(uv_work_t *work)
1747 {
1748     CHKPV(work);
1749     if (work->data == nullptr) {
1750         JsUtil::DeletePtr<uv_work_t *>(work);
1751         MMI_HILOGE("Check data is nullptr");
1752         return;
1753     }
1754     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1755     CHKPV(cb->env);
1756     auto callback = [&] (std::vector<bool>& keystrokeAbility) {
1757         cb->data.keystrokeAbility = keystrokeAbility;
1758     };
1759     int32_t napiCode = InputManager::GetInstance()->SupportKeys(cb->data.deviceId, cb->data.ids, callback);
1760     cb->errCode = napiCode;
1761 }
CallIntervalSinceLastInputTask(uv_work_t * work)1762 void JsEventTarget::CallIntervalSinceLastInputTask(uv_work_t *work)
1763 {
1764     CHKPV(work);
1765     if (work->data == nullptr) {
1766         JsUtil::DeletePtr<uv_work_t *>(work);
1767         MMI_HILOGE("Check data is nullptr");
1768         return;
1769     }
1770     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1771     CHKPV(cb->env);
1772     int32_t napiCode = InputManager::GetInstance()->GetIntervalSinceLastInput(cb->data.IntervalSinceLastInput);
1773     cb->errCode = napiCode;
1774 }
1775 } // namespace MMI
1776 } // namespace OHOS
1777