• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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