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