• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #include "js_util.h"
18 #include "napi_constants.h"
19 #include "util_napi_error.h"
20 
21 namespace OHOS {
22 namespace MMI {
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "JsEventTarget" };
25 constexpr int32_t INPUT_PARAMETER_MIDDLE = 2;
26 
27 std::mutex mutex_;
28 const std::string ADD_EVENT = "add";
29 const std::string REMOVE_EVENT = "remove";
30 } // namespace
31 
JsEventTarget()32 JsEventTarget::JsEventTarget()
33 {
34     CALL_DEBUG_ENTER;
35     std::lock_guard<std::mutex> lock(mutex_);
36     auto ret = devListener_.insert({ CHANGED_TYPE, std::vector<std::unique_ptr<JsUtil::CallbackInfo>>() });
37     CK(ret.second, VAL_NOT_EXP);
38 }
39 
EmitAddedDeviceEvent(uv_work_t * work,int32_t status)40 void JsEventTarget::EmitAddedDeviceEvent(uv_work_t *work, int32_t status)
41 {
42     CALL_DEBUG_ENTER;
43     std::lock_guard<std::mutex> guard(mutex_);
44     CHKPV(work);
45     if (work->data == nullptr) {
46         JsUtil::DeletePtr<uv_work_t *>(work);
47         MMI_HILOGE("Check data is nullptr");
48         return;
49     }
50     auto temp = static_cast<std::unique_ptr<JsUtil::CallbackInfo> *>(work->data);
51     JsUtil::DeletePtr<uv_work_t *>(work);
52     auto addEvent = devListener_.find(CHANGED_TYPE);
53     if (addEvent == devListener_.end()) {
54         MMI_HILOGE("Find change event failed");
55         return;
56     }
57 
58     for (const auto &item : addEvent->second) {
59         CHKPC(item->env);
60         if (item->ref != (*temp)->ref) {
61             continue;
62         }
63         napi_handle_scope scope = nullptr;
64         napi_open_handle_scope(item->env, &scope);
65         if (scope == nullptr) {
66             MMI_HILOGE("scope is nullptr");
67             return;
68         }
69         napi_value eventType = nullptr;
70         CHKRV_SCOPE(item->env, napi_create_string_utf8(item->env, ADD_EVENT.c_str(), NAPI_AUTO_LENGTH, &eventType),
71             CREATE_STRING_UTF8, scope);
72         napi_value object = nullptr;
73         CHKRV_SCOPE(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
74         CHKRV_SCOPE(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
75             scope);
76         napi_value handler = nullptr;
77         CHKRV_SCOPE(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE, scope);
78         for (const auto &devId : item->data.deviceIds) {
79             napi_value deviceId = nullptr;
80             CHKRV_SCOPE(item->env, napi_create_int32(item->env, devId, &deviceId), CREATE_INT32, scope);
81             CHKRV_SCOPE(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
82                 scope);
83             napi_value ret = nullptr;
84             CHKRV_SCOPE(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
85                 scope);
86         }
87         item->data.deviceIds.clear();
88         napi_close_handle_scope(item->env, scope);
89     }
90 }
91 
EmitRemoveDeviceEvent(uv_work_t * work,int32_t status)92 void JsEventTarget::EmitRemoveDeviceEvent(uv_work_t *work, int32_t status)
93 {
94     CALL_DEBUG_ENTER;
95     std::lock_guard<std::mutex> guard(mutex_);
96     CHKPV(work);
97     if (work->data == nullptr) {
98         JsUtil::DeletePtr<uv_work_t *>(work);
99         MMI_HILOGE("Check data is nullptr");
100         return;
101     }
102     auto temp = static_cast<std::unique_ptr<JsUtil::CallbackInfo> *>(work->data);
103     JsUtil::DeletePtr<uv_work_t *>(work);
104     auto removeEvent = devListener_.find(CHANGED_TYPE);
105     if (removeEvent == devListener_.end()) {
106         MMI_HILOGE("Find change event failed");
107         return;
108     }
109 
110     for (const auto &item : removeEvent->second) {
111         CHKPC(item->env);
112         if (item->ref != (*temp)->ref) {
113             continue;
114         }
115         napi_handle_scope scope = nullptr;
116         napi_open_handle_scope(item->env, &scope);
117         CHKPV(scope);
118         for (const auto &devId : item->data.deviceIds) {
119             napi_value eventType = nullptr;
120             CHKRV_SCOPE(item->env,
121                 napi_create_string_utf8(item->env, REMOVE_EVENT.c_str(), NAPI_AUTO_LENGTH, &eventType),
122                 CREATE_STRING_UTF8, scope);
123 
124             napi_value deviceId = nullptr;
125             CHKRV_SCOPE(item->env, napi_create_int32(item->env, devId, &deviceId), CREATE_INT32, scope);
126 
127             napi_value object = nullptr;
128             CHKRV_SCOPE(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
129             CHKRV_SCOPE(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
130                 scope);
131             CHKRV_SCOPE(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
132                 scope);
133 
134             napi_value handler = nullptr;
135             CHKRV_SCOPE(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE,
136                 scope);
137 
138             napi_value ret = nullptr;
139             CHKRV_SCOPE(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
140                 scope);
141         }
142         item->data.deviceIds.clear();
143         napi_close_handle_scope(item->env, scope);
144     }
145 }
146 
OnDeviceAdded(int32_t deviceId,const std::string & type)147 void JsEventTarget::OnDeviceAdded(int32_t deviceId, const std::string &type)
148 {
149     CALL_DEBUG_ENTER;
150     std::lock_guard<std::mutex> guard(mutex_);
151     auto changeEvent = devListener_.find(CHANGED_TYPE);
152     if (changeEvent == devListener_.end()) {
153         MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
154         return;
155     }
156 
157     for (auto &item : changeEvent->second) {
158         CHKPC(item);
159         CHKPC(item->env);
160         uv_loop_s *loop = nullptr;
161         CHKRV(napi_get_uv_event_loop(item->env, &loop), GET_UV_EVENT_LOOP);
162         uv_work_t *work = new (std::nothrow) uv_work_t;
163         CHKPV(work);
164         item->data.deviceIds.push_back(deviceId);
165         work->data = static_cast<void *>(&item);
166         int32_t ret = uv_queue_work(
167             loop, work, [](uv_work_t *work) {}, EmitAddedDeviceEvent);
168         if (ret != 0) {
169             MMI_HILOGE("uv_queue_work failed");
170             JsUtil::DeletePtr<uv_work_t *>(work);
171             return;
172         }
173     }
174 }
175 
OnDeviceRemoved(int32_t deviceId,const std::string & type)176 void JsEventTarget::OnDeviceRemoved(int32_t deviceId, const std::string &type)
177 {
178     CALL_DEBUG_ENTER;
179     std::lock_guard<std::mutex> guard(mutex_);
180     auto changeEvent = devListener_.find(CHANGED_TYPE);
181     if (changeEvent == devListener_.end()) {
182         MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
183         return;
184     }
185     for (auto &item : changeEvent->second) {
186         CHKPC(item);
187         CHKPC(item->env);
188         uv_loop_s *loop = nullptr;
189         CHKRV(napi_get_uv_event_loop(item->env, &loop), GET_UV_EVENT_LOOP);
190         uv_work_t *work = new (std::nothrow) uv_work_t;
191         CHKPV(work);
192         item->data.deviceIds.push_back(deviceId);
193         work->data = static_cast<void *>(&item);
194         int32_t ret = uv_queue_work(
195             loop, work, [](uv_work_t *work) {}, EmitRemoveDeviceEvent);
196         if (ret != 0) {
197             MMI_HILOGE("uv_queue_work failed");
198             JsUtil::DeletePtr<uv_work_t *>(work);
199             return;
200         }
201     }
202 }
203 
CallIdsAsyncWork(uv_work_t * work,int32_t status)204 void JsEventTarget::CallIdsAsyncWork(uv_work_t *work, int32_t status)
205 {
206     CALL_DEBUG_ENTER;
207     CHKPV(work);
208     if (work->data == nullptr) {
209         JsUtil::DeletePtr<uv_work_t *>(work);
210         MMI_HILOGE("Check data is nullptr");
211         return;
212     }
213     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
214     JsUtil::DeletePtr<uv_work_t *>(work);
215     cb->DecStrongRef(nullptr);
216     CHKPV(cb->env);
217     napi_handle_scope scope = nullptr;
218     napi_open_handle_scope(cb->env, &scope);
219     if (scope == nullptr) {
220         MMI_HILOGE("scope is nullptr");
221         return;
222     }
223     napi_value arr[2];
224     CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &arr[0]), GET_UNDEFINED, scope);
225     CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr[1]), CREATE_ARRAY, scope);
226     uint32_t index = 0;
227     napi_value value = nullptr;
228     for (const auto &item : cb->data.ids) {
229         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
230         CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr[1], index, value), SET_ELEMENT, scope);
231         ++index;
232     }
233 
234     napi_value handler = nullptr;
235     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
236     napi_value result = nullptr;
237     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, arr, &result),
238         CALL_FUNCTION, scope);
239     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
240     napi_close_handle_scope(cb->env, scope);
241 }
242 
CallIdsPromiseWork(uv_work_t * work,int32_t status)243 void JsEventTarget::CallIdsPromiseWork(uv_work_t *work, int32_t status)
244 {
245     CALL_DEBUG_ENTER;
246     CHKPV(work);
247     if (work->data == nullptr) {
248         JsUtil::DeletePtr<uv_work_t *>(work);
249         MMI_HILOGE("Check data is nullptr");
250         return;
251     }
252     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
253     JsUtil::DeletePtr<uv_work_t *>(work);
254     cb->DecStrongRef(nullptr);
255     CHKPV(cb->env);
256     napi_handle_scope scope = nullptr;
257     napi_open_handle_scope(cb->env, &scope);
258     if (scope == nullptr) {
259         MMI_HILOGE("scope is nullptr");
260         return;
261     }
262     napi_value arr = nullptr;
263     CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr), CREATE_ARRAY, scope);
264     uint32_t index = 0;
265     napi_value value = nullptr;
266     for (const auto &item : cb->data.ids) {
267         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
268         CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr, index, value), SET_ELEMENT, scope);
269         ++index;
270     }
271     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, arr), RESOLVE_DEFERRED, scope);
272     napi_close_handle_scope(cb->env, scope);
273 }
274 
EmitJsIds(sptr<JsUtil::CallbackInfo> cb,std::vector<int32_t> & ids)275 void JsEventTarget::EmitJsIds(sptr<JsUtil::CallbackInfo> cb, std::vector<int32_t> &ids)
276 {
277     CALL_DEBUG_ENTER;
278     CHKPV(cb);
279     CHKPV(cb->env);
280     cb->data.ids = ids;
281     cb->errCode = RET_OK;
282     uv_loop_s *loop = nullptr;
283     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
284     uv_work_t *work = new (std::nothrow) uv_work_t;
285     CHKPV(work);
286     cb->IncStrongRef(nullptr);
287     work->data = cb.GetRefPtr();
288     int32_t ret;
289     if (cb->isApi9) {
290         if (cb->ref == nullptr) {
291             ret = uv_queue_work(
292                 loop, work, [](uv_work_t *work) {}, CallDevListPromiseWork);
293         } else {
294             ret = uv_queue_work(
295                 loop, work, [](uv_work_t *work) {}, CallDevListAsyncWork);
296         }
297     } else {
298         if (cb->ref == nullptr) {
299             ret = uv_queue_work(
300                 loop, work, [](uv_work_t *work) {}, CallIdsPromiseWork);
301         } else {
302             ret = uv_queue_work(
303                 loop, work, [](uv_work_t *work) {}, CallIdsAsyncWork);
304         }
305     }
306     if (ret != 0) {
307         MMI_HILOGE("uv_queue_work failed");
308         JsUtil::DeletePtr<uv_work_t *>(work);
309     }
310 }
311 
CallDevAsyncWork(uv_work_t * work,int32_t status)312 void JsEventTarget::CallDevAsyncWork(uv_work_t *work, int32_t status)
313 {
314     CALL_DEBUG_ENTER;
315     CHKPV(work);
316     if (work->data == nullptr) {
317         JsUtil::DeletePtr<uv_work_t *>(work);
318         MMI_HILOGE("Check data is nullptr");
319         return;
320     }
321     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
322     JsUtil::DeletePtr<uv_work_t *>(work);
323     cb->DecStrongRef(nullptr);
324     CHKPV(cb->env);
325     napi_handle_scope scope = nullptr;
326     napi_open_handle_scope(cb->env, &scope);
327     if (scope == nullptr) {
328         MMI_HILOGE("scope is nullptr");
329         return;
330     }
331     napi_value object[2];
332     CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &object[0]), GET_UNDEFINED, scope);
333     object[1] = JsUtil::GetDeviceInfo(cb);
334     napi_value handler = nullptr;
335     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
336     napi_value result = nullptr;
337     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, object, &result),
338         CALL_FUNCTION, scope);
339     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
340     napi_close_handle_scope(cb->env, scope);
341 }
342 
CallDevPromiseWork(uv_work_t * work,int32_t status)343 void JsEventTarget::CallDevPromiseWork(uv_work_t *work, int32_t status)
344 {
345     CALL_DEBUG_ENTER;
346     CHKPV(work);
347     if (work->data == nullptr) {
348         JsUtil::DeletePtr<uv_work_t *>(work);
349         MMI_HILOGE("Check data is nullptr");
350         return;
351     }
352     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
353     JsUtil::DeletePtr<uv_work_t *>(work);
354     cb->DecStrongRef(nullptr);
355     CHKPV(cb->env);
356     napi_handle_scope scope = nullptr;
357     napi_open_handle_scope(cb->env, &scope);
358     if (scope == nullptr) {
359         MMI_HILOGE("scope is nullptr");
360         return;
361     }
362     napi_value object = JsUtil::GetDeviceInfo(cb);
363     if (object == nullptr) {
364         MMI_HILOGE("Check object is nullptr");
365         napi_close_handle_scope(cb->env, scope);
366         return;
367     }
368     CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
369     napi_close_handle_scope(cb->env, scope);
370 }
371 
EmitJsDev(sptr<JsUtil::CallbackInfo> cb,std::shared_ptr<InputDevice> device)372 void JsEventTarget::EmitJsDev(sptr<JsUtil::CallbackInfo> cb, std::shared_ptr<InputDevice> device)
373 {
374     CALL_DEBUG_ENTER;
375     CHKPV(device);
376     CHKPV(cb);
377     CHKPV(cb->env);
378     cb->data.device = device;
379     cb->errCode = RET_OK;
380     uv_loop_s *loop = nullptr;
381     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
382     uv_work_t *work = new (std::nothrow) uv_work_t;
383     CHKPV(work);
384     cb->IncStrongRef(nullptr);
385     work->data = cb.GetRefPtr();
386     int32_t ret;
387     if (cb->isApi9) {
388         if (cb->ref == nullptr) {
389             ret = uv_queue_work(
390                 loop, work, [](uv_work_t *work) {}, CallDevInfoPromiseWork);
391         } else {
392             ret = uv_queue_work(
393                 loop, work, [](uv_work_t *work) {}, CallDevInfoAsyncWork);
394         }
395     } else {
396         if (cb->ref == nullptr) {
397             ret = uv_queue_work(
398                 loop, work, [](uv_work_t *work) {}, CallDevPromiseWork);
399         } else {
400             ret = uv_queue_work(
401                 loop, work, [](uv_work_t *work) {}, CallDevAsyncWork);
402         }
403     }
404     if (ret != 0) {
405         MMI_HILOGE("uv_queue_work failed");
406         JsUtil::DeletePtr<uv_work_t *>(work);
407     }
408 }
409 
CallKeystrokeAbilityPromise(uv_work_t * work,int32_t status)410 void JsEventTarget::CallKeystrokeAbilityPromise(uv_work_t *work, int32_t status)
411 {
412     CALL_DEBUG_ENTER;
413     CHKPV(work);
414     if (work->data == nullptr) {
415         JsUtil::DeletePtr<uv_work_t *>(work);
416         MMI_HILOGE("Check data is nullptr");
417         return;
418     }
419     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
420     JsUtil::DeletePtr<uv_work_t *>(work);
421     cb->DecStrongRef(nullptr);
422     CHKPV(cb->env);
423     napi_handle_scope scope = nullptr;
424     napi_open_handle_scope(cb->env, &scope);
425     CHKPV(scope);
426     napi_value callResult = nullptr;
427     if (cb->errCode != RET_OK) {
428         if (cb->errCode == RET_ERR) {
429             napi_close_handle_scope(cb->env, scope);
430             MMI_HILOGE("Other errors");
431             return;
432         }
433         NapiError codeMsg;
434         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
435             napi_close_handle_scope(cb->env, scope);
436             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
437             return;
438         }
439         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
440         if (callResult == nullptr) {
441             MMI_HILOGE("callResult is nullptr");
442             napi_close_handle_scope(cb->env, scope);
443             return;
444         }
445         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
446     } else {
447         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult), CREATE_ARRAY, scope);
448         for (size_t i = 0; i < cb->data.keystrokeAbility.size(); ++i) {
449             napi_value ret = nullptr;
450             napi_value isSupport = nullptr;
451             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keystrokeAbility[i] ? 1 : 0, &ret), CREATE_INT32,
452                 scope);
453             CHKRV_SCOPE(cb->env, napi_coerce_to_bool(cb->env, ret, &isSupport), COERCE_TO_BOOL, scope);
454             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult, static_cast<uint32_t>(i), isSupport),
455                 SET_ELEMENT, scope);
456         }
457         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
458     }
459     napi_close_handle_scope(cb->env, scope);
460 }
461 
CallKeystrokeAbilityAsync(uv_work_t * work,int32_t status)462 void JsEventTarget::CallKeystrokeAbilityAsync(uv_work_t *work, int32_t status)
463 {
464     CALL_DEBUG_ENTER;
465     CHKPV(work);
466     if (work->data == nullptr) {
467         JsUtil::DeletePtr<uv_work_t *>(work);
468         MMI_HILOGE("Check data is nullptr");
469         return;
470     }
471     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
472     JsUtil::DeletePtr<uv_work_t *>(work);
473     cb->DecStrongRef(nullptr);
474     CHKPV(cb->env);
475     napi_handle_scope scope = nullptr;
476     napi_open_handle_scope(cb->env, &scope);
477     CHKPV(scope);
478     napi_value callResult[2] = { 0 };
479     if (cb->errCode != RET_OK) {
480         if (cb->errCode == RET_ERR) {
481             napi_close_handle_scope(cb->env, scope);
482             MMI_HILOGE("Other errors");
483             return;
484         }
485         NapiError codeMsg;
486         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
487             napi_close_handle_scope(cb->env, scope);
488             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
489             return;
490         }
491         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
492         if (callResult[0] == nullptr) {
493             MMI_HILOGE("callResult[0] is nullptr");
494             napi_close_handle_scope(cb->env, scope);
495             return;
496         }
497         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
498     } else {
499         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult[1]), CREATE_ARRAY, scope);
500         for (size_t i = 0; i < cb->data.keystrokeAbility.size(); ++i) {
501             napi_value ret = nullptr;
502             napi_value isSupport = nullptr;
503             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keystrokeAbility[i] ? 1 : 0, &ret), CREATE_INT32,
504                 scope);
505             CHKRV_SCOPE(cb->env, napi_coerce_to_bool(cb->env, ret, &isSupport), COERCE_TO_BOOL, scope);
506             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult[1], static_cast<uint32_t>(i), isSupport),
507                 SET_ELEMENT, scope);
508         }
509         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
510     }
511     napi_value handler = nullptr;
512     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
513     napi_value result = nullptr;
514     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
515         CALL_FUNCTION, scope);
516     napi_close_handle_scope(cb->env, scope);
517 }
518 
EmitSupportKeys(sptr<JsUtil::CallbackInfo> cb,std::vector<bool> & keystrokeAbility)519 void JsEventTarget::EmitSupportKeys(sptr<JsUtil::CallbackInfo> cb, std::vector<bool> &keystrokeAbility)
520 {
521     CALL_DEBUG_ENTER;
522     CHKPV(cb);
523     CHKPV(cb->env);
524     cb->data.keystrokeAbility = keystrokeAbility;
525     cb->errCode = RET_OK;
526     uv_loop_s *loop = nullptr;
527     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
528     uv_work_t *work = new (std::nothrow) uv_work_t;
529     CHKPV(work);
530     cb->IncStrongRef(nullptr);
531     work->data = cb.GetRefPtr();
532     int32_t ret;
533     if (cb->ref == nullptr) {
534         ret = uv_queue_work(
535             loop, work, [](uv_work_t *work) {}, CallKeystrokeAbilityPromise);
536     } else {
537         ret = uv_queue_work(
538             loop, work, [](uv_work_t *work) {}, CallKeystrokeAbilityAsync);
539     }
540     if (ret != 0) {
541         MMI_HILOGE("uv_queue_work failed");
542         JsUtil::DeletePtr<uv_work_t *>(work);
543     }
544 }
545 
EmitJsKeyboardType(sptr<JsUtil::CallbackInfo> cb,int32_t keyboardType)546 void JsEventTarget::EmitJsKeyboardType(sptr<JsUtil::CallbackInfo> cb, int32_t keyboardType)
547 {
548     CALL_DEBUG_ENTER;
549     CHKPV(cb);
550     CHKPV(cb->env);
551     cb->data.keyboardType = keyboardType;
552     cb->errCode = RET_OK;
553     uv_loop_s *loop = nullptr;
554     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
555 
556     uv_work_t *work = new (std::nothrow) uv_work_t;
557     CHKPV(work);
558     cb->IncStrongRef(nullptr);
559     work->data = cb.GetRefPtr();
560     int32_t ret;
561     if (cb->ref == nullptr) {
562         ret = uv_queue_work(
563             loop, work, [](uv_work_t *work) {}, CallKeyboardTypePromise);
564     } else {
565         ret = uv_queue_work(
566             loop, work, [](uv_work_t *work) {}, CallKeyboardTypeAsync);
567     }
568     if (ret != 0) {
569         MMI_HILOGE("uv_queue_work failed");
570         JsUtil::DeletePtr<uv_work_t *>(work);
571     }
572 }
573 
CallKeyboardTypeAsync(uv_work_t * work,int32_t status)574 void JsEventTarget::CallKeyboardTypeAsync(uv_work_t *work, int32_t status)
575 {
576     CALL_DEBUG_ENTER;
577     CHKPV(work);
578     if (work->data == nullptr) {
579         JsUtil::DeletePtr<uv_work_t *>(work);
580         MMI_HILOGE("Check data is nullptr");
581         return;
582     }
583     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
584     JsUtil::DeletePtr<uv_work_t *>(work);
585     cb->DecStrongRef(nullptr);
586     CHKPV(cb->env);
587 
588     napi_handle_scope scope = nullptr;
589     napi_open_handle_scope(cb->env, &scope);
590     CHKPV(scope);
591 
592     napi_value callResult[2] = { 0 };
593     if (cb->errCode != RET_OK) {
594         if (cb->errCode == RET_ERR) {
595             napi_close_handle_scope(cb->env, scope);
596             MMI_HILOGE("Other errors");
597             return;
598         }
599         NapiError codeMsg;
600         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
601             napi_close_handle_scope(cb->env, scope);
602             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
603             return;
604         }
605         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
606         if (callResult[0] == nullptr) {
607             MMI_HILOGE("callResult[0] is nullptr");
608             napi_close_handle_scope(cb->env, scope);
609             return;
610         }
611         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
612     } else {
613         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keyboardType, &callResult[1]), CREATE_INT32, scope);
614         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
615     }
616     napi_value handler = nullptr;
617     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
618     napi_value result = nullptr;
619     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
620         CALL_FUNCTION, scope);
621     napi_close_handle_scope(cb->env, scope);
622 }
623 
CallKeyboardTypePromise(uv_work_t * work,int32_t status)624 void JsEventTarget::CallKeyboardTypePromise(uv_work_t *work, int32_t status)
625 {
626     CALL_DEBUG_ENTER;
627     CHKPV(work);
628     if (work->data == nullptr) {
629         JsUtil::DeletePtr<uv_work_t *>(work);
630         MMI_HILOGE("Check data is nullptr");
631         return;
632     }
633     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
634     JsUtil::DeletePtr<uv_work_t *>(work);
635     cb->DecStrongRef(nullptr);
636     CHKPV(cb->env);
637 
638     napi_handle_scope scope = nullptr;
639     napi_open_handle_scope(cb->env, &scope);
640     CHKPV(scope);
641 
642     napi_value callResult;
643     if (cb->errCode != RET_OK) {
644         if (cb->errCode == RET_ERR) {
645             napi_close_handle_scope(cb->env, scope);
646             MMI_HILOGE("Other errors");
647             return;
648         }
649         NapiError codeMsg;
650         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
651             napi_close_handle_scope(cb->env, scope);
652             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
653             return;
654         }
655         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
656         if (callResult == nullptr) {
657             MMI_HILOGE("callResult is nullptr");
658             napi_close_handle_scope(cb->env, scope);
659             return;
660         }
661         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
662     } else {
663         CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keyboardType, &callResult), CREATE_INT32, scope);
664         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
665     }
666     napi_close_handle_scope(cb->env, scope);
667 }
668 
CallDevListAsyncWork(uv_work_t * work,int32_t status)669 void JsEventTarget::CallDevListAsyncWork(uv_work_t *work, int32_t status)
670 {
671     CALL_DEBUG_ENTER;
672     CHKPV(work);
673     if (work->data == nullptr) {
674         JsUtil::DeletePtr<uv_work_t *>(work);
675         MMI_HILOGE("Check data is nullptr");
676         return;
677     }
678     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
679     JsUtil::DeletePtr<uv_work_t *>(work);
680     cb->DecStrongRef(nullptr);
681     CHKPV(cb->env);
682     napi_handle_scope scope = nullptr;
683     napi_open_handle_scope(cb->env, &scope);
684     CHKPV(scope);
685 
686     napi_value callResult[2] = { 0 };
687     if (cb->errCode != RET_OK) {
688         if (cb->errCode == RET_ERR) {
689             napi_close_handle_scope(cb->env, scope);
690             MMI_HILOGE("Other errors");
691             return;
692         }
693         NapiError codeMsg;
694         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
695             napi_close_handle_scope(cb->env, scope);
696             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
697             return;
698         }
699         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
700         CHKNRV_SCOPE(cb->env, callResult[0], "callResult[0]", scope);
701         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
702     } else {
703         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult[1]), CREATE_ARRAY, scope);
704         uint32_t index = 0;
705         napi_value value = nullptr;
706         for (const auto &item : cb->data.ids) {
707             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
708             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult[1], index, value), SET_ELEMENT, scope);
709             ++index;
710         }
711         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
712     }
713     napi_value handler = nullptr;
714     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
715     napi_value result = nullptr;
716     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
717         CALL_FUNCTION, scope);
718     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
719     napi_close_handle_scope(cb->env, scope);
720 }
721 
CallDevListPromiseWork(uv_work_t * work,int32_t status)722 void JsEventTarget::CallDevListPromiseWork(uv_work_t *work, int32_t status)
723 {
724     CALL_DEBUG_ENTER;
725     CHKPV(work);
726     if (work->data == nullptr) {
727         JsUtil::DeletePtr<uv_work_t *>(work);
728         MMI_HILOGE("Check data is nullptr");
729         return;
730     }
731     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
732     JsUtil::DeletePtr<uv_work_t *>(work);
733     cb->DecStrongRef(nullptr);
734     CHKPV(cb->env);
735     napi_handle_scope scope = nullptr;
736     napi_open_handle_scope(cb->env, &scope);
737     CHKPV(scope);
738     napi_value callResult = nullptr;
739     if (cb->errCode != RET_OK) {
740         if (cb->errCode == RET_ERR) {
741             napi_close_handle_scope(cb->env, scope);
742             MMI_HILOGE("Other errors");
743             return;
744         }
745         NapiError codeMsg;
746         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
747             napi_close_handle_scope(cb->env, scope);
748             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
749             return;
750         }
751         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
752         if (callResult == nullptr) {
753             MMI_HILOGE("callResult is nullptr");
754             napi_close_handle_scope(cb->env, scope);
755             return;
756         }
757         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
758     } else {
759         CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult), CREATE_ARRAY, scope);
760         uint32_t index = 0;
761         napi_value value = nullptr;
762         for (const auto &item : cb->data.ids) {
763             CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
764             CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult, index, value), SET_ELEMENT, scope);
765             ++index;
766         }
767         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
768     }
769     napi_close_handle_scope(cb->env, scope);
770 }
771 
CallDevInfoPromiseWork(uv_work_t * work,int32_t status)772 void JsEventTarget::CallDevInfoPromiseWork(uv_work_t *work, int32_t status)
773 {
774     CALL_DEBUG_ENTER;
775     CHKPV(work);
776     if (work->data == nullptr) {
777         JsUtil::DeletePtr<uv_work_t *>(work);
778         MMI_HILOGE("Check data is nullptr");
779         return;
780     }
781     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
782     JsUtil::DeletePtr<uv_work_t *>(work);
783     cb->DecStrongRef(nullptr);
784     CHKPV(cb->env);
785     napi_handle_scope scope = nullptr;
786     napi_open_handle_scope(cb->env, &scope);
787     if (scope == nullptr) {
788         MMI_HILOGE("scope is nullptr");
789         return;
790     }
791     napi_value callResult = nullptr;
792     if (cb->errCode != RET_OK) {
793         if (cb->errCode == RET_ERR) {
794             napi_close_handle_scope(cb->env, scope);
795             MMI_HILOGE("Other errors");
796             return;
797         }
798         NapiError codeMsg;
799         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
800             napi_close_handle_scope(cb->env, scope);
801             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
802             return;
803         }
804         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
805         if (callResult == nullptr) {
806             MMI_HILOGE("callResult is nullptr");
807             napi_close_handle_scope(cb->env, scope);
808             return;
809         }
810         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
811     } else {
812         callResult = JsUtil::GetDeviceInfo(cb);
813         if (callResult == nullptr) {
814             MMI_HILOGE("Check callResult is nullptr");
815             napi_close_handle_scope(cb->env, scope);
816             return;
817         }
818         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
819     }
820     napi_close_handle_scope(cb->env, scope);
821 }
822 
CallDevInfoAsyncWork(uv_work_t * work,int32_t status)823 void JsEventTarget::CallDevInfoAsyncWork(uv_work_t *work, int32_t status)
824 {
825     CALL_DEBUG_ENTER;
826     CHKPV(work);
827     if (work->data == nullptr) {
828         JsUtil::DeletePtr<uv_work_t *>(work);
829         MMI_HILOGE("Check data is nullptr");
830         return;
831     }
832     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
833     JsUtil::DeletePtr<uv_work_t *>(work);
834     cb->DecStrongRef(nullptr);
835     CHKPV(cb->env);
836     napi_handle_scope scope = nullptr;
837     napi_open_handle_scope(cb->env, &scope);
838     CHKPV(scope);
839     napi_value callResult[2] = { 0 };
840     if (cb->errCode != RET_OK) {
841         if (cb->errCode == RET_ERR) {
842             napi_close_handle_scope(cb->env, scope);
843             MMI_HILOGE("Other errors");
844             return;
845         }
846         NapiError codeMsg;
847         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
848             napi_close_handle_scope(cb->env, scope);
849             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
850             return;
851         }
852         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
853         if (callResult[0] == nullptr) {
854             MMI_HILOGE("callResult[0] is nullptr");
855             napi_close_handle_scope(cb->env, scope);
856             return;
857         }
858         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
859     } else {
860         callResult[1] = JsUtil::GetDeviceInfo(cb);
861         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
862     }
863     napi_value handler = nullptr;
864     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
865     napi_value result = nullptr;
866     CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
867         CALL_FUNCTION, scope);
868     CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
869     napi_close_handle_scope(cb->env, scope);
870 }
871 
EmitJsKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb,int32_t delay)872 void JsEventTarget::EmitJsKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb, int32_t delay)
873 {
874     CALL_DEBUG_ENTER;
875     CHKPV(cb);
876     CHKPV(cb->env);
877     cb->data.keyboardRepeatDelay = delay;
878     cb->errCode = RET_OK;
879     uv_loop_s *loop = nullptr;
880     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
881 
882     uv_work_t *work = new (std::nothrow) uv_work_t;
883     CHKPV(work);
884     cb->IncStrongRef(nullptr);
885     work->data = cb.GetRefPtr();
886     int32_t ret;
887     if (cb->ref == nullptr) {
888         ret = uv_queue_work(
889             loop, work, [](uv_work_t *work) {}, CallKeyboardRepeatDelayPromise);
890     } else {
891         ret = uv_queue_work(
892             loop, work, [](uv_work_t *work) {}, CallKeyboardRepeatDelayAsync);
893     }
894     if (ret != 0) {
895         MMI_HILOGE("uv_queue_work failed");
896         JsUtil::DeletePtr<uv_work_t *>(work);
897     }
898 }
899 
CallKeyboardRepeatDelayAsync(uv_work_t * work,int32_t status)900 void JsEventTarget::CallKeyboardRepeatDelayAsync(uv_work_t *work, int32_t status)
901 {
902     CALL_DEBUG_ENTER;
903     CHKPV(work);
904     if (work->data == nullptr) {
905         JsUtil::DeletePtr<uv_work_t *>(work);
906         MMI_HILOGE("Check data is nullptr");
907         return;
908     }
909     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
910     JsUtil::DeletePtr<uv_work_t *>(work);
911     cb->DecStrongRef(nullptr);
912     CHKPV(cb->env);
913 
914     napi_handle_scope scope = nullptr;
915     napi_open_handle_scope(cb->env, &scope);
916     CHKPV(scope);
917 
918     napi_value callResult[2] = {0};
919     if (cb->errCode != RET_OK) {
920         if (cb->errCode == RET_ERR) {
921             napi_close_handle_scope(cb->env, scope);
922             MMI_HILOGE("Other errors");
923             return;
924         }
925         NapiError codeMsg;
926         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
927             napi_close_handle_scope(cb->env, scope);
928             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
929             return;
930         }
931         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
932         if (callResult[0] == nullptr) {
933             MMI_HILOGE("callResult[0] is nullptr");
934             napi_close_handle_scope(cb->env, scope);
935             return;
936         }
937         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
938     } else {
939         CHKRV_SCOPE(
940             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatDelay, &callResult[1]), CREATE_INT32, scope);
941         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
942     }
943     napi_value handler = nullptr;
944     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
945     napi_value result = nullptr;
946     CHKRV_SCOPE(cb->env,
947         napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
948         CALL_FUNCTION,
949         scope);
950     napi_close_handle_scope(cb->env, scope);
951 }
952 
CallKeyboardRepeatDelayPromise(uv_work_t * work,int32_t status)953 void JsEventTarget::CallKeyboardRepeatDelayPromise(uv_work_t *work, int32_t status)
954 {
955     CALL_DEBUG_ENTER;
956     CHKPV(work);
957     if (work->data == nullptr) {
958         JsUtil::DeletePtr<uv_work_t *>(work);
959         MMI_HILOGE("Check data is nullptr");
960         return;
961     }
962     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
963     JsUtil::DeletePtr<uv_work_t *>(work);
964     cb->DecStrongRef(nullptr);
965     CHKPV(cb->env);
966 
967     napi_handle_scope scope = nullptr;
968     napi_open_handle_scope(cb->env, &scope);
969     CHKPV(scope);
970 
971     napi_value callResult;
972     if (cb->errCode != RET_OK) {
973         if (cb->errCode == RET_ERR) {
974             napi_close_handle_scope(cb->env, scope);
975             MMI_HILOGE("Other errors");
976             return;
977         }
978         NapiError codeMsg;
979         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
980             napi_close_handle_scope(cb->env, scope);
981             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
982             return;
983         }
984         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
985         if (callResult == nullptr) {
986             MMI_HILOGE("callResult is nullptr");
987             napi_close_handle_scope(cb->env, scope);
988             return;
989         }
990         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
991     } else {
992         CHKRV_SCOPE(
993             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatDelay, &callResult), CREATE_INT32, scope);
994         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
995     }
996     napi_close_handle_scope(cb->env, scope);
997 }
998 
EmitJsKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb,int32_t rate)999 void JsEventTarget::EmitJsKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb, int32_t rate)
1000 {
1001     CALL_DEBUG_ENTER;
1002     CHKPV(cb);
1003     CHKPV(cb->env);
1004     cb->data.keyboardRepeatRate = rate;
1005     cb->errCode = RET_OK;
1006     uv_loop_s *loop = nullptr;
1007     CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1008 
1009     uv_work_t *work = new (std::nothrow) uv_work_t;
1010     CHKPV(work);
1011     cb->IncStrongRef(nullptr);
1012     work->data = cb.GetRefPtr();
1013     int32_t ret;
1014     if (cb->ref == nullptr) {
1015         ret = uv_queue_work(
1016             loop, work, [](uv_work_t *work) {}, CallKeyboardRepeatRatePromise);
1017     } else {
1018         ret = uv_queue_work(
1019             loop, work, [](uv_work_t *work) {}, CallKeyboardRepeatRateAsync);
1020     }
1021     if (ret != 0) {
1022         MMI_HILOGE("uv_queue_work failed");
1023         JsUtil::DeletePtr<uv_work_t *>(work);
1024     }
1025 }
1026 
CallKeyboardRepeatRateAsync(uv_work_t * work,int32_t status)1027 void JsEventTarget::CallKeyboardRepeatRateAsync(uv_work_t *work, int32_t status)
1028 {
1029     CALL_DEBUG_ENTER;
1030     CHKPV(work);
1031     if (work->data == nullptr) {
1032         JsUtil::DeletePtr<uv_work_t *>(work);
1033         MMI_HILOGE("Check data is nullptr");
1034         return;
1035     }
1036     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1037     JsUtil::DeletePtr<uv_work_t *>(work);
1038     cb->DecStrongRef(nullptr);
1039     CHKPV(cb->env);
1040 
1041     napi_handle_scope scope = nullptr;
1042     napi_open_handle_scope(cb->env, &scope);
1043     CHKPV(scope);
1044 
1045     napi_value callResult[2] = {0};
1046     if (cb->errCode != RET_OK) {
1047         if (cb->errCode == RET_ERR) {
1048             napi_close_handle_scope(cb->env, scope);
1049             MMI_HILOGE("Other errors");
1050             return;
1051         }
1052         NapiError codeMsg;
1053         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1054             napi_close_handle_scope(cb->env, scope);
1055             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1056             return;
1057         }
1058         callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1059         if (callResult[0] == nullptr) {
1060             MMI_HILOGE("callResult[0] is nullptr");
1061             napi_close_handle_scope(cb->env, scope);
1062             return;
1063         }
1064         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
1065     } else {
1066         CHKRV_SCOPE(
1067             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatRate, &callResult[1]), CREATE_INT32, scope);
1068         CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
1069     }
1070     napi_value handler = nullptr;
1071     CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
1072     napi_value result = nullptr;
1073     CHKRV_SCOPE(cb->env,
1074         napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
1075         CALL_FUNCTION,
1076         scope);
1077     napi_close_handle_scope(cb->env, scope);
1078 }
1079 
CallKeyboardRepeatRatePromise(uv_work_t * work,int32_t status)1080 void JsEventTarget::CallKeyboardRepeatRatePromise(uv_work_t *work, int32_t status)
1081 {
1082     CALL_DEBUG_ENTER;
1083     CHKPV(work);
1084     if (work->data == nullptr) {
1085         JsUtil::DeletePtr<uv_work_t *>(work);
1086         MMI_HILOGE("Check data is nullptr");
1087         return;
1088     }
1089     sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1090     JsUtil::DeletePtr<uv_work_t *>(work);
1091     cb->DecStrongRef(nullptr);
1092     CHKPV(cb->env);
1093 
1094     napi_handle_scope scope = nullptr;
1095     napi_open_handle_scope(cb->env, &scope);
1096     CHKPV(scope);
1097 
1098     napi_value callResult;
1099     if (cb->errCode != RET_OK) {
1100         if (cb->errCode == RET_ERR) {
1101             napi_close_handle_scope(cb->env, scope);
1102             MMI_HILOGE("Other errors");
1103             return;
1104         }
1105         NapiError codeMsg;
1106         if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1107             napi_close_handle_scope(cb->env, scope);
1108             MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1109             return;
1110         }
1111         callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1112         if (callResult == nullptr) {
1113             MMI_HILOGE("callResult is nullptr");
1114             napi_close_handle_scope(cb->env, scope);
1115             return;
1116         }
1117         CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1118     } else {
1119         CHKRV_SCOPE(
1120             cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatRate, &callResult), CREATE_INT32, scope);
1121         CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1122     }
1123     napi_close_handle_scope(cb->env, scope);
1124 }
1125 
AddListener(napi_env env,const std::string & type,napi_value handle)1126 void JsEventTarget::AddListener(napi_env env, const std::string &type, napi_value handle)
1127 {
1128     CALL_DEBUG_ENTER;
1129     std::lock_guard<std::mutex> guard(mutex_);
1130     auto iter = devListener_.find(type);
1131     if (iter == devListener_.end()) {
1132         MMI_HILOGE("Find %{public}s failed", type.c_str());
1133         return;
1134     }
1135 
1136     for (const auto &temp : iter->second) {
1137         CHKPC(temp);
1138         if (temp->env != env) {
1139             continue;
1140         }
1141         if (JsUtil::IsSameHandle(env, handle, temp->ref)) {
1142             MMI_HILOGW("The handle already exists");
1143             return;
1144         }
1145     }
1146     napi_ref ref = nullptr;
1147     CHKRV(napi_create_reference(env, handle, 1, &ref), CREATE_REFERENCE);
1148     auto monitor = std::make_unique<JsUtil::CallbackInfo>();
1149     monitor->env = env;
1150     monitor->ref = ref;
1151     iter->second.push_back(std::move(monitor));
1152     if (!isListeningProcess_) {
1153         isListeningProcess_ = true;
1154         InputManager::GetInstance()->RegisterDevListener("change", shared_from_this());
1155     }
1156 }
1157 
RemoveListener(napi_env env,const std::string & type,napi_value handle)1158 void JsEventTarget::RemoveListener(napi_env env, const std::string &type, napi_value handle)
1159 {
1160     CALL_DEBUG_ENTER;
1161     std::lock_guard<std::mutex> guard(mutex_);
1162     auto iter = devListener_.find(type);
1163     if (iter == devListener_.end()) {
1164         MMI_HILOGE("Find %{public}s failed", type.c_str());
1165         return;
1166     }
1167     if (handle == nullptr) {
1168         iter->second.clear();
1169         goto monitorLabel;
1170     }
1171     for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
1172         if ((*it)->env != env) {
1173             continue;
1174         }
1175         if (JsUtil::IsSameHandle(env, handle, (*it)->ref)) {
1176             MMI_HILOGD("Succeeded in removing monitor");
1177             JsUtil::DeleteCallbackInfo(std::move(*it));
1178             iter->second.erase(it);
1179             goto monitorLabel;
1180         }
1181     }
1182 
1183 monitorLabel:
1184     if (isListeningProcess_ && iter->second.empty()) {
1185         isListeningProcess_ = false;
1186         InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1187     }
1188 }
1189 
GreateBusinessError(napi_env env,int32_t errCode,std::string errMessage)1190 napi_value JsEventTarget::GreateBusinessError(napi_env env, int32_t errCode, std::string errMessage)
1191 {
1192     CALL_DEBUG_ENTER;
1193     napi_value result = nullptr;
1194     napi_value resultCode = nullptr;
1195     napi_value resultMessage = nullptr;
1196     CHKRP(napi_create_int32(env, errCode, &resultCode), CREATE_INT32);
1197     CHKRP(napi_create_string_utf8(env, errMessage.data(), NAPI_AUTO_LENGTH, &resultMessage), CREATE_STRING_UTF8);
1198     CHKRP(napi_create_error(env, nullptr, resultMessage, &result), CREATE_ERROR);
1199     CHKRP(napi_set_named_property(env, result, ERR_CODE.c_str(), resultCode), SET_NAMED_PROPERTY);
1200     return result;
1201 }
1202 
CreateCallbackInfo(napi_env env,napi_value handle,sptr<JsUtil::CallbackInfo> cb)1203 napi_value JsEventTarget::CreateCallbackInfo(napi_env env, napi_value handle, sptr<JsUtil::CallbackInfo> cb)
1204 {
1205     CALL_DEBUG_ENTER;
1206     CHKPP(cb);
1207     cb->env = env;
1208     napi_value promise = nullptr;
1209     if (handle == nullptr) {
1210         CHKRP(napi_create_promise(env, &cb->deferred, &promise), CREATE_PROMISE);
1211     } else {
1212         CHKRP(napi_create_reference(env, handle, 1, &cb->ref), CREATE_REFERENCE);
1213     }
1214     return promise;
1215 }
1216 
ResetEnv()1217 void JsEventTarget::ResetEnv()
1218 {
1219     CALL_DEBUG_ENTER;
1220     std::lock_guard<std::mutex> guard(mutex_);
1221     devListener_.clear();
1222     InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1223 }
1224 } // namespace MMI
1225 } // namespace OHOS
1226