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
18 #include "bytrace_adapter.h"
19 #include "napi_constants.h"
20 #include "util_napi_error.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 reportData->DecStrongRef(nullptr);
53 auto addEvent = devListener_.find(CHANGED_TYPE);
54 if (addEvent == devListener_.end()) {
55 MMI_HILOGE("Find change event failed");
56 return;
57 }
58 for (const auto &item : addEvent->second) {
59 CHKPC(item->env);
60 if (item->ref != reportData->ref) {
61 continue;
62 }
63 napi_handle_scope scope = nullptr;
64 napi_open_handle_scope(item->env, &scope);
65 CHKPV(scope);
66 napi_value eventType = nullptr;
67 CHKRV_SCOPE_DEL(item->env, napi_create_string_utf8(item->env, ADD_EVENT.c_str(), NAPI_AUTO_LENGTH, &eventType),
68 CREATE_STRING_UTF8, scope);
69 napi_value object = nullptr;
70 CHKRV_SCOPE_DEL(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
71 CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
72 scope);
73 napi_value handler = nullptr;
74 CHKRV_SCOPE_DEL(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE,
75 scope);
76 napi_value deviceId = nullptr;
77 CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope);
78 CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
79 scope);
80 napi_value ret = nullptr;
81 CHKRV_SCOPE_DEL(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
82 scope);
83 napi_close_handle_scope(item->env, scope);
84 BytraceAdapter::StartDevListener(ADD_EVENT, reportData->deviceId);
85 MMI_HILOGI("Report device change task, event type:%{public}s, deviceid:%{public}d",
86 ADD_EVENT.c_str(), reportData->deviceId);
87 BytraceAdapter::StopDevListener();
88 }
89 }
90
EmitRemoveDeviceEvent(sptr<JsUtil::ReportData> reportData)91 void JsEventTarget::EmitRemoveDeviceEvent(sptr<JsUtil::ReportData> reportData)
92 {
93 CALL_DEBUG_ENTER;
94 reportData->DecStrongRef(nullptr);
95 auto removeEvent = devListener_.find(CHANGED_TYPE);
96 if (removeEvent == devListener_.end()) {
97 MMI_HILOGE("Find change event failed");
98 return;
99 }
100 for (const auto &item : removeEvent->second) {
101 CHKPC(item->env);
102 if (item->ref != reportData->ref) {
103 continue;
104 }
105 napi_handle_scope scope = nullptr;
106 napi_open_handle_scope(item->env, &scope);
107 CHKPV(scope);
108 napi_value eventType = nullptr;
109 CHKRV_SCOPE_DEL(item->env, napi_create_string_utf8(item->env, REMOVE_EVENT.c_str(), NAPI_AUTO_LENGTH,
110 &eventType), CREATE_STRING_UTF8, scope);
111 napi_value deviceId = nullptr;
112 CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope);
113 napi_value object = nullptr;
114 CHKRV_SCOPE_DEL(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
115 CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY,
116 scope);
117 CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY,
118 scope);
119 napi_value handler = nullptr;
120 CHKRV_SCOPE_DEL(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE,
121 scope);
122 napi_value ret = nullptr;
123 CHKRV_SCOPE_DEL(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION,
124 scope);
125 napi_close_handle_scope(item->env, scope);
126 BytraceAdapter::StartDevListener(REMOVE_EVENT, reportData->deviceId);
127 MMI_HILOGI("Report device change task, event type:%{public}s, deviceid:%{public}d",
128 REMOVE_EVENT.c_str(), reportData->deviceId);
129 BytraceAdapter::StopDevListener();
130 }
131 }
132
OnDeviceAdded(int32_t deviceId,const std::string & type)133 void JsEventTarget::OnDeviceAdded(int32_t deviceId, const std::string &type)
134 {
135 CALL_DEBUG_ENTER;
136 std::lock_guard<std::mutex> guard(mutex_);
137 auto changeEvent = devListener_.find(CHANGED_TYPE);
138 if (changeEvent == devListener_.end()) {
139 MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
140 return;
141 }
142
143 for (auto &item : changeEvent->second) {
144 CHKPC(item);
145 CHKPC(item->env);
146 sptr<JsUtil::ReportData> reportData = new (std::nothrow) JsUtil::ReportData;
147 if (reportData == nullptr) {
148 MMI_HILOGE("Memory allocation failed");
149 return;
150 }
151 reportData->deviceId = deviceId;
152 reportData->ref = item->ref;
153 reportData->IncStrongRef(nullptr);
154 auto task = [reportData, this] () { EmitAddedDeviceEvent(reportData); };
155 int32_t ret = napi_send_event(item->env, task, napi_eprio_vip);
156 if (ret != 0) {
157 MMI_HILOGE("napi_send_event failed");
158 return;
159 }
160 }
161 }
162
OnDeviceRemoved(int32_t deviceId,const std::string & type)163 void JsEventTarget::OnDeviceRemoved(int32_t deviceId, const std::string &type)
164 {
165 CALL_DEBUG_ENTER;
166 std::lock_guard<std::mutex> guard(mutex_);
167 auto changeEvent = devListener_.find(CHANGED_TYPE);
168 if (changeEvent == devListener_.end()) {
169 MMI_HILOGE("Find %{public}s failed", CHANGED_TYPE.c_str());
170 return;
171 }
172 for (auto &item : changeEvent->second) {
173 CHKPC(item);
174 CHKPC(item->env);
175 sptr<JsUtil::ReportData> reportData = new (std::nothrow) JsUtil::ReportData;
176 if (reportData == nullptr) {
177 MMI_HILOGE("Memory allocation failed");
178 return;
179 }
180 reportData->deviceId = deviceId;
181 reportData->ref = item->ref;
182 reportData->IncStrongRef(nullptr);
183 auto task = [reportData, this] () { EmitRemoveDeviceEvent(reportData); };
184 int32_t ret = napi_send_event(item->env, task, napi_eprio_vip);
185 if (ret != 0) {
186 MMI_HILOGE("napi_send_event failed");
187 return;
188 }
189 }
190 }
191
CallIdsAsyncWork(uv_work_t * work,int32_t status)192 void JsEventTarget::CallIdsAsyncWork(uv_work_t *work, int32_t status)
193 {
194 CALL_DEBUG_ENTER;
195 CHKPV(work);
196 if (work->data == nullptr) {
197 JsUtil::DeletePtr<uv_work_t *>(work);
198 MMI_HILOGE("Check data is nullptr");
199 return;
200 }
201 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
202 JsUtil::DeletePtr<uv_work_t *>(work);
203 cb->DecStrongRef(nullptr);
204 CHKPV(cb->env);
205 napi_handle_scope scope = nullptr;
206 napi_open_handle_scope(cb->env, &scope);
207 CHKPV(scope);
208 napi_value arr[2];
209 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &arr[0]), GET_UNDEFINED, scope);
210 CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr[1]), CREATE_ARRAY, scope);
211 uint32_t index = 0;
212 napi_value value = nullptr;
213 for (const auto &item : cb->data.ids) {
214 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
215 CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr[1], index, value), SET_ELEMENT, scope);
216 ++index;
217 }
218
219 napi_value handler = nullptr;
220 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
221 napi_value result = nullptr;
222 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, arr, &result),
223 CALL_FUNCTION, scope);
224 CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
225 napi_close_handle_scope(cb->env, scope);
226 }
227
CallIdsPromiseWork(uv_work_t * work,int32_t status)228 void JsEventTarget::CallIdsPromiseWork(uv_work_t *work, int32_t status)
229 {
230 CALL_DEBUG_ENTER;
231 CHKPV(work);
232 if (work->data == nullptr) {
233 JsUtil::DeletePtr<uv_work_t *>(work);
234 MMI_HILOGE("Check data is nullptr");
235 return;
236 }
237 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
238 JsUtil::DeletePtr<uv_work_t *>(work);
239 cb->DecStrongRef(nullptr);
240 CHKPV(cb->env);
241 napi_handle_scope scope = nullptr;
242 napi_open_handle_scope(cb->env, &scope);
243 CHKPV(scope);
244 napi_value arr = nullptr;
245 CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &arr), CREATE_ARRAY, scope);
246 uint32_t index = 0;
247 napi_value value = nullptr;
248 for (const auto &item : cb->data.ids) {
249 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
250 CHKRV_SCOPE(cb->env, napi_set_element(cb->env, arr, index, value), SET_ELEMENT, scope);
251 ++index;
252 }
253 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, arr), RESOLVE_DEFERRED, scope);
254 napi_close_handle_scope(cb->env, scope);
255 }
256
EmitJsIds(sptr<JsUtil::CallbackInfo> cb,std::vector<int32_t> & ids)257 void JsEventTarget::EmitJsIds(sptr<JsUtil::CallbackInfo> cb, std::vector<int32_t> &ids)
258 {
259 CALL_DEBUG_ENTER;
260 CHKPV(cb);
261 CHKPV(cb->env);
262 cb->data.ids = ids;
263 cb->errCode = RET_OK;
264 EmitJsIdsInternal(cb);
265 }
266
EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)267 void JsEventTarget::EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)
268 {
269 uv_loop_s *loop = nullptr;
270 CHKPV(cb);
271 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
272 uv_work_t *work = new (std::nothrow) uv_work_t;
273 CHKPV(work);
274 cb->IncStrongRef(nullptr);
275 work->data = cb.GetRefPtr();
276 int32_t ret = -1;
277 if (cb->isApi9) {
278 if (cb->ref == nullptr) {
279 ret = uv_queue_work_with_qos(
280 loop, work,
281 [](uv_work_t *work) {
282 MMI_HILOGD("uv_queue_work callback function is called");
283 CallJsIdsTask(work);
284 }, CallDevListPromiseWork, uv_qos_user_initiated);
285 } else {
286 ret = uv_queue_work_with_qos(
287 loop, work,
288 [](uv_work_t *work) {
289 MMI_HILOGD("uv_queue_work callback function is called");
290 CallJsIdsTask(work);
291 }, CallDevListAsyncWork, uv_qos_user_initiated);
292 }
293 } else {
294 if (cb->ref == nullptr) {
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 CallJsIdsTask(work);
300 }, CallIdsPromiseWork, uv_qos_user_initiated);
301 } else {
302 ret = uv_queue_work_with_qos(
303 loop, work,
304 [](uv_work_t *work) {
305 MMI_HILOGD("uv_queue_work callback function is called");
306 CallJsIdsTask(work);
307 }, CallIdsAsyncWork, uv_qos_user_initiated);
308 }
309 }
310 if (ret != 0) {
311 MMI_HILOGE("uv_queue_work_with_qos failed");
312 JsUtil::DeletePtr<uv_work_t *>(work);
313 }
314 }
315
CallDevAsyncWork(uv_work_t * work,int32_t status)316 void JsEventTarget::CallDevAsyncWork(uv_work_t *work, int32_t status)
317 {
318 CALL_DEBUG_ENTER;
319 CHKPV(work);
320 if (work->data == nullptr) {
321 JsUtil::DeletePtr<uv_work_t *>(work);
322 MMI_HILOGE("Check data is nullptr");
323 return;
324 }
325 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
326 JsUtil::DeletePtr<uv_work_t *>(work);
327 cb->DecStrongRef(nullptr);
328 CHKPV(cb->env);
329 napi_handle_scope scope = nullptr;
330 napi_open_handle_scope(cb->env, &scope);
331 CHKPV(scope);
332 napi_value object[2];
333 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &object[0]), GET_UNDEFINED, scope);
334 object[1] = JsUtil::GetDeviceInfo(cb);
335 napi_value handler = nullptr;
336 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
337 napi_value result = nullptr;
338 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, object, &result),
339 CALL_FUNCTION, scope);
340 CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
341 napi_close_handle_scope(cb->env, scope);
342 }
343
CallDevPromiseWork(uv_work_t * work,int32_t status)344 void JsEventTarget::CallDevPromiseWork(uv_work_t *work, int32_t status)
345 {
346 CALL_DEBUG_ENTER;
347 CHKPV(work);
348 if (work->data == nullptr) {
349 JsUtil::DeletePtr<uv_work_t *>(work);
350 MMI_HILOGE("Check data is nullptr");
351 return;
352 }
353 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
354 JsUtil::DeletePtr<uv_work_t *>(work);
355 cb->DecStrongRef(nullptr);
356 CHKPV(cb->env);
357 napi_handle_scope scope = nullptr;
358 napi_open_handle_scope(cb->env, &scope);
359 CHKPV(scope);
360 napi_value object = JsUtil::GetDeviceInfo(cb);
361 if (object == nullptr) {
362 MMI_HILOGE("Check object is nullptr");
363 napi_close_handle_scope(cb->env, scope);
364 return;
365 }
366 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
367 napi_close_handle_scope(cb->env, scope);
368 }
369
EmitJsDev(sptr<JsUtil::CallbackInfo> cb,int32_t deviceid)370 void JsEventTarget::EmitJsDev(sptr<JsUtil::CallbackInfo> cb, int32_t deviceid)
371 {
372 CALL_DEBUG_ENTER;
373 CHKPV(cb);
374 CHKPV(cb->env);
375 cb->data.deviceId = deviceid;
376 cb->errCode = RET_OK;
377 EmitJsDevInternal(cb);
378 }
379
EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)380 void JsEventTarget::EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)
381 {
382 uv_loop_s *loop = nullptr;
383 CHKPV(cb);
384 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
385 uv_work_t *work = new (std::nothrow) uv_work_t;
386 CHKPV(work);
387 cb->IncStrongRef(nullptr);
388 work->data = cb.GetRefPtr();
389 int32_t ret = -1;
390 if (cb->isApi9) {
391 if (cb->ref == nullptr) {
392 ret = uv_queue_work_with_qos(
393 loop, work,
394 [](uv_work_t *work) {
395 MMI_HILOGD("uv_queue_work callback function is called");
396 CallJsDevTask(work);
397 }, CallDevInfoPromiseWork, 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 CallJsDevTask(work);
404 }, CallDevInfoAsyncWork, uv_qos_user_initiated);
405 }
406 } else {
407 if (cb->ref == nullptr) {
408 ret = uv_queue_work_with_qos(
409 loop, work,
410 [](uv_work_t *work) {
411 MMI_HILOGD("uv_queue_work callback function is called");
412 CallJsDevTask(work);
413 }, CallDevPromiseWork, uv_qos_user_initiated);
414 } else {
415 ret = uv_queue_work_with_qos(
416 loop, work,
417 [](uv_work_t *work) {
418 MMI_HILOGD("uv_queue_work callback function is called");
419 CallJsDevTask(work);
420 }, CallDevAsyncWork, uv_qos_user_initiated);
421 }
422 }
423 if (ret != 0) {
424 MMI_HILOGE("uv_queue_work_with_qos failed");
425 JsUtil::DeletePtr<uv_work_t *>(work);
426 }
427 }
428
CallKeystrokeAbilityPromise(uv_work_t * work,int32_t status)429 void JsEventTarget::CallKeystrokeAbilityPromise(uv_work_t *work, int32_t status)
430 {
431 CALL_DEBUG_ENTER;
432 CHKPV(work);
433 if (work->data == nullptr) {
434 JsUtil::DeletePtr<uv_work_t *>(work);
435 MMI_HILOGE("Check data is nullptr");
436 return;
437 }
438 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
439 JsUtil::DeletePtr<uv_work_t *>(work);
440 cb->DecStrongRef(nullptr);
441 CHKPV(cb->env);
442 napi_handle_scope scope = nullptr;
443 napi_open_handle_scope(cb->env, &scope);
444 CHKPV(scope);
445 napi_value callResult = nullptr;
446 if (cb->errCode != RET_OK) {
447 if (cb->errCode == RET_ERR) {
448 napi_close_handle_scope(cb->env, scope);
449 MMI_HILOGE("Other errors");
450 return;
451 }
452 NapiError codeMsg;
453 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
454 napi_close_handle_scope(cb->env, scope);
455 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
456 return;
457 }
458 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
459 if (callResult == nullptr) {
460 MMI_HILOGE("The callResult is nullptr");
461 napi_close_handle_scope(cb->env, scope);
462 return;
463 }
464 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
465 } else {
466 CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult), CREATE_ARRAY, scope);
467 for (size_t i = 0; i < cb->data.keystrokeAbility.size(); ++i) {
468 napi_value ret = nullptr;
469 napi_value isSupport = nullptr;
470 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keystrokeAbility[i] ? 1 : 0, &ret), CREATE_INT32,
471 scope);
472 CHKRV_SCOPE(cb->env, napi_coerce_to_bool(cb->env, ret, &isSupport), COERCE_TO_BOOL, scope);
473 CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult, static_cast<uint32_t>(i), isSupport),
474 SET_ELEMENT, scope);
475 }
476 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
477 }
478 napi_close_handle_scope(cb->env, scope);
479 }
480
CallKeystrokeAbilityAsync(uv_work_t * work,int32_t status)481 void JsEventTarget::CallKeystrokeAbilityAsync(uv_work_t *work, int32_t status)
482 {
483 CALL_DEBUG_ENTER;
484 CHKPV(work);
485 if (work->data == nullptr) {
486 JsUtil::DeletePtr<uv_work_t *>(work);
487 MMI_HILOGE("Check data is nullptr");
488 return;
489 }
490 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
491 JsUtil::DeletePtr<uv_work_t *>(work);
492 cb->DecStrongRef(nullptr);
493 CHKPV(cb->env);
494 napi_handle_scope scope = nullptr;
495 napi_open_handle_scope(cb->env, &scope);
496 CHKPV(scope);
497 napi_value callResult[2] = { 0 };
498 if (cb->errCode != RET_OK) {
499 if (cb->errCode == RET_ERR) {
500 napi_close_handle_scope(cb->env, scope);
501 MMI_HILOGE("Other errors");
502 return;
503 }
504 NapiError codeMsg;
505 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
506 napi_close_handle_scope(cb->env, scope);
507 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
508 return;
509 }
510 callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
511 if (callResult[0] == nullptr) {
512 MMI_HILOGE("The callResult[0] is nullptr");
513 napi_close_handle_scope(cb->env, scope);
514 return;
515 }
516 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
517 } else {
518 CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult[1]), CREATE_ARRAY, scope);
519 for (size_t i = 0; i < cb->data.keystrokeAbility.size(); ++i) {
520 napi_value ret = nullptr;
521 napi_value isSupport = nullptr;
522 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keystrokeAbility[i] ? 1 : 0, &ret), CREATE_INT32,
523 scope);
524 CHKRV_SCOPE(cb->env, napi_coerce_to_bool(cb->env, ret, &isSupport), COERCE_TO_BOOL, scope);
525 CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult[1], static_cast<uint32_t>(i), isSupport),
526 SET_ELEMENT, scope);
527 }
528 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
529 }
530 napi_value handler = nullptr;
531 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
532 napi_value result = nullptr;
533 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
534 CALL_FUNCTION, scope);
535 napi_close_handle_scope(cb->env, scope);
536 }
537
EmitSupportKeys(sptr<JsUtil::CallbackInfo> cb,std::vector<int32_t> & keycode,int32_t id)538 void JsEventTarget::EmitSupportKeys(sptr<JsUtil::CallbackInfo> cb, std::vector<int32_t> &keycode, int32_t id)
539 {
540 CALL_DEBUG_ENTER;
541 CHKPV(cb);
542 CHKPV(cb->env);
543 cb->data.ids = keycode;
544 cb->data.deviceId = id;
545 cb->errCode = RET_OK;
546 uv_loop_s *loop = nullptr;
547 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
548 uv_work_t *work = new (std::nothrow) uv_work_t;
549 CHKPV(work);
550 cb->IncStrongRef(nullptr);
551 work->data = cb.GetRefPtr();
552 int32_t ret = -1;
553 if (cb->ref == nullptr) {
554 ret = uv_queue_work_with_qos(
555 loop, work,
556 [](uv_work_t *work) {
557 MMI_HILOGD("uv_queue_work callback function is called");
558 CallSupportKeysTask(work);
559 },
560 CallKeystrokeAbilityPromise, uv_qos_user_initiated);
561 } else {
562 ret = uv_queue_work_with_qos(
563 loop, work,
564 [](uv_work_t *work) {
565 MMI_HILOGD("uv_queue_work callback function is called");
566 CallSupportKeysTask(work);
567 },
568 CallKeystrokeAbilityAsync, uv_qos_user_initiated);
569 }
570 if (ret != 0) {
571 MMI_HILOGE("uv_queue_work_with_qos failed");
572 JsUtil::DeletePtr<uv_work_t *>(work);
573 }
574 }
575
EmitJsKeyboardType(sptr<JsUtil::CallbackInfo> cb,int32_t deviceid)576 void JsEventTarget::EmitJsKeyboardType(sptr<JsUtil::CallbackInfo> cb, int32_t deviceid)
577 {
578 CALL_DEBUG_ENTER;
579 CHKPV(cb);
580 CHKPV(cb->env);
581 cb->data.deviceId = deviceid;
582 cb->errCode = RET_OK;
583 uv_loop_s *loop = nullptr;
584 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
585
586 uv_work_t *work = new (std::nothrow) uv_work_t;
587 CHKPV(work);
588 cb->IncStrongRef(nullptr);
589 work->data = cb.GetRefPtr();
590 int32_t ret = -1;
591 if (cb->ref == nullptr) {
592 ret = uv_queue_work_with_qos(
593 loop, work,
594 [](uv_work_t *work) {
595 MMI_HILOGD("uv_queue_work callback function is called");
596 CallGetKeyboardTypeTask(work);
597 },
598 CallKeyboardTypePromise, uv_qos_user_initiated);
599 } else {
600 ret = uv_queue_work_with_qos(
601 loop, work,
602 [](uv_work_t *work) {
603 MMI_HILOGD("uv_queue_work callback function is called");
604 CallGetKeyboardTypeTask(work);
605 },
606 CallKeyboardTypeAsync, uv_qos_user_initiated);
607 }
608 if (ret != 0) {
609 MMI_HILOGE("uv_queue_work_with_qos failed");
610 JsUtil::DeletePtr<uv_work_t *>(work);
611 }
612 }
613
CallKeyboardTypeAsync(uv_work_t * work,int32_t status)614 void JsEventTarget::CallKeyboardTypeAsync(uv_work_t *work, int32_t status)
615 {
616 CALL_DEBUG_ENTER;
617 CHKPV(work);
618 if (work->data == nullptr) {
619 JsUtil::DeletePtr<uv_work_t *>(work);
620 MMI_HILOGE("Check data is nullptr");
621 return;
622 }
623 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
624 JsUtil::DeletePtr<uv_work_t *>(work);
625 cb->DecStrongRef(nullptr);
626 CHKPV(cb->env);
627
628 napi_handle_scope scope = nullptr;
629 napi_open_handle_scope(cb->env, &scope);
630 CHKPV(scope);
631
632 napi_value callResult[2] = { 0 };
633 if (cb->errCode != RET_OK) {
634 if (cb->errCode == RET_ERR) {
635 napi_close_handle_scope(cb->env, scope);
636 MMI_HILOGE("Other errors");
637 return;
638 }
639 NapiError codeMsg;
640 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
641 napi_close_handle_scope(cb->env, scope);
642 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
643 return;
644 }
645 callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
646 if (callResult[0] == nullptr) {
647 MMI_HILOGE("The callResult[0] is nullptr");
648 napi_close_handle_scope(cb->env, scope);
649 return;
650 }
651 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
652 } else {
653 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keyboardType, &callResult[1]), CREATE_INT32, scope);
654 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
655 }
656 napi_value handler = nullptr;
657 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
658 napi_value result = nullptr;
659 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
660 CALL_FUNCTION, scope);
661 napi_close_handle_scope(cb->env, scope);
662 }
663
CallKeyboardTypePromise(uv_work_t * work,int32_t status)664 void JsEventTarget::CallKeyboardTypePromise(uv_work_t *work, int32_t status)
665 {
666 CALL_DEBUG_ENTER;
667 CHKPV(work);
668 if (work->data == nullptr) {
669 JsUtil::DeletePtr<uv_work_t *>(work);
670 MMI_HILOGE("Check data is nullptr");
671 return;
672 }
673 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
674 JsUtil::DeletePtr<uv_work_t *>(work);
675 cb->DecStrongRef(nullptr);
676 CHKPV(cb->env);
677
678 napi_handle_scope scope = nullptr;
679 napi_open_handle_scope(cb->env, &scope);
680 CHKPV(scope);
681
682 napi_value callResult;
683 if (cb->errCode != RET_OK) {
684 if (cb->errCode == RET_ERR) {
685 napi_close_handle_scope(cb->env, scope);
686 MMI_HILOGE("Other errors");
687 return;
688 }
689 NapiError codeMsg;
690 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
691 napi_close_handle_scope(cb->env, scope);
692 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
693 return;
694 }
695 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
696 if (callResult == nullptr) {
697 MMI_HILOGE("The callResult is nullptr");
698 napi_close_handle_scope(cb->env, scope);
699 return;
700 }
701 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
702 } else {
703 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, cb->data.keyboardType, &callResult), CREATE_INT32, scope);
704 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
705 }
706 napi_close_handle_scope(cb->env, scope);
707 }
708
CallDevListAsyncWork(uv_work_t * work,int32_t status)709 void JsEventTarget::CallDevListAsyncWork(uv_work_t *work, int32_t status)
710 {
711 CALL_DEBUG_ENTER;
712 CHKPV(work);
713 if (work->data == nullptr) {
714 JsUtil::DeletePtr<uv_work_t *>(work);
715 MMI_HILOGE("Check data is nullptr");
716 return;
717 }
718 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
719 JsUtil::DeletePtr<uv_work_t *>(work);
720 cb->DecStrongRef(nullptr);
721 CHKPV(cb->env);
722 napi_handle_scope scope = nullptr;
723 napi_open_handle_scope(cb->env, &scope);
724 CHKPV(scope);
725
726 napi_value callResult[2] = { 0 };
727 if (cb->errCode != RET_OK) {
728 if (cb->errCode == RET_ERR) {
729 napi_close_handle_scope(cb->env, scope);
730 MMI_HILOGE("Other errors");
731 return;
732 }
733 NapiError codeMsg;
734 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
735 napi_close_handle_scope(cb->env, scope);
736 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
737 return;
738 }
739 callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
740 CHKNRV_SCOPE(cb->env, callResult[0], "callResult[0]", scope);
741 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
742 } else {
743 CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult[1]), CREATE_ARRAY, scope);
744 uint32_t index = 0;
745 napi_value value = nullptr;
746 for (const auto &item : cb->data.ids) {
747 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
748 CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult[1], index, value), SET_ELEMENT, scope);
749 ++index;
750 }
751 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
752 }
753 napi_value handler = nullptr;
754 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
755 napi_value result = nullptr;
756 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
757 CALL_FUNCTION, scope);
758 CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
759 napi_close_handle_scope(cb->env, scope);
760 }
761
CallDevListPromiseWork(uv_work_t * work,int32_t status)762 void JsEventTarget::CallDevListPromiseWork(uv_work_t *work, int32_t status)
763 {
764 CALL_DEBUG_ENTER;
765 CHKPV(work);
766 if (work->data == nullptr) {
767 JsUtil::DeletePtr<uv_work_t *>(work);
768 MMI_HILOGE("Check data is nullptr");
769 return;
770 }
771 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
772 JsUtil::DeletePtr<uv_work_t *>(work);
773 cb->DecStrongRef(nullptr);
774 CHKPV(cb->env);
775 napi_handle_scope scope = nullptr;
776 napi_open_handle_scope(cb->env, &scope);
777 CHKPV(scope);
778 napi_value callResult = nullptr;
779 if (cb->errCode != RET_OK) {
780 if (cb->errCode == RET_ERR) {
781 napi_close_handle_scope(cb->env, scope);
782 MMI_HILOGE("Other errors");
783 return;
784 }
785 NapiError codeMsg;
786 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
787 napi_close_handle_scope(cb->env, scope);
788 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
789 return;
790 }
791 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
792 if (callResult == nullptr) {
793 MMI_HILOGE("The callResult is nullptr");
794 napi_close_handle_scope(cb->env, scope);
795 return;
796 }
797 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
798 } else {
799 CHKRV_SCOPE(cb->env, napi_create_array(cb->env, &callResult), CREATE_ARRAY, scope);
800 uint32_t index = 0;
801 napi_value value = nullptr;
802 for (const auto &item : cb->data.ids) {
803 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, item, &value), CREATE_INT32, scope);
804 CHKRV_SCOPE(cb->env, napi_set_element(cb->env, callResult, index, value), SET_ELEMENT, scope);
805 ++index;
806 }
807 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
808 }
809 napi_close_handle_scope(cb->env, scope);
810 }
811
CallDevInfoPromiseWork(uv_work_t * work,int32_t status)812 void JsEventTarget::CallDevInfoPromiseWork(uv_work_t *work, int32_t status)
813 {
814 CALL_DEBUG_ENTER;
815 CHKPV(work);
816 if (work->data == nullptr) {
817 JsUtil::DeletePtr<uv_work_t *>(work);
818 MMI_HILOGE("Check data is nullptr");
819 return;
820 }
821 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
822 JsUtil::DeletePtr<uv_work_t *>(work);
823 cb->DecStrongRef(nullptr);
824 CHKPV(cb->env);
825 napi_handle_scope scope = nullptr;
826 napi_open_handle_scope(cb->env, &scope);
827 CHKPV(scope);
828 napi_value callResult = nullptr;
829 if (cb->errCode != RET_OK) {
830 if (cb->errCode == RET_ERR) {
831 napi_close_handle_scope(cb->env, scope);
832 MMI_HILOGE("Other errors");
833 return;
834 }
835 NapiError codeMsg;
836 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
837 napi_close_handle_scope(cb->env, scope);
838 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
839 return;
840 }
841 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
842 if (callResult == nullptr) {
843 MMI_HILOGE("The callResult is nullptr");
844 napi_close_handle_scope(cb->env, scope);
845 return;
846 }
847 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
848 } else {
849 callResult = JsUtil::GetDeviceInfo(cb);
850 if (callResult == nullptr) {
851 MMI_HILOGE("Check callResult is nullptr");
852 napi_close_handle_scope(cb->env, scope);
853 return;
854 }
855 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
856 }
857 napi_close_handle_scope(cb->env, scope);
858 }
859
CallDevInfoAsyncWork(uv_work_t * work,int32_t status)860 void JsEventTarget::CallDevInfoAsyncWork(uv_work_t *work, int32_t status)
861 {
862 CALL_DEBUG_ENTER;
863 CHKPV(work);
864 if (work->data == nullptr) {
865 JsUtil::DeletePtr<uv_work_t *>(work);
866 MMI_HILOGE("Check data is nullptr");
867 return;
868 }
869 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
870 JsUtil::DeletePtr<uv_work_t *>(work);
871 cb->DecStrongRef(nullptr);
872 CHKPV(cb->env);
873 napi_handle_scope scope = nullptr;
874 napi_open_handle_scope(cb->env, &scope);
875 CHKPV(scope);
876 napi_value callResult[2] = { 0 };
877 if (cb->errCode != RET_OK) {
878 if (cb->errCode == RET_ERR) {
879 napi_close_handle_scope(cb->env, scope);
880 MMI_HILOGE("Other errors");
881 return;
882 }
883 NapiError codeMsg;
884 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
885 napi_close_handle_scope(cb->env, scope);
886 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
887 return;
888 }
889 callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
890 if (callResult[0] == nullptr) {
891 MMI_HILOGE("The callResult[0] is nullptr");
892 napi_close_handle_scope(cb->env, scope);
893 return;
894 }
895 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
896 } else {
897 callResult[1] = JsUtil::GetDeviceInfo(cb);
898 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
899 }
900 napi_value handler = nullptr;
901 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
902 napi_value result = nullptr;
903 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
904 CALL_FUNCTION, scope);
905 CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
906 napi_close_handle_scope(cb->env, scope);
907 }
908
EmitJsSetKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb,int32_t delay)909 void JsEventTarget::EmitJsSetKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb, int32_t delay)
910 {
911 CALL_DEBUG_ENTER;
912 CHKPV(cb);
913 CHKPV(cb->env);
914 cb->data.keyboardRepeatDelay = delay;
915 cb->errCode = RET_OK;
916 uv_loop_s *loop = nullptr;
917 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
918
919 uv_work_t *work = new (std::nothrow) uv_work_t;
920 CHKPV(work);
921 cb->IncStrongRef(nullptr);
922 work->data = cb.GetRefPtr();
923 int32_t ret = -1;
924 if (cb->ref == nullptr) {
925 ret = uv_queue_work_with_qos(
926 loop, work,
927 [](uv_work_t *work) {
928 MMI_HILOGD("uv_queue_work callback function is called");
929 CallKeyboardRepeatDelayTask(work, "set");
930 },
931 CallKeyboardRepeatDelayPromise, uv_qos_user_initiated);
932 } else {
933 ret = uv_queue_work_with_qos(
934 loop, work,
935 [](uv_work_t *work) {
936 MMI_HILOGD("uv_queue_work callback function is called");
937 CallKeyboardRepeatDelayTask(work, "set");
938 },
939 CallKeyboardRepeatDelayAsync, uv_qos_user_initiated);
940 }
941 if (ret != 0) {
942 MMI_HILOGE("uv_queue_work_with_qos failed");
943 JsUtil::DeletePtr<uv_work_t *>(work);
944 }
945 }
946
EmitJsKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb,int32_t delay)947 void JsEventTarget::EmitJsKeyboardRepeatDelay(sptr<JsUtil::CallbackInfo> cb, int32_t delay)
948 {
949 CALL_DEBUG_ENTER;
950 CHKPV(cb);
951 CHKPV(cb->env);
952 cb->data.keyboardRepeatDelay = delay;
953 cb->errCode = RET_OK;
954 uv_loop_s *loop = nullptr;
955 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
956
957 uv_work_t *work = new (std::nothrow) uv_work_t;
958 CHKPV(work);
959 cb->IncStrongRef(nullptr);
960 work->data = cb.GetRefPtr();
961 int32_t ret = -1;
962 if (cb->ref == nullptr) {
963 ret = uv_queue_work_with_qos(
964 loop, work,
965 [](uv_work_t *work) {
966 MMI_HILOGD("uv_queue_work callback function is called");
967 CallKeyboardRepeatDelayTask(work, "get");
968 },
969 CallKeyboardRepeatDelayPromise, uv_qos_user_initiated);
970 } else {
971 ret = uv_queue_work_with_qos(
972 loop, work,
973 [](uv_work_t *work) {
974 MMI_HILOGD("uv_queue_work callback function is called");
975 CallKeyboardRepeatDelayTask(work, "get");
976 },
977 CallKeyboardRepeatDelayAsync, uv_qos_user_initiated);
978 }
979 if (ret != 0) {
980 MMI_HILOGE("uv_queue_work_with_qos failed");
981 JsUtil::DeletePtr<uv_work_t *>(work);
982 }
983 }
984
CallKeyboardRepeatDelayAsync(uv_work_t * work,int32_t status)985 void JsEventTarget::CallKeyboardRepeatDelayAsync(uv_work_t *work, int32_t status)
986 {
987 CALL_DEBUG_ENTER;
988 CHKPV(work);
989 if (work->data == nullptr) {
990 JsUtil::DeletePtr<uv_work_t *>(work);
991 MMI_HILOGE("Check data is nullptr");
992 return;
993 }
994 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
995 JsUtil::DeletePtr<uv_work_t *>(work);
996 cb->DecStrongRef(nullptr);
997 CHKPV(cb->env);
998
999 napi_handle_scope scope = nullptr;
1000 napi_open_handle_scope(cb->env, &scope);
1001 CHKPV(scope);
1002
1003 napi_value callResult[2] = {0};
1004 if (cb->errCode != RET_OK) {
1005 if (cb->errCode == RET_ERR) {
1006 napi_close_handle_scope(cb->env, scope);
1007 MMI_HILOGE("Other errors");
1008 return;
1009 }
1010 NapiError codeMsg;
1011 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1012 napi_close_handle_scope(cb->env, scope);
1013 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1014 return;
1015 }
1016 callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1017 if (callResult[0] == nullptr) {
1018 MMI_HILOGE("callResult[0] is nullptr");
1019 napi_close_handle_scope(cb->env, scope);
1020 return;
1021 }
1022 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
1023 } else {
1024 CHKRV_SCOPE(
1025 cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatDelay, &callResult[1]), CREATE_INT32, scope);
1026 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
1027 }
1028 napi_value handler = nullptr;
1029 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
1030 napi_value result = nullptr;
1031 CHKRV_SCOPE(cb->env,
1032 napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
1033 CALL_FUNCTION,
1034 scope);
1035 napi_close_handle_scope(cb->env, scope);
1036 }
1037
CallKeyboardRepeatDelayPromise(uv_work_t * work,int32_t status)1038 void JsEventTarget::CallKeyboardRepeatDelayPromise(uv_work_t *work, int32_t status)
1039 {
1040 CALL_DEBUG_ENTER;
1041 CHKPV(work);
1042 if (work->data == nullptr) {
1043 JsUtil::DeletePtr<uv_work_t *>(work);
1044 MMI_HILOGE("Check data is nullptr");
1045 return;
1046 }
1047 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1048 JsUtil::DeletePtr<uv_work_t *>(work);
1049 cb->DecStrongRef(nullptr);
1050 CHKPV(cb->env);
1051
1052 napi_handle_scope scope = nullptr;
1053 napi_open_handle_scope(cb->env, &scope);
1054 CHKPV(scope);
1055
1056 napi_value callResult;
1057 if (cb->errCode != RET_OK) {
1058 if (cb->errCode == RET_ERR) {
1059 napi_close_handle_scope(cb->env, scope);
1060 MMI_HILOGE("Other errors");
1061 return;
1062 }
1063 NapiError codeMsg;
1064 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1065 napi_close_handle_scope(cb->env, scope);
1066 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1067 return;
1068 }
1069 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1070 if (callResult == nullptr) {
1071 MMI_HILOGE("The callResult is nullptr");
1072 napi_close_handle_scope(cb->env, scope);
1073 return;
1074 }
1075 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1076 } else {
1077 CHKRV_SCOPE(
1078 cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatDelay, &callResult), CREATE_INT32, scope);
1079 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1080 }
1081 napi_close_handle_scope(cb->env, scope);
1082 }
1083
EmitJsSetKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb,int32_t rate)1084 void JsEventTarget::EmitJsSetKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb, int32_t rate)
1085 {
1086 CALL_DEBUG_ENTER;
1087 CHKPV(cb);
1088 CHKPV(cb->env);
1089 cb->data.keyboardRepeatRate = rate;
1090 cb->errCode = RET_OK;
1091 uv_loop_s *loop = nullptr;
1092 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1093
1094 uv_work_t *work = new (std::nothrow) uv_work_t;
1095 CHKPV(work);
1096 cb->IncStrongRef(nullptr);
1097 work->data = cb.GetRefPtr();
1098 int32_t ret = -1;
1099 if (cb->ref == nullptr) {
1100 ret = uv_queue_work_with_qos(
1101 loop, work,
1102 [](uv_work_t *work) {
1103 MMI_HILOGD("uv_queue_work callback function is called");
1104 CallKeyboardRepeatRateTask(work, "set");
1105 },
1106 CallKeyboardRepeatRatePromise, uv_qos_user_initiated);
1107 } else {
1108 ret = uv_queue_work_with_qos(
1109 loop, work,
1110 [](uv_work_t *work) {
1111 MMI_HILOGD("uv_queue_work callback function is called");
1112 CallKeyboardRepeatRateTask(work, "set");
1113 },
1114 CallKeyboardRepeatRateAsync, uv_qos_user_initiated);
1115 }
1116 if (ret != 0) {
1117 MMI_HILOGE("uv_queue_work_with_qos failed");
1118 JsUtil::DeletePtr<uv_work_t *>(work);
1119 }
1120 }
1121
EmitJsKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb,int32_t rate)1122 void JsEventTarget::EmitJsKeyboardRepeatRate(sptr<JsUtil::CallbackInfo> cb, int32_t rate)
1123 {
1124 CALL_DEBUG_ENTER;
1125 CHKPV(cb);
1126 CHKPV(cb->env);
1127 cb->data.keyboardRepeatRate = rate;
1128 cb->errCode = RET_OK;
1129 uv_loop_s *loop = nullptr;
1130 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1131
1132 uv_work_t *work = new (std::nothrow) uv_work_t;
1133 CHKPV(work);
1134 cb->IncStrongRef(nullptr);
1135 work->data = cb.GetRefPtr();
1136 int32_t ret = -1;
1137 if (cb->ref == nullptr) {
1138 ret = uv_queue_work_with_qos(
1139 loop, work,
1140 [](uv_work_t *work) {
1141 MMI_HILOGD("uv_queue_work callback function is called");
1142 CallKeyboardRepeatRateTask(work, "get");
1143 },
1144 CallKeyboardRepeatRatePromise, uv_qos_user_initiated);
1145 } else {
1146 ret = uv_queue_work_with_qos(
1147 loop, work,
1148 [](uv_work_t *work) {
1149 MMI_HILOGD("uv_queue_work callback function is called");
1150 CallKeyboardRepeatRateTask(work, "get");
1151 },
1152 CallKeyboardRepeatRateAsync, uv_qos_user_initiated);
1153 }
1154 if (ret != 0) {
1155 MMI_HILOGE("uv_queue_work_with_qos failed");
1156 JsUtil::DeletePtr<uv_work_t *>(work);
1157 }
1158 }
1159
CallKeyboardRepeatRateAsync(uv_work_t * work,int32_t status)1160 void JsEventTarget::CallKeyboardRepeatRateAsync(uv_work_t *work, int32_t status)
1161 {
1162 CALL_DEBUG_ENTER;
1163 CHKPV(work);
1164 if (work->data == nullptr) {
1165 JsUtil::DeletePtr<uv_work_t *>(work);
1166 MMI_HILOGE("Check data is nullptr");
1167 return;
1168 }
1169 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1170 JsUtil::DeletePtr<uv_work_t *>(work);
1171 cb->DecStrongRef(nullptr);
1172 CHKPV(cb->env);
1173
1174 napi_handle_scope scope = nullptr;
1175 napi_open_handle_scope(cb->env, &scope);
1176 CHKPV(scope);
1177
1178 napi_value callResult[2] = {0};
1179 if (cb->errCode != RET_OK) {
1180 if (cb->errCode == RET_ERR) {
1181 napi_close_handle_scope(cb->env, scope);
1182 MMI_HILOGE("Other errors");
1183 return;
1184 }
1185 NapiError codeMsg;
1186 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1187 napi_close_handle_scope(cb->env, scope);
1188 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1189 return;
1190 }
1191 callResult[0] = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1192 if (callResult[0] == nullptr) {
1193 MMI_HILOGE("The callResult[0] is nullptr");
1194 napi_close_handle_scope(cb->env, scope);
1195 return;
1196 }
1197 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[1]), GET_UNDEFINED, scope);
1198 } else {
1199 CHKRV_SCOPE(
1200 cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatRate, &callResult[1]), CREATE_INT32, scope);
1201 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult[0]), GET_UNDEFINED, scope);
1202 }
1203 napi_value handler = nullptr;
1204 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
1205 napi_value result = nullptr;
1206 CHKRV_SCOPE(cb->env,
1207 napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, callResult, &result),
1208 CALL_FUNCTION,
1209 scope);
1210 napi_close_handle_scope(cb->env, scope);
1211 }
1212
CallKeyboardRepeatRatePromise(uv_work_t * work,int32_t status)1213 void JsEventTarget::CallKeyboardRepeatRatePromise(uv_work_t *work, int32_t status)
1214 {
1215 CALL_DEBUG_ENTER;
1216 CHKPV(work);
1217 if (work->data == nullptr) {
1218 JsUtil::DeletePtr<uv_work_t *>(work);
1219 MMI_HILOGE("Check data is nullptr");
1220 return;
1221 }
1222 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1223 JsUtil::DeletePtr<uv_work_t *>(work);
1224 cb->DecStrongRef(nullptr);
1225 CHKPV(cb->env);
1226
1227 napi_handle_scope scope = nullptr;
1228 napi_open_handle_scope(cb->env, &scope);
1229 CHKPV(scope);
1230
1231 napi_value callResult;
1232 if (cb->errCode != RET_OK) {
1233 if (cb->errCode == RET_ERR) {
1234 napi_close_handle_scope(cb->env, scope);
1235 MMI_HILOGE("Other errors");
1236 return;
1237 }
1238 NapiError codeMsg;
1239 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1240 napi_close_handle_scope(cb->env, scope);
1241 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1242 return;
1243 }
1244 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1245 if (callResult == nullptr) {
1246 MMI_HILOGE("The callResult is nullptr");
1247 napi_close_handle_scope(cb->env, scope);
1248 return;
1249 }
1250 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1251 } else {
1252 CHKRV_SCOPE(
1253 cb->env, napi_create_int32(cb->env, cb->data.keyboardRepeatRate, &callResult), CREATE_INT32, scope);
1254 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1255 }
1256 napi_close_handle_scope(cb->env, scope);
1257 }
1258
AddListener(napi_env env,const std::string & type,napi_value handle)1259 void JsEventTarget::AddListener(napi_env env, const std::string &type, napi_value handle)
1260 {
1261 CALL_DEBUG_ENTER;
1262 bool isListening { false };
1263 {
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 for (const auto &temp : iter->second) {
1271 CHKPC(temp);
1272 if (temp->env != env) {
1273 continue;
1274 }
1275 if (JsUtil::IsSameHandle(env, handle, temp->ref)) {
1276 MMI_HILOGW("The handle already exists");
1277 return;
1278 }
1279 }
1280 napi_ref ref = nullptr;
1281 CHKRV(napi_create_reference(env, handle, 1, &ref), CREATE_REFERENCE);
1282 auto monitor = std::make_unique<JsUtil::CallbackInfo>();
1283 monitor->env = env;
1284 monitor->ref = ref;
1285 iter->second.push_back(std::move(monitor));
1286 isListening = isListeningProcess_;
1287 }
1288 if (!isListening) {
1289 auto ret = InputManager::GetInstance()->RegisterDevListener("change", shared_from_this());
1290 if (ret != RET_OK) {
1291 MMI_HILOGE("RegisterDevListener fail, error:%{public}d", ret);
1292 } else {
1293 std::lock_guard<std::mutex> guard(mutex_);
1294 isListeningProcess_ = true;
1295 }
1296 }
1297 }
1298
RemoveListener(napi_env env,const std::string & type,napi_value handle)1299 void JsEventTarget::RemoveListener(napi_env env, const std::string &type, napi_value handle)
1300 {
1301 CALL_DEBUG_ENTER;
1302 bool needStopListening { false };
1303 {
1304 std::lock_guard<std::mutex> guard(mutex_);
1305 auto iter = devListener_.find(type);
1306 if (iter == devListener_.end()) {
1307 MMI_HILOGE("Find %{public}s failed", type.c_str());
1308 return;
1309 }
1310 if (handle == nullptr) {
1311 iter->second.clear();
1312 goto monitorLabel;
1313 }
1314 for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
1315 if ((*it)->env != env) {
1316 continue;
1317 }
1318 if (JsUtil::IsSameHandle(env, handle, (*it)->ref)) {
1319 MMI_HILOGD("Succeeded in removing monitor");
1320 JsUtil::DeleteCallbackInfo(std::move(*it));
1321 iter->second.erase(it);
1322 goto monitorLabel;
1323 }
1324 }
1325
1326 monitorLabel:
1327 if (isListeningProcess_ && iter->second.empty()) {
1328 needStopListening = true;
1329 isListeningProcess_ = false;
1330 }
1331 }
1332 if (needStopListening) {
1333 auto ret = InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1334 if (ret != RET_OK) {
1335 MMI_HILOGE("UnregisterDevListener fail, error:%{public}d", ret);
1336 }
1337 }
1338 }
1339
GreateBusinessError(napi_env env,int32_t errCode,std::string errMessage)1340 napi_value JsEventTarget::GreateBusinessError(napi_env env, int32_t errCode, std::string errMessage)
1341 {
1342 CALL_DEBUG_ENTER;
1343 napi_value result = nullptr;
1344 napi_value resultCode = nullptr;
1345 napi_value resultMessage = nullptr;
1346 CHKRP(napi_create_int32(env, errCode, &resultCode), CREATE_INT32);
1347 CHKRP(napi_create_string_utf8(env, errMessage.data(), NAPI_AUTO_LENGTH, &resultMessage), CREATE_STRING_UTF8);
1348 CHKRP(napi_create_error(env, nullptr, resultMessage, &result), CREATE_ERROR);
1349 CHKRP(napi_set_named_property(env, result, ERR_CODE.c_str(), resultCode), SET_NAMED_PROPERTY);
1350 return result;
1351 }
1352
CreateCallbackInfo(napi_env env,napi_value handle,sptr<JsUtil::CallbackInfo> cb)1353 napi_value JsEventTarget::CreateCallbackInfo(napi_env env, napi_value handle, sptr<JsUtil::CallbackInfo> cb)
1354 {
1355 CALL_DEBUG_ENTER;
1356 CHKPP(cb);
1357 cb->env = env;
1358 napi_value promise = nullptr;
1359 if (handle == nullptr) {
1360 CHKRP(napi_create_promise(env, &cb->deferred, &promise), CREATE_PROMISE);
1361 } else {
1362 CHKRP(napi_create_reference(env, handle, 1, &cb->ref), CREATE_REFERENCE);
1363 }
1364 return promise;
1365 }
1366
EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)1367 void JsEventTarget::EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)
1368 {
1369 CALL_DEBUG_ENTER;
1370 CHKPV(cb);
1371 CHKPV(cb->env);
1372 uv_loop_s *loop = nullptr;
1373 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1374 uv_work_t *work = new (std::nothrow) uv_work_t;
1375 CHKPV(work);
1376 cb->IncStrongRef(nullptr);
1377 work->data = cb.GetRefPtr();
1378 int32_t ret = 0;
1379 ret = uv_queue_work_with_qos(
1380 loop, work,
1381 [](uv_work_t *work) {
1382 MMI_HILOGD("uv_queue_work callback function is called");
1383 CallIntervalSinceLastInputTask(work);
1384 },
1385 CallIntervalSinceLastInputPromise, uv_qos_user_initiated);
1386 if (ret != 0) {
1387 MMI_HILOGE("uv_queue_work_with_qos failed");
1388 cb->DecStrongRef(nullptr);
1389 JsUtil::DeletePtr<uv_work_t *>(work);
1390 }
1391 }
1392
CallIntervalSinceLastInputPromise(uv_work_t * work,int32_t status)1393 void JsEventTarget::CallIntervalSinceLastInputPromise(uv_work_t *work, int32_t status)
1394 {
1395 CALL_DEBUG_ENTER;
1396 CHKPV(work);
1397 if (work->data == nullptr) {
1398 JsUtil::DeletePtr<uv_work_t *>(work);
1399 MMI_HILOGE("Check data is nullptr");
1400 return;
1401 }
1402 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1403 JsUtil::DeletePtr<uv_work_t *>(work);
1404 cb->DecStrongRef(nullptr);
1405 CHKPV(cb->env);
1406
1407 napi_handle_scope scope = nullptr;
1408 napi_open_handle_scope(cb->env, &scope);
1409 CHKPV(scope);
1410 napi_value callResult;
1411 CHKRV_SCOPE(cb->env, napi_create_int64(cb->env, cb->data.IntervalSinceLastInput, &callResult),
1412 CREATE_INT64, scope);
1413 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1414 napi_close_handle_scope(cb->env, scope);
1415 }
1416
ResetEnv()1417 void JsEventTarget::ResetEnv()
1418 {
1419 CALL_DEBUG_ENTER;
1420 {
1421 std::lock_guard<std::mutex> guard(mutex_);
1422 devListener_.clear();
1423 }
1424 auto ret = InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1425 if (ret != RET_OK) {
1426 MMI_HILOGE("UnregisterDevListener fail, error:%{public}d", ret);
1427 }
1428 }
1429
CallSetInputDeviceEnabledPromise(uv_work_t * work,int32_t status)1430 void JsEventTarget::CallSetInputDeviceEnabledPromise(uv_work_t *work, int32_t status)
1431 {
1432 CALL_DEBUG_ENTER;
1433 CHKPV(work);
1434 if (work->data == nullptr) {
1435 JsUtil::DeletePtr<uv_work_t *>(work);
1436 MMI_HILOGE("Check data is nullptr");
1437 return;
1438 }
1439 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1440 JsUtil::DeletePtr<uv_work_t *>(work);
1441 cb->DecStrongRef(nullptr);
1442 CHKPV(cb->env);
1443
1444 napi_handle_scope scope = nullptr;
1445 napi_open_handle_scope(cb->env, &scope);
1446 CHKPV(scope);
1447
1448 napi_value callResult;
1449 if (cb->errCode != RET_OK) {
1450 if (cb->errCode == RET_ERR) {
1451 napi_close_handle_scope(cb->env, scope);
1452 MMI_HILOGE("Other errors");
1453 return;
1454 }
1455 NapiError codeMsg;
1456 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1457 napi_close_handle_scope(cb->env, scope);
1458 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1459 return;
1460 }
1461 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1462 if (callResult == nullptr) {
1463 MMI_HILOGE("The callResult is nullptr");
1464 napi_close_handle_scope(cb->env, scope);
1465 return;
1466 }
1467 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1468 } else {
1469 CHKRV_SCOPE(
1470 cb->env, napi_create_int32(cb->env, cb->errCode, &callResult), CREATE_INT32, scope);
1471 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1472 }
1473 napi_close_handle_scope(cb->env, scope);
1474 }
1475
EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb,int32_t errCode)1476 void JsEventTarget::EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb, int32_t errCode)
1477 {
1478 CALL_DEBUG_ENTER;
1479 CHKPV(cb);
1480 CHKPV(cb->env);
1481 cb->errCode = errCode;
1482 uv_loop_s *loop = nullptr;
1483 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1484
1485 uv_work_t *work = new (std::nothrow) uv_work_t;
1486 CHKPV(work);
1487 cb->IncStrongRef(nullptr);
1488 work->data = cb.GetRefPtr();
1489 int32_t ret = -1;
1490 if (cb->ref == nullptr) {
1491 ret = uv_queue_work_with_qos(
1492 loop, work,
1493 [](uv_work_t *work) {
1494 MMI_HILOGD("uv_queue_work callback function is called");
1495 },
1496 CallSetInputDeviceEnabledPromise, uv_qos_user_initiated);
1497 }
1498 if (ret != 0) {
1499 MMI_HILOGE("uv_queue_work_with_qos failed");
1500 JsUtil::DeletePtr<uv_work_t *>(work);
1501 }
1502 }
1503
EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey,bool state)1504 void JsEventTarget::EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey, bool state)
1505 {
1506 CALL_DEBUG_ENTER;
1507 CHKPV(cb);
1508 int32_t keyState = state ? 1 : 0;
1509 cb->uData.keys.push_back(funcKey);
1510 cb->uData.keys.push_back(keyState);
1511 cb->setFuncKeyType = true;
1512 cb->errCode = -1;
1513 uv_loop_s *loop = nullptr;
1514 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1515 uv_work_t *work = new (std::nothrow) uv_work_t;
1516 CHKPV(work);
1517 cb->IncStrongRef(nullptr);
1518 // data heap point cb pointer
1519 work->data = cb.GetRefPtr();
1520 int32_t ret = -1;
1521 ret = uv_queue_work_with_qos(
1522 loop, work,
1523 [](uv_work_t *work) {
1524 MMI_HILOGD("uv_queue_work callback function is called");
1525 CallFunctionKeyStateTask(work);
1526 },
1527 CallFunctionKeyState, uv_qos_user_initiated);
1528 if (ret != 0) {
1529 MMI_HILOGE("uv_queue_work_with_qos failed");
1530 cb->DecStrongRef(nullptr);
1531 JsUtil::DeletePtr<uv_work_t *>(work);
1532 }
1533 }
1534
EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey)1535 void JsEventTarget::EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey)
1536 {
1537 CALL_DEBUG_ENTER;
1538 CHKPV(cb);
1539 cb->uData.keys.push_back(funcKey);
1540 cb->getFuncKeyType = true;
1541 uv_loop_s *loop = nullptr;
1542 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1543 uv_work_t *work = new (std::nothrow) uv_work_t;
1544 CHKPV(work);
1545 cb->IncStrongRef(nullptr);
1546 work->data = cb.GetRefPtr();
1547 int32_t ret = -1;
1548 ret = uv_queue_work_with_qos(
1549 loop, work,
1550 [](uv_work_t *work) {
1551 MMI_HILOGD("uv_queue_work callback function is called");
1552 CallFunctionKeyStateTask(work);
1553 },
1554 CallFunctionKeyState, uv_qos_user_initiated);
1555 if (ret != 0) {
1556 MMI_HILOGE("uv_queue_work_with_qos failed");
1557 cb->DecStrongRef(nullptr);
1558 JsUtil::DeletePtr<uv_work_t *>(work);
1559 }
1560 }
1561
CallFunctionKeyStateTask(uv_work_t * work)1562 void JsEventTarget::CallFunctionKeyStateTask(uv_work_t *work)
1563 {
1564 CHKPV(work);
1565 if (work->data == nullptr) {
1566 JsUtil::DeletePtr<uv_work_t *>(work);
1567 MMI_HILOGE("Check data is nullptr");
1568 return;
1569 }
1570 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1571 CHKPV(cb->env);
1572 if (cb->getFuncKeyType) {
1573 bool resultState = false;
1574 auto funcKey = cb->uData.keys.front();
1575 int32_t napiCode = InputManager::GetInstance()->GetFunctionKeyState(funcKey, resultState);
1576 int32_t keyState = resultState ? 1 : 0;
1577 cb->errCode = napiCode;
1578 cb->uData.keys.push_back(keyState);
1579 }
1580 if (cb->setFuncKeyType) {
1581 auto funcKey = cb->uData.keys.front();
1582 auto state = cb->uData.keys.back();
1583 int32_t napiCode = InputManager::GetInstance()->SetFunctionKeyState(funcKey, state);
1584 cb->errCode = napiCode;
1585 }
1586 }
1587
GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb,napi_handle_scope scope,napi_value & callResult)1588 bool JsEventTarget::GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb, napi_handle_scope scope,
1589 napi_value &callResult)
1590 {
1591 CALL_DEBUG_ENTER;
1592 CHKPF(cb);
1593 if (cb->errCode == RET_ERR) {
1594 napi_close_handle_scope(cb->env, scope);
1595 MMI_HILOGE("return value errors");
1596 return false;
1597 }
1598 NapiError codeMsg;
1599 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1600 napi_close_handle_scope(cb->env, scope);
1601 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1602 return false;
1603 }
1604 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1605 if (callResult == nullptr) {
1606 MMI_HILOGE("The callResult is nullptr");
1607 napi_close_handle_scope(cb->env, scope);
1608 return false;
1609 }
1610 return true;
1611 }
1612
CallFunctionKeyState(uv_work_t * work,int32_t status)1613 void JsEventTarget::CallFunctionKeyState(uv_work_t *work, int32_t status)
1614 {
1615 CALL_DEBUG_ENTER;
1616 CHKPV(work);
1617 if (work->data == nullptr) {
1618 JsUtil::DeletePtr<uv_work_t *>(work);
1619 return;
1620 }
1621 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1622 JsUtil::DeletePtr<uv_work_t *>(work);
1623 cb->DecStrongRef(nullptr);
1624 CHKPV(cb->env);
1625 napi_handle_scope scope = nullptr;
1626 napi_open_handle_scope(cb->env, &scope);
1627 CHKPV(scope);
1628 napi_value callResult = nullptr;
1629 if (cb->errCode != RET_OK) {
1630 if (!GetFunctionKeyStateErrCode(cb, scope, callResult)) {
1631 MMI_HILOGE("promise get function key state error");
1632 return;
1633 }
1634 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1635 } else {
1636 if (cb->getFuncKeyType) {
1637 auto state = cb->uData.keys.back();
1638 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, state, &callResult), CREATE_INT32, scope);
1639 } else {
1640 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult), GET_UNDEFINED, scope);
1641 }
1642 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1643 }
1644 napi_close_handle_scope(cb->env, scope);
1645 }
1646
CallKeyboardRepeatDelayTask(uv_work_t * work,const std::string & operateType)1647 void JsEventTarget::CallKeyboardRepeatDelayTask(uv_work_t *work, const std::string& operateType)
1648 {
1649 CHKPV(work);
1650 if (work->data == nullptr) {
1651 JsUtil::DeletePtr<uv_work_t *>(work);
1652 MMI_HILOGE("Check data is nullptr");
1653 return;
1654 }
1655 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1656 CHKPV(cb->env);
1657
1658 if (operateType == "get") {
1659 int32_t _delay = -1;
1660 auto callback = [&_delay] (int32_t delay) { _delay = delay; };
1661 int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatDelay(callback);
1662 cb->errCode = napiCode;
1663 cb->data.keyboardRepeatDelay = _delay;
1664 } else {
1665 int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatDelay(cb->data.keyboardRepeatDelay);
1666 cb->errCode = napiCode;
1667 }
1668 }
1669
CallKeyboardRepeatRateTask(uv_work_t * work,const std::string & operateType)1670 void JsEventTarget::CallKeyboardRepeatRateTask(uv_work_t *work, const std::string& operateType)
1671 {
1672 CHKPV(work);
1673 if (work->data == nullptr) {
1674 JsUtil::DeletePtr<uv_work_t *>(work);
1675 MMI_HILOGE("Check data is nullptr");
1676 return;
1677 }
1678 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1679 CHKPV(cb->env);
1680
1681 if (operateType == "get") {
1682 int32_t _rate = -1;
1683 auto callback = [&_rate] (int32_t rate) { _rate = rate; };
1684 int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatRate(callback);
1685 cb->errCode = napiCode;
1686 cb->data.keyboardRepeatRate = _rate;
1687 } else {
1688 int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatRate(cb->data.keyboardRepeatRate);
1689 cb->errCode = napiCode;
1690 }
1691 }
1692
CallGetKeyboardTypeTask(uv_work_t * work)1693 void JsEventTarget::CallGetKeyboardTypeTask(uv_work_t *work)
1694 {
1695 CHKPV(work);
1696 if (work->data == nullptr) {
1697 JsUtil::DeletePtr<uv_work_t *>(work);
1698 MMI_HILOGE("Check data is nullptr");
1699 return;
1700 }
1701 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1702 CHKPV(cb->env);
1703
1704 int32_t _keyboardtype = -1;
1705 auto callback = [&_keyboardtype] (int32_t keyboardtype) { _keyboardtype = keyboardtype; };
1706 int32_t napiCode = InputManager::GetInstance()->GetKeyboardType(cb->data.deviceId, callback);
1707 cb->errCode = napiCode;
1708 cb->data.keyboardType = _keyboardtype;
1709 }
1710
CallJsIdsTask(uv_work_t * work)1711 void JsEventTarget::CallJsIdsTask(uv_work_t *work)
1712 {
1713 CHKPV(work);
1714 if (work->data == nullptr) {
1715 JsUtil::DeletePtr<uv_work_t *>(work);
1716 MMI_HILOGE("Check data is nullptr");
1717 return;
1718 }
1719 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1720 CHKPV(cb->env);
1721 std::vector<int32_t> _ids;
1722 auto callback = [&_ids] (std::vector<int32_t>& ids) { _ids = ids; };
1723 int32_t napiCode = InputManager::GetInstance()->GetDeviceIds(callback);
1724 cb->errCode = napiCode;
1725 cb->data.ids = _ids;
1726 }
1727
CallJsDevTask(uv_work_t * work)1728 void JsEventTarget::CallJsDevTask(uv_work_t *work)
1729 {
1730 CHKPV(work);
1731 if (work->data == nullptr) {
1732 JsUtil::DeletePtr<uv_work_t *>(work);
1733 MMI_HILOGE("Check data is nullptr");
1734 return;
1735 }
1736 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1737 CHKPV(cb->env);
1738 std::shared_ptr<InputDevice> _device = std::make_shared<InputDevice>();
1739 auto callback = [&_device] (std::shared_ptr<InputDevice> device) { _device = device; };
1740 int32_t napiCode = InputManager::GetInstance()->GetDevice(cb->data.deviceId, callback);
1741 CHKPV(_device);
1742 cb->errCode = napiCode;
1743 cb->data.device = _device;
1744 }
1745
CallSupportKeysTask(uv_work_t * work)1746 void JsEventTarget::CallSupportKeysTask(uv_work_t *work)
1747 {
1748 CHKPV(work);
1749 if (work->data == nullptr) {
1750 JsUtil::DeletePtr<uv_work_t *>(work);
1751 MMI_HILOGE("Check data is nullptr");
1752 return;
1753 }
1754 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1755 CHKPV(cb->env);
1756 auto callback = [&] (std::vector<bool>& keystrokeAbility) {
1757 cb->data.keystrokeAbility = keystrokeAbility;
1758 };
1759 int32_t napiCode = InputManager::GetInstance()->SupportKeys(cb->data.deviceId, cb->data.ids, callback);
1760 cb->errCode = napiCode;
1761 }
CallIntervalSinceLastInputTask(uv_work_t * work)1762 void JsEventTarget::CallIntervalSinceLastInputTask(uv_work_t *work)
1763 {
1764 CHKPV(work);
1765 if (work->data == nullptr) {
1766 JsUtil::DeletePtr<uv_work_t *>(work);
1767 MMI_HILOGE("Check data is nullptr");
1768 return;
1769 }
1770 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1771 CHKPV(cb->env);
1772 int32_t napiCode = InputManager::GetInstance()->GetIntervalSinceLastInput(cb->data.IntervalSinceLastInput);
1773 cb->errCode = napiCode;
1774 }
1775 } // namespace MMI
1776 } // namespace OHOS
1777