• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "subscribe.h"
17 
18 #include <mutex>
19 #include <uv.h>
20 
21 namespace OHOS {
22 namespace NotificationNapi {
23 const int SUBSRIBE_MAX_PARA = 3;
24 const int NO_DELETE_REASON = -1;
25 const std::string CONSUME = "onConsume";
26 const std::string CANCEL = "onCancel";
27 const std::string UPDATE = "onUpdate";
28 const std::string CONNECTED = "onConnect";
29 const std::string DIS_CONNECTED = "onDisconnect";
30 const std::string DIE = "onDestroy";
31 const std::string DISTURB_MODE_CHANGE = "onDisturbModeChange";
32 const std::string DISTURB_DATE_CHANGE = "onDoNotDisturbDateChange";
33 const std::string ENABLE_NOTIFICATION_CHANGED = "OnEnabledNotificationChanged";
34 
35 struct NotificationReceiveDataWorker {
36     napi_env env = nullptr;
37     napi_ref ref = nullptr;
38     std::shared_ptr<OHOS::Notification::Notification> request;
39     std::shared_ptr<NotificationSortingMap> sortingMap;
40     NotificationDoNotDisturbDate date;
41     EnabledNotificationCallbackData callbackData;
42     int deleteReason = 0;
43     int result = 0;
44     int disturbMode = 0;
45     SubscriberInstance *subscriber = nullptr;
46 };
47 
SetSubscribeCallbackData(const napi_env & env,const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap,int deleteReason,napi_value & result)48 napi_value SetSubscribeCallbackData(const napi_env &env,
49     const std::shared_ptr<OHOS::Notification::Notification> &request,
50     const std::shared_ptr<NotificationSortingMap> &sortingMap, int deleteReason, napi_value &result)
51 {
52     ANS_LOGI("enter");
53     if (request == nullptr) {
54         ANS_LOGE("request is null");
55         return Common::NapiGetBoolean(env, false);
56     }
57 
58     if (sortingMap == nullptr) {
59         ANS_LOGE("sortingMap is null");
60         return Common::NapiGetBoolean(env, false);
61     }
62 
63     // request: NotificationRequest
64     napi_value requestResult = nullptr;
65     napi_create_object(env, &requestResult);
66     if (!Common::SetNotification(env, request.get(), requestResult)) {
67         ANS_LOGE("SetNotification call failed");
68         return Common::NapiGetBoolean(env, false);
69     }
70     napi_set_named_property(env, result, "request", requestResult);
71 
72     // sortingMap?: NotificationSortingMap
73     napi_value sortingMapResult = nullptr;
74     napi_create_object(env, &sortingMapResult);
75     if (!Common::SetNotificationSortingMap(env, sortingMap, sortingMapResult)) {
76         ANS_LOGE("SetNotificationSortingMap call failed");
77         return Common::NapiGetBoolean(env, false);
78     }
79     napi_set_named_property(env, result, "sortingMap", sortingMapResult);
80 
81     // reason?: number
82     if (deleteReason != NO_DELETE_REASON) {
83         napi_value value = nullptr;
84         int outReason = 0;
85         if (!Common::ReasonCToJS(deleteReason, outReason)) {
86             return Common::NapiGetBoolean(env, false);
87         }
88         napi_create_int32(env, outReason, &value);
89         napi_set_named_property(env, result, "reason", value);
90     }
91 
92     // sound?: string
93     napi_value soundResult = nullptr;
94     std::string sound;
95     if (request->EnableSound()) {
96         sound = request->GetSound().ToString();
97     }
98     napi_create_string_utf8(env, sound.c_str(), NAPI_AUTO_LENGTH, &soundResult);
99     napi_set_named_property(env, result, "sound", soundResult);
100 
101     // vibrationValues?: Array<number>
102     napi_value arr = nullptr;
103     napi_create_array(env, &arr);
104     size_t count = 0;
105     if (request->EnableVibrate()) {
106         for (auto vec : request->GetVibrationStyle()) {
107             napi_value nVibrationValue = nullptr;
108             napi_create_int64(env, vec, &nVibrationValue);
109             napi_set_element(env, arr, count, nVibrationValue);
110             count++;
111         }
112     }
113     napi_set_named_property(env, result, "vibrationValues", arr);
114 
115     return Common::NapiGetBoolean(env, true);
116 }
117 
SubscriberInstance()118 SubscriberInstance::SubscriberInstance()
119 {}
120 
~SubscriberInstance()121 SubscriberInstance::~SubscriberInstance()
122 {
123     if (canceCallbackInfo_.ref != nullptr) {
124         napi_delete_reference(canceCallbackInfo_.env, canceCallbackInfo_.ref);
125     }
126     if (consumeCallbackInfo_.ref != nullptr) {
127         napi_delete_reference(consumeCallbackInfo_.env, consumeCallbackInfo_.ref);
128     }
129     if (updateCallbackInfo_.ref != nullptr) {
130         napi_delete_reference(updateCallbackInfo_.env, updateCallbackInfo_.ref);
131     }
132     if (subscribeCallbackInfo_.ref != nullptr) {
133         napi_delete_reference(subscribeCallbackInfo_.env, subscribeCallbackInfo_.ref);
134     }
135     if (unsubscribeCallbackInfo_.ref != nullptr) {
136         napi_delete_reference(unsubscribeCallbackInfo_.env, unsubscribeCallbackInfo_.ref);
137     }
138     if (dieCallbackInfo_.ref != nullptr) {
139         napi_delete_reference(dieCallbackInfo_.env, dieCallbackInfo_.ref);
140     }
141     if (disturbModeCallbackInfo_.ref != nullptr) {
142         napi_delete_reference(disturbModeCallbackInfo_.env, disturbModeCallbackInfo_.ref);
143     }
144     if (enabledNotificationCallbackInfo_.ref != nullptr) {
145         napi_delete_reference(enabledNotificationCallbackInfo_.env, enabledNotificationCallbackInfo_.ref);
146     }
147 }
148 
OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> & request)149 void SubscriberInstance::OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> &request)
150 {}
151 
UvQueueWorkOnCanceled(uv_work_t * work,int status)152 void UvQueueWorkOnCanceled(uv_work_t *work, int status)
153 {
154     ANS_LOGI("OnCanceled uv_work_t start");
155 
156     if (work == nullptr) {
157         ANS_LOGE("work is null");
158         return;
159     }
160 
161     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
162     if (dataWorkerData == nullptr) {
163         ANS_LOGE("dataWorkerData is null");
164         delete work;
165         work = nullptr;
166         return;
167     }
168     napi_value result = nullptr;
169     napi_create_object(dataWorkerData->env, &result);
170     if (!SetSubscribeCallbackData(dataWorkerData->env,
171         dataWorkerData->request,
172         dataWorkerData->sortingMap,
173         dataWorkerData->deleteReason,
174         result)) {
175         ANS_LOGE("Failed to convert data to JS");
176     } else {
177         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
178     }
179 
180     delete dataWorkerData;
181     dataWorkerData = nullptr;
182     delete work;
183     work = nullptr;
184 }
185 
OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap,int deleteReason)186 void SubscriberInstance::OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> &request,
187     const std::shared_ptr<NotificationSortingMap> &sortingMap, int deleteReason)
188 {
189     ANS_LOGI("enter");
190 
191     if (canceCallbackInfo_.ref == nullptr) {
192         ANS_LOGI("cancel callback unset");
193         return;
194     }
195 
196     if (request == nullptr) {
197         ANS_LOGE("request is null");
198         return;
199     }
200 
201     if (sortingMap == nullptr) {
202         ANS_LOGE("sortingMap is null");
203         return;
204     }
205     ANS_LOGI("OnCanceled NotificationId = %{public}d", request->GetNotificationRequest().GetNotificationId());
206     ANS_LOGI("OnCanceled sortingMap size = %{public}zu", sortingMap->GetKey().size());
207     ANS_LOGI("OnCanceled deleteReason = %{public}d", deleteReason);
208 
209     uv_loop_s *loop = nullptr;
210     napi_get_uv_event_loop(canceCallbackInfo_.env, &loop);
211     if (loop == nullptr) {
212         ANS_LOGE("loop instance is nullptr");
213         return;
214     }
215 
216     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
217     if (dataWorker == nullptr) {
218         ANS_LOGE("new dataWorker failed");
219         return;
220     }
221 
222     dataWorker->request = request;
223     dataWorker->sortingMap = sortingMap;
224     dataWorker->deleteReason = deleteReason;
225     dataWorker->env = canceCallbackInfo_.env;
226     dataWorker->ref = canceCallbackInfo_.ref;
227 
228     uv_work_t *work = new (std::nothrow) uv_work_t;
229     if (work == nullptr) {
230         ANS_LOGE("new work failed");
231         delete dataWorker;
232         dataWorker = nullptr;
233         return;
234     }
235 
236     work->data = (void *)dataWorker;
237 
238     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnCanceled);
239     if (ret != 0) {
240         delete dataWorker;
241         dataWorker = nullptr;
242         delete work;
243         work = nullptr;
244     }
245 }
246 
OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> & request)247 void SubscriberInstance::OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> &request)
248 {}
249 
UvQueueWorkOnConsumed(uv_work_t * work,int status)250 void UvQueueWorkOnConsumed(uv_work_t *work, int status)
251 {
252     ANS_LOGI("OnConsumed uv_work_t start");
253 
254     if (work == nullptr) {
255         ANS_LOGE("work is null");
256         return;
257     }
258 
259     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
260     if (dataWorkerData == nullptr) {
261         ANS_LOGE("dataWorkerData is null");
262         delete work;
263         work = nullptr;
264         return;
265     }
266     napi_value result = nullptr;
267     napi_create_object(dataWorkerData->env, &result);
268     if (!SetSubscribeCallbackData(dataWorkerData->env,
269         dataWorkerData->request,
270         dataWorkerData->sortingMap,
271         NO_DELETE_REASON,
272         result)) {
273         ANS_LOGE("Failed to convert data to JS");
274     } else {
275         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
276     }
277 
278     delete dataWorkerData;
279     dataWorkerData = nullptr;
280     delete work;
281     work = nullptr;
282 }
283 
OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap)284 void SubscriberInstance::OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> &request,
285     const std::shared_ptr<NotificationSortingMap> &sortingMap)
286 {
287     ANS_LOGI("enter");
288 
289     if (consumeCallbackInfo_.ref == nullptr) {
290         ANS_LOGI("consume callback unset");
291         return;
292     }
293 
294     if (request == nullptr) {
295         ANS_LOGE("request is null");
296         return;
297     }
298 
299     if (sortingMap == nullptr) {
300         ANS_LOGE("sortingMap is null");
301         return;
302     }
303     ANS_LOGI("OnConsumed Notification key = %{public}s, sortingMap size = %{public}zu",
304         request->GetKey().c_str(), sortingMap->GetKey().size());
305 
306     uv_loop_s *loop = nullptr;
307     napi_get_uv_event_loop(consumeCallbackInfo_.env, &loop);
308     if (loop == nullptr) {
309         ANS_LOGE("loop instance is nullptr");
310         return;
311     }
312 
313     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
314     if (dataWorker == nullptr) {
315         ANS_LOGE("new dataWorker failed");
316         return;
317     }
318 
319     dataWorker->request = request;
320     dataWorker->sortingMap = sortingMap;
321     dataWorker->env = consumeCallbackInfo_.env;
322     dataWorker->ref = consumeCallbackInfo_.ref;
323 
324     uv_work_t *work = new (std::nothrow) uv_work_t;
325     if (work == nullptr) {
326         ANS_LOGE("new work failed");
327         delete dataWorker;
328         dataWorker = nullptr;
329         return;
330     }
331 
332     work->data = (void *)dataWorker;
333 
334     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnConsumed);
335     if (ret != 0) {
336         delete dataWorker;
337         dataWorker = nullptr;
338         delete work;
339         work = nullptr;
340     }
341 }
342 
UvQueueWorkOnUpdate(uv_work_t * work,int status)343 void UvQueueWorkOnUpdate(uv_work_t *work, int status)
344 {
345     ANS_LOGI("OnUpdate uv_work_t start");
346 
347     if (work == nullptr) {
348         ANS_LOGE("work is null");
349         return;
350     }
351 
352     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
353     if (dataWorkerData == nullptr) {
354         ANS_LOGE("dataWorkerData is null");
355         delete work;
356         work = nullptr;
357         return;
358     }
359     napi_value result = nullptr;
360     napi_create_object(dataWorkerData->env, &result);
361     if (!Common::SetNotificationSortingMap(dataWorkerData->env, dataWorkerData->sortingMap, result)) {
362         ANS_LOGE("Failed to convert data to JS");
363     } else {
364         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
365     }
366 
367     delete dataWorkerData;
368     dataWorkerData = nullptr;
369     delete work;
370     work = nullptr;
371 }
372 
OnUpdate(const std::shared_ptr<NotificationSortingMap> & sortingMap)373 void SubscriberInstance::OnUpdate(const std::shared_ptr<NotificationSortingMap> &sortingMap)
374 {
375     ANS_LOGI("enter");
376 
377     if (updateCallbackInfo_.ref == nullptr) {
378         ANS_LOGI("update callback unset");
379         return;
380     }
381 
382     if (sortingMap == nullptr) {
383         ANS_LOGE("sortingMap is null");
384         return;
385     }
386     ANS_LOGI("OnUpdate sortingMap size = %{public}zu", sortingMap->GetKey().size());
387 
388     uv_loop_s *loop = nullptr;
389     napi_get_uv_event_loop(updateCallbackInfo_.env, &loop);
390     if (loop == nullptr) {
391         ANS_LOGE("loop instance is nullptr");
392         return;
393     }
394 
395     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
396     if (dataWorker == nullptr) {
397         ANS_LOGE("new dataWorker failed");
398         return;
399     }
400 
401     dataWorker->sortingMap = sortingMap;
402     dataWorker->env = updateCallbackInfo_.env;
403     dataWorker->ref = updateCallbackInfo_.ref;
404 
405     uv_work_t *work = new (std::nothrow) uv_work_t;
406     if (work == nullptr) {
407         ANS_LOGE("new work failed");
408         delete dataWorker;
409         dataWorker = nullptr;
410         return;
411     }
412 
413     work->data = (void *)dataWorker;
414 
415     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnUpdate);
416     if (ret != 0) {
417         delete dataWorker;
418         dataWorker = nullptr;
419         delete work;
420         work = nullptr;
421     }
422 }
423 
UvQueueWorkOnConnected(uv_work_t * work,int status)424 void UvQueueWorkOnConnected(uv_work_t *work, int status)
425 {
426     ANS_LOGI("OnConnected uv_work_t start");
427 
428     if (work == nullptr) {
429         ANS_LOGE("work is null");
430         return;
431     }
432 
433     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
434     if (dataWorkerData == nullptr) {
435         ANS_LOGE("dataWorkerData is null");
436         delete work;
437         work = nullptr;
438         return;
439     }
440 
441     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
442 
443     delete dataWorkerData;
444     dataWorkerData = nullptr;
445     delete work;
446     work = nullptr;
447 }
448 
OnConnected()449 void SubscriberInstance::OnConnected()
450 {
451     ANS_LOGI("enter");
452 
453     if (subscribeCallbackInfo_.ref == nullptr) {
454         ANS_LOGI("subscribe callback unset");
455         return;
456     }
457 
458     uv_loop_s *loop = nullptr;
459     napi_get_uv_event_loop(subscribeCallbackInfo_.env, &loop);
460     if (loop == nullptr) {
461         ANS_LOGE("loop instance is nullptr");
462         return;
463     }
464 
465     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
466     if (dataWorker == nullptr) {
467         ANS_LOGE("new dataWorker failed");
468         return;
469     }
470 
471     dataWorker->env = subscribeCallbackInfo_.env;
472     dataWorker->ref = subscribeCallbackInfo_.ref;
473 
474     uv_work_t *work = new (std::nothrow) uv_work_t;
475     if (work == nullptr) {
476         ANS_LOGE("new work failed");
477         delete dataWorker;
478         dataWorker = nullptr;
479         return;
480     }
481 
482     work->data = (void *)dataWorker;
483 
484     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnConnected);
485     if (ret != 0) {
486         delete dataWorker;
487         dataWorker = nullptr;
488         delete work;
489         work = nullptr;
490     }
491 }
492 
UvQueueWorkOnDisconnected(uv_work_t * work,int status)493 void UvQueueWorkOnDisconnected(uv_work_t *work, int status)
494 {
495     ANS_LOGI("OnDisconnected uv_work_t start");
496 
497     if (work == nullptr) {
498         ANS_LOGE("work is null");
499         return;
500     }
501 
502     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
503     if (dataWorkerData == nullptr) {
504         ANS_LOGE("dataWorkerData is null");
505         delete work;
506         work = nullptr;
507         return;
508     }
509 
510     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
511 
512     DelSubscriberInstancesInfo(dataWorkerData->env, dataWorkerData->subscriber);
513 
514     delete dataWorkerData;
515     dataWorkerData = nullptr;
516     delete work;
517     work = nullptr;
518 }
519 
OnDisconnected()520 void SubscriberInstance::OnDisconnected()
521 {
522     ANS_LOGI("enter");
523 
524     if (unsubscribeCallbackInfo_.ref == nullptr) {
525         ANS_LOGI("unsubscribe callback unset");
526         return;
527     }
528 
529     uv_loop_s *loop = nullptr;
530     napi_get_uv_event_loop(unsubscribeCallbackInfo_.env, &loop);
531     if (loop == nullptr) {
532         ANS_LOGE("loop instance is nullptr");
533         return;
534     }
535 
536     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
537     if (dataWorker == nullptr) {
538         ANS_LOGE("new dataWorker failed");
539         return;
540     }
541 
542     dataWorker->env = unsubscribeCallbackInfo_.env;
543     dataWorker->ref = unsubscribeCallbackInfo_.ref;
544     dataWorker->subscriber = this;
545 
546     uv_work_t *work = new (std::nothrow) uv_work_t;
547     if (work == nullptr) {
548         ANS_LOGE("new work failed");
549         delete dataWorker;
550         dataWorker = nullptr;
551         return;
552     }
553 
554     work->data = (void *)dataWorker;
555 
556     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnDisconnected);
557     if (ret != 0) {
558         delete dataWorker;
559         dataWorker = nullptr;
560         delete work;
561         work = nullptr;
562     }
563 }
564 
UvQueueWorkOnDied(uv_work_t * work,int status)565 void UvQueueWorkOnDied(uv_work_t *work, int status)
566 {
567     ANS_LOGI("OnDied uv_work_t start");
568 
569     if (work == nullptr) {
570         ANS_LOGE("work is null");
571         return;
572     }
573 
574     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
575     if (dataWorkerData == nullptr) {
576         ANS_LOGE("dataWorkerData is null");
577         delete work;
578         work = nullptr;
579         return;
580     }
581 
582     Common::SetCallback(
583         dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
584 
585     delete dataWorkerData;
586     dataWorkerData = nullptr;
587     delete work;
588     work = nullptr;
589 }
590 
OnDied()591 void SubscriberInstance::OnDied()
592 {
593     ANS_LOGI("enter");
594 
595     if (dieCallbackInfo_.ref == nullptr) {
596         ANS_LOGE("die callback unset");
597         return;
598     }
599 
600     uv_loop_s *loop = nullptr;
601     napi_get_uv_event_loop(dieCallbackInfo_.env, &loop);
602     if (loop == nullptr) {
603         ANS_LOGE("loop instance is nullptr");
604         return;
605     }
606 
607     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
608     if (dataWorker == nullptr) {
609         ANS_LOGE("new dataWorker failed");
610         return;
611     }
612 
613     dataWorker->env = dieCallbackInfo_.env;
614     dataWorker->ref = dieCallbackInfo_.ref;
615 
616     uv_work_t *work = new (std::nothrow) uv_work_t;
617     if (work == nullptr) {
618         ANS_LOGE("new work failed");
619         delete dataWorker;
620         dataWorker = nullptr;
621         return;
622     }
623 
624     work->data = (void *)dataWorker;
625 
626     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnDied);
627     if (ret != 0) {
628         delete dataWorker;
629         dataWorker = nullptr;
630         delete work;
631         work = nullptr;
632     }
633 }
634 
UvQueueWorkOnDoNotDisturbDateChange(uv_work_t * work,int status)635 void UvQueueWorkOnDoNotDisturbDateChange(uv_work_t *work, int status)
636 {
637     ANS_LOGI("OnDoNotDisturbDateChange uv_work_t start");
638 
639     if (work == nullptr) {
640         ANS_LOGE("work is null");
641         return;
642     }
643 
644     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
645     if (dataWorkerData == nullptr) {
646         ANS_LOGE("dataWorkerData is null");
647         delete work;
648         work = nullptr;
649         return;
650     }
651 
652     napi_value result = nullptr;
653     napi_create_object(dataWorkerData->env, &result);
654 
655     if (!Common::SetDoNotDisturbDate(dataWorkerData->env, dataWorkerData->date, result)) {
656         result = Common::NapiGetNull(dataWorkerData->env);
657     }
658 
659     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
660 
661     delete dataWorkerData;
662     dataWorkerData = nullptr;
663     delete work;
664     work = nullptr;
665 }
666 
OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> & date)667 void SubscriberInstance::OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> &date)
668 {
669     ANS_LOGI("enter");
670 
671     if (disturbDateCallbackInfo_.ref == nullptr) {
672         ANS_LOGI("disturbDateCallbackInfo_ callback unset");
673         return;
674     }
675 
676     if (date == nullptr) {
677         ANS_LOGE("date is null");
678         return;
679     }
680 
681     uv_loop_s *loop = nullptr;
682     napi_get_uv_event_loop(disturbDateCallbackInfo_.env, &loop);
683     if (loop == nullptr) {
684         ANS_LOGE("loop instance is nullptr");
685         return;
686     }
687 
688     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
689     if (dataWorker == nullptr) {
690         ANS_LOGE("new dataWorker failed");
691         return;
692     }
693 
694     dataWorker->date = *date;
695     dataWorker->env = disturbDateCallbackInfo_.env;
696     dataWorker->ref = disturbDateCallbackInfo_.ref;
697 
698     uv_work_t *work = new (std::nothrow) uv_work_t;
699     if (work == nullptr) {
700         ANS_LOGE("new work failed");
701         delete dataWorker;
702         dataWorker = nullptr;
703         return;
704     }
705 
706     work->data = (void *)dataWorker;
707 
708     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnDoNotDisturbDateChange);
709     if (ret != 0) {
710         delete dataWorker;
711         dataWorker = nullptr;
712         delete work;
713         work = nullptr;
714     }
715 }
716 
UvQueueWorkOnEnabledNotificationChanged(uv_work_t * work,int status)717 void UvQueueWorkOnEnabledNotificationChanged(uv_work_t *work, int status)
718 {
719     ANS_LOGI("OnEnabledNotificationChanged uv_work_t start");
720 
721     if (work == nullptr) {
722         ANS_LOGE("work is null");
723         return;
724     }
725 
726     NotificationReceiveDataWorker *dataWorkerData = (NotificationReceiveDataWorker *)work->data;
727     if (dataWorkerData == nullptr) {
728         ANS_LOGE("dataWorkerData is null");
729         delete work;
730         work = nullptr;
731         return;
732     }
733 
734     napi_value result = nullptr;
735     napi_create_object(dataWorkerData->env, &result);
736 
737     if (!Common::SetEnabledNotificationCallbackData(dataWorkerData->env, dataWorkerData->callbackData, result)) {
738         result = Common::NapiGetNull(dataWorkerData->env);
739     }
740 
741     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
742 
743     delete dataWorkerData;
744     dataWorkerData = nullptr;
745     delete work;
746     work = nullptr;
747 }
748 
OnEnabledNotificationChanged(const std::shared_ptr<EnabledNotificationCallbackData> & callbackData)749 void SubscriberInstance::OnEnabledNotificationChanged(
750     const std::shared_ptr<EnabledNotificationCallbackData> &callbackData)
751 {
752     ANS_LOGI("enter");
753 
754     if (enabledNotificationCallbackInfo_.ref == nullptr) {
755         ANS_LOGI("enabledNotificationCallbackInfo_ callback unset");
756         return;
757     }
758 
759     if (callbackData == nullptr) {
760         ANS_LOGE("callbackData is null");
761         return;
762     }
763 
764     uv_loop_s *loop = nullptr;
765     napi_get_uv_event_loop(enabledNotificationCallbackInfo_.env, &loop);
766     if (loop == nullptr) {
767         ANS_LOGE("loop instance is nullptr");
768         return;
769     }
770 
771     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
772     if (dataWorker == nullptr) {
773         ANS_LOGE("new dataWorker failed");
774         return;
775     }
776 
777     dataWorker->callbackData = *callbackData;
778     dataWorker->env = enabledNotificationCallbackInfo_.env;
779     dataWorker->ref = enabledNotificationCallbackInfo_.ref;
780 
781     uv_work_t *work = new (std::nothrow) uv_work_t;
782     if (work == nullptr) {
783         ANS_LOGE("new work failed");
784         delete dataWorker;
785         dataWorker = nullptr;
786         return;
787     }
788 
789     work->data = (void *)dataWorker;
790 
791     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnEnabledNotificationChanged);
792     if (ret != 0) {
793         delete dataWorker;
794         dataWorker = nullptr;
795         delete work;
796         work = nullptr;
797     }
798 }
799 
SetCancelCallbackInfo(const napi_env & env,const napi_ref & ref)800 void SubscriberInstance::SetCancelCallbackInfo(const napi_env &env, const napi_ref &ref)
801 {
802     canceCallbackInfo_.env = env;
803     canceCallbackInfo_.ref = ref;
804 }
805 
SetConsumeCallbackInfo(const napi_env & env,const napi_ref & ref)806 void SubscriberInstance::SetConsumeCallbackInfo(const napi_env &env, const napi_ref &ref)
807 {
808     consumeCallbackInfo_.env = env;
809     consumeCallbackInfo_.ref = ref;
810 }
811 
SetUpdateCallbackInfo(const napi_env & env,const napi_ref & ref)812 void SubscriberInstance::SetUpdateCallbackInfo(const napi_env &env, const napi_ref &ref)
813 {
814     updateCallbackInfo_.env = env;
815     updateCallbackInfo_.ref = ref;
816 }
817 
SetSubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)818 void SubscriberInstance::SetSubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
819 {
820     subscribeCallbackInfo_.env = env;
821     subscribeCallbackInfo_.ref = ref;
822 }
823 
SetUnsubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)824 void SubscriberInstance::SetUnsubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
825 {
826     unsubscribeCallbackInfo_.env = env;
827     unsubscribeCallbackInfo_.ref = ref;
828 }
829 
SetDieCallbackInfo(const napi_env & env,const napi_ref & ref)830 void SubscriberInstance::SetDieCallbackInfo(const napi_env &env, const napi_ref &ref)
831 {
832     dieCallbackInfo_.env = env;
833     dieCallbackInfo_.ref = ref;
834 }
835 
SetDisturbModeCallbackInfo(const napi_env & env,const napi_ref & ref)836 void SubscriberInstance::SetDisturbModeCallbackInfo(const napi_env &env, const napi_ref &ref)
837 {
838     disturbModeCallbackInfo_.env = env;
839     disturbModeCallbackInfo_.ref = ref;
840 }
841 
SetEnabledNotificationCallbackInfo(const napi_env & env,const napi_ref & ref)842 void SubscriberInstance::SetEnabledNotificationCallbackInfo(const napi_env &env, const napi_ref &ref)
843 {
844     enabledNotificationCallbackInfo_.env = env;
845     enabledNotificationCallbackInfo_.ref = ref;
846 }
847 
SetDisturbDateCallbackInfo(const napi_env & env,const napi_ref & ref)848 void SubscriberInstance::SetDisturbDateCallbackInfo(const napi_env &env, const napi_ref &ref)
849 {
850     disturbDateCallbackInfo_.env = env;
851     disturbDateCallbackInfo_.ref = ref;
852 }
853 
SetCallbackInfo(const napi_env & env,const std::string & type,const napi_ref & ref)854 void SubscriberInstance::SetCallbackInfo(const napi_env &env, const std::string &type, const napi_ref &ref)
855 {
856     if (type == CONSUME) {
857         SetConsumeCallbackInfo(env, ref);
858     } else if (type == CANCEL) {
859         SetCancelCallbackInfo(env, ref);
860     } else if (type == UPDATE) {
861         SetUpdateCallbackInfo(env, ref);
862     } else if (type == CONNECTED) {
863         SetSubscribeCallbackInfo(env, ref);
864     } else if (type == DIS_CONNECTED) {
865         SetUnsubscribeCallbackInfo(env, ref);
866     } else if (type == DIE) {
867         SetDieCallbackInfo(env, ref);
868     } else if (type == DISTURB_MODE_CHANGE) {
869         SetDisturbModeCallbackInfo(env, ref);
870     } else if (type == DISTURB_DATE_CHANGE) {
871         SetDisturbDateCallbackInfo(env, ref);
872     } else if (type == ENABLE_NOTIFICATION_CHANGED) {
873         SetEnabledNotificationCallbackInfo(env, ref);
874     } else {
875         ANS_LOGW("type is error");
876     }
877 }
878 
879 struct AsyncCallbackInfoSubscribe {
880     napi_env env = nullptr;
881     napi_async_work asyncWork = nullptr;
882     SubscriberInstance *objectInfo = nullptr;
883     NotificationSubscribeInfo subscriberInfo;
884     CallbackPromiseInfo info;
885 };
886 
HasNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)887 bool HasNotificationSubscriber(const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
888 {
889     std::lock_guard<std::mutex> lock(mutex_);
890     for (auto vec : subscriberInstances_) {
891         napi_value callback = nullptr;
892         napi_get_reference_value(env, vec.ref, &callback);
893         bool isEquals = false;
894         napi_strict_equals(env, value, callback, &isEquals);
895         if (isEquals) {
896             subscriberInfo = vec;
897             return true;
898         }
899     }
900     return false;
901 }
902 
GetNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)903 napi_value GetNotificationSubscriber(
904     const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
905 {
906     ANS_LOGI("enter");
907     bool hasProperty = false;
908     napi_valuetype valuetype = napi_undefined;
909     napi_ref result = nullptr;
910 
911     subscriberInfo.subscriber = new (std::nothrow) SubscriberInstance();
912     if (subscriberInfo.subscriber == nullptr) {
913         ANS_LOGE("subscriber is null");
914         return nullptr;
915     }
916 
917     napi_create_reference(env, value, 1, &subscriberInfo.ref);
918 
919     // onConsume?:(data: SubscribeCallbackData) => void
920     NAPI_CALL(env, napi_has_named_property(env, value, "onConsume", &hasProperty));
921     if (hasProperty) {
922         napi_value nOnConsumed = nullptr;
923         napi_get_named_property(env, value, "onConsume", &nOnConsumed);
924         NAPI_CALL(env, napi_typeof(env, nOnConsumed, &valuetype));
925         if (valuetype != napi_function) {
926             ANS_LOGE("Wrong argument type. Function expected.");
927             return nullptr;
928         }
929         napi_create_reference(env, nOnConsumed, 1, &result);
930         subscriberInfo.subscriber->SetCallbackInfo(env, CONSUME, result);
931     }
932     // onCancel?:(data: SubscribeCallbackData) => void
933     NAPI_CALL(env, napi_has_named_property(env, value, "onCancel", &hasProperty));
934     if (hasProperty) {
935         napi_value nOnCanceled = nullptr;
936         napi_get_named_property(env, value, "onCancel", &nOnCanceled);
937         NAPI_CALL(env, napi_typeof(env, nOnCanceled, &valuetype));
938         if (valuetype != napi_function) {
939             ANS_LOGE("Wrong argument type. Function expected.");
940             return nullptr;
941         }
942         napi_create_reference(env, nOnCanceled, 1, &result);
943         subscriberInfo.subscriber->SetCallbackInfo(env, CANCEL, result);
944     }
945     // onUpdate?:(data: NotificationSortingMap) => void
946     NAPI_CALL(env, napi_has_named_property(env, value, "onUpdate", &hasProperty));
947     if (hasProperty) {
948         napi_value nOnUpdate = nullptr;
949         napi_get_named_property(env, value, "onUpdate", &nOnUpdate);
950         NAPI_CALL(env, napi_typeof(env, nOnUpdate, &valuetype));
951         if (valuetype != napi_function) {
952             ANS_LOGE("Wrong argument type. Function expected.");
953             return nullptr;
954         }
955         napi_create_reference(env, nOnUpdate, 1, &result);
956         subscriberInfo.subscriber->SetCallbackInfo(env, UPDATE, result);
957     }
958     // onConnect?:() => void
959     NAPI_CALL(env, napi_has_named_property(env, value, "onConnect", &hasProperty));
960     if (hasProperty) {
961         napi_value nOnConnected = nullptr;
962         napi_get_named_property(env, value, "onConnect", &nOnConnected);
963         NAPI_CALL(env, napi_typeof(env, nOnConnected, &valuetype));
964         if (valuetype != napi_function) {
965             ANS_LOGE("Wrong argument type. Function expected.");
966             return nullptr;
967         }
968         napi_create_reference(env, nOnConnected, 1, &result);
969         subscriberInfo.subscriber->SetCallbackInfo(env, CONNECTED, result);
970     }
971     // onDisconnect?:() => void
972     NAPI_CALL(env, napi_has_named_property(env, value, "onDisconnect", &hasProperty));
973     if (hasProperty) {
974         napi_value nOnDisConnect = nullptr;
975         napi_get_named_property(env, value, "onDisconnect", &nOnDisConnect);
976         NAPI_CALL(env, napi_typeof(env, nOnDisConnect, &valuetype));
977         if (valuetype != napi_function) {
978             ANS_LOGE("Wrong argument type. Function expected.");
979             return nullptr;
980         }
981         napi_create_reference(env, nOnDisConnect, 1, &result);
982         subscriberInfo.subscriber->SetCallbackInfo(env, DIS_CONNECTED, result);
983     }
984     // onDestroy?:() => void
985     NAPI_CALL(env, napi_has_named_property(env, value, "onDestroy", &hasProperty));
986     if (hasProperty) {
987         napi_value nOnDied = nullptr;
988         napi_get_named_property(env, value, "onDestroy", &nOnDied);
989         NAPI_CALL(env, napi_typeof(env, nOnDied, &valuetype));
990         if (valuetype != napi_function) {
991             ANS_LOGE("Wrong argument type. Function expected.");
992             return nullptr;
993         }
994         napi_create_reference(env, nOnDied, 1, &result);
995         subscriberInfo.subscriber->SetCallbackInfo(env, DIE, result);
996     }
997     // onDisturbModeChange?:(mode: notification.DoNotDisturbMode) => void
998     NAPI_CALL(env, napi_has_named_property(env, value, "onDisturbModeChange", &hasProperty));
999     if (hasProperty) {
1000         napi_value nOnDisturbModeChanged = nullptr;
1001         napi_get_named_property(env, value, "onDisturbModeChange", &nOnDisturbModeChanged);
1002         NAPI_CALL(env, napi_typeof(env, nOnDisturbModeChanged, &valuetype));
1003         if (valuetype != napi_function) {
1004             ANS_LOGE("Wrong argument type. Function expected.");
1005             return nullptr;
1006         }
1007         napi_create_reference(env, nOnDisturbModeChanged, 1, &result);
1008         subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_MODE_CHANGE, result);
1009     }
1010 
1011     // onDoNotDisturbDateChange?:(mode: notification.DoNotDisturbDate) => void
1012     NAPI_CALL(env, napi_has_named_property(env, value, "onDoNotDisturbDateChange", &hasProperty));
1013     if (hasProperty) {
1014         napi_value nOnDisturbDateChanged = nullptr;
1015         napi_get_named_property(env, value, "onDoNotDisturbDateChange", &nOnDisturbDateChanged);
1016         NAPI_CALL(env, napi_typeof(env, nOnDisturbDateChanged, &valuetype));
1017         if (valuetype != napi_function) {
1018             ANS_LOGE("Wrong argument type. Function expected.");
1019             return nullptr;
1020         }
1021         napi_create_reference(env, nOnDisturbDateChanged, 1, &result);
1022         subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_DATE_CHANGE, result);
1023     }
1024 
1025     // onEnabledNotificationChanged?:(data: notification.EnabledNotificationCallbackData) => void
1026     NAPI_CALL(env, napi_has_named_property(env, value, "onEnabledNotificationChanged", &hasProperty));
1027     if (hasProperty) {
1028         napi_value nOnEnabledNotificationChanged = nullptr;
1029         napi_get_named_property(env, value, "onEnabledNotificationChanged", &nOnEnabledNotificationChanged);
1030         NAPI_CALL(env, napi_typeof(env, nOnEnabledNotificationChanged, &valuetype));
1031         if (valuetype != napi_function) {
1032             ANS_LOGE("Wrong argument type. Function expected.");
1033             return nullptr;
1034         }
1035         napi_create_reference(env, nOnEnabledNotificationChanged, 1, &result);
1036         subscriberInfo.subscriber->SetCallbackInfo(env, ENABLE_NOTIFICATION_CHANGED, result);
1037     }
1038 
1039     return Common::NapiGetNull(env);
1040 }
1041 
AddSubscriberInstancesInfo(const napi_env & env,const SubscriberInstancesInfo & subscriberInfo)1042 bool AddSubscriberInstancesInfo(const napi_env &env, const SubscriberInstancesInfo &subscriberInfo)
1043 {
1044     ANS_LOGI("enter");
1045     if (subscriberInfo.ref == nullptr) {
1046         ANS_LOGE("subscriberInfo.ref is null");
1047         return false;
1048     }
1049     if (subscriberInfo.subscriber == nullptr) {
1050         ANS_LOGE("subscriberInfo.subscriber is null");
1051         return false;
1052     }
1053     std::lock_guard<std::mutex> lock(mutex_);
1054     subscriberInstances_.emplace_back(subscriberInfo);
1055 
1056     return true;
1057 }
1058 
DelSubscriberInstancesInfo(const napi_env & env,SubscriberInstance * subscriber)1059 bool DelSubscriberInstancesInfo(const napi_env &env, SubscriberInstance *subscriber)
1060 {
1061     ANS_LOGI("enter");
1062     if (subscriber == nullptr) {
1063         ANS_LOGE("subscriber is null");
1064         return false;
1065     }
1066 
1067     std::lock_guard<std::mutex> lock(mutex_);
1068     for (auto it = subscriberInstances_.begin(); it != subscriberInstances_.end(); ++it) {
1069         if ((*it).subscriber == subscriber) {
1070             if ((*it).ref != nullptr) {
1071                 napi_delete_reference(env, (*it).ref);
1072             }
1073             delete (*it).subscriber;
1074             (*it).subscriber = nullptr;
1075             subscriberInstances_.erase(it);
1076             return true;
1077         }
1078     }
1079     return false;
1080 }
ParseParameters(const napi_env & env,const napi_callback_info & info,NotificationSubscribeInfo & subscriberInfo,SubscriberInstance * & subscriber,napi_ref & callback)1081 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info,
1082     NotificationSubscribeInfo &subscriberInfo, SubscriberInstance *&subscriber, napi_ref &callback)
1083 {
1084     ANS_LOGI("enter");
1085 
1086     size_t argc = SUBSRIBE_MAX_PARA;
1087     napi_value argv[SUBSRIBE_MAX_PARA] = {nullptr};
1088     napi_value thisVar = nullptr;
1089     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
1090     if (argc < 1) {
1091         ANS_LOGE("Wrong number of arguments");
1092         return nullptr;
1093     }
1094 
1095     napi_valuetype valuetype = napi_undefined;
1096 
1097     // argv[0]:subscriber
1098     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
1099     if (valuetype != napi_object) {
1100         ANS_LOGE("Wrong argument type for arg0. NotificationSubscriber object expected.");
1101         return nullptr;
1102     }
1103 
1104     SubscriberInstancesInfo subscriberInstancesInfo;
1105     if (!HasNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo)) {
1106         if (GetNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo) == nullptr) {
1107             ANS_LOGE("NotificationSubscriber parse failed");
1108             if (subscriberInstancesInfo.subscriber) {
1109                 delete subscriberInstancesInfo.subscriber;
1110                 subscriberInstancesInfo.subscriber = nullptr;
1111             }
1112             return nullptr;
1113         }
1114         if (!AddSubscriberInstancesInfo(env, subscriberInstancesInfo)) {
1115             ANS_LOGE("AddSubscriberInstancesInfo add failed");
1116             if (subscriberInstancesInfo.subscriber) {
1117                 delete subscriberInstancesInfo.subscriber;
1118                 subscriberInstancesInfo.subscriber = nullptr;
1119             }
1120             return nullptr;
1121         }
1122     }
1123     subscriber = subscriberInstancesInfo.subscriber;
1124 
1125     // argv[1]:callback or NotificationSubscribeInfo
1126     if (argc >= SUBSRIBE_MAX_PARA - 1) {
1127         NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
1128         NAPI_ASSERT(env,
1129             (valuetype == napi_function) || (valuetype == napi_object),
1130             "Wrong argument type for arg1. Function or NotificationSubscribeInfo object expected.");
1131         if (valuetype == napi_function) {
1132             napi_create_reference(env, argv[PARAM1], 1, &callback);
1133         } else {
1134             if (Common::GetNotificationSubscriberInfo(env, argv[PARAM1], subscriberInfo) == nullptr) {
1135                 ANS_LOGE("NotificationSubscribeInfo parse failed");
1136                 return nullptr;
1137             }
1138         }
1139     }
1140 
1141     // argv[2]:callback
1142     if (argc >= SUBSRIBE_MAX_PARA) {
1143         NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
1144         if (valuetype != napi_function) {
1145             ANS_LOGE("Wrong argument type. Function expected.");
1146             return nullptr;
1147         }
1148         napi_create_reference(env, argv[PARAM2], 1, &callback);
1149     }
1150 
1151     return Common::NapiGetNull(env);
1152 }
1153 
Subscribe(napi_env env,napi_callback_info info)1154 napi_value Subscribe(napi_env env, napi_callback_info info)
1155 {
1156     ANS_LOGI("enter");
1157 
1158     napi_ref callback = nullptr;
1159     SubscriberInstance *objectInfo = nullptr;
1160     NotificationSubscribeInfo subscriberInfo;
1161     if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
1162         if (objectInfo) {
1163             delete objectInfo;
1164             objectInfo = nullptr;
1165         }
1166         return Common::NapiGetUndefined(env);
1167     }
1168     ANS_LOGI("Subscribe objectInfo = %{public}p", objectInfo);
1169 
1170     AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
1171         .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
1172     };
1173     if (!asynccallbackinfo) {
1174         if (objectInfo) {
1175             delete objectInfo;
1176             objectInfo = nullptr;
1177         }
1178         return Common::JSParaError(env, callback);
1179     }
1180     napi_value promise = nullptr;
1181     Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
1182 
1183     napi_value resourceName = nullptr;
1184     napi_create_string_latin1(env, "subscribeNotification", NAPI_AUTO_LENGTH, &resourceName);
1185     // Asynchronous function call
1186     napi_create_async_work(env,
1187         nullptr,
1188         resourceName,
1189         [](napi_env env, void *data) {
1190             ANS_LOGI("Subscribe napi_create_async_work start");
1191             if (!data) {
1192                 ANS_LOGE("Invalid asynccallbackinfo!");
1193                 return;
1194             }
1195             AsyncCallbackInfoSubscribe *asynccallbackinfo = (AsyncCallbackInfoSubscribe *)data;
1196             if (asynccallbackinfo->subscriberInfo.hasSubscribeInfo) {
1197                 ANS_LOGI("Subscribe with NotificationSubscribeInfo");
1198                 OHOS::Notification::NotificationSubscribeInfo subscribeInfo;
1199                 subscribeInfo.AddAppNames(asynccallbackinfo->subscriberInfo.bundleNames);
1200                 subscribeInfo.AddAppUserId(asynccallbackinfo->subscriberInfo.userId);
1201                 asynccallbackinfo->info.errorCode =
1202                     NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo), subscribeInfo);
1203             } else {
1204                 asynccallbackinfo->info.errorCode =
1205                     NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo));
1206             }
1207         },
1208         [](napi_env env, napi_status status, void *data) {
1209             ANS_LOGI("Subscribe napi_create_async_work end");
1210             if (!data) {
1211                 ANS_LOGE("Invalid asynccallbackinfo!");
1212                 return;
1213             }
1214             AsyncCallbackInfoSubscribe *asynccallbackinfo = (AsyncCallbackInfoSubscribe *)data;
1215             if (!asynccallbackinfo) {
1216                 ANS_LOGE("Invalid asynccallbackinfo!");
1217                 return;
1218             }
1219 
1220             Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
1221 
1222             if (asynccallbackinfo->info.callback != nullptr) {
1223                 napi_delete_reference(env, asynccallbackinfo->info.callback);
1224             }
1225             napi_delete_async_work(env, asynccallbackinfo->asyncWork);
1226 
1227             delete asynccallbackinfo;
1228             asynccallbackinfo = nullptr;
1229         },
1230         (void *)asynccallbackinfo,
1231         &asynccallbackinfo->asyncWork);
1232 
1233     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
1234 
1235     if (asynccallbackinfo->info.isCallback) {
1236         return Common::NapiGetNull(env);
1237     } else {
1238         return promise;
1239     }
1240 }
1241 }  // namespace NotificationNapi
1242 }  // namespace OHOS