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