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