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