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