1 /*
2 * Copyright (c) 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_cooperate_target.h"
17
18 #include "devicestatus_define.h"
19 #include "devicestatus_errors.h"
20 #include "interaction_manager.h"
21 #include "napi_constants.h"
22 #include "util_napi_error.h"
23
24 #undef LOG_TAG
25 #define LOG_TAG "JsEventCooperateTarget"
26
27 namespace OHOS {
28 namespace Msdp {
29 namespace DeviceStatus {
30 namespace {
31 inline constexpr std::string_view COORDINATION { "cooperation" };
32 inline constexpr std::string_view CREATE_PROMISE { "napi_create_promise" };
33 inline constexpr std::string_view GET_UNDEFINED { "napi_get_undefined" };
34 inline constexpr std::string_view RESOLVE_DEFERRED { "napi_resolve_deferred" };
35 inline constexpr std::string_view REJECT_DEFERRED { "napi_reject_deferred" };
36 inline constexpr std::string_view CLOSE_SCOPE { "napi_close_handle_scope" };
37 std::mutex mutex_;
38 } // namespace
39
JsEventCooperateTarget()40 JsEventCooperateTarget::JsEventCooperateTarget()
41 {
42 CALL_DEBUG_ENTER;
43 auto ret = coordinationListeners_.insert({ COORDINATION,
44 std::vector<sptr<JsUtilCooperate::CallbackInfo>>()});
45 if (!ret.second) {
46 FI_HILOGW("Failed to add listener, errCode:%{public}d", static_cast<int32_t>(DeviceStatus::VAL_NOT_EXP));
47 }
48 }
49
EmitJsEnable(sptr<JsUtilCooperate::CallbackInfo> cb,const std::string & networkId,const CoordinationMsgInfo & msgInfo)50 void JsEventCooperateTarget::EmitJsEnable(sptr<JsUtilCooperate::CallbackInfo> cb,
51 const std::string &networkId, const CoordinationMsgInfo &msgInfo)
52 {
53 CALL_INFO_TRACE;
54 CHKPV(cb);
55 CHKPV(cb->env);
56 cb->data.enableResult = (msgInfo.msg == CoordinationMessage::PREPARE ||
57 msgInfo.msg == CoordinationMessage::UNPREPARE);
58 cb->data.msgInfo = msgInfo;
59 uv_loop_s *loop = nullptr;
60 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
61 uv_work_s *work = new (std::nothrow) uv_work_t;
62 CHKPV(work);
63 cb->IncStrongRef(nullptr);
64 work->data = cb.GetRefPtr();
65 int32_t ret = 0;
66 if (cb->ref == nullptr) {
67 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallEnablePromiseWork, uv_qos_default);
68 } else {
69 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallEnableAsyncWork, uv_qos_default);
70 }
71
72 if (ret != 0) {
73 FI_HILOGE("Failed to execute uv_queue_work_with_qos");
74 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
75 cb->DecStrongRef(nullptr);
76 }
77 }
78
EmitJsStart(sptr<JsUtilCooperate::CallbackInfo> cb,const std::string & remoteNetworkId,const CoordinationMsgInfo & msgInfo)79 void JsEventCooperateTarget::EmitJsStart(sptr<JsUtilCooperate::CallbackInfo> cb,
80 const std::string &remoteNetworkId, const CoordinationMsgInfo &msgInfo)
81 {
82 CALL_INFO_TRACE;
83 CHKPV(cb);
84 CHKPV(cb->env);
85 cb->data.startResult = (msgInfo.msg == CoordinationMessage::ACTIVATE_SUCCESS);
86 cb->data.msgInfo = msgInfo;
87 uv_loop_s *loop = nullptr;
88 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
89 uv_work_s *work = new (std::nothrow) uv_work_t;
90 CHKPV(work);
91 cb->IncStrongRef(nullptr);
92 work->data = cb.GetRefPtr();
93 int32_t ret = 0;
94 if (cb->ref == nullptr) {
95 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallStartPromiseWork, uv_qos_default);
96 } else {
97 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallStartAsyncWork, uv_qos_default);
98 }
99
100 if (ret != 0) {
101 FI_HILOGE("Failed to execute uv_queue_work_with_qos");
102 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
103 cb->DecStrongRef(nullptr);
104 }
105 }
106
EmitJsStop(sptr<JsUtilCooperate::CallbackInfo> cb,const std::string & networkId,const CoordinationMsgInfo & msgInfo)107 void JsEventCooperateTarget::EmitJsStop(sptr<JsUtilCooperate::CallbackInfo> cb,
108 const std::string &networkId, const CoordinationMsgInfo &msgInfo)
109 {
110 CALL_INFO_TRACE;
111 CHKPV(cb);
112 CHKPV(cb->env);
113 cb->data.stopResult = (msgInfo.msg == CoordinationMessage::DEACTIVATE_SUCCESS);
114 cb->data.msgInfo = msgInfo;
115 uv_loop_s *loop = nullptr;
116 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
117 uv_work_s *work = new (std::nothrow) uv_work_t;
118 CHKPV(work);
119 cb->IncStrongRef(nullptr);
120 work->data = cb.GetRefPtr();
121 int32_t ret = 0;
122 if (cb->ref == nullptr) {
123 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallStopPromiseWork, uv_qos_default);
124 } else {
125 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallStopAsyncWork, uv_qos_default);
126 }
127
128 if (ret != 0) {
129 FI_HILOGE("Failed to execute uv_queue_work_with_qos");
130 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
131 cb->DecStrongRef(nullptr);
132 }
133 }
134
EmitJsGetState(sptr<JsUtilCooperate::CallbackInfo> cb,bool state)135 void JsEventCooperateTarget::EmitJsGetState(sptr<JsUtilCooperate::CallbackInfo> cb, bool state)
136 {
137 CALL_INFO_TRACE;
138 CHKPV(cb);
139 CHKPV(cb->env);
140 cb->data.coordinationOpened = state;
141 uv_loop_s *loop = nullptr;
142 CHKRV(napi_get_uv_event_loop(cb->env, &loop), GET_UV_EVENT_LOOP);
143 uv_work_s *work = new (std::nothrow) uv_work_t;
144 CHKPV(work);
145 cb->IncStrongRef(nullptr);
146 work->data = cb.GetRefPtr();
147 int32_t ret = 0;
148 if (cb->ref == nullptr) {
149 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallGetStatePromiseWork, uv_qos_default);
150 } else {
151 ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CallGetStateAsyncWork, uv_qos_default);
152 }
153
154 if (ret != 0) {
155 FI_HILOGE("Failed to execute uv_queue_work_with_qos");
156 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
157 cb->DecStrongRef(nullptr);
158 }
159 }
160
AddListener(napi_env env,const std::string & type,napi_value handle)161 void JsEventCooperateTarget::AddListener(napi_env env, const std::string &type, napi_value handle)
162 {
163 CALL_INFO_TRACE;
164 std::lock_guard<std::mutex> guard(mutex_);
165 auto iter = coordinationListeners_.find(type);
166 if (iter == coordinationListeners_.end()) {
167 FI_HILOGE("Failed to add listener, type:%{public}s", type.c_str());
168 return;
169 }
170
171 for (const auto &item : iter->second) {
172 CHKPC(item);
173 if (JsUtilCooperate::IsSameHandle(env, handle, item->ref)) {
174 FI_HILOGE("The handle already exists");
175 return;
176 }
177 }
178 napi_ref ref = nullptr;
179 CHKRV(napi_create_reference(env, handle, 1, &ref), CREATE_REFERENCE);
180 sptr<JsUtilCooperate::CallbackInfo> monitor = new (std::nothrow) JsUtilCooperate::CallbackInfo();
181 CHKPV(monitor);
182 monitor->env = env;
183 monitor->ref = ref;
184 iter->second.push_back(std::move(monitor));
185 if (!isListeningProcess_) {
186 isListeningProcess_ = true;
187 INTERACTION_MGR->RegisterCoordinationListener(shared_from_this());
188 }
189 }
190
RemoveListener(napi_env env,const std::string & type,napi_value handle)191 void JsEventCooperateTarget::RemoveListener(napi_env env, const std::string &type, napi_value handle)
192 {
193 CALL_INFO_TRACE;
194 std::lock_guard<std::mutex> guard(mutex_);
195 auto iter = coordinationListeners_.find(type);
196 if (iter == coordinationListeners_.end()) {
197 FI_HILOGE("Failed to remove listener, type:%{public}s", type.c_str());
198 return;
199 }
200 if (handle == nullptr) {
201 iter->second.clear();
202 goto monitorTag;
203 }
204 for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
205 if (JsUtilCooperate::IsSameHandle(env, handle, (*it)->ref)) {
206 FI_HILOGE("Successfully removed the listener");
207 iter->second.erase(it);
208 goto monitorTag;
209 }
210 }
211
212 monitorTag:
213 if (isListeningProcess_ && iter->second.empty()) {
214 isListeningProcess_ = false;
215 INTERACTION_MGR->UnregisterCoordinationListener(shared_from_this());
216 }
217 }
218
CreateCallbackInfo(napi_env env,napi_value handle,sptr<JsUtilCooperate::CallbackInfo> callback)219 napi_value JsEventCooperateTarget::CreateCallbackInfo(napi_env env,
220 napi_value handle, sptr<JsUtilCooperate::CallbackInfo> callback)
221 {
222 CALL_INFO_TRACE;
223 CHKPP(callback);
224 callback->env = env;
225 napi_value promise = nullptr;
226 if (handle == nullptr) {
227 CHKRP(napi_create_promise(env, &callback->deferred, &promise), CREATE_PROMISE);
228 } else {
229 CHKRP(napi_create_reference(env, handle, 1, &callback->ref), CREATE_REFERENCE);
230 }
231 return promise;
232 }
233
ResetEnv()234 void JsEventCooperateTarget::ResetEnv()
235 {
236 CALL_INFO_TRACE;
237 std::lock_guard<std::mutex> guard(mutex_);
238 INTERACTION_MGR->UnregisterCoordinationListener(shared_from_this());
239 }
240
OnCoordinationMessage(const std::string & networkId,CoordinationMessage msg)241 void JsEventCooperateTarget::OnCoordinationMessage(const std::string &networkId, CoordinationMessage msg)
242 {
243 CALL_INFO_TRACE;
244 std::lock_guard<std::mutex> guard(mutex_);
245 auto changeEvent = coordinationListeners_.find(COORDINATION);
246 if (changeEvent == coordinationListeners_.end()) {
247 FI_HILOGE("Failed to find the %{public}s", std::string(COORDINATION).c_str());
248 return;
249 }
250
251 for (auto &item : changeEvent->second) {
252 CHKPC(item);
253 CHKPC(item->env);
254 uv_loop_s *loop = nullptr;
255 CHKRV(napi_get_uv_event_loop(item->env, &loop), GET_UV_EVENT_LOOP);
256 uv_work_t *uvWork = new (std::nothrow) uv_work_t;
257 CHKPV(uvWork);
258 item->data.msgInfo.msg = msg;
259 item->data.deviceDescriptor = networkId;
260 item->IncStrongRef(nullptr);
261 uvWork->data = item.GetRefPtr();
262 int32_t ret = uv_queue_work_with_qos(loop, uvWork, [](uv_work_t *uvWork) {},
263 EmitCoordinationMessageEvent, uv_qos_default);
264 if (ret != 0) {
265 FI_HILOGE("Failed to execute uv_queue_work_with_qos");
266 item->DecStrongRef(nullptr);
267 JsUtilCooperate::DeletePtr<uv_work_t*>(uvWork);
268 }
269 }
270 }
271
CallEnablePromiseWork(uv_work_t * work,int32_t status)272 void JsEventCooperateTarget::CallEnablePromiseWork(uv_work_t *work, int32_t status)
273 {
274 CALL_INFO_TRACE;
275 CHKPV(work);
276 if (work->data == nullptr) {
277 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
278 FI_HILOGE("Enable promise, check data is nullptr");
279 return;
280 }
281 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
282 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
283 cb->DecStrongRef(nullptr);
284 CHKPV(cb->env);
285 napi_handle_scope scope = nullptr;
286 napi_open_handle_scope(cb->env, &scope);
287 if (scope == nullptr) {
288 FI_HILOGE("Enable promise, scope is nullptr");
289 RELEASE_CALLBACKINFO(cb->env, cb->ref);
290 return;
291 }
292 napi_value object = JsUtilCooperate::GetEnableInfo(cb);
293 if (object == nullptr) {
294 FI_HILOGE("Enable promise, object is nullptr");
295 RELEASE_CALLBACKINFO(cb->env, cb->ref);
296 napi_close_handle_scope(cb->env, scope);
297 return;
298 }
299 napi_valuetype valueType = napi_undefined;
300 if (napi_typeof(cb->env, object, &valueType) != napi_ok) {
301 FI_HILOGE("Enable promise, napi typeof failed");
302 RELEASE_CALLBACKINFO(cb->env, cb->ref);
303 napi_close_handle_scope(cb->env, scope);
304 return;
305 }
306 if (valueType != napi_undefined) {
307 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, object), REJECT_DEFERRED, scope);
308 } else {
309 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
310 }
311 RELEASE_CALLBACKINFO(cb->env, cb->ref);
312 napi_close_handle_scope(cb->env, scope);
313 }
314
CallEnableAsyncWork(uv_work_t * work,int32_t status)315 void JsEventCooperateTarget::CallEnableAsyncWork(uv_work_t *work, int32_t status)
316 {
317 CALL_INFO_TRACE;
318 CHKPV(work);
319 if (work->data == nullptr) {
320 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
321 FI_HILOGE("Enable async, check data is nullptr");
322 return;
323 }
324 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
325 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
326 cb->DecStrongRef(nullptr);
327 CHKPV(cb->env);
328 napi_handle_scope scope = nullptr;
329 napi_open_handle_scope(cb->env, &scope);
330 if (scope == nullptr) {
331 FI_HILOGE("Enable async, scope is nullptr");
332 RELEASE_CALLBACKINFO(cb->env, cb->ref);
333 return;
334 }
335 napi_value object = JsUtilCooperate::GetEnableInfo(cb);
336 if (object == nullptr) {
337 FI_HILOGE("Enable async, object is nullptr");
338 RELEASE_CALLBACKINFO(cb->env, cb->ref);
339 napi_close_handle_scope(cb->env, scope);
340 return;
341 }
342 napi_value processor = nullptr;
343 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &processor), GET_REFERENCE_VALUE, scope);
344 napi_value ret = nullptr;
345 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, processor, 1, &object, &ret), CALL_FUNCTION, scope);
346 RELEASE_CALLBACKINFO(cb->env, cb->ref);
347 napi_close_handle_scope(cb->env, scope);
348 }
349
CallStartPromiseWork(uv_work_t * work,int32_t status)350 void JsEventCooperateTarget::CallStartPromiseWork(uv_work_t *work, int32_t status)
351 {
352 CALL_INFO_TRACE;
353 CHKPV(work);
354 if (work->data == nullptr) {
355 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
356 FI_HILOGE("Start promise, check data is nullptr");
357 return;
358 }
359 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
360 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
361 cb->DecStrongRef(nullptr);
362 CHKPV(cb->env);
363 napi_handle_scope scope = nullptr;
364 napi_open_handle_scope(cb->env, &scope);
365 if (scope == nullptr) {
366 FI_HILOGE("Start promise, scope is nullptr");
367 RELEASE_CALLBACKINFO(cb->env, cb->ref);
368 return;
369 }
370 napi_value object = JsUtilCooperate::GetStartInfo(cb);
371 if (object == nullptr) {
372 FI_HILOGE("Start promise, object is nullptr");
373 RELEASE_CALLBACKINFO(cb->env, cb->ref);
374 napi_close_handle_scope(cb->env, scope);
375 return;
376 }
377 napi_valuetype napiValueType = napi_undefined;
378 if (napi_typeof(cb->env, object, &napiValueType) != napi_ok) {
379 FI_HILOGE("Start promise, napi typeof failed");
380 RELEASE_CALLBACKINFO(cb->env, cb->ref);
381 napi_close_handle_scope(cb->env, scope);
382 return;
383 }
384 if (napiValueType != napi_undefined) {
385 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, object), REJECT_DEFERRED, scope);
386 } else {
387 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
388 }
389 RELEASE_CALLBACKINFO(cb->env, cb->ref);
390 napi_close_handle_scope(cb->env, scope);
391 }
392
CallStartAsyncWork(uv_work_t * work,int32_t status)393 void JsEventCooperateTarget::CallStartAsyncWork(uv_work_t *work, int32_t status)
394 {
395 CALL_INFO_TRACE;
396 CHKPV(work);
397 if (work->data == nullptr) {
398 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
399 FI_HILOGE("Start async, check data is nullptr");
400 return;
401 }
402 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
403 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
404 cb->DecStrongRef(nullptr);
405 CHKPV(cb->env);
406 napi_handle_scope scope = nullptr;
407 napi_open_handle_scope(cb->env, &scope);
408 if (scope == nullptr) {
409 FI_HILOGE("Start async, scope is nullptr");
410 RELEASE_CALLBACKINFO(cb->env, cb->ref);
411 return;
412 }
413 napi_value object = JsUtilCooperate::GetStartInfo(cb);
414 if (object == nullptr) {
415 FI_HILOGE("Start async, object is nullptr");
416 RELEASE_CALLBACKINFO(cb->env, cb->ref);
417 napi_close_handle_scope(cb->env, scope);
418 return;
419 }
420 napi_value napiHandler = nullptr;
421 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &napiHandler), GET_REFERENCE_VALUE, scope);
422 napi_value ret = nullptr;
423 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, napiHandler, 1, &object, &ret), CALL_FUNCTION, scope);
424 RELEASE_CALLBACKINFO(cb->env, cb->ref);
425 napi_close_handle_scope(cb->env, scope);
426 }
427
CallStopPromiseWork(uv_work_t * work,int32_t status)428 void JsEventCooperateTarget::CallStopPromiseWork(uv_work_t *work, int32_t status)
429 {
430 CALL_INFO_TRACE;
431 CHKPV(work);
432 if (work->data == nullptr) {
433 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
434 FI_HILOGE("Stop promise, check data is nullptr");
435 return;
436 }
437 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
438 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
439 cb->DecStrongRef(nullptr);
440 CHKPV(cb->env);
441 napi_handle_scope napiHandleScope = nullptr;
442 napi_open_handle_scope(cb->env, &napiHandleScope);
443 if (napiHandleScope == nullptr) {
444 FI_HILOGE("Stop promise, napiHandleScope is nullptr");
445 RELEASE_CALLBACKINFO(cb->env, cb->ref);
446 return;
447 }
448 napi_value object = JsUtilCooperate::GetStopInfo(cb);
449 if (object == nullptr) {
450 FI_HILOGE("Stop promise, object is nullptr");
451 RELEASE_CALLBACKINFO(cb->env, cb->ref);
452 napi_close_handle_scope(cb->env, napiHandleScope);
453 return;
454 }
455
456 napi_valuetype valueType = napi_undefined;
457 if (napi_typeof(cb->env, object, &valueType) != napi_ok) {
458 FI_HILOGE("Stop promise, napi typeof failed");
459 RELEASE_CALLBACKINFO(cb->env, cb->ref);
460 napi_close_handle_scope(cb->env, napiHandleScope);
461 return;
462 }
463 if (valueType != napi_undefined) {
464 CHKRV_SCOPE(cb->env, napi_reject_deferred(cb->env, cb->deferred, object), REJECT_DEFERRED, napiHandleScope);
465 } else {
466 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, napiHandleScope);
467 }
468 RELEASE_CALLBACKINFO(cb->env, cb->ref);
469 napi_close_handle_scope(cb->env, napiHandleScope);
470 }
471
CallStopAsyncWork(uv_work_t * work,int32_t status)472 void JsEventCooperateTarget::CallStopAsyncWork(uv_work_t *work, int32_t status)
473 {
474 CALL_INFO_TRACE;
475 CHKPV(work);
476 if (work->data == nullptr) {
477 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
478 FI_HILOGE("Stop async, check data is nullptr");
479 return;
480 }
481 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
482 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
483 cb->DecStrongRef(nullptr);
484 CHKPV(cb->env);
485 napi_handle_scope scope = nullptr;
486 napi_open_handle_scope(cb->env, &scope);
487 if (scope == nullptr) {
488 FI_HILOGE("Stop async, scope is nullptr");
489 RELEASE_CALLBACKINFO(cb->env, cb->ref);
490 return;
491 }
492 napi_value object = JsUtilCooperate::GetStopInfo(cb);
493 if (object == nullptr) {
494 FI_HILOGE("Stop async, object is nullptr");
495 RELEASE_CALLBACKINFO(cb->env, cb->ref);
496 napi_close_handle_scope(cb->env, scope);
497 return;
498 }
499 napi_value napiHandler = nullptr;
500 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &napiHandler), GET_REFERENCE_VALUE, scope);
501 napi_value result = nullptr;
502 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, napiHandler, 1, &object, &result), CALL_FUNCTION, scope);
503 RELEASE_CALLBACKINFO(cb->env, cb->ref);
504 napi_close_handle_scope(cb->env, scope);
505 }
506
CallGetStatePromiseWork(uv_work_t * work,int32_t status)507 void JsEventCooperateTarget::CallGetStatePromiseWork(uv_work_t *work, int32_t status)
508 {
509 CALL_INFO_TRACE;
510 CHKPV(work);
511 if (work->data == nullptr) {
512 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
513 FI_HILOGE("Get start promise, check data is nullptr");
514 return;
515 }
516 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
517 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
518 cb->DecStrongRef(nullptr);
519 CHKPV(cb->env);
520 napi_handle_scope scope = nullptr;
521 napi_open_handle_scope(cb->env, &scope);
522 if (scope == nullptr) {
523 FI_HILOGE("Get start promise, scope is nullptr");
524 RELEASE_CALLBACKINFO(cb->env, cb->ref);
525 return;
526 }
527 napi_value object = JsUtilCooperate::GetStateInfo(cb);
528 if (object == nullptr) {
529 FI_HILOGE("Get start promise, object is nullptr");
530 RELEASE_CALLBACKINFO(cb->env, cb->ref);
531 napi_close_handle_scope(cb->env, scope);
532 return;
533 }
534 CHKRV_SCOPE(cb->env, napi_resolve_deferred(cb->env, cb->deferred, object), RESOLVE_DEFERRED, scope);
535 RELEASE_CALLBACKINFO(cb->env, cb->ref);
536 napi_close_handle_scope(cb->env, scope);
537 }
538
CallGetStateAsyncWork(uv_work_t * work,int32_t status)539 void JsEventCooperateTarget::CallGetStateAsyncWork(uv_work_t *work, int32_t status)
540 {
541 CALL_INFO_TRACE;
542 CHKPV(work);
543 if (work->data == nullptr) {
544 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
545 FI_HILOGE("Get start async, check data is nullptr");
546 return;
547 }
548 sptr<JsUtilCooperate::CallbackInfo> cb(static_cast<JsUtilCooperate::CallbackInfo *>(work->data));
549 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
550 cb->DecStrongRef(nullptr);
551 CHKPV(cb->env);
552 napi_handle_scope scope = nullptr;
553 napi_open_handle_scope(cb->env, &scope);
554 if (scope == nullptr) {
555 FI_HILOGE("Get start async, scope is nullptr");
556 RELEASE_CALLBACKINFO(cb->env, cb->ref);
557 return;
558 }
559 napi_value resultObj[2];
560 CHKRV_SCOPE(cb->env, napi_get_undefined(cb->env, &resultObj[0]), GET_UNDEFINED, scope);
561 resultObj[1] = JsUtilCooperate::GetStateInfo(cb);
562 if (resultObj[1] == nullptr) {
563 FI_HILOGE("Get start async, object is nullptr");
564 napi_close_handle_scope(cb->env, scope);
565 return;
566 }
567 napi_value handlerInfo = nullptr;
568 CHKRV_SCOPE(cb->env, napi_get_reference_value(cb->env, cb->ref, &handlerInfo), GET_REFERENCE_VALUE, scope);
569 napi_value ret = nullptr;
570 size_t argc = TWO_PARAM;
571 CHKRV_SCOPE(cb->env, napi_call_function(cb->env, nullptr, handlerInfo, argc, resultObj, &ret),
572 CALL_FUNCTION, scope);
573 RELEASE_CALLBACKINFO(cb->env, cb->ref);
574 napi_close_handle_scope(cb->env, scope);
575 }
576
EmitCoordinationMessageEvent(uv_work_t * work,int32_t status)577 void JsEventCooperateTarget::EmitCoordinationMessageEvent(uv_work_t *work, int32_t status)
578 {
579 CALL_INFO_TRACE;
580 CHKPV(work);
581 if (work->data == nullptr) {
582 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
583 FI_HILOGE("The data is nullptr");
584 return;
585 }
586 sptr<JsUtilCooperate::CallbackInfo> temp(static_cast<JsUtilCooperate::CallbackInfo*>(work->data));
587 JsUtilCooperate::DeletePtr<uv_work_t*>(work);
588 std::lock_guard<std::mutex> guard(mutex_);
589 temp->DecStrongRef(nullptr);
590 auto msgEvent = coordinationListeners_.find(COORDINATION);
591 if (msgEvent == coordinationListeners_.end()) {
592 FI_HILOGE("Failed to find the msgEvent");
593 return;
594 }
595 for (const auto &item : msgEvent->second) {
596 CHKPC(item->env);
597 if (item->ref != temp->ref) {
598 continue;
599 }
600 napi_handle_scope scope = nullptr;
601 napi_open_handle_scope(item->env, &scope);
602 napi_value deviceDescriptor = nullptr;
603 CHKRV_SCOPE(item->env, napi_create_string_utf8(item->env, item->data.deviceDescriptor.c_str(),
604 NAPI_AUTO_LENGTH, &deviceDescriptor), CREATE_STRING_UTF8, scope);
605 napi_value eventMsg = nullptr;
606 auto iter = messageTransform.find(item->data.msgInfo.msg);
607 if (iter == messageTransform.end()) {
608 FI_HILOGE("Failed to find the message code");
609 CHKRV(napi_close_handle_scope(item->env, scope), CLOSE_SCOPE);
610 return;
611 }
612 CHKRV_SCOPE(item->env, napi_create_int32(item->env, static_cast<int32_t>(iter->second), &eventMsg),
613 CREATE_INT32, scope);
614 napi_value object = nullptr;
615 CHKRV_SCOPE(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope);
616 CHKRV_SCOPE(item->env, napi_set_named_property(item->env, object, "deviceDescriptor", deviceDescriptor),
617 SET_NAMED_PROPERTY, scope);
618 CHKRV_SCOPE(item->env, napi_set_named_property(item->env, object, "eventMsg", eventMsg),
619 SET_NAMED_PROPERTY, scope);
620 napi_value handler = nullptr;
621 CHKRV_SCOPE(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE, scope);
622 napi_value ret = nullptr;
623 CHKRV_SCOPE(item->env, napi_call_function(item->env, nullptr, handler, 1, &object, &ret), CALL_FUNCTION, scope);
624 napi_close_handle_scope(item->env, scope);
625 }
626 }
627 } // namespace DeviceStatus
628 } // namespace Msdp
629 } // namespace OHOS
630