• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "common_event.h"
17 #include <memory>
18 #include <uv.h>
19 #include "event_log_wrapper.h"
20 #include "napi_common.h"
21 #include "support.h"
22 
23 namespace OHOS {
24 namespace EventFwkNapi {
25 using namespace OHOS::EventFwk;
26 namespace {
27 static const int32_t PUBLISH_MAX_PARA = 2;
28 static const int32_t PUBLISH_MAX_PARA_AS_USER = 3;
29 static const int32_t GETSUBSCREBEINFO_MAX_PARA = 1;
30 static const int32_t ARGS_TWO_EVENT = 2;
31 static const int32_t PARAM0_EVENT = 0;
32 static const int32_t PARAM1_EVENT = 1;
33 }
34 
35 std::atomic_ullong SubscriberInstance::subscriberID_ = 0;
36 
AsyncCallbackInfoUnsubscribe()37 AsyncCallbackInfoUnsubscribe::AsyncCallbackInfoUnsubscribe()
38 {
39     EVENT_LOGD("constructor AsyncCallbackInfoUnsubscribe");
40 }
41 
~AsyncCallbackInfoUnsubscribe()42 AsyncCallbackInfoUnsubscribe::~AsyncCallbackInfoUnsubscribe()
43 {
44     EVENT_LOGD("destructor AsyncCallbackInfoUnsubscribe");
45 }
46 
SubscriberInstanceWrapper(const CommonEventSubscribeInfo & info)47 SubscriberInstanceWrapper::SubscriberInstanceWrapper(const CommonEventSubscribeInfo &info)
48 {
49     EVENT_LOGD("enter");
50     auto objectInfo = new (std::nothrow) SubscriberInstance(info);
51     if (objectInfo == nullptr) {
52         EVENT_LOGE("objectInfo is nullptr");
53         return;
54     }
55 
56     subscriber = std::shared_ptr<SubscriberInstance>(objectInfo);
57     EVENT_LOGD("end");
58 }
59 
GetSubscriber()60 std::shared_ptr<SubscriberInstance> SubscriberInstanceWrapper::GetSubscriber()
61 {
62     return subscriber;
63 }
64 
SetCommonEventData(const CommonEventDataWorker * commonEventDataWorkerData,napi_env env,napi_value & result)65 napi_value SetCommonEventData(const CommonEventDataWorker *commonEventDataWorkerData, napi_env env, napi_value &result)
66 {
67     EVENT_LOGD("enter");
68     if (commonEventDataWorkerData == nullptr) {
69         EVENT_LOGE("commonEventDataWorkerData is nullptr");
70         return nullptr;
71     }
72     napi_value value = nullptr;
73 
74     // event
75     napi_create_string_utf8(env, commonEventDataWorkerData->want.GetAction().c_str(), NAPI_AUTO_LENGTH, &value);
76     napi_set_named_property(env, result, "event", value);
77 
78     // bundleName
79     napi_create_string_utf8(env, commonEventDataWorkerData->want.GetBundle().c_str(), NAPI_AUTO_LENGTH, &value);
80     napi_set_named_property(env, result, "bundleName", value);
81 
82     // code
83     napi_create_int32(env, commonEventDataWorkerData->code, &value);
84     napi_set_named_property(env, result, "code", value);
85 
86     // data
87     napi_create_string_utf8(env, commonEventDataWorkerData->data.c_str(), NAPI_AUTO_LENGTH, &value);
88     napi_set_named_property(env, result, "data", value);
89 
90     // parameters ?: {[key:string] : any}
91     AAFwk::WantParams wantParams = commonEventDataWorkerData->want.GetParams();
92     napi_value wantParamsValue = nullptr;
93     wantParamsValue = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
94     if (wantParamsValue) {
95         napi_set_named_property(env, result, "parameters", wantParamsValue);
96     } else {
97         napi_set_named_property(env, result, "parameters", NapiGetNull(env));
98     }
99 
100     return NapiGetNull(env);
101 }
102 
ThreadSafeCallback(napi_env env,napi_value jsCallback,void * context,void * data)103 void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void* data)
104 {
105     EVENT_LOGD("OnReceiveEvent ThreadSafeCallback excute");
106     CommonEventDataWorker *commonEventDataWorkerData = static_cast<CommonEventDataWorker *>(data);
107     if (commonEventDataWorkerData == nullptr) {
108         EVENT_LOGE("OnReceiveEvent commonEventDataWorkerData is nullptr");
109         return;
110     }
111     std::shared_ptr<SubscriberInstance> subscriber = commonEventDataWorkerData->subscriber.lock();
112     if (subscriber == nullptr) {
113         EVENT_LOGE("ThreadSafeCallback subscriber is null or invalid which may be previously released");
114         delete commonEventDataWorkerData;
115         commonEventDataWorkerData = nullptr;
116         return;
117     }
118     napi_handle_scope scope;
119     napi_open_handle_scope(env, &scope);
120     if (scope == nullptr) {
121         EVENT_LOGE("Scope is null");
122         return;
123     }
124 
125     napi_value result = nullptr;
126     napi_create_object(env, &result);
127     if (SetCommonEventData(commonEventDataWorkerData, env, result) == nullptr) {
128         napi_close_handle_scope(env, scope);
129         delete commonEventDataWorkerData;
130         commonEventDataWorkerData = nullptr;
131         return;
132     }
133 
134     napi_value undefined = nullptr;
135     napi_get_undefined(env, &undefined);
136 
137     napi_ref ref = subscriber->GetCallbackRef();
138     if (ref == nullptr) {
139         EVENT_LOGE("ThreadSafeCallback ref is null which may be previously released");
140         napi_close_handle_scope(env, scope);
141         delete commonEventDataWorkerData;
142         commonEventDataWorkerData = nullptr;
143         return;
144     }
145     napi_value callback = nullptr;
146     napi_value resultout = nullptr;
147     napi_get_reference_value(env, ref, &callback);
148 
149     napi_value results[ARGS_TWO_EVENT] = {nullptr};
150     results[PARAM0_EVENT] = GetCallbackErrorValue(env, NO_ERROR);
151     results[PARAM1_EVENT] = result;
152     napi_call_function(env, undefined, callback, ARGS_TWO_EVENT, &results[PARAM0_EVENT], &resultout);
153     napi_close_handle_scope(env, scope);
154     delete commonEventDataWorkerData;
155     commonEventDataWorkerData = nullptr;
156 }
157 
ClearEnvCallback(void * data)158 static void ClearEnvCallback(void *data)
159 {
160     EVENT_LOGD("Env expired, need to clear env");
161     SubscriberInstance *subscriber = reinterpret_cast<SubscriberInstance *>(data);
162     subscriber->ClearEnv();
163 }
164 
SubscriberInstance(const CommonEventSubscribeInfo & sp)165 SubscriberInstance::SubscriberInstance(const CommonEventSubscribeInfo &sp) : CommonEventSubscriber(sp)
166 {
167     id_ = ++subscriberID_;
168     EVENT_LOGD("constructor SubscriberInstance");
169 }
170 
~SubscriberInstance()171 SubscriberInstance::~SubscriberInstance()
172 {
173     EVENT_LOGD("destructor SubscriberInstance[%{public}llu]", id_.load());
174     std::lock_guard<ffrt::mutex> lock(envMutex_);
175     if (env_ != nullptr && tsfn_ != nullptr) {
176         napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
177     }
178 }
179 
GetID()180 unsigned long long SubscriberInstance::GetID()
181 {
182     return id_.load();
183 }
184 
SetEnv(const napi_env & env)185 void SubscriberInstance::SetEnv(const napi_env &env)
186 {
187     EVENT_LOGD("Enter");
188     env_ = env;
189 }
190 
GetEnv()191 napi_env SubscriberInstance::GetEnv()
192 {
193     EVENT_LOGD("Enter");
194     std::lock_guard<ffrt::mutex> lock(envMutex_);
195     return env_;
196 }
197 
ClearEnv()198 void SubscriberInstance::ClearEnv()
199 {
200     EVENT_LOGD("Env expired, clear SubscriberInstance env");
201     std::lock_guard<ffrt::mutex> lock(envMutex_);
202     env_ = nullptr;
203     tsfn_ = nullptr;
204 }
205 
SetCallbackRef(const napi_ref & ref)206 void SubscriberInstance::SetCallbackRef(const napi_ref &ref)
207 {
208     std::lock_guard<ffrt::mutex> lockRef(refMutex_);
209     if (ref == nullptr) {
210         napi_delete_reference(env_, ref_);
211     }
212     ref_ = ref;
213 }
214 
GetCallbackRef()215 napi_ref SubscriberInstance::GetCallbackRef()
216 {
217     std::lock_guard<ffrt::mutex> lockRef(refMutex_);
218     return ref_;
219 }
220 
SetThreadSafeFunction(const napi_threadsafe_function & tsfn)221 void SubscriberInstance::SetThreadSafeFunction(const napi_threadsafe_function &tsfn)
222 {
223     tsfn_ = tsfn;
224 }
225 
OnReceiveEvent(const CommonEventData & data)226 void SubscriberInstance::OnReceiveEvent(const CommonEventData &data)
227 {
228     EVENT_LOGD("OnReceiveEvent start action: %{public}s.", data.GetWant().GetAction().c_str());
229 
230     if (this->IsOrderedCommonEvent()) {
231         EVENT_LOGD("IsOrderedCommonEvent is true");
232         std::lock_guard<ffrt::mutex> lock(subscriberInsMutex);
233         for (auto subscriberInstance : subscriberInstances) {
234             if (subscriberInstance.first.get() == this) {
235                 EVENT_LOGD("Get success.");
236                 subscriberInstances[subscriberInstance.first].commonEventResult = GoAsyncCommonEvent();
237                 break;
238             }
239         }
240     }
241     std::lock_guard<ffrt::mutex> lock(envMutex_);
242     std::lock_guard<ffrt::mutex> lockRef(refMutex_);
243     if (env_ != nullptr && tsfn_ != nullptr && ref_ != nullptr) {
244         CommonEventDataWorker *commonEventDataWorker = new (std::nothrow) CommonEventDataWorker();
245         if (commonEventDataWorker == nullptr) {
246             EVENT_LOGE("commonEventDataWorker is null");
247             return;
248         }
249         commonEventDataWorker->want = data.GetWant();
250         commonEventDataWorker->code = data.GetCode();
251         commonEventDataWorker->data = data.GetData();
252         commonEventDataWorker->subscriber = shared_from_this();
253         napi_acquire_threadsafe_function(tsfn_);
254         napi_call_threadsafe_function(tsfn_, commonEventDataWorker, napi_tsfn_nonblocking);
255         napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
256         EVENT_LOGD("OnReceiveEvent end");
257     }
258 }
259 
ThreadFinished(napi_env env,void * data,void * context)260 void ThreadFinished(napi_env env, void* data, [[maybe_unused]] void* context)
261 {
262     EVENT_LOGD("ThreadFinished");
263 }
264 
ParseParametersByGetSubscribeInfo(const napi_env & env,const size_t & argc,const napi_value (& argv)[1],napi_ref & callback)265 napi_value ParseParametersByGetSubscribeInfo(
266     const napi_env &env, const size_t &argc, const napi_value (&argv)[1], napi_ref &callback)
267 {
268     napi_valuetype valuetype;
269 
270     // argv[0]:callback
271     if (argc >= GETSUBSCREBEINFO_MAX_PARA) {
272         NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
273         if (valuetype != napi_function) {
274             EVENT_LOGE("Wrong argument type. Function expected.");
275             return nullptr;
276         }
277 
278         napi_create_reference(env, argv[0], 1, &callback);
279     }
280 
281     return NapiGetNull(env);
282 }
283 
GetSubscribeInfo(napi_env env,napi_callback_info info)284 napi_value GetSubscribeInfo(napi_env env, napi_callback_info info)
285 {
286     EVENT_LOGD("GetSubscribeInfo start");
287 
288     size_t argc = 1;
289     napi_value argv[1] = {nullptr};
290     napi_value thisVar = nullptr;
291     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
292 
293     napi_ref callback = nullptr;
294     if (ParseParametersByGetSubscribeInfo(env, argc, argv, callback) == nullptr) {
295         EVENT_LOGE("ParseParametersByGetSubscribeInfo failed");
296         if (callback != nullptr) {
297             napi_delete_reference(env, callback);
298         }
299         return NapiGetNull(env);
300     }
301 
302     AsyncCallbackInfoSubscribeInfo *asyncCallbackInfo =
303         new (std::nothrow) AsyncCallbackInfoSubscribeInfo {.env = env, .asyncWork = nullptr};
304     if (asyncCallbackInfo == nullptr) {
305         EVENT_LOGD("asyncCallbackInfo is null");
306         if (callback != nullptr) {
307             napi_delete_reference(env, callback);
308         }
309         return NapiGetNull(env);
310     }
311 
312     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
313     if (asyncCallbackInfo->subscriber == nullptr) {
314         EVENT_LOGE("subscriber is nullptr");
315         if (callback != nullptr) {
316             napi_delete_reference(env, callback);
317         }
318         delete asyncCallbackInfo;
319         return NapiGetNull(env);
320     }
321 
322     napi_value promise = nullptr;
323     PaddingAsyncCallbackInfoGetSubscribeInfo(env, argc, asyncCallbackInfo, callback, promise);
324 
325     EVENT_LOGD("Create getSubscribeInfo string.");
326     napi_value resourceName = nullptr;
327     napi_create_string_latin1(env, "getSubscribeInfo", NAPI_AUTO_LENGTH, &resourceName);
328     // Asynchronous function call
329     napi_create_async_work(env,
330         nullptr,
331         resourceName,
332         [](napi_env env, void *data) {
333             EVENT_LOGD("GetSubscribeInfo napi_create_async_work start");
334             AsyncCallbackInfoSubscribeInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfoSubscribeInfo *>(data);
335             if (asyncCallbackInfo == nullptr) {
336                 EVENT_LOGE("asyncCallbackInfo is null");
337                 return;
338             }
339             PaddingNapiCreateAsyncWorkCallbackInfo(asyncCallbackInfo);
340         },
341         [](napi_env env, napi_status status, void *data) {
342             EVENT_LOGD("GetSubscribeInfo napi_create_async_work end");
343             AsyncCallbackInfoSubscribeInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfoSubscribeInfo *>(data);
344             if (asyncCallbackInfo == nullptr) {
345                 EVENT_LOGE("asyncCallbackInfo is null");
346                 return;
347             }
348             napi_value result = nullptr;
349             napi_create_object(env, &result);
350             SetNapiResult(env, asyncCallbackInfo, result);
351             ReturnCallbackPromise(env, asyncCallbackInfo->info, result);
352             if (asyncCallbackInfo->info.callback != nullptr) {
353                 napi_delete_reference(env, asyncCallbackInfo->info.callback);
354             }
355             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
356             delete asyncCallbackInfo;
357             asyncCallbackInfo = nullptr;
358             EVENT_LOGD("delete asyncCallbackInfo");
359         },
360         (void *)asyncCallbackInfo,
361         &asyncCallbackInfo->asyncWork);
362 
363     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
364 
365     if (asyncCallbackInfo->info.isCallback) {
366         EVENT_LOGD("Delete GetSubscribeInfo callback reference.");
367         return NapiGetNull(env);
368     } else {
369         return promise;
370     }
371 }
372 
GetAsyncResult(const SubscriberInstance * objectInfo)373 std::shared_ptr<AsyncCommonEventResult> GetAsyncResult(const SubscriberInstance *objectInfo)
374 {
375     EVENT_LOGD("GetAsyncResult start");
376     if (!objectInfo) {
377         EVENT_LOGE("Invalidity objectInfo");
378         return nullptr;
379     }
380     std::lock_guard<ffrt::mutex> lock(subscriberInsMutex);
381     for (auto subscriberInstance : subscriberInstances) {
382         if (subscriberInstance.first.get() == objectInfo) {
383             return subscriberInstance.second.commonEventResult;
384         }
385     }
386     EVENT_LOGW("No found objectInfo");
387     return nullptr;
388 }
389 
IsOrderedCommonEvent(napi_env env,napi_callback_info info)390 napi_value IsOrderedCommonEvent(napi_env env, napi_callback_info info)
391 {
392     EVENT_LOGD("IsOrderedCommonEvent start");
393 
394     size_t argc = 1;
395     napi_value argv[1] = {nullptr};
396     napi_value thisVar = nullptr;
397     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
398     napi_ref callback = nullptr;
399     if (ParseParametersByIsOrderedCommonEvent(env, argv, argc, callback) == nullptr) {
400         EVENT_LOGE("ParseParametersByIsOrderedCommonEvent failed");
401         if (callback != nullptr) {
402             napi_delete_reference(env, callback);
403         }
404         return NapiGetNull(env);
405     }
406 
407     AsyncCallbackInfoOrderedCommonEvent *asyncCallbackInfo = new (std::nothrow)
408         AsyncCallbackInfoOrderedCommonEvent {.env = env, .asyncWork = nullptr};
409     if (asyncCallbackInfo == nullptr) {
410         EVENT_LOGE("asyncCallbackInfo is null");
411         if (callback != nullptr) {
412             napi_delete_reference(env, callback);
413         }
414         return NapiGetNull(env);
415     }
416 
417     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
418     if (asyncCallbackInfo->subscriber == nullptr) {
419         EVENT_LOGD("subscriber is nullptr");
420         if (callback != nullptr) {
421             napi_delete_reference(env, callback);
422         }
423         delete asyncCallbackInfo;
424         return NapiGetNull(env);
425     }
426 
427     napi_value promise = nullptr;
428     PaddingAsyncCallbackInfoIsOrderedCommonEvent(env, argc, asyncCallbackInfo, callback, promise);
429 
430     EVENT_LOGD("Create isOrderedCommonEvent string.");
431     napi_value resourceName = nullptr;
432     napi_create_string_latin1(env, "isOrderedCommonEvent", NAPI_AUTO_LENGTH, &resourceName);
433     // Asynchronous function call
434     napi_create_async_work(env,
435         nullptr,
436         resourceName,
437         [](napi_env env, void *data) {
438             EVENT_LOGD("IsOrderedCommonEvent work excute.");
439             AsyncCallbackInfoOrderedCommonEvent *asyncCallbackInfo =
440                 static_cast<AsyncCallbackInfoOrderedCommonEvent *>(data);
441             if (asyncCallbackInfo == nullptr) {
442                 EVENT_LOGE("asyncCallbackInfo is null");
443                 return;
444             }
445             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
446             if (asyncResult) {
447                 asyncCallbackInfo->isOrdered = asyncResult->IsOrderedCommonEvent();
448             } else {
449                 asyncCallbackInfo->isOrdered = asyncCallbackInfo->subscriber->IsOrderedCommonEvent();
450             }
451         },
452         [](napi_env env, napi_status status, void *data) {
453             EVENT_LOGD("IsOrderedCommonEvent napi_create_async_work end");
454             AsyncCallbackInfoOrderedCommonEvent *asyncCallbackInfo =
455                 static_cast<AsyncCallbackInfoOrderedCommonEvent *>(data);
456             if (asyncCallbackInfo == nullptr) {
457                 EVENT_LOGE("asyncCallbackInfo is null");
458                 return;
459             }
460             napi_value result = nullptr;
461             napi_get_boolean(env, asyncCallbackInfo->isOrdered, &result);
462             ReturnCallbackPromise(env, asyncCallbackInfo->info, result);
463             if (asyncCallbackInfo->info.callback != nullptr) {
464                 napi_delete_reference(env, asyncCallbackInfo->info.callback);
465             }
466             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
467             delete asyncCallbackInfo;
468             asyncCallbackInfo = nullptr;
469             EVENT_LOGD("asyncCallbackInfo is null");
470         },
471         (void *)asyncCallbackInfo,
472         &asyncCallbackInfo->asyncWork);
473 
474     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
475 
476     if (asyncCallbackInfo->info.isCallback) {
477         EVENT_LOGD("Delete IsOrderedCommonEvent callback reference.");
478         return NapiGetNull(env);
479     } else {
480         return promise;
481     }
482 }
483 
IsStickyCommonEvent(napi_env env,napi_callback_info info)484 napi_value IsStickyCommonEvent(napi_env env, napi_callback_info info)
485 {
486     EVENT_LOGD("IsStickyCommonEvent start");
487 
488     size_t argc = 1;
489     napi_value argv[1] = {nullptr};
490     napi_value thisVar = nullptr;
491     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
492 
493     napi_ref callback = nullptr;
494     if (ParseParametersByIsStickyCommonEvent(env, argv, argc, callback) == nullptr) {
495         EVENT_LOGE("ParseParametersByIsStickyCommonEvent failed");
496         if (callback != nullptr) {
497             napi_delete_reference(env, callback);
498         }
499         return NapiGetNull(env);
500     }
501 
502     AsyncCallbackInfoStickyCommonEvent *asyncCallbackInfo = new (std::nothrow)
503         AsyncCallbackInfoStickyCommonEvent {.env = env, .asyncWork = nullptr};
504     if (asyncCallbackInfo == nullptr) {
505         EVENT_LOGD("asyncCallbackInfo is fail.");
506         if (callback != nullptr) {
507             napi_delete_reference(env, callback);
508         }
509         return NapiGetNull(env);
510     }
511 
512     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
513     if (asyncCallbackInfo->subscriber == nullptr) {
514         EVENT_LOGE("subscriber is nullptr");
515         delete asyncCallbackInfo;
516         return NapiGetNull(env);
517     }
518 
519     napi_value promise = nullptr;
520     PaddingAsyncCallbackInfoIsStickyCommonEvent(env, argc, asyncCallbackInfo, callback, promise);
521 
522     EVENT_LOGD("Create isStickyCommonEvent string.");
523     napi_value resourceName = nullptr;
524     napi_create_string_latin1(env, "isStickyCommonEvent", NAPI_AUTO_LENGTH, &resourceName);
525     // Asynchronous function call
526     napi_create_async_work(env,
527         nullptr,
528         resourceName,
529         [](napi_env env, void *data) {
530             EVENT_LOGD("isStickyCommonEvent napi_create_async_work start");
531             AsyncCallbackInfoStickyCommonEvent *asyncCallbackInfo =
532                 static_cast<AsyncCallbackInfoStickyCommonEvent *>(data);
533             if (asyncCallbackInfo == nullptr) {
534                 EVENT_LOGE("asyncCallbackInfo is null");
535                 return;
536             }
537             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
538             if (asyncResult) {
539                 asyncCallbackInfo->isSticky = asyncResult->IsStickyCommonEvent();
540             } else {
541                 asyncCallbackInfo->isSticky = asyncCallbackInfo->subscriber->IsStickyCommonEvent();
542             }
543         },
544         [](napi_env env, napi_status status, void *data) {
545             EVENT_LOGD("isStickyCommonEvent napi_create_async_work end");
546             AsyncCallbackInfoStickyCommonEvent *asyncCallbackInfo =
547                 static_cast<AsyncCallbackInfoStickyCommonEvent *>(data);
548             if (asyncCallbackInfo == nullptr) {
549                 EVENT_LOGE("asyncCallbackInfo is null");
550                 return;
551             }
552             napi_value result = nullptr;
553             napi_get_boolean(env, asyncCallbackInfo->isSticky, &result);
554             ReturnCallbackPromise(env, asyncCallbackInfo->info, result);
555             if (asyncCallbackInfo->info.callback != nullptr) {
556                 napi_delete_reference(env, asyncCallbackInfo->info.callback);
557             }
558             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
559             delete asyncCallbackInfo;
560             asyncCallbackInfo = nullptr;
561             EVENT_LOGD("asyncCallbackInfo is nullptr");
562         },
563         (void *)asyncCallbackInfo,
564         &asyncCallbackInfo->asyncWork);
565 
566     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
567 
568     if (asyncCallbackInfo->info.isCallback) {
569         EVENT_LOGD("Delete isStickyCommonEvent callback reference.");
570         return NapiGetNull(env);
571     } else {
572         return promise;
573     }
574 }
575 
GetCode(napi_env env,napi_callback_info info)576 napi_value GetCode(napi_env env, napi_callback_info info)
577 {
578     EVENT_LOGD("GetCode start");
579     size_t argc = 1;
580     napi_value argv[1] = {nullptr};
581     napi_value thisVar = nullptr;
582     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
583 
584     napi_ref callback = nullptr;
585     if (ParseParametersByGetCode(env, argv, argc, callback) == nullptr) {
586         EVENT_LOGE("ParseParametersByGetCode failed");
587         if (callback != nullptr) {
588             napi_delete_reference(env, callback);
589         }
590         return NapiGetNull(env);
591     }
592 
593     AsyncCallbackInfoGetCode *asyncCallbackInfo =
594         new (std::nothrow) AsyncCallbackInfoGetCode {.env = env, .asyncWork = nullptr};
595     if (asyncCallbackInfo == nullptr) {
596         EVENT_LOGE("Failed to create asyncCallbackInfo.");
597         if (callback != nullptr) {
598             napi_delete_reference(env, callback);
599         }
600         return NapiGetNull(env);
601     }
602 
603     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
604     if (asyncCallbackInfo->subscriber == nullptr) {
605         EVENT_LOGE("subscriber is nullptr");
606         if (callback != nullptr) {
607             napi_delete_reference(env, callback);
608         }
609         delete asyncCallbackInfo;
610         return NapiGetNull(env);
611     }
612 
613     napi_value promise = nullptr;
614     PaddingAsyncCallbackInfoGetCode(env, argc, asyncCallbackInfo, callback, promise);
615 
616     EVENT_LOGD("Create getCode string.");
617     napi_value resourceName = nullptr;
618     napi_create_string_latin1(env, "getCode", NAPI_AUTO_LENGTH, &resourceName);
619     // Asynchronous function call
620     napi_create_async_work(env,
621         nullptr,
622         resourceName,
623         [](napi_env env, void *data) {
624             EVENT_LOGD("GetCode napi_create_async_work start");
625             AsyncCallbackInfoGetCode *asyncCallbackInfo = static_cast<AsyncCallbackInfoGetCode *>(data);
626             if (asyncCallbackInfo == nullptr) {
627                 EVENT_LOGE("asyncCallbackInfo is null");
628                 return;
629             }
630             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
631             if (asyncResult) {
632                 asyncCallbackInfo->code = asyncResult->GetCode();
633             } else {
634                 asyncCallbackInfo->code = 0;
635             }
636         },
637         [](napi_env env, napi_status status, void *data) {
638             EVENT_LOGD("GetCode napi_create_async_work end");
639             AsyncCallbackInfoGetCode *asyncCallbackInfo = static_cast<AsyncCallbackInfoGetCode *>(data);
640             if (asyncCallbackInfo) {
641                 napi_value result = nullptr;
642                 napi_create_int32(env, asyncCallbackInfo->code, &result);
643                 ReturnCallbackPromise(env, asyncCallbackInfo->info, result);
644                 if (asyncCallbackInfo->info.callback != nullptr) {
645                     napi_delete_reference(env, asyncCallbackInfo->info.callback);
646                     EVENT_LOGD("Delete GetCode callback reference.");
647                 }
648                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
649                 delete asyncCallbackInfo;
650                 asyncCallbackInfo = nullptr;
651             }
652             EVENT_LOGD("GetCode work complete end.");
653         },
654         (void *)asyncCallbackInfo,
655         &asyncCallbackInfo->asyncWork);
656 
657     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
658 
659     if (asyncCallbackInfo->info.isCallback) {
660         EVENT_LOGD("Delete GetCode callback reference.");
661         return NapiGetNull(env);
662     } else {
663         return promise;
664     }
665 }
666 
GetData(napi_env env,napi_callback_info info)667 napi_value GetData(napi_env env, napi_callback_info info)
668 {
669     EVENT_LOGD("GetData start");
670     size_t argc = 1;
671     napi_value argv[1] = {nullptr};
672     napi_value thisVar = nullptr;
673     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
674 
675     napi_ref callback = nullptr;
676     if (ParseParametersByGetData(env, argv, argc, callback) == nullptr) {
677         EVENT_LOGE("ParseParametersByGetData failed");
678         if (callback != nullptr) {
679             napi_delete_reference(env, callback);
680         }
681         return NapiGetNull(env);
682     }
683 
684     AsyncCallbackInfoGetData *asyncCallbackInfo =
685         new (std::nothrow) AsyncCallbackInfoGetData {.env = env, .asyncWork = nullptr};
686     if (asyncCallbackInfo == nullptr) {
687         EVENT_LOGE("asyncCallbackInfo is null");
688         if (callback != nullptr) {
689             napi_delete_reference(env, callback);
690         }
691         return NapiGetNull(env);
692     }
693 
694     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
695     if (asyncCallbackInfo->subscriber == nullptr) {
696         EVENT_LOGD("subscriber is defeat.");
697         if (callback != nullptr) {
698             napi_delete_reference(env, callback);
699         }
700         delete asyncCallbackInfo;
701         return NapiGetNull(env);
702     }
703 
704     napi_value promise = nullptr;
705     PaddingAsyncCallbackInfoGetData(env, argc, asyncCallbackInfo, callback, promise);
706 
707     EVENT_LOGD("Create getData string.");
708     napi_value resourceName = nullptr;
709     napi_create_string_latin1(env, "getData", NAPI_AUTO_LENGTH, &resourceName);
710     // Asynchronous function call
711     napi_create_async_work(env,
712         nullptr,
713         resourceName,
714         [](napi_env env, void *data) {
715             EVENT_LOGD("GetData napi_create_async_work start");
716             AsyncCallbackInfoGetData *asyncCallbackInfo = static_cast<AsyncCallbackInfoGetData *>(data);
717             if (asyncCallbackInfo == nullptr) {
718                 EVENT_LOGE("asyncCallbackInfo is null");
719                 return;
720             }
721             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
722             if (asyncResult) {
723                 asyncCallbackInfo->data = asyncResult->GetData();
724             } else {
725                 asyncCallbackInfo->data = std::string();
726             }
727         },
728         [](napi_env env, napi_status status, void *data) {
729             EVENT_LOGD("GetData work complete.");
730             AsyncCallbackInfoGetData *asyncCallbackInfo = static_cast<AsyncCallbackInfoGetData *>(data);
731             if (asyncCallbackInfo) {
732                 napi_value result = nullptr;
733                 napi_create_string_utf8(env, asyncCallbackInfo->data.c_str(), NAPI_AUTO_LENGTH, &result);
734                 ReturnCallbackPromise(env, asyncCallbackInfo->info, result);
735                 if (asyncCallbackInfo->info.callback != nullptr) {
736                     napi_delete_reference(env, asyncCallbackInfo->info.callback);
737                     EVENT_LOGD("Delete GetData callback reference.");
738                 }
739                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
740                 delete asyncCallbackInfo;
741                 asyncCallbackInfo = nullptr;
742             }
743             EVENT_LOGD("GetData work complete end.");
744         },
745         (void *)asyncCallbackInfo,
746         &asyncCallbackInfo->asyncWork);
747 
748     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
749 
750     if (asyncCallbackInfo->info.isCallback) {
751         EVENT_LOGD("Delete GetData callback reference.");
752         return NapiGetNull(env);
753     } else {
754         return promise;
755     }
756 }
757 
AbortCommonEvent(napi_env env,napi_callback_info info)758 napi_value AbortCommonEvent(napi_env env, napi_callback_info info)
759 {
760     EVENT_LOGD("Abort start");
761     size_t argc = 1;
762     napi_value argv[1] = {nullptr};
763     napi_value thisVar = nullptr;
764     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
765 
766     napi_ref callback = nullptr;
767     if (ParseParametersByAbort(env, argv, argc, callback) == nullptr) {
768         EVENT_LOGE("ParseParametersByAbort failed");
769         if (callback != nullptr) {
770             napi_delete_reference(env, callback);
771         }
772         return NapiGetNull(env);
773     }
774 
775     AsyncCallbackInfoAbort *asyncCallbackInfo =
776         new (std::nothrow) AsyncCallbackInfoAbort {.env = env, .asyncWork = nullptr};
777     if (asyncCallbackInfo == nullptr) {
778         EVENT_LOGE("AsyncCallbackInfo failed.");
779         if (callback != nullptr) {
780             napi_delete_reference(env, callback);
781         }
782         return NapiGetNull(env);
783     }
784 
785     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
786     if (asyncCallbackInfo->subscriber == nullptr) {
787         EVENT_LOGD("subscriber is unsuccessful");
788         if (callback != nullptr) {
789             napi_delete_reference(env, callback);
790         }
791         delete asyncCallbackInfo;
792         return NapiGetNull(env);
793     }
794     napi_value promise = nullptr;
795     PaddingAsyncCallbackInfoAbort(env, argc, asyncCallbackInfo, callback, promise);
796 
797     EVENT_LOGD("Create abort string.");
798     napi_value resourceName = nullptr;
799     napi_create_string_latin1(env, "abort", NAPI_AUTO_LENGTH, &resourceName);
800     // Asynchronous function call
801     napi_create_async_work(env,
802         nullptr,
803         resourceName,
804         [](napi_env env, void *data) {
805             EVENT_LOGD("Abort napi_create_async_work start");
806             AsyncCallbackInfoAbort *asyncCallbackInfo = static_cast<AsyncCallbackInfoAbort *>(data);
807             if (asyncCallbackInfo == nullptr) {
808                 EVENT_LOGE("asyncCallbackInfo is null");
809                 return;
810             }
811             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
812             if (asyncResult) {
813                 asyncCallbackInfo->info.errorCode = asyncResult->AbortCommonEvent() ? NO_ERROR : ERR_CES_FAILED;
814             }
815         },
816         [](napi_env env, napi_status status, void *data) {
817             EVENT_LOGD("Abort napi_create_async_work end");
818             AsyncCallbackInfoAbort *asyncCallbackInfo = static_cast<AsyncCallbackInfoAbort *>(data);
819             if (asyncCallbackInfo) {
820                 ReturnCallbackPromise(env, asyncCallbackInfo->info, NapiGetNull(env));
821                 if (asyncCallbackInfo->info.callback != nullptr) {
822                     napi_delete_reference(env, asyncCallbackInfo->info.callback);
823                 }
824                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
825                 delete asyncCallbackInfo;
826                 asyncCallbackInfo = nullptr;
827             }
828             EVENT_LOGD("Abort work complete end");
829         },
830         (void *)asyncCallbackInfo,
831         &asyncCallbackInfo->asyncWork);
832 
833     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
834 
835     if (asyncCallbackInfo->info.isCallback) {
836         EVENT_LOGD("Delete Abort callback reference.");
837         return NapiGetNull(env);
838     } else {
839         return promise;
840     }
841 }
842 
ClearAbortCommonEvent(napi_env env,napi_callback_info info)843 napi_value ClearAbortCommonEvent(napi_env env, napi_callback_info info)
844 {
845     EVENT_LOGD("enter");
846     size_t argc = 1;
847     napi_value argv[1] = {nullptr};
848     napi_value thisVar = nullptr;
849     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
850 
851     napi_ref callback = nullptr;
852     if (ParseParametersByClearAbort(env, argv, argc, callback) == nullptr) {
853         EVENT_LOGE("ParseParametersByClearAbort failed");
854         if (callback != nullptr) {
855             napi_delete_reference(env, callback);
856         }
857         return NapiGetNull(env);
858     }
859 
860     AsyncCallbackInfoClearAbort *asyncCallbackInfo =
861         new (std::nothrow) AsyncCallbackInfoClearAbort {.env = env, .asyncWork = nullptr};
862     if (asyncCallbackInfo == nullptr) {
863         EVENT_LOGD("asyncCallbackInfo is nullptr.");
864         if (callback != nullptr) {
865             napi_delete_reference(env, callback);
866         }
867         return NapiGetNull(env);
868     }
869 
870     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
871     if (asyncCallbackInfo->subscriber == nullptr) {
872         EVENT_LOGE("subscriber is nullptr");
873         if (callback != nullptr) {
874             napi_delete_reference(env, callback);
875         }
876         delete asyncCallbackInfo;
877         return NapiGetNull(env);
878     }
879 
880     napi_value promise = nullptr;
881     PaddingAsyncCallbackInfoClearAbort(env, argc, asyncCallbackInfo, callback, promise);
882 
883     EVENT_LOGD("Create clearAbort string.");
884     napi_value resourceName = nullptr;
885     napi_create_string_latin1(env, "clearAbort", NAPI_AUTO_LENGTH, &resourceName);
886     // Asynchronous function call
887     napi_create_async_work(env,
888         nullptr,
889         resourceName,
890         [](napi_env env, void *data) {
891             EVENT_LOGD("Excute create async ClearAbort");
892             AsyncCallbackInfoClearAbort *asyncCallbackInfo = static_cast<AsyncCallbackInfoClearAbort *>(data);
893             if (asyncCallbackInfo == nullptr) {
894                 EVENT_LOGE("asyncCallbackInfo is null");
895                 return;
896             }
897             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
898             if (asyncResult) {
899                 asyncCallbackInfo->info.errorCode = asyncResult->ClearAbortCommonEvent() ? NO_ERROR : ERR_CES_FAILED;
900             }
901         },
902         [](napi_env env, napi_status status, void *data) {
903             EVENT_LOGD("ClearAbort napi_create_async_work end");
904             AsyncCallbackInfoClearAbort *asyncCallbackInfo = static_cast<AsyncCallbackInfoClearAbort *>(data);
905             if (asyncCallbackInfo) {
906                 ReturnCallbackPromise(env, asyncCallbackInfo->info, NapiGetNull(env));
907                 if (asyncCallbackInfo->info.callback != nullptr) {
908                     napi_delete_reference(env, asyncCallbackInfo->info.callback);
909                 }
910                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
911                 delete asyncCallbackInfo;
912                 asyncCallbackInfo = nullptr;
913             }
914             EVENT_LOGD("ClearAbort work complete end");
915         },
916         (void *)asyncCallbackInfo,
917         &asyncCallbackInfo->asyncWork);
918 
919     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
920 
921     if (asyncCallbackInfo->info.isCallback) {
922         EVENT_LOGD("Delete ClearAbort callback reference.");
923         return NapiGetNull(env);
924     } else {
925         return promise;
926     }
927 }
928 
GetAbortCommonEvent(napi_env env,napi_callback_info info)929 napi_value GetAbortCommonEvent(napi_env env, napi_callback_info info)
930 {
931     EVENT_LOGD("GetAbort start");
932     size_t argc = 1;
933     napi_value argv[1] = {nullptr};
934     napi_value thisVar = nullptr;
935     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
936 
937     napi_ref callback = nullptr;
938     if (ParseParametersByGetAbort(env, argv, argc, callback) == nullptr) {
939         EVENT_LOGE("ParseParametersByGetAbort failed");
940         if (callback != nullptr) {
941             napi_delete_reference(env, callback);
942         }
943         return NapiGetNull(env);
944     }
945 
946     AsyncCallbackInfoGetAbort *asyncCallbackInfo =
947         new (std::nothrow) AsyncCallbackInfoGetAbort {.env = env, .asyncWork = nullptr};
948     if (asyncCallbackInfo == nullptr) {
949         EVENT_LOGD("Create asyncCallbackInfo is failed");
950         if (callback != nullptr) {
951             napi_delete_reference(env, callback);
952         }
953         return NapiGetNull(env);
954     }
955 
956     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
957     if (asyncCallbackInfo->subscriber == nullptr) {
958         EVENT_LOGE("subscriber is nullptr");
959         if (callback != nullptr) {
960             napi_delete_reference(env, callback);
961         }
962         delete asyncCallbackInfo;
963         return NapiGetNull(env);
964     }
965 
966     napi_value promise = nullptr;
967     PaddingAsyncCallbackInfoGetAbort(env, argc, asyncCallbackInfo, callback, promise);
968 
969     EVENT_LOGD("Create getAbort string.");
970     napi_value resourceName = nullptr;
971     napi_create_string_latin1(env, "getAbort", NAPI_AUTO_LENGTH, &resourceName);
972     // Asynchronous function call
973     napi_create_async_work(env,
974         nullptr,
975         resourceName,
976         [](napi_env env, void *data) {
977             EVENT_LOGD("GetAbort napi_create_async_work start");
978             AsyncCallbackInfoGetAbort *asyncCallbackInfo = static_cast<AsyncCallbackInfoGetAbort *>(data);
979             if (asyncCallbackInfo == nullptr) {
980                 EVENT_LOGE("asyncCallbackInfo is null");
981                 return;
982             }
983             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
984             if (asyncResult) {
985                 asyncCallbackInfo->abortEvent = asyncResult->GetAbortCommonEvent();
986             } else {
987                 asyncCallbackInfo->abortEvent = false;
988             }
989         },
990         [](napi_env env, napi_status status, void *data) {
991             EVENT_LOGD("GetAbort napi_create_async_work end");
992             AsyncCallbackInfoGetAbort *asyncCallbackInfo = static_cast<AsyncCallbackInfoGetAbort *>(data);
993             if (asyncCallbackInfo) {
994                 napi_value result = nullptr;
995                 napi_get_boolean(env, asyncCallbackInfo->abortEvent, &result);
996                 ReturnCallbackPromise(env, asyncCallbackInfo->info, result);
997                 if (asyncCallbackInfo->info.callback != nullptr) {
998                     napi_delete_reference(env, asyncCallbackInfo->info.callback);
999                     EVENT_LOGD("Delete GetAbort callback reference.");
1000                 }
1001                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1002                 delete asyncCallbackInfo;
1003                 asyncCallbackInfo = nullptr;
1004             }
1005             EVENT_LOGD("GetAbort work complete end.");
1006         },
1007         (void *)asyncCallbackInfo,
1008         &asyncCallbackInfo->asyncWork);
1009 
1010     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
1011 
1012     if (asyncCallbackInfo->info.isCallback) {
1013         EVENT_LOGD("Delete GetAbort callback reference.");
1014         return NapiGetNull(env);
1015     } else {
1016         return promise;
1017     }
1018 }
1019 
FinishCommonEvent(napi_env env,napi_callback_info info)1020 napi_value FinishCommonEvent(napi_env env, napi_callback_info info)
1021 {
1022     EVENT_LOGD("Finish start");
1023     size_t argc = 1;
1024     napi_value argv[1] = {nullptr};
1025     napi_value thisVar = nullptr;
1026     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
1027 
1028     napi_ref callback = nullptr;
1029     if (ParseParametersByFinish(env, argv, argc, callback) == nullptr) {
1030         EVENT_LOGE("ParseParametersByFinish failed");
1031         if (callback != nullptr) {
1032             napi_delete_reference(env, callback);
1033         }
1034         return NapiGetNull(env);
1035     }
1036 
1037     AsyncCallbackInfoFinish *asyncCallbackInfo =
1038         new (std::nothrow) AsyncCallbackInfoFinish {.env = env, .asyncWork = nullptr};
1039     if (asyncCallbackInfo == nullptr) {
1040         EVENT_LOGE("asyncCallbackInfo is null");
1041         if (callback != nullptr) {
1042             napi_delete_reference(env, callback);
1043         }
1044         return NapiGetNull(env);
1045     }
1046 
1047     asyncCallbackInfo->subscriber = GetSubscriber(env, thisVar);
1048     if (asyncCallbackInfo->subscriber == nullptr) {
1049         EVENT_LOGE("subscriber is nullptr");
1050         if (callback != nullptr) {
1051             napi_delete_reference(env, callback);
1052         }
1053         delete asyncCallbackInfo;
1054         return NapiGetNull(env);
1055     }
1056 
1057     napi_value promise = nullptr;
1058     PaddingAsyncCallbackInfoFinish(env, argc, asyncCallbackInfo, callback, promise);
1059 
1060     EVENT_LOGD("Create finish string.");
1061     napi_value resourceName = nullptr;
1062     napi_create_string_latin1(env, "finish", NAPI_AUTO_LENGTH, &resourceName);
1063     // Asynchronous function call
1064     napi_create_async_work(env,
1065         nullptr,
1066         resourceName,
1067         [](napi_env env, void *data) {
1068             EVENT_LOGD("Finish napi_create_async_work start");
1069             AsyncCallbackInfoFinish *asyncCallbackInfo = static_cast<AsyncCallbackInfoFinish *>(data);
1070             if (asyncCallbackInfo == nullptr) {
1071                 EVENT_LOGE("asyncCallbackInfo is null");
1072                 return;
1073             }
1074             std::shared_ptr<AsyncCommonEventResult> asyncResult = GetAsyncResult(asyncCallbackInfo->subscriber.get());
1075             if (asyncResult) {
1076                 asyncCallbackInfo->info.errorCode = asyncResult->FinishCommonEvent() ? NO_ERROR : ERR_CES_FAILED;
1077             }
1078         },
1079         [](napi_env env, napi_status status, void *data) {
1080             EVENT_LOGD("Finish work complete");
1081             AsyncCallbackInfoFinish *asyncCallbackInfo = static_cast<AsyncCallbackInfoFinish *>(data);
1082             if (asyncCallbackInfo) {
1083                 ReturnCallbackPromise(env, asyncCallbackInfo->info, NapiGetNull(env));
1084                 if (asyncCallbackInfo->info.callback != nullptr) {
1085                     napi_delete_reference(env, asyncCallbackInfo->info.callback);
1086                 }
1087                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1088                 delete asyncCallbackInfo;
1089                 asyncCallbackInfo = nullptr;
1090             }
1091             EVENT_LOGD("Finish work complete end");
1092         },
1093         (void *)asyncCallbackInfo,
1094         &asyncCallbackInfo->asyncWork);
1095 
1096     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
1097 
1098     if (asyncCallbackInfo->info.isCallback) {
1099         EVENT_LOGD("Delete Finish callback reference.");
1100         return NapiGetNull(env);
1101     } else {
1102         return promise;
1103     }
1104 }
1105 
GetSubscriber(const napi_env & env,const napi_value & value)1106 std::shared_ptr<SubscriberInstance> GetSubscriber(const napi_env &env, const napi_value &value)
1107 {
1108     EVENT_LOGD("GetSubscriber start");
1109 
1110     SubscriberInstanceWrapper *wrapper = nullptr;
1111     napi_unwrap(env, value, (void **)&wrapper);
1112     if (wrapper == nullptr) {
1113         EVENT_LOGW("GetSubscriber wrapper is nullptr");
1114         return nullptr;
1115     }
1116 
1117     return GetSubscriberByWrapper(wrapper);
1118 }
1119 
GetSubscriberByWrapper(SubscriberInstanceWrapper * wrapper)1120 std::shared_ptr<SubscriberInstance> GetSubscriberByWrapper(SubscriberInstanceWrapper *wrapper)
1121 {
1122     if (wrapper->GetSubscriber() == nullptr) {
1123         EVENT_LOGE("subscriber is null");
1124         return nullptr;
1125     }
1126     std::lock_guard<ffrt::mutex> lock(subscriberInsMutex);
1127     for (auto subscriberInstance : subscriberInstances) {
1128         if (subscriberInstance.first.get() == wrapper->GetSubscriber().get()) {
1129             return subscriberInstance.first;
1130         }
1131     }
1132     return wrapper->GetSubscriber();
1133 }
1134 
GetSubscriberByUnsubscribe(const napi_env & env,const napi_value & value,std::shared_ptr<SubscriberInstance> & subscriber,bool & isFind)1135 napi_value GetSubscriberByUnsubscribe(
1136     const napi_env &env, const napi_value &value, std::shared_ptr<SubscriberInstance> &subscriber, bool &isFind)
1137 {
1138     EVENT_LOGD("GetSubscriberByUnsubscribe start");
1139 
1140     isFind = false;
1141     subscriber = GetSubscriber(env, value);
1142     if (subscriber == nullptr) {
1143         EVENT_LOGE("subscriber is nullptr");
1144         return nullptr;
1145     }
1146     isFind = true;
1147     return NapiGetNull(env);
1148 }
1149 
NapiDeleteSubscribe(const napi_env & env,std::shared_ptr<SubscriberInstance> & subscriber)1150 void NapiDeleteSubscribe(const napi_env &env, std::shared_ptr<SubscriberInstance> &subscriber)
1151 {
1152     EVENT_LOGD("NapiDeleteSubscribe start");
1153     std::lock_guard<ffrt::mutex> lock(subscriberInsMutex);
1154     auto subscribe = subscriberInstances.find(subscriber);
1155     if (subscribe != subscriberInstances.end()) {
1156         for (auto asyncCallbackInfoSubscribe : subscribe->second.asyncCallbackInfo) {
1157             delete asyncCallbackInfoSubscribe;
1158             asyncCallbackInfoSubscribe = nullptr;
1159         }
1160         subscriber->SetCallbackRef(nullptr);
1161         napi_remove_env_cleanup_hook(subscriber->GetEnv(), ClearEnvCallback, subscriber.get());
1162         subscriberInstances.erase(subscribe);
1163     }
1164 }
1165 
CommonEventSubscriberConstructor(napi_env env,napi_callback_info info)1166 napi_value CommonEventSubscriberConstructor(napi_env env, napi_callback_info info)
1167 {
1168     EVENT_LOGD("CommonEventSubscriberConstructor start");
1169     napi_value thisVar = nullptr;
1170     CommonEventSubscribeInfo subscribeInfo;
1171     if (!ParseParametersConstructor(env, info, thisVar, subscribeInfo)) {
1172         EVENT_LOGE("ParseParametersConstructor failed");
1173         return NapiGetNull(env);
1174     }
1175 
1176     auto wrapper = new (std::nothrow) SubscriberInstanceWrapper(subscribeInfo);
1177     if (wrapper == nullptr) {
1178         EVENT_LOGE("wrapper is null");
1179         return NapiGetNull(env);
1180     }
1181 
1182     napi_wrap(env, thisVar, wrapper,
1183         [](napi_env env, void *data, void *hint) {
1184             auto *wrapper = reinterpret_cast<SubscriberInstanceWrapper *>(data);
1185             EVENT_LOGD("Constructor destroy");
1186             auto subscriber = GetSubscriberByWrapper(wrapper);
1187             if (subscriber != nullptr) {
1188                 CommonEventManager::UnSubscribeCommonEvent(subscriber);
1189                 NapiDeleteSubscribe(env, subscriber);
1190             }
1191             delete wrapper;
1192             wrapper = nullptr;
1193         },
1194         nullptr,
1195         nullptr);
1196 
1197     EVENT_LOGD("End");
1198     return thisVar;
1199 }
1200 
PublishAsUser(napi_env env,napi_callback_info info)1201 napi_value PublishAsUser(napi_env env, napi_callback_info info)
1202 {
1203     EVENT_LOGD("Publish start");
1204 
1205     size_t argc = PUBLISH_MAX_PARA_BY_USERID;
1206     napi_value argv[PUBLISH_MAX_PARA_BY_USERID] = {nullptr};
1207     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
1208     if (argc < PUBLISH_MAX_PARA_AS_USER) {
1209         EVENT_LOGE("Wrong number of arguments.");
1210         return NapiGetNull(env);
1211     }
1212 
1213     std::string event;
1214     int32_t userId = UNDEFINED_USER;
1215     CommonEventPublishDataByjs commonEventPublishDatajs;
1216     napi_ref callback = nullptr;
1217 
1218     if (ParseParametersByPublishAsUser(env, argv, argc, event, userId, commonEventPublishDatajs, callback) == nullptr) {
1219         EVENT_LOGE("ParseParametersByPublishAsUser failed");
1220         if (callback != nullptr) {
1221             napi_delete_reference(env, callback);
1222         }
1223         return NapiGetNull(env);
1224     }
1225 
1226     AsyncCallbackInfoPublish *asyncCallbackInfo =
1227         new (std::nothrow) AsyncCallbackInfoPublish {.env = env, .asyncWork = nullptr};
1228     if (asyncCallbackInfo == nullptr) {
1229         EVENT_LOGE("asyncCallbackInfo is null");
1230         if (callback != nullptr) {
1231             napi_delete_reference(env, callback);
1232         }
1233         return NapiGetNull(env);
1234     }
1235     asyncCallbackInfo->callback = callback;
1236 
1237     // CommonEventData::want->action
1238     Want want;
1239     want.SetAction(event);
1240     if (argc == PUBLISH_MAX_PARA_BY_USERID) {
1241         EVENT_LOGD("argc is PUBLISH_MAX_PARA_BY_USERID.");
1242         PaddingCallbackInfoPublish(want, asyncCallbackInfo, commonEventPublishDatajs);
1243     }
1244     asyncCallbackInfo->commonEventData.SetWant(want);
1245     asyncCallbackInfo->userId = userId;
1246 
1247     EVENT_LOGD("Create publish string.");
1248     napi_value resourceName = nullptr;
1249     napi_create_string_latin1(env, "Publish", NAPI_AUTO_LENGTH, &resourceName);
1250 
1251     // Calling Asynchronous functions
1252     napi_create_async_work(env,
1253         nullptr,
1254         resourceName,
1255         [](napi_env env, void *data) {
1256             EVENT_LOGD("Publish napi_create_async_work start");
1257             AsyncCallbackInfoPublish *asyncCallbackInfo = static_cast<AsyncCallbackInfoPublish *>(data);
1258             if (asyncCallbackInfo == nullptr) {
1259                 EVENT_LOGE("asyncCallbackInfo is nullptr");
1260                 return;
1261             }
1262             asyncCallbackInfo->errorCode = CommonEventManager::PublishCommonEventAsUser(
1263                 asyncCallbackInfo->commonEventData, asyncCallbackInfo->commonEventPublishInfo,
1264                 asyncCallbackInfo->userId) ? NO_ERROR : ERR_CES_FAILED;
1265         },
1266         [](napi_env env, napi_status status, void *data) {
1267             EVENT_LOGD("PublishAsUser work complete.");
1268             AsyncCallbackInfoPublish *asyncCallbackInfo = static_cast<AsyncCallbackInfoPublish *>(data);
1269             if (asyncCallbackInfo) {
1270                 SetCallback(env, asyncCallbackInfo->callback, asyncCallbackInfo->errorCode, NapiGetNull(env));
1271                 if (asyncCallbackInfo->callback != nullptr) {
1272                     EVENT_LOGD("Delete PublishAsUser callback reference.");
1273                     napi_delete_reference(env, asyncCallbackInfo->callback);
1274                 }
1275                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1276                 delete asyncCallbackInfo;
1277                 asyncCallbackInfo = nullptr;
1278             }
1279             EVENT_LOGD("PublishAsUser work complete end.");
1280         },
1281         (void *)asyncCallbackInfo,
1282         &asyncCallbackInfo->asyncWork);
1283 
1284     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
1285 
1286     return NapiGetNull(env);
1287 }
1288 
CreateSubscriber(napi_env env,napi_callback_info info)1289 napi_value CreateSubscriber(napi_env env, napi_callback_info info)
1290 {
1291     EVENT_LOGD("CreateSubscriber start");
1292 
1293     size_t argc = CREATE_MAX_PARA;
1294     napi_value argv[CREATE_MAX_PARA] = {nullptr};
1295     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
1296     if (argc < 1) {
1297         EVENT_LOGE("Wrong number of arguments");
1298         return NapiGetNull(env);
1299     }
1300 
1301     napi_ref callback = nullptr;
1302     if (ParseParametersByCreateSubscriber(env, argv, argc, callback) == nullptr) {
1303         EVENT_LOGE("ParseParametersByCreateSubscriber failed");
1304         if (callback != nullptr) {
1305             napi_delete_reference(env, callback);
1306         }
1307         return NapiGetNull(env);
1308     }
1309 
1310     AsyncCallbackInfoCreate *asyncCallbackInfo =
1311         new (std::nothrow) AsyncCallbackInfoCreate {.env = env, .asyncWork = nullptr, .subscribeInfo = nullptr};
1312     if (asyncCallbackInfo == nullptr) {
1313         EVENT_LOGD("asyncCallbackInfo is failed.");
1314         if (callback != nullptr) {
1315             napi_delete_reference(env, callback);
1316         }
1317         return NapiGetNull(env);
1318     }
1319     napi_value promise = nullptr;
1320 
1321     PaddingAsyncCallbackInfoCreateSubscriber(env, asyncCallbackInfo, callback, promise);
1322 
1323     napi_create_reference(env, argv[0], 1, &asyncCallbackInfo->subscribeInfo);
1324 
1325     EVENT_LOGD("Create createSubscriber string.");
1326     napi_value resourceName = nullptr;
1327     napi_create_string_latin1(env, "CreateSubscriber", NAPI_AUTO_LENGTH, &resourceName);
1328 
1329     // Asynchronous function call
1330     napi_create_async_work(env,
1331         nullptr,
1332         resourceName,
1333         [](napi_env env, void *data) {
1334             EVENT_LOGD("CreateSubscriber napi_create_async_work start");
1335         },
1336         [](napi_env env, napi_status status, void *data) {
1337             EVENT_LOGD("CreateSubscriber napi_create_async_work end");
1338             AsyncCallbackInfoCreate *asyncCallbackInfo = static_cast<AsyncCallbackInfoCreate *>(data);
1339             if (asyncCallbackInfo == nullptr) {
1340                 EVENT_LOGE("asyncCallbackInfo is null");
1341                 return;
1342             }
1343             napi_value constructor = nullptr;
1344             napi_value subscribeInfoRefValue = nullptr;
1345             napi_get_reference_value(env, asyncCallbackInfo->subscribeInfo, &subscribeInfoRefValue);
1346             napi_get_reference_value(env, g_CommonEventSubscriber, &constructor);
1347             napi_new_instance(env, constructor, 1, &subscribeInfoRefValue, &asyncCallbackInfo->result);
1348 
1349             if (asyncCallbackInfo->result == nullptr) {
1350                 EVENT_LOGE("Failed to create subscriber instance.");
1351                 asyncCallbackInfo->info.errorCode = ERR_CES_FAILED;
1352             }
1353             ReturnCallbackPromise(env, asyncCallbackInfo->info, asyncCallbackInfo->result);
1354             if (asyncCallbackInfo->info.callback != nullptr) {
1355                 EVENT_LOGD("Delete CreateSubscriber callback reference.");
1356                 napi_delete_reference(env, asyncCallbackInfo->info.callback);
1357             }
1358             if (asyncCallbackInfo->subscribeInfo != nullptr) {
1359                 napi_delete_reference(env, asyncCallbackInfo->subscribeInfo);
1360             }
1361             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1362             delete asyncCallbackInfo;
1363             asyncCallbackInfo = nullptr;
1364         },
1365         (void *)asyncCallbackInfo,
1366         &asyncCallbackInfo->asyncWork);
1367 
1368     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
1369 
1370     if (asyncCallbackInfo->info.isCallback) {
1371         EVENT_LOGD("Delete create callback reference.");
1372         return NapiGetNull(env);
1373     } else {
1374         return promise;
1375     }
1376 }
1377 
Subscribe(napi_env env,napi_callback_info info)1378 napi_value Subscribe(napi_env env, napi_callback_info info)
1379 {
1380     EVENT_LOGD("Subscribe start");
1381 
1382     // Argument parsing
1383     size_t argc = SUBSCRIBE_MAX_PARA;
1384     napi_value argv[SUBSCRIBE_MAX_PARA] = {nullptr};
1385     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
1386     if (argc < SUBSCRIBE_MAX_PARA) {
1387         EVENT_LOGE("Wrong number of arguments.");
1388         return NapiGetNull(env);
1389     }
1390 
1391     napi_ref callback = nullptr;
1392     std::shared_ptr<SubscriberInstance> subscriber = nullptr;
1393 
1394     if (ParseParametersBySubscribe(env, argv, subscriber, callback) == nullptr) {
1395         EVENT_LOGE("ParseParametersBySubscribe failed");
1396         if (callback != nullptr) {
1397             napi_delete_reference(env, callback);
1398         }
1399         return NapiGetNull(env);
1400     }
1401 
1402     AsyncCallbackInfoSubscribe *asyncCallbackInfo =
1403         new (std::nothrow) AsyncCallbackInfoSubscribe {.env = env, .asyncWork = nullptr, .subscriber = nullptr};
1404     if (asyncCallbackInfo == nullptr) {
1405         EVENT_LOGE("asyncCallbackInfo is null");
1406         if (callback != nullptr) {
1407             napi_delete_reference(env, callback);
1408         }
1409         return NapiGetNull(env);
1410     }
1411 
1412     EVENT_LOGD("Create subscribe string.");
1413     napi_threadsafe_function tsfn = nullptr;
1414     napi_value resourceName = nullptr;
1415     napi_create_string_latin1(env, "Subscribe", NAPI_AUTO_LENGTH, &resourceName);
1416     napi_create_threadsafe_function(env, argv[1], nullptr, resourceName, 0, 1, asyncCallbackInfo->callback,
1417         ThreadFinished, nullptr, ThreadSafeCallback, &tsfn);
1418     subscriber->SetEnv(env);
1419     subscriber->SetCallbackRef(callback);
1420     subscriber->SetThreadSafeFunction(tsfn);
1421     asyncCallbackInfo->subscriber = subscriber;
1422     asyncCallbackInfo->callback = callback;
1423 
1424     // Asynchronous function call
1425     napi_create_async_work(env,
1426         nullptr,
1427         resourceName,
1428         [](napi_env env, void *data) {
1429             EVENT_LOGD("Subscribe napi_create_async_work start");
1430             AsyncCallbackInfoSubscribe *asyncCallbackInfo = static_cast<AsyncCallbackInfoSubscribe *>(data);
1431             if (asyncCallbackInfo == nullptr) {
1432                 EVENT_LOGE("asyncCallbackInfo is null");
1433                 return;
1434             }
1435             asyncCallbackInfo->errorCode = CommonEventManager::SubscribeCommonEvent(asyncCallbackInfo->subscriber) ?
1436                 NO_ERROR : ERR_CES_FAILED;
1437         },
1438         [](napi_env env, napi_status status, void *data) {
1439             EVENT_LOGD("Subscribe work complete");
1440             AsyncCallbackInfoSubscribe *asyncCallbackInfo = static_cast<AsyncCallbackInfoSubscribe *>(data);
1441             if (asyncCallbackInfo == nullptr) {
1442                 EVENT_LOGE("asyncCallbackInfo is null");
1443                 return;
1444             }
1445             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1446             if (asyncCallbackInfo->errorCode == NO_ERROR) {
1447                 std::lock_guard<ffrt::mutex> lock(subscriberInsMutex);
1448                 subscriberInstances[asyncCallbackInfo->subscriber].asyncCallbackInfo.emplace_back(asyncCallbackInfo);
1449             } else {
1450                 SetCallback(env, asyncCallbackInfo->callback, asyncCallbackInfo->errorCode, NapiGetNull(env));
1451 
1452                 if (asyncCallbackInfo->callback != nullptr) {
1453                     EVENT_LOGD("Delete subscribe callback reference.");
1454                     napi_delete_reference(env, asyncCallbackInfo->callback);
1455                 }
1456 
1457                 delete asyncCallbackInfo;
1458                 asyncCallbackInfo = nullptr;
1459             }
1460             EVENT_LOGD("Subscribe work complete end");
1461         },
1462         (void *)asyncCallbackInfo,
1463         &asyncCallbackInfo->asyncWork);
1464     napi_add_env_cleanup_hook(env, ClearEnvCallback, subscriber.get());
1465     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
1466     return NapiGetNull(env);
1467 }
1468 
Unsubscribe(napi_env env,napi_callback_info info)1469 napi_value Unsubscribe(napi_env env, napi_callback_info info)
1470 {
1471     EVENT_LOGD("Unsubscribe start");
1472 
1473     // Argument parsing
1474     size_t argc = UNSUBSCRIBE_MAX_PARA;
1475     napi_value argv[UNSUBSCRIBE_MAX_PARA] = {nullptr};
1476     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
1477     if (argc < 1) {
1478         EVENT_LOGE("Wrong number of arguments");
1479         return NapiGetNull(env);
1480     }
1481 
1482     napi_ref callback = nullptr;
1483     std::shared_ptr<SubscriberInstance> subscriber = nullptr;
1484     napi_value result = nullptr;
1485     result = ParseParametersByUnsubscribe(env, argc, argv, subscriber, callback);
1486     if (result == nullptr) {
1487         EVENT_LOGE("ParseParametersByUnsubscribe failed");
1488         if (callback != nullptr) {
1489             napi_delete_reference(env, callback);
1490         }
1491         return NapiGetNull(env);
1492     }
1493     bool isFind = false;
1494     napi_get_value_bool(env, result, &isFind);
1495     if (!isFind) {
1496         EVENT_LOGE("Unsubscribe failed. The current subscriber does not exist");
1497         if (callback != nullptr) {
1498             napi_delete_reference(env, callback);
1499         }
1500         return NapiGetNull(env);
1501     }
1502 
1503     AsyncCallbackInfoUnsubscribe *asynccallback = new (std::nothrow) AsyncCallbackInfoUnsubscribe();
1504     if (asynccallback == nullptr) {
1505         EVENT_LOGE("asynccallback is null");
1506         if (callback != nullptr) {
1507             napi_delete_reference(env, callback);
1508         }
1509         return NapiGetNull(env);
1510     }
1511     asynccallback->env = env;
1512     asynccallback->subscriber = subscriber;
1513     asynccallback->argc = argc;
1514     if (argc >= UNSUBSCRIBE_MAX_PARA) {
1515         asynccallback->callback = callback;
1516     }
1517 
1518     EVENT_LOGD("Create unsubscribe string.");
1519     napi_value resourceName = nullptr;
1520     napi_create_string_latin1(env, "Unsubscribe", NAPI_AUTO_LENGTH, &resourceName);
1521 
1522     // Asynchronous function call
1523     napi_create_async_work(env,
1524         nullptr,
1525         resourceName,
1526         [](napi_env env, void *data) {
1527             EVENT_LOGD("Excute create async Unsubscribe");
1528             AsyncCallbackInfoUnsubscribe *asyncCallbackInfo = static_cast<AsyncCallbackInfoUnsubscribe *>(data);
1529             if (asyncCallbackInfo == nullptr) {
1530                 EVENT_LOGE("asyncCallbackInfo is null");
1531                 return;
1532             }
1533             asyncCallbackInfo->errorCode = CommonEventManager::UnSubscribeCommonEvent(asyncCallbackInfo->subscriber) ?
1534                 NO_ERROR : ERR_CES_FAILED;
1535         },
1536         [](napi_env env, napi_status status, void *data) {
1537             EVENT_LOGD("Unsubscribe napi_create_async_work end");
1538             AsyncCallbackInfoUnsubscribe *asyncCallbackInfo = static_cast<AsyncCallbackInfoUnsubscribe *>(data);
1539             if (asyncCallbackInfo) {
1540                 if (asyncCallbackInfo->argc >= UNSUBSCRIBE_MAX_PARA) {
1541                     napi_value result = nullptr;
1542                     napi_get_null(env, &result);
1543                     SetCallback(env, asyncCallbackInfo->callback, asyncCallbackInfo->errorCode, result);
1544                 }
1545                 if (asyncCallbackInfo->callback != nullptr) {
1546                     napi_delete_reference(env, asyncCallbackInfo->callback);
1547                 }
1548                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1549                 NapiDeleteSubscribe(env, asyncCallbackInfo->subscriber);
1550                 EVENT_LOGD("delete asyncCallbackInfo");
1551                 delete asyncCallbackInfo;
1552                 asyncCallbackInfo = nullptr;
1553             }
1554         },
1555         (void *)asynccallback,
1556         &asynccallback->asyncWork);
1557 
1558     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asynccallback->asyncWork, napi_qos_user_initiated));
1559     return NapiGetNull(env);
1560 }
1561 
Publish(napi_env env,napi_callback_info info)1562 napi_value Publish(napi_env env, napi_callback_info info)
1563 {
1564     EVENT_LOGD("Publish start");
1565 
1566     size_t argc = PUBLISH_MAX_PARA_BY_PUBLISHDATA;
1567     napi_value argv[PUBLISH_MAX_PARA_BY_PUBLISHDATA] = {nullptr};
1568     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
1569     if (argc < PUBLISH_MAX_PARA) {
1570         EVENT_LOGE("Error number of arguments.");
1571         return NapiGetNull(env);
1572     }
1573 
1574     std::string event;
1575     CommonEventPublishDataByjs commonEventPublishDatajs;
1576     napi_ref callback = nullptr;
1577 
1578     if (ParseParametersByPublish(env, argv, argc, event, commonEventPublishDatajs, callback) == nullptr) {
1579         EVENT_LOGE("ParseParametersByPublish failed");
1580         if (callback != nullptr) {
1581             napi_delete_reference(env, callback);
1582         }
1583         return NapiGetNull(env);
1584     }
1585 
1586     AsyncCallbackInfoPublish *asyncCallbackInfo =
1587         new (std::nothrow) AsyncCallbackInfoPublish {.env = env, .asyncWork = nullptr};
1588     if (asyncCallbackInfo == nullptr) {
1589         EVENT_LOGE("asyncCallbackInfo failed.");
1590         if (callback != nullptr) {
1591             napi_delete_reference(env, callback);
1592         }
1593         return NapiGetNull(env);
1594     }
1595     asyncCallbackInfo->callback = callback;
1596 
1597     // CommonEventData::want->action
1598     Want want;
1599     want.SetAction(event);
1600     if (argc == PUBLISH_MAX_PARA_BY_PUBLISHDATA) {
1601         PaddingCallbackInfoPublish(want, asyncCallbackInfo, commonEventPublishDatajs);
1602     }
1603     asyncCallbackInfo->commonEventData.SetWant(want);
1604 
1605     EVENT_LOGD("Create publish string.");
1606     napi_value resourceName = nullptr;
1607     napi_create_string_latin1(env, "Publish", NAPI_AUTO_LENGTH, &resourceName);
1608 
1609     // Asynchronous function call
1610     napi_create_async_work(env,
1611         nullptr,
1612         resourceName,
1613         [](napi_env env, void *data) {
1614             EVENT_LOGD("Publish napi_create_async_work start");
1615             AsyncCallbackInfoPublish *asyncCallbackInfo = static_cast<AsyncCallbackInfoPublish *>(data);
1616             if (asyncCallbackInfo == nullptr) {
1617                 EVENT_LOGE("asyncCallbackInfo is null");
1618                 return;
1619             }
1620             bool ret = CommonEventManager::PublishCommonEvent(
1621                 asyncCallbackInfo->commonEventData, asyncCallbackInfo->commonEventPublishInfo);
1622             asyncCallbackInfo->errorCode = ret ? NO_ERROR : ERR_CES_FAILED;
1623         },
1624         [](napi_env env, napi_status status, void *data) {
1625             AsyncCallbackInfoPublish *asyncCallbackInfo = static_cast<AsyncCallbackInfoPublish *>(data);
1626             if (asyncCallbackInfo) {
1627                 SetCallback(env, asyncCallbackInfo->callback, asyncCallbackInfo->errorCode, NapiGetNull(env));
1628                 if (asyncCallbackInfo->callback != nullptr) {
1629                     EVENT_LOGD("Delete cancel callback reference");
1630                     napi_delete_reference(env, asyncCallbackInfo->callback);
1631                 }
1632                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1633                 delete asyncCallbackInfo;
1634                 asyncCallbackInfo = nullptr;
1635             }
1636             EVENT_LOGD("Publish work complete end.");
1637         },
1638         (void *)asyncCallbackInfo,
1639         &asyncCallbackInfo->asyncWork);
1640 
1641     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated));
1642 
1643     return NapiGetNull(env);
1644 }
1645 
CommonEventInit(napi_env env,napi_value exports)1646 napi_value CommonEventInit(napi_env env, napi_value exports)
1647 {
1648     EVENT_LOGD("enter");
1649 
1650     napi_property_descriptor desc[] = {
1651         DECLARE_NAPI_FUNCTION("publish", Publish),
1652         DECLARE_NAPI_FUNCTION("publishAsUser", PublishAsUser),
1653         DECLARE_NAPI_FUNCTION("createSubscriber", CreateSubscriber),
1654         DECLARE_NAPI_FUNCTION("subscribe", Subscribe),
1655         DECLARE_NAPI_FUNCTION("unsubscribe", Unsubscribe),
1656     };
1657 
1658     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
1659 
1660     OHOS::EventFwkNapi::SupportInit(env, exports);
1661     return exports;
1662 }
1663 
CommonEventSubscriberInit(napi_env env,napi_value exports)1664 napi_value CommonEventSubscriberInit(napi_env env, napi_value exports)
1665 {
1666     EVENT_LOGD("enter");
1667     napi_property_descriptor properties[] = {
1668         DECLARE_NAPI_FUNCTION("getSubscribeInfo", GetSubscribeInfo),
1669         DECLARE_NAPI_FUNCTION("isOrderedCommonEvent", IsOrderedCommonEvent),
1670         DECLARE_NAPI_FUNCTION("isStickyCommonEvent", IsStickyCommonEvent),
1671         DECLARE_NAPI_FUNCTION("getCode", GetCode),
1672         DECLARE_NAPI_FUNCTION("setCode", SetCode),
1673         DECLARE_NAPI_FUNCTION("getData", GetData),
1674         DECLARE_NAPI_FUNCTION("setData", SetData),
1675         DECLARE_NAPI_FUNCTION("setCodeAndData", SetCodeAndData),
1676         DECLARE_NAPI_FUNCTION("abortCommonEvent", AbortCommonEvent),
1677         DECLARE_NAPI_FUNCTION("clearAbortCommonEvent", ClearAbortCommonEvent),
1678         DECLARE_NAPI_FUNCTION("getAbortCommonEvent", GetAbortCommonEvent),
1679         DECLARE_NAPI_FUNCTION("finishCommonEvent", FinishCommonEvent),
1680     };
1681     napi_value constructor = nullptr;
1682 
1683     NAPI_CALL(env,
1684         napi_define_class(env,
1685             "commonEventSubscriber",
1686             NAPI_AUTO_LENGTH,
1687             CommonEventSubscriberConstructor,
1688             nullptr,
1689             sizeof(properties) / sizeof(*properties),
1690             properties,
1691             &constructor));
1692 
1693     EVENT_LOGD("Create commonEventSubscriber reference.");
1694     napi_create_reference(env, constructor, 1, &g_CommonEventSubscriber);
1695     napi_set_named_property(env, exports, "commonEventSubscriber", constructor);
1696     return exports;
1697 }
1698 
1699 }  // namespace EventFwkNapi
1700 }  // namespace OHOS
1701