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 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, deviceid:%{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, deviceid:%{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 EmitJsIdsInternal(cb);
267 }
268
EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)269 void JsEventTarget::EmitJsIdsInternal(sptr<JsUtil::CallbackInfo> cb)
270 {
271 uv_loop_s *loop = nullptr;
272 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
273 uv_work_t *work = new (std::nothrow) uv_work_t;
274 CHKPV(work);
275 cb->IncStrongRef(nullptr);
276 work->data = cb.GetRefPtr();
277 int32_t ret = -1;
278 if (cb->isApi9) {
279 if (cb->ref == nullptr) {
280 ret = uv_queue_work_with_qos(
281 loop, work,
282 [](uv_work_t *work) {
283 MMI_HILOGD("uv_queue_work callback function is called");
284 CallJsIdsTask(work);
285 }, CallDevListPromiseWork, uv_qos_user_initiated);
286 } else {
287 ret = uv_queue_work_with_qos(
288 loop, work,
289 [](uv_work_t *work) {
290 MMI_HILOGD("uv_queue_work callback function is called");
291 CallJsIdsTask(work);
292 }, CallDevListAsyncWork, uv_qos_user_initiated);
293 }
294 } else {
295 if (cb->ref == nullptr) {
296 ret = uv_queue_work_with_qos(
297 loop, work,
298 [](uv_work_t *work) {
299 MMI_HILOGD("uv_queue_work callback function is called");
300 CallJsIdsTask(work);
301 }, CallIdsPromiseWork, uv_qos_user_initiated);
302 } else {
303 ret = uv_queue_work_with_qos(
304 loop, work,
305 [](uv_work_t *work) {
306 MMI_HILOGD("uv_queue_work callback function is called");
307 CallJsIdsTask(work);
308 }, CallIdsAsyncWork, uv_qos_user_initiated);
309 }
310 }
311 if (ret != 0) {
312 MMI_HILOGE("uv_queue_work_with_qos failed");
313 JsUtil::DeletePtr<uv_work_t *>(work);
314 }
315 }
316
CallDevAsyncWork(uv_work_t * work,int32_t status)317 void JsEventTarget::CallDevAsyncWork(uv_work_t *work, int32_t status)
318 {
319 CALL_DEBUG_ENTER;
320 CHKPV(work);
321 if (work->data == nullptr) {
322 JsUtil::DeletePtr<uv_work_t *>(work);
323 MMI_HILOGE("Check data is nullptr");
324 return;
325 }
326 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
327 JsUtil::DeletePtr<uv_work_t *>(work);
328 cb->DecStrongRef(nullptr);
329 CHKPV(cb->env);
330 napi_handle_scope scope = nullptr;
331 napi_open_handle_scope(cb->env, &scope);
332 CHKPV(scope);
333 napi_value object[2];
334 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &object[0]), GET_UNDEFINED, scope);
335 object[1] = JsUtil::GetDeviceInfo(cb);
336 napi_value handler = nullptr;
337 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handler), GET_REFERENCE_VALUE, scope);
338 napi_value result = nullptr;
339 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handler, INPUT_PARAMETER_MIDDLE, object, &result),
340 CALL_FUNCTION, scope);
341 CHKRV_SCOPE(cb->env, napi_delete_reference(cb->env, cb->ref), DELETE_REFERENCE, scope);
342 napi_close_handle_scope(cb->env, scope);
343 }
344
CallDevPromiseWork(uv_work_t * work,int32_t status)345 void JsEventTarget::CallDevPromiseWork(uv_work_t *work, int32_t status)
346 {
347 CALL_DEBUG_ENTER;
348 CHKPV(work);
349 if (work->data == nullptr) {
350 JsUtil::DeletePtr<uv_work_t *>(work);
351 MMI_HILOGE("Check data is nullptr");
352 return;
353 }
354 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
355 JsUtil::DeletePtr<uv_work_t *>(work);
356 cb->DecStrongRef(nullptr);
357 CHKPV(cb->env);
358 napi_handle_scope scope = nullptr;
359 napi_open_handle_scope(cb->env, &scope);
360 CHKPV(scope);
361 napi_value object = JsUtil::GetDeviceInfo(cb);
362 if (object == nullptr) {
363 MMI_HILOGE("Check object is nullptr");
364 napi_close_handle_scope(cb->env, scope);
365 return;
366 }
367 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
368 napi_close_handle_scope(cb->env, scope);
369 }
370
EmitJsDev(sptr<JsUtil::CallbackInfo> cb,int32_t deviceid)371 void JsEventTarget::EmitJsDev(sptr<JsUtil::CallbackInfo> cb, int32_t deviceid)
372 {
373 CALL_DEBUG_ENTER;
374 CHKPV(cb);
375 CHKPV(cb->env);
376 cb->data.deviceId = deviceid;
377 cb->errCode = RET_OK;
378 EmitJsDevInternal(cb);
379 }
380
EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)381 void JsEventTarget::EmitJsDevInternal(sptr<JsUtil::CallbackInfo> cb)
382 {
383 uv_loop_s *loop = nullptr;
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 std::lock_guard<std::mutex> guard(mutex_);
1263 auto iter = devListener_.find(type);
1264 if (iter == devListener_.end()) {
1265 MMI_HILOGE("Find %{public}s failed", type.c_str());
1266 return;
1267 }
1268
1269 for (const auto &temp : iter->second) {
1270 CHKPC(temp);
1271 if (temp->env != env) {
1272 continue;
1273 }
1274 if (JsUtil::IsSameHandle(env, handle, temp->ref)) {
1275 MMI_HILOGW("The handle already exists");
1276 return;
1277 }
1278 }
1279 napi_ref ref = nullptr;
1280 CHKRV(napi_create_reference(env, handle, 1, &ref), CREATE_REFERENCE);
1281 auto monitor = std::make_unique<JsUtil::CallbackInfo>();
1282 monitor->env = env;
1283 monitor->ref = ref;
1284 iter->second.push_back(std::move(monitor));
1285 if (!isListeningProcess_) {
1286 isListeningProcess_ = true;
1287 InputManager::GetInstance()->RegisterDevListener("change", shared_from_this());
1288 }
1289 }
1290
RemoveListener(napi_env env,const std::string & type,napi_value handle)1291 void JsEventTarget::RemoveListener(napi_env env, const std::string &type, napi_value handle)
1292 {
1293 CALL_DEBUG_ENTER;
1294 std::lock_guard<std::mutex> guard(mutex_);
1295 auto iter = devListener_.find(type);
1296 if (iter == devListener_.end()) {
1297 MMI_HILOGE("Find %{public}s failed", type.c_str());
1298 return;
1299 }
1300 if (handle == nullptr) {
1301 iter->second.clear();
1302 goto monitorLabel;
1303 }
1304 for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
1305 if ((*it)->env != env) {
1306 continue;
1307 }
1308 if (JsUtil::IsSameHandle(env, handle, (*it)->ref)) {
1309 MMI_HILOGD("Succeeded in removing monitor");
1310 JsUtil::DeleteCallbackInfo(std::move(*it));
1311 iter->second.erase(it);
1312 goto monitorLabel;
1313 }
1314 }
1315
1316 monitorLabel:
1317 if (isListeningProcess_ && iter->second.empty()) {
1318 isListeningProcess_ = false;
1319 InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1320 }
1321 }
1322
GreateBusinessError(napi_env env,int32_t errCode,std::string errMessage)1323 napi_value JsEventTarget::GreateBusinessError(napi_env env, int32_t errCode, std::string errMessage)
1324 {
1325 CALL_DEBUG_ENTER;
1326 napi_value result = nullptr;
1327 napi_value resultCode = nullptr;
1328 napi_value resultMessage = nullptr;
1329 CHKRP(napi_create_int32(env, errCode, &resultCode), CREATE_INT32);
1330 CHKRP(napi_create_string_utf8(env, errMessage.data(), NAPI_AUTO_LENGTH, &resultMessage), CREATE_STRING_UTF8);
1331 CHKRP(napi_create_error(env, nullptr, resultMessage, &result), CREATE_ERROR);
1332 CHKRP(napi_set_named_property(env, result, ERR_CODE.c_str(), resultCode), SET_NAMED_PROPERTY);
1333 return result;
1334 }
1335
CreateCallbackInfo(napi_env env,napi_value handle,sptr<JsUtil::CallbackInfo> cb)1336 napi_value JsEventTarget::CreateCallbackInfo(napi_env env, napi_value handle, sptr<JsUtil::CallbackInfo> cb)
1337 {
1338 CALL_DEBUG_ENTER;
1339 CHKPP(cb);
1340 cb->env = env;
1341 napi_value promise = nullptr;
1342 if (handle == nullptr) {
1343 CHKRP(napi_create_promise(env, &cb->deferred, &promise), CREATE_PROMISE);
1344 } else {
1345 CHKRP(napi_create_reference(env, handle, 1, &cb->ref), CREATE_REFERENCE);
1346 }
1347 return promise;
1348 }
1349
EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)1350 void JsEventTarget::EmitJsGetIntervalSinceLastInput(sptr<JsUtil::CallbackInfo> cb)
1351 {
1352 CALL_DEBUG_ENTER;
1353 CHKPV(cb);
1354 CHKPV(cb->env);
1355 uv_loop_s *loop = nullptr;
1356 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1357 uv_work_t *work = new (std::nothrow) uv_work_t;
1358 CHKPV(work);
1359 cb->IncStrongRef(nullptr);
1360 work->data = cb.GetRefPtr();
1361 int32_t ret = 0;
1362 ret = uv_queue_work_with_qos(
1363 loop, work,
1364 [](uv_work_t *work) {
1365 MMI_HILOGD("uv_queue_work callback function is called");
1366 CallIntervalSinceLastInputTask(work);
1367 },
1368 CallIntervalSinceLastInputPromise, uv_qos_user_initiated);
1369 if (ret != 0) {
1370 MMI_HILOGE("uv_queue_work_with_qos failed");
1371 cb->DecStrongRef(nullptr);
1372 JsUtil::DeletePtr<uv_work_t *>(work);
1373 }
1374 }
1375
CallIntervalSinceLastInputPromise(uv_work_t * work,int32_t status)1376 void JsEventTarget::CallIntervalSinceLastInputPromise(uv_work_t *work, int32_t status)
1377 {
1378 CALL_DEBUG_ENTER;
1379 CHKPV(work);
1380 if (work->data == nullptr) {
1381 JsUtil::DeletePtr<uv_work_t *>(work);
1382 MMI_HILOGE("Check data is nullptr");
1383 return;
1384 }
1385 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1386 JsUtil::DeletePtr<uv_work_t *>(work);
1387 cb->DecStrongRef(nullptr);
1388 CHKPV(cb->env);
1389
1390 napi_handle_scope scope = nullptr;
1391 napi_open_handle_scope(cb->env, &scope);
1392 CHKPV(scope);
1393 napi_value callResult;
1394 CHKRV_SCOPE(cb->env, napi_create_int64(cb->env, cb->data.IntervalSinceLastInput, &callResult),
1395 CREATE_INT64, scope);
1396 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1397 napi_close_handle_scope(cb->env, scope);
1398 }
1399
ResetEnv()1400 void JsEventTarget::ResetEnv()
1401 {
1402 CALL_DEBUG_ENTER;
1403 std::lock_guard<std::mutex> guard(mutex_);
1404 devListener_.clear();
1405 InputManager::GetInstance()->UnregisterDevListener("change", shared_from_this());
1406 }
1407
CallSetInputDeviceEnabledPromise(uv_work_t * work,int32_t status)1408 void JsEventTarget::CallSetInputDeviceEnabledPromise(uv_work_t *work, int32_t status)
1409 {
1410 CALL_DEBUG_ENTER;
1411 CHKPV(work);
1412 if (work->data == nullptr) {
1413 JsUtil::DeletePtr<uv_work_t *>(work);
1414 MMI_HILOGE("Check data is nullptr");
1415 return;
1416 }
1417 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1418 JsUtil::DeletePtr<uv_work_t *>(work);
1419 cb->DecStrongRef(nullptr);
1420 CHKPV(cb->env);
1421
1422 napi_handle_scope scope = nullptr;
1423 napi_open_handle_scope(cb->env, &scope);
1424 CHKPV(scope);
1425
1426 napi_value callResult;
1427 if (cb->errCode != RET_OK) {
1428 if (cb->errCode == RET_ERR) {
1429 napi_close_handle_scope(cb->env, scope);
1430 MMI_HILOGE("Other errors");
1431 return;
1432 }
1433 NapiError codeMsg;
1434 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1435 napi_close_handle_scope(cb->env, scope);
1436 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1437 return;
1438 }
1439 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1440 if (callResult == nullptr) {
1441 MMI_HILOGE("The callResult is nullptr");
1442 napi_close_handle_scope(cb->env, scope);
1443 return;
1444 }
1445 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1446 } else {
1447 CHKRV_SCOPE(
1448 cb->env, napi_create_int32(cb->env, cb->errCode, &callResult), CREATE_INT32, scope);
1449 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1450 }
1451 napi_close_handle_scope(cb->env, scope);
1452 }
1453
EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb,int32_t errCode)1454 void JsEventTarget::EmitJsSetInputDeviceEnabled(sptr<JsUtil::CallbackInfo> cb, int32_t errCode)
1455 {
1456 CALL_DEBUG_ENTER;
1457 CHKPV(cb);
1458 CHKPV(cb->env);
1459 cb->errCode = errCode;
1460 uv_loop_s *loop = nullptr;
1461 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1462
1463 uv_work_t *work = new (std::nothrow) uv_work_t;
1464 CHKPV(work);
1465 cb->IncStrongRef(nullptr);
1466 work->data = cb.GetRefPtr();
1467 int32_t ret = -1;
1468 if (cb->ref == nullptr) {
1469 ret = uv_queue_work_with_qos(
1470 loop, work,
1471 [](uv_work_t *work) {
1472 MMI_HILOGD("uv_queue_work callback function is called");
1473 },
1474 CallSetInputDeviceEnabledPromise, uv_qos_user_initiated);
1475 }
1476 if (ret != 0) {
1477 MMI_HILOGE("uv_queue_work_with_qos failed");
1478 JsUtil::DeletePtr<uv_work_t *>(work);
1479 }
1480 }
1481
EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey,bool state)1482 void JsEventTarget::EmitJsSetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey, bool state)
1483 {
1484 CALL_DEBUG_ENTER;
1485 CHKPV(cb);
1486 int32_t keyState = state ? 1 : 0;
1487 cb->uData.keys.push_back(funcKey);
1488 cb->uData.keys.push_back(keyState);
1489 cb->setFuncKeyType = true;
1490 cb->errCode = -1;
1491 uv_loop_s *loop = nullptr;
1492 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1493 uv_work_t *work = new (std::nothrow) uv_work_t;
1494 CHKPV(work);
1495 cb->IncStrongRef(nullptr);
1496 // data heap point cb pointer
1497 work->data = cb.GetRefPtr();
1498 int32_t ret = -1;
1499 ret = uv_queue_work_with_qos(
1500 loop, work,
1501 [](uv_work_t *work) {
1502 MMI_HILOGD("uv_queue_work callback function is called");
1503 CallFunctionKeyStateTask(work);
1504 },
1505 CallFunctionKeyState, uv_qos_user_initiated);
1506 if (ret != 0) {
1507 MMI_HILOGE("uv_queue_work_with_qos failed");
1508 cb->DecStrongRef(nullptr);
1509 JsUtil::DeletePtr<uv_work_t *>(work);
1510 }
1511 }
1512
EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb,int32_t funcKey)1513 void JsEventTarget::EmitJsGetFunctionKeyState(sptr<JsUtil::CallbackInfo> cb, int32_t funcKey)
1514 {
1515 CALL_DEBUG_ENTER;
1516 CHKPV(cb);
1517 cb->uData.keys.push_back(funcKey);
1518 cb->getFuncKeyType = true;
1519 uv_loop_s *loop = nullptr;
1520 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
1521 uv_work_t *work = new (std::nothrow) uv_work_t;
1522 CHKPV(work);
1523 cb->IncStrongRef(nullptr);
1524 work->data = cb.GetRefPtr();
1525 int32_t ret = -1;
1526 ret = uv_queue_work_with_qos(
1527 loop, work,
1528 [](uv_work_t *work) {
1529 MMI_HILOGD("uv_queue_work callback function is called");
1530 CallFunctionKeyStateTask(work);
1531 },
1532 CallFunctionKeyState, uv_qos_user_initiated);
1533 if (ret != 0) {
1534 MMI_HILOGE("uv_queue_work_with_qos failed");
1535 cb->DecStrongRef(nullptr);
1536 JsUtil::DeletePtr<uv_work_t *>(work);
1537 }
1538 }
1539
CallFunctionKeyStateTask(uv_work_t * work)1540 void JsEventTarget::CallFunctionKeyStateTask(uv_work_t *work)
1541 {
1542 CHKPV(work);
1543 if (work->data == nullptr) {
1544 JsUtil::DeletePtr<uv_work_t *>(work);
1545 MMI_HILOGE("Check data is nullptr");
1546 return;
1547 }
1548 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1549 CHKPV(cb->env);
1550 if (cb->getFuncKeyType) {
1551 bool resultState = false;
1552 auto funcKey = cb->uData.keys.front();
1553 int32_t napiCode = InputManager::GetInstance()->GetFunctionKeyState(funcKey, resultState);
1554 int32_t keyState = resultState ? 1 : 0;
1555 cb->errCode = napiCode;
1556 cb->uData.keys.push_back(keyState);
1557 }
1558 if (cb->setFuncKeyType) {
1559 auto funcKey = cb->uData.keys.front();
1560 auto state = cb->uData.keys.back();
1561 int32_t napiCode = InputManager::GetInstance()->SetFunctionKeyState(funcKey, state);
1562 cb->errCode = napiCode;
1563 }
1564 }
1565
GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb,napi_handle_scope scope,napi_value & callResult)1566 bool JsEventTarget::GetFunctionKeyStateErrCode(sptr<JsUtil::CallbackInfo> cb, napi_handle_scope scope,
1567 napi_value &callResult)
1568 {
1569 CALL_DEBUG_ENTER;
1570 CHKPF(cb);
1571 if (cb->errCode == RET_ERR) {
1572 napi_close_handle_scope(cb->env, scope);
1573 MMI_HILOGE("return value errors");
1574 return false;
1575 }
1576 NapiError codeMsg;
1577 if (!UtilNapiError::GetApiError(cb->errCode, codeMsg)) {
1578 napi_close_handle_scope(cb->env, scope);
1579 MMI_HILOGE("Error code %{public}d not found", cb->errCode);
1580 return false;
1581 }
1582 callResult = GreateBusinessError(cb->env, cb->errCode, codeMsg.msg);
1583 if (callResult == nullptr) {
1584 MMI_HILOGE("The callResult is nullptr");
1585 napi_close_handle_scope(cb->env, scope);
1586 return false;
1587 }
1588 return true;
1589 }
1590
CallFunctionKeyState(uv_work_t * work,int32_t status)1591 void JsEventTarget::CallFunctionKeyState(uv_work_t *work, int32_t status)
1592 {
1593 CALL_DEBUG_ENTER;
1594 CHKPV(work);
1595 if (work->data == nullptr) {
1596 JsUtil::DeletePtr<uv_work_t *>(work);
1597 return;
1598 }
1599 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo *>(work->data));
1600 JsUtil::DeletePtr<uv_work_t *>(work);
1601 cb->DecStrongRef(nullptr);
1602 CHKPV(cb->env);
1603 napi_handle_scope scope = nullptr;
1604 napi_open_handle_scope(cb->env, &scope);
1605 CHKPV(scope);
1606 napi_value callResult = nullptr;
1607 if (cb->errCode != RET_OK) {
1608 if (!GetFunctionKeyStateErrCode(cb, scope, callResult)) {
1609 MMI_HILOGE("promise get function key state error");
1610 return;
1611 }
1612 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, callResult), REJECT_DEFERRED, scope);
1613 } else {
1614 if (cb->getFuncKeyType) {
1615 auto state = cb->uData.keys.back();
1616 CHKRV_SCOPE(cb->env, napi_create_int32(cb->env, state, &callResult), CREATE_INT32, scope);
1617 } else {
1618 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &callResult), GET_UNDEFINED, scope);
1619 }
1620 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, callResult), RESOLVE_DEFERRED, scope);
1621 }
1622 napi_close_handle_scope(cb->env, scope);
1623 }
1624
CallKeyboardRepeatDelayTask(uv_work_t * work,const std::string & operateType)1625 void JsEventTarget::CallKeyboardRepeatDelayTask(uv_work_t *work, const std::string& operateType)
1626 {
1627 CHKPV(work);
1628 if (work->data == nullptr) {
1629 JsUtil::DeletePtr<uv_work_t *>(work);
1630 MMI_HILOGE("Check data is nullptr");
1631 return;
1632 }
1633 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1634 CHKPV(cb->env);
1635
1636 if (operateType == "get") {
1637 int32_t _delay = -1;
1638 auto callback = [&_delay] (int32_t delay) { _delay = delay; };
1639 int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatDelay(callback);
1640 cb->errCode = napiCode;
1641 cb->data.keyboardRepeatDelay = _delay;
1642 } else {
1643 int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatDelay(cb->data.keyboardRepeatDelay);
1644 cb->errCode = napiCode;
1645 }
1646 }
1647
CallKeyboardRepeatRateTask(uv_work_t * work,const std::string & operateType)1648 void JsEventTarget::CallKeyboardRepeatRateTask(uv_work_t *work, const std::string& operateType)
1649 {
1650 CHKPV(work);
1651 if (work->data == nullptr) {
1652 JsUtil::DeletePtr<uv_work_t *>(work);
1653 MMI_HILOGE("Check data is nullptr");
1654 return;
1655 }
1656 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1657 CHKPV(cb->env);
1658
1659 if (operateType == "get") {
1660 int32_t _rate = -1;
1661 auto callback = [&_rate] (int32_t rate) { _rate = rate; };
1662 int32_t napiCode = InputManager::GetInstance()->GetKeyboardRepeatRate(callback);
1663 cb->errCode = napiCode;
1664 cb->data.keyboardRepeatRate = _rate;
1665 } else {
1666 int32_t napiCode = InputManager::GetInstance()->SetKeyboardRepeatRate(cb->data.keyboardRepeatRate);
1667 cb->errCode = napiCode;
1668 }
1669 }
1670
CallGetKeyboardTypeTask(uv_work_t * work)1671 void JsEventTarget::CallGetKeyboardTypeTask(uv_work_t *work)
1672 {
1673 CHKPV(work);
1674 if (work->data == nullptr) {
1675 JsUtil::DeletePtr<uv_work_t *>(work);
1676 MMI_HILOGE("Check data is nullptr");
1677 return;
1678 }
1679 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1680 CHKPV(cb->env);
1681
1682 int32_t _keyboardtype = -1;
1683 auto callback = [&_keyboardtype] (int32_t keyboardtype) { _keyboardtype = keyboardtype; };
1684 int32_t napiCode = InputManager::GetInstance()->GetKeyboardType(cb->data.deviceId, callback);
1685 cb->errCode = napiCode;
1686 cb->data.keyboardType = _keyboardtype;
1687 }
1688
CallJsIdsTask(uv_work_t * work)1689 void JsEventTarget::CallJsIdsTask(uv_work_t *work)
1690 {
1691 CHKPV(work);
1692 if (work->data == nullptr) {
1693 JsUtil::DeletePtr<uv_work_t *>(work);
1694 MMI_HILOGE("Check data is nullptr");
1695 return;
1696 }
1697 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1698 CHKPV(cb->env);
1699 std::vector<int32_t> _ids;
1700 auto callback = [&_ids] (std::vector<int32_t>& ids) { _ids = ids; };
1701 int32_t napiCode = InputManager::GetInstance()->GetDeviceIds(callback);
1702 cb->errCode = napiCode;
1703 cb->data.ids = _ids;
1704 }
1705
CallJsDevTask(uv_work_t * work)1706 void JsEventTarget::CallJsDevTask(uv_work_t *work)
1707 {
1708 CHKPV(work);
1709 if (work->data == nullptr) {
1710 JsUtil::DeletePtr<uv_work_t *>(work);
1711 MMI_HILOGE("Check data is nullptr");
1712 return;
1713 }
1714 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1715 CHKPV(cb->env);
1716 std::shared_ptr<InputDevice> _device = std::make_shared<InputDevice>();
1717 auto callback = [&_device] (std::shared_ptr<InputDevice> device) { _device = device; };
1718 int32_t napiCode = InputManager::GetInstance()->GetDevice(cb->data.deviceId, callback);
1719 CHKPV(_device);
1720 cb->errCode = napiCode;
1721 cb->data.device = _device;
1722 }
1723
CallSupportKeysTask(uv_work_t * work)1724 void JsEventTarget::CallSupportKeysTask(uv_work_t *work)
1725 {
1726 CHKPV(work);
1727 if (work->data == nullptr) {
1728 JsUtil::DeletePtr<uv_work_t *>(work);
1729 MMI_HILOGE("Check data is nullptr");
1730 return;
1731 }
1732 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1733 CHKPV(cb->env);
1734 auto callback = [&] (std::vector<bool>& keystrokeAbility) {
1735 cb->data.keystrokeAbility = keystrokeAbility;
1736 };
1737 int32_t napiCode = InputManager::GetInstance()->SupportKeys(cb->data.deviceId, cb->data.ids, callback);
1738 cb->errCode = napiCode;
1739 }
CallIntervalSinceLastInputTask(uv_work_t * work)1740 void JsEventTarget::CallIntervalSinceLastInputTask(uv_work_t *work)
1741 {
1742 CHKPV(work);
1743 if (work->data == nullptr) {
1744 JsUtil::DeletePtr<uv_work_t *>(work);
1745 MMI_HILOGE("Check data is nullptr");
1746 return;
1747 }
1748 sptr<JsUtil::CallbackInfo> cb(static_cast<JsUtil::CallbackInfo*>(work->data));
1749 CHKPV(cb->env);
1750 int32_t napiCode = InputManager::GetInstance()->GetIntervalSinceLastInput(cb->data.IntervalSinceLastInput);
1751 cb->errCode = napiCode;
1752 }
1753 } // namespace MMI
1754 } // namespace OHOS
1755