• 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 
18 namespace OHOS {
19 namespace MMI {
20 namespace {
21 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "JsEventTarget" };
22 JsEventTarget::DeviceType g_deviceType[] = {
23     {"keyboard", JsEventTarget::EVDEV_UDEV_TAG_KEYBOARD},
24     {"mouse", JsEventTarget::EVDEV_UDEV_TAG_MOUSE},
25     {"touchpad", JsEventTarget::EVDEV_UDEV_TAG_TOUCHPAD},
26     {"touchscreen", JsEventTarget::EVDEV_UDEV_TAG_TOUCHSCREEN},
27     {"joystick", JsEventTarget::EVDEV_UDEV_TAG_JOYSTICK},
28     {"trackball", JsEventTarget::EVDEV_UDEV_TAG_TRACKBALL},
29 };
30 } // namespace
31 
32 napi_env JsEventTarget::env_ = nullptr;
33 static std::map<int32_t, JsEventTarget::CallbackInfo*> callback_ {};
34 int32_t JsEventTarget::userData_ = 0;
35 
CallIdsAsyncWork(uv_work_t * work,int32_t status)36 void JsEventTarget::CallIdsAsyncWork(uv_work_t *work, int32_t status)
37 {
38     CHKPV(work);
39     CHKPV(work->data);
40     CallbackInfo *cb = static_cast<CallbackInfo*>(work->data);
41     CallbackInfo cbTemp = *cb;
42     delete cb;
43     cb = nullptr;
44     delete work;
45     work = nullptr;
46 
47     if (CheckEnv(env_)) {
48         MMI_LOGE("env_ is nullptr");
49         return;
50     }
51     napi_handle_scope scope = nullptr;
52     napi_status status_ = napi_open_handle_scope(env_, &scope);
53     if (status_ != napi_ok) {
54         napi_delete_reference(env_, cbTemp.ref);
55         napi_throw_error(env_, nullptr, "JsEventTarget: failed to open scope");
56         MMI_LOGE("failed to open scope");
57         return;
58     }
59     napi_value arr = nullptr;
60     status_ = napi_create_array(env_, &arr);
61     if (status_ != napi_ok) {
62         napi_delete_reference(env_, cbTemp.ref);
63         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_array failed");
64         MMI_LOGE("call to napi_create_array failed");
65         return;
66     }
67 
68     uint32_t index = 0;
69     napi_value value = nullptr;
70     for (const auto &item : cbTemp.ids) {
71         status_ = napi_create_int64(env_, item, &value);
72         if (status_ != napi_ok) {
73             napi_delete_reference(env_, cbTemp.ref);
74             napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_int64 failed");
75             MMI_LOGE("call to napi_create_int64 failed");
76             return;
77         }
78         status_ = napi_set_element(env_, arr, index, value);
79         if (status_ != napi_ok) {
80             napi_delete_reference(env_, cbTemp.ref);
81             napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_element failed");
82             MMI_LOGE("call to napi_set_element failed");
83             return;
84         }
85         index++;
86     }
87 
88     napi_value handlerTemp = nullptr;
89     status_ = napi_get_reference_value(env_, cbTemp.ref, &handlerTemp);
90     if (status_ != napi_ok) {
91         napi_delete_reference(env_, cbTemp.ref);
92         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_get_reference_value failed");
93         MMI_LOGE("call to napi_get_reference_value failed");
94         return;
95     }
96     napi_value result = nullptr;
97     status_ = napi_call_function(env_, nullptr, handlerTemp, 1, &arr, &result);
98     if (status_ != napi_ok) {
99         napi_delete_reference(env_, cbTemp.ref);
100         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_call_function failed");
101         MMI_LOGE("call to napi_call_function failed");
102         return;
103     }
104     status_ = napi_delete_reference(env_, cbTemp.ref);
105     if (status_ != napi_ok) {
106         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_delete_reference failed");
107         MMI_LOGE("call to napi_delete_reference failed");
108         return;
109     }
110 
111     status_ = napi_close_handle_scope(env_, scope);
112     if (status_ != napi_ok) {
113         napi_throw_error(env_, nullptr, "JsEventTarget: failed to close scope");
114         MMI_LOGE("failed to close scope");
115         return;
116     }
117 }
118 
EmitJsIdsAsync(int32_t userData,std::vector<int32_t> ids)119 void JsEventTarget::EmitJsIdsAsync(int32_t userData, std::vector<int32_t> ids)
120 {
121     if (CheckEnv(env_)) {
122         MMI_LOGE("env_ is nullptr");
123         return;
124     }
125     auto iter = callback_.find(userData);
126     if (iter == callback_.end()) {
127         MMI_LOGE("Failed to search for userData");
128         return;
129     }
130     CHKPV(iter->second);
131     iter->second->ids = ids;
132     uv_loop_s *loop = nullptr;
133     napi_status status = napi_get_uv_event_loop(env_, &loop);
134     if (status != napi_ok) {
135         MMI_LOGE("napi_get_uv_event_loop failed");
136         return;
137     }
138     uv_work_t *work = new (std::nothrow) uv_work_t;
139     CHKPV(work);
140     work->data = static_cast<void*>(iter->second);
141     int32_t ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, CallIdsAsyncWork);
142     if (ret != 0) {
143         MMI_LOGE("uv_queue_work failed");
144         return;
145     }
146 }
147 
CallDevAsyncWork(uv_work_t * work,int32_t status)148 void JsEventTarget::CallDevAsyncWork(uv_work_t *work, int32_t status)
149 {
150     CHKPV(work);
151     CHKPV(work->data);
152     CallbackInfo *cb = static_cast<CallbackInfo*>(work->data);
153     CallbackInfo cbTemp = *cb;
154     delete cb;
155     cb = nullptr;
156     delete work;
157     work = nullptr;
158 
159     if (CheckEnv(env_)) {
160         MMI_LOGE("env_ is nullptr");
161         return;
162     }
163     napi_handle_scope scope = nullptr;
164     napi_status status_ = napi_open_handle_scope(env_, &scope);
165     if (status_ != napi_ok) {
166         napi_delete_reference(env_, cbTemp.ref);
167         napi_throw_error(env_, nullptr, "JsEventTarget: failed to open scope");
168         MMI_LOGE("failed to open scope");
169         return;
170     }
171 
172     napi_value id = nullptr;
173     status_ = napi_create_int64(env_, cbTemp.device->id, &id);
174     if (status_ != napi_ok) {
175         napi_delete_reference(env_, cbTemp.ref);
176         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_int64 failed");
177         MMI_LOGE("call to napi_create_int64 failed");
178         return;
179     }
180     napi_value name = nullptr;
181     status_ = napi_create_string_utf8(env_, (cbTemp.device->name).c_str(), NAPI_AUTO_LENGTH, &name);
182     if (status_ != napi_ok) {
183         napi_delete_reference(env_, cbTemp.ref);
184         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_string_utf8 failed");
185         MMI_LOGE("call to napi_create_string_utf8 failed");
186         return;
187     }
188 
189     napi_value object = nullptr;
190     status_ = napi_create_object(env_, &object);
191     if (status_ != napi_ok) {
192         napi_delete_reference(env_, cbTemp.ref);
193         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_object failed");
194         MMI_LOGE("call to napi_create_object failed");
195         return;
196     }
197 
198     status_ = napi_set_named_property(env_, object, "id", id);
199     if (status_ != napi_ok) {
200         napi_delete_reference(env_, cbTemp.ref);
201         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_named_property failed");
202         MMI_LOGE("call to napi_set_named_property failed");
203         return;
204     }
205     status_ = napi_set_named_property(env_, object, "name", name);
206     if (status_ != napi_ok) {
207         napi_delete_reference(env_, cbTemp.ref);
208         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_named_property failed");
209         MMI_LOGE("call to napi_set_named_property failed");
210         return;
211     }
212 
213     uint32_t types = cbTemp.device->devcieType;
214     std::vector<std::string> sources;
215     for (const auto & item : g_deviceType) {
216         if (types & item.typeBit) {
217             sources.push_back(item.deviceTypeName);
218         }
219     }
220     napi_value devSources = nullptr;
221     status_ = napi_create_array(env_, &devSources);
222     if (status_ != napi_ok) {
223         napi_delete_reference(env_, cbTemp.ref);
224         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_array failed");
225         MMI_LOGE("call to napi_create_array failed");
226         return;
227     }
228     uint32_t index = 0;
229     napi_value value = nullptr;
230     for (const auto &item : sources) {
231         status_ = napi_create_string_utf8(env_, item.c_str(), NAPI_AUTO_LENGTH, &value);
232         if (status_ != napi_ok) {
233             napi_delete_reference(env_, cbTemp.ref);
234             napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_string_utf8 failed");
235             MMI_LOGE("call to napi_create_string_utf8 failed");
236             return;
237         }
238         status_ = napi_set_element(env_, devSources, index, value);
239         if (status_ != napi_ok) {
240             napi_delete_reference(env_, cbTemp.ref);
241             napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_element failed");
242             MMI_LOGE("call to napi_set_element failed");
243             return;
244         }
245     }
246     status_ = napi_set_named_property(env_, object, "sources", devSources);
247     if (status_ != napi_ok) {
248         napi_delete_reference(env_, cbTemp.ref);
249         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_named_property failed");
250         MMI_LOGE("call to napi_set_named_property failed");
251         return;
252     }
253 
254     napi_value axisRanges = nullptr;
255     status_ = napi_create_array(env_, &axisRanges);
256     if (status_ != napi_ok) {
257         napi_delete_reference(env_, cbTemp.ref);
258         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_array failed");
259         MMI_LOGE("call to napi_create_array failed");
260         return;
261     }
262     status_ = napi_set_named_property(env_, object, "axisRanges", axisRanges);
263     if (status_ != napi_ok) {
264         napi_delete_reference(env_, cbTemp.ref);
265         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_named_property failed");
266         MMI_LOGE("call to napi_set_named_property failed");
267         return;
268     }
269 
270     napi_value handlerTemp = nullptr;
271     status_ = napi_get_reference_value(env_, cbTemp.ref, &handlerTemp);
272     if (status_ != napi_ok) {
273         napi_delete_reference(env_, cbTemp.ref);
274         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_get_reference_value failed");
275         MMI_LOGE("call to napi_get_reference_value failed");
276         return;
277     }
278     napi_value result = nullptr;
279     status_ = napi_call_function(env_, nullptr, handlerTemp, 1, &object, &result);
280     if (status_ != napi_ok) {
281         napi_delete_reference(env_, cbTemp.ref);
282         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_call_function failed");
283         MMI_LOGE("call to napi_call_function failed");
284         return;
285     }
286     status_ = napi_delete_reference(env_, cbTemp.ref);
287     if (status_ != napi_ok) {
288         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_delete_reference failed");
289         MMI_LOGE("call to napi_delete_reference failed");
290         return;
291     }
292 
293     status_ = napi_close_handle_scope(env_, scope);
294     if (status_ != napi_ok) {
295         napi_throw_error(env_, nullptr, "JsEventTarget: failed to close scope");
296         MMI_LOGE("failed to close scope");
297         return;
298     }
299 }
300 
EmitJsDevAsync(int32_t userData,std::shared_ptr<InputDeviceImpl::InputDeviceInfo> device)301 void JsEventTarget::EmitJsDevAsync(int32_t userData, std::shared_ptr<InputDeviceImpl::InputDeviceInfo> device)
302 {
303     CHKPV(device);
304     if (CheckEnv(env_)) {
305         MMI_LOGE("env_ is nullptr");
306         return;
307     }
308     auto iter = callback_.find(userData);
309     if (iter == callback_.end()) {
310         MMI_LOGE("Failed to search for userData");
311         return;
312     }
313     CHKPV(iter->second);
314     iter->second->device = device;
315     uv_loop_s *loop = nullptr;
316     napi_status status = napi_get_uv_event_loop(env_, &loop);
317     if (status != napi_ok) {
318         MMI_LOGE("napi_get_uv_event_loop failed");
319         return;
320     }
321     uv_work_t *work = new (std::nothrow) uv_work_t;
322     CHKPV(work);
323     work->data = static_cast<void*>(iter->second);
324     int32_t ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, CallDevAsyncWork);
325     if (ret != 0) {
326         MMI_LOGE("uv_queue_work failed");
327         return;
328     }
329 }
330 
CallIdsPromiseWork(uv_work_t * work,int32_t status)331 void JsEventTarget::CallIdsPromiseWork(uv_work_t *work, int32_t status)
332 {
333     CHKPV(work);
334     CHKPV(work->data);
335     CallbackInfo *cb = static_cast<CallbackInfo*>(work->data);
336     CallbackInfo cbTemp = *cb;
337     delete cb;
338     cb = nullptr;
339     delete work;
340     work = nullptr;
341     if (CheckEnv(env_)) {
342         MMI_LOGE("env_ is nullptr");
343         return;
344     }
345 
346     napi_handle_scope scope = nullptr;
347     napi_status status_ = napi_open_handle_scope(env_, &scope);
348     if (status_ != napi_ok) {
349         napi_delete_reference(env_, cbTemp.ref);
350         napi_throw_error(env_, nullptr, "JsEventTarget: failed to open scope");
351         MMI_LOGE("failed to open scope");
352         return;
353     }
354     napi_value arr = nullptr;
355     status_ = napi_create_array(env_, &arr);
356     if (status_ != napi_ok) {
357         napi_delete_reference(env_, cbTemp.ref);
358         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_array failed");
359         MMI_LOGE("call to napi_create_array failed");
360         return;
361     }
362     uint32_t index = 0;
363     napi_value value = nullptr;
364     for (const auto &item : cbTemp.ids) {
365         status_ = napi_create_int64(env_, item, &value);
366         if (status_ != napi_ok) {
367             napi_delete_reference(env_, cbTemp.ref);
368             napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_int64 failed");
369             MMI_LOGE("call to napi_create_int64 failed");
370             return;
371         }
372         status_ = napi_set_element(env_, arr, index, value);
373         if (status_ != napi_ok) {
374             napi_delete_reference(env_, cbTemp.ref);
375             napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_element failed");
376             MMI_LOGE("call to napi_set_element failed");
377             return;
378         }
379         index++;
380     }
381 
382     status_ = napi_resolve_deferred(env_, cbTemp.deferred, arr);
383     if (status_ != napi_ok) {
384         napi_delete_reference(env_, cbTemp.ref);
385         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_call_function failed");
386         MMI_LOGE("call to napi_call_function failed");
387         return;
388     }
389 
390     status_ = napi_close_handle_scope(env_, scope);
391     if (status_ != napi_ok) {
392         napi_delete_reference(env_, cbTemp.ref);
393         napi_throw_error(env_, nullptr, "JsEventTarget: failed to close scope");
394         MMI_LOGE("failed to close scope");
395         return;
396     }
397 }
398 
EmitJsIdsPromise(int32_t userData,std::vector<int32_t> ids)399 void JsEventTarget::EmitJsIdsPromise(int32_t userData, std::vector<int32_t> ids)
400 {
401     if (CheckEnv(env_)) {
402         MMI_LOGE("env_ is nullptr");
403         return;
404     }
405     auto iter = callback_.find(userData);
406     if (iter == callback_.end()) {
407         MMI_LOGE("Failed to search for userData");
408         return;
409     }
410     CHKPV(iter->second);
411     iter->second->ids = ids;
412     uv_loop_s *loop = nullptr;
413     napi_status status = napi_get_uv_event_loop(env_, &loop);
414     if (status != napi_ok) {
415         MMI_LOGE("napi_get_uv_event_loop failed");
416         return;
417     }
418     uv_work_t *work = new (std::nothrow) uv_work_t;
419     CHKPV(work);
420     work->data = static_cast<void*>(iter->second);
421     int32_t ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, CallIdsPromiseWork);
422     if (ret != 0) {
423         MMI_LOGE("uv_queue_work failed");
424         return;
425     }
426 }
427 
CallDevPromiseWork(uv_work_t * work,int32_t status)428 void JsEventTarget::CallDevPromiseWork(uv_work_t *work, int32_t status)
429 {
430     CHKPV(work);
431     CHKPV(work->data);
432     CallbackInfo *cb = static_cast<CallbackInfo*>(work->data);
433     CallbackInfo cbTemp = *cb;
434     delete cb;
435     cb = nullptr;
436     delete work;
437     work = nullptr;
438 
439     if (CheckEnv(env_)) {
440         MMI_LOGE("env_ is nullptr");
441         return;
442     }
443     napi_handle_scope scope = nullptr;
444     napi_status status_ = napi_open_handle_scope(env_, &scope);
445     if (status_ != napi_ok) {
446         napi_delete_reference(env_, cbTemp.ref);
447         napi_throw_error(env_, nullptr, "JsEventTarget: failed to open scope");
448         MMI_LOGE("failed to open scope");
449         return;
450     }
451 
452     napi_value id = nullptr;
453     status_ = napi_create_int64(env_, cbTemp.device->id, &id);
454     if (status_ != napi_ok) {
455         napi_delete_reference(env_, cbTemp.ref);
456         napi_throw_error(env_, nullptr, "napi_create_int64 failed");
457         MMI_LOGE("napi_create_int64 failed");
458         return;
459     }
460     napi_value name = nullptr;
461     status_ = napi_create_string_utf8(env_, (cbTemp.device->name).c_str(), NAPI_AUTO_LENGTH, &name);
462     if (status_ != napi_ok) {
463         napi_delete_reference(env_, cbTemp.ref);
464         napi_throw_error(env_, nullptr, "napi_create_string_utf8 failed");
465         MMI_LOGE("napi_create_string_utf8 failed");
466         return;
467     }
468     napi_value object = nullptr;
469     status_ = napi_create_object(env_, &object);
470     if (status_ != napi_ok) {
471         napi_delete_reference(env_, cbTemp.ref);
472         napi_throw_error(env_, nullptr, "napi_create_object failed");
473         MMI_LOGE("napi_create_object failed");
474         return;
475     }
476 
477     status_ = napi_set_named_property(env_, object, "id", id);
478     if (status_ != napi_ok) {
479         napi_delete_reference(env_, cbTemp.ref);
480         napi_throw_error(env_, nullptr, "napi_set_named_property set id failed");
481         MMI_LOGE("napi_set_named_property set id failed");
482         return;
483     }
484     status_ = napi_set_named_property(env_, object, "name", name);
485     if (status_ != napi_ok) {
486         napi_delete_reference(env_, cbTemp.ref);
487         napi_throw_error(env_, nullptr, "napi_set_named_property set name failed");
488         MMI_LOGE("napi_set_named_property set name failed");
489         return;
490     }
491 
492     uint32_t types = cbTemp.device->devcieType;
493     if (types <= 0) {
494         napi_delete_reference(env_, cbTemp.ref);
495         napi_throw_error(env_, nullptr, "devcieType is less than zero");
496         MMI_LOGE("devcieType is less than zero");
497     }
498     std::vector<std::string> sources;
499     for (const auto & item : g_deviceType) {
500         if (static_cast<uint32_t>(types) & item.typeBit) {
501             sources.push_back(item.deviceTypeName);
502         }
503     }
504     napi_value devSources = nullptr;
505     status_ = napi_create_array(env_, &devSources);
506     if (status_ != napi_ok) {
507         napi_delete_reference(env_, cbTemp.ref);
508         napi_throw_error(env_, nullptr, "napi_create_array failed");
509         MMI_LOGE("napi_create_array failed");
510         return;
511     }
512 
513     uint32_t index = 0;
514     napi_value value = nullptr;
515     for (const auto &item : sources) {
516         status_ = napi_create_string_utf8(env_, item.c_str(), NAPI_AUTO_LENGTH, &value);
517         if (status_ != napi_ok) {
518             napi_delete_reference(env_, cbTemp.ref);
519             napi_throw_error(env_, nullptr, "napi_create_string_utf8 failed");
520             MMI_LOGE("napi_create_string_utf8 failed");
521             return;
522         }
523         status_ = napi_set_element(env_, devSources, index, value);
524         if (status_ != napi_ok) {
525             napi_delete_reference(env_, cbTemp.ref);
526             napi_throw_error(env_, nullptr, "napi_set_element failed");
527             MMI_LOGE("napi_set_element failed");
528         }
529     }
530     status_ = napi_set_named_property(env_, object, "sources", devSources);
531     if (status_ != napi_ok) {
532         napi_delete_reference(env_, cbTemp.ref);
533         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_named_property failed");
534         MMI_LOGE("call to napi_set_named_property failed");
535         return;
536     }
537 
538     napi_value axisRanges = nullptr;
539     status_ = napi_create_array(env_, &axisRanges);
540     if (status_ != napi_ok) {
541         napi_delete_reference(env_, cbTemp.ref);
542         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_array failed");
543         MMI_LOGE("call to napi_create_array failed");
544         return;
545     }
546     status_ = napi_set_named_property(env_, object, "axisRanges", axisRanges);
547     if (status_ != napi_ok) {
548         napi_delete_reference(env_, cbTemp.ref);
549         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_set_named_property failed");
550         MMI_LOGE("call to napi_set_named_property failed");
551         return;
552     }
553 
554     status_ = napi_resolve_deferred(env_, cbTemp.deferred, object);
555     if (status_ != napi_ok) {
556         napi_delete_async_work(env_, cbTemp.asyncWork);
557         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_call_function failed");
558         MMI_LOGE("call to napi_call_function failed");
559         return;
560     }
561 
562     status_ = napi_close_handle_scope(env_, scope);
563     if (status_ != napi_ok) {
564         napi_throw_error(env_, nullptr, "JsEventTarget: failed to close scope");
565         MMI_LOGE("failed to close scope");
566         return;
567     }
568 }
569 
EmitJsDevPromise(int32_t userData,std::shared_ptr<InputDeviceImpl::InputDeviceInfo> device)570 void JsEventTarget::EmitJsDevPromise(int32_t userData, std::shared_ptr<InputDeviceImpl::InputDeviceInfo> device)
571 {
572     CHKPV(device);
573     if (CheckEnv(env_)) {
574         MMI_LOGE("env_ is nullptr");
575         return;
576     }
577     auto iter = callback_.find(userData);
578     if (iter == callback_.end()) {
579         MMI_LOGE("Failed to search for userData");
580         return;
581     }
582     CHKPV(iter->second);
583     iter->second->device = device;
584     uv_loop_s *loop = nullptr;
585     napi_status status = napi_get_uv_event_loop(env_, &loop);
586     if (status != napi_ok) {
587         MMI_LOGE("napi_get_uv_event_loop failed");
588         return;
589     }
590     uv_work_t *work = new (std::nothrow) uv_work_t;
591     CHKPV(work);
592     work->data = static_cast<void*>(iter->second);
593     int32_t ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, CallDevPromiseWork);
594     if (ret != 0) {
595         MMI_LOGE("uv_queue_work failed");
596         return;
597     }
598 }
599 
CreateCallbackInfo(napi_env env,napi_value handle)600 napi_value JsEventTarget::CreateCallbackInfo(napi_env env, napi_value handle)
601 {
602     env_ = env;
603     CallbackInfo* cb = new (std::nothrow) CallbackInfo;
604     CHKPP(cb);
605 
606     napi_status status = napi_generic_failure;
607     if (handle == nullptr) {
608         status = napi_create_promise(env_, &cb->deferred, &cb->promise);
609         if (status != napi_ok) {
610             delete cb;
611             cb = nullptr;
612             napi_throw_error(env_, nullptr, "JsEventTarget: failed to create promise");
613             MMI_LOGE("failed to create promise");
614             return nullptr;
615         }
616         callback_[userData_] = cb;
617         if (userData_ == INT32_MAX) {
618             MMI_LOGE("userData_ exceeds the maximum");
619             return nullptr;
620         }
621         ++userData_;
622         return cb->promise;
623     }
624 
625     status = napi_create_reference(env_, handle, 1, &cb->ref);
626     if (status != napi_ok) {
627         delete cb;
628         cb = nullptr;
629         napi_throw_error(env_, nullptr, "JsEventTarget: call to napi_create_reference failed");
630         MMI_LOGE("call to napi_create_reference failed");
631         return nullptr;
632     }
633     callback_[userData_] = cb;
634     if (userData_ == INT32_MAX) {
635         MMI_LOGE("userData_ exceeds the maximum");
636         return nullptr;
637     }
638     ++userData_;
639     return nullptr;
640 }
641 
ResetEnv()642 void JsEventTarget::ResetEnv()
643 {
644     env_ = nullptr;
645 }
646 
CheckEnv(napi_env env)647 bool JsEventTarget::CheckEnv(napi_env env)
648 {
649     if (env_ != nullptr) {
650         return false;
651     }
652 
653     for (auto &item : callback_) {
654         if (item.second == nullptr) {
655             continue;
656         }
657         delete item.second;
658         item.second = nullptr;
659     }
660     return true;
661 }
662 } // namespace MMI
663 } // namespace OHOS