• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "subscribe.h"
17 
18 #include <mutex>
19 #include <uv.h>
20 
21 namespace OHOS {
22 namespace NotificationNapi {
23 const int32_t SUBSRIBE_MAX_PARA = 3;
24 const int32_t 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     int32_t deleteReason = 0;
43     int32_t result = 0;
44     int32_t 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,int32_t 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, int32_t 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         int32_t 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     if (request->EnableVibrate()) {
105         uint32_t count = 0;
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 
UvQueueWorkOnCanceled(uv_work_t * work,int status)149 void UvQueueWorkOnCanceled(uv_work_t *work, int status)
150 {
151     ANS_LOGI("OnCanceled uv_work_t start");
152 
153     if (work == nullptr) {
154         ANS_LOGE("work is null");
155         return;
156     }
157 
158     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(work->data);
159     if (dataWorkerData == nullptr) {
160         ANS_LOGE("dataWorkerData is null");
161         delete work;
162         work = nullptr;
163         return;
164     }
165 
166     napi_value result = nullptr;
167     napi_handle_scope scope;
168     napi_open_handle_scope(dataWorkerData->env, &scope);
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     napi_close_handle_scope(dataWorkerData->env, scope);
180 
181     delete dataWorkerData;
182     dataWorkerData = nullptr;
183     delete work;
184 }
185 
OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap,int32_t deleteReason)186 void SubscriberInstance::OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> &request,
187     const std::shared_ptr<NotificationSortingMap> &sortingMap, int32_t 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 = reinterpret_cast<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     auto dataWorkerData = reinterpret_cast<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_handle_scope scope;
268     napi_open_handle_scope(dataWorkerData->env, &scope);
269     napi_create_object(dataWorkerData->env, &result);
270     if (!SetSubscribeCallbackData(dataWorkerData->env,
271         dataWorkerData->request,
272         dataWorkerData->sortingMap,
273         NO_DELETE_REASON,
274         result)) {
275         ANS_LOGE("Failed to convert data to JS");
276     } else {
277         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
278     }
279     napi_close_handle_scope(dataWorkerData->env, scope);
280 
281     delete dataWorkerData;
282     dataWorkerData = nullptr;
283     delete work;
284 }
285 
OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap)286 void SubscriberInstance::OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> &request,
287     const std::shared_ptr<NotificationSortingMap> &sortingMap)
288 {
289     ANS_LOGI("enter");
290 
291     if (consumeCallbackInfo_.ref == nullptr) {
292         ANS_LOGI("consume callback unset");
293         return;
294     }
295 
296     if (request == nullptr) {
297         ANS_LOGE("request is null");
298         return;
299     }
300 
301     if (sortingMap == nullptr) {
302         ANS_LOGE("sortingMap is null");
303         return;
304     }
305     ANS_LOGI("OnConsumed Notification key = %{public}s, sortingMap size = %{public}zu",
306         request->GetKey().c_str(), sortingMap->GetKey().size());
307 
308     uv_loop_s *loop = nullptr;
309     napi_get_uv_event_loop(consumeCallbackInfo_.env, &loop);
310     if (loop == nullptr) {
311         ANS_LOGE("loop instance is nullptr");
312         return;
313     }
314 
315     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
316     if (dataWorker == nullptr) {
317         ANS_LOGE("new dataWorker failed");
318         return;
319     }
320 
321     dataWorker->request = request;
322     dataWorker->sortingMap = sortingMap;
323     dataWorker->env = consumeCallbackInfo_.env;
324     dataWorker->ref = consumeCallbackInfo_.ref;
325 
326     uv_work_t *work = new (std::nothrow) uv_work_t;
327     if (work == nullptr) {
328         ANS_LOGE("new work failed");
329         delete dataWorker;
330         dataWorker = nullptr;
331         return;
332     }
333 
334     work->data = reinterpret_cast<void *>(dataWorker);
335 
336     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnConsumed);
337     if (ret != 0) {
338         delete dataWorker;
339         dataWorker = nullptr;
340         delete work;
341         work = nullptr;
342     }
343 }
344 
UvQueueWorkOnUpdate(uv_work_t * work,int status)345 void UvQueueWorkOnUpdate(uv_work_t *work, int status)
346 {
347     ANS_LOGI("OnUpdate uv_work_t start");
348 
349     if (work == nullptr) {
350         ANS_LOGE("work is null");
351         return;
352     }
353     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(work->data);
354     if (dataWorkerData == nullptr) {
355         ANS_LOGE("dataWorkerData is null");
356         delete work;
357         work = nullptr;
358         return;
359     }
360     napi_value result = nullptr;
361     napi_handle_scope scope;
362     napi_open_handle_scope(dataWorkerData->env, &scope);
363     napi_create_object(dataWorkerData->env, &result);
364     if (!Common::SetNotificationSortingMap(dataWorkerData->env, dataWorkerData->sortingMap, result)) {
365         ANS_LOGE("Failed to convert data to JS");
366     } else {
367         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
368     }
369     napi_close_handle_scope(dataWorkerData->env, scope);
370 
371     delete dataWorkerData;
372     dataWorkerData = nullptr;
373     delete work;
374 }
375 
OnUpdate(const std::shared_ptr<NotificationSortingMap> & sortingMap)376 void SubscriberInstance::OnUpdate(const std::shared_ptr<NotificationSortingMap> &sortingMap)
377 {
378     ANS_LOGI("enter");
379 
380     if (updateCallbackInfo_.ref == nullptr) {
381         ANS_LOGI("update callback unset");
382         return;
383     }
384 
385     if (sortingMap == nullptr) {
386         ANS_LOGE("sortingMap is null");
387         return;
388     }
389     ANS_LOGI("OnUpdate sortingMap size = %{public}zu", sortingMap->GetKey().size());
390 
391     uv_loop_s *loop = nullptr;
392     napi_get_uv_event_loop(updateCallbackInfo_.env, &loop);
393     if (loop == nullptr) {
394         ANS_LOGE("loop instance is nullptr");
395         return;
396     }
397 
398     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
399     if (dataWorker == nullptr) {
400         ANS_LOGE("new dataWorker failed");
401         return;
402     }
403 
404     dataWorker->sortingMap = sortingMap;
405     dataWorker->env = updateCallbackInfo_.env;
406     dataWorker->ref = updateCallbackInfo_.ref;
407 
408     uv_work_t *work = new (std::nothrow) uv_work_t;
409     if (work == nullptr) {
410         ANS_LOGE("new work failed");
411         delete dataWorker;
412         dataWorker = nullptr;
413         return;
414     }
415 
416     work->data = reinterpret_cast<void *>(dataWorker);
417 
418     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnUpdate);
419     if (ret != 0) {
420         delete dataWorker;
421         dataWorker = nullptr;
422         delete work;
423         work = nullptr;
424     }
425 }
426 
UvQueueWorkOnConnected(uv_work_t * work,int status)427 void UvQueueWorkOnConnected(uv_work_t *work, int status)
428 {
429     ANS_LOGI("OnConnected uv_work_t start");
430 
431     if (work == nullptr) {
432         ANS_LOGE("work is null");
433         return;
434     }
435 
436     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(work->data);
437     if (dataWorkerData == nullptr) {
438         ANS_LOGE("dataWorkerData is null");
439         delete work;
440         work = nullptr;
441         return;
442     }
443 
444     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
445 
446     delete dataWorkerData;
447     dataWorkerData = nullptr;
448     delete work;
449 }
450 
OnConnected()451 void SubscriberInstance::OnConnected()
452 {
453     ANS_LOGI("enter");
454 
455     if (subscribeCallbackInfo_.ref == nullptr) {
456         ANS_LOGI("subscribe callback unset");
457         return;
458     }
459 
460     uv_loop_s *loop = nullptr;
461     napi_get_uv_event_loop(subscribeCallbackInfo_.env, &loop);
462     if (loop == nullptr) {
463         ANS_LOGE("loop instance is nullptr");
464         return;
465     }
466 
467     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
468     if (dataWorker == nullptr) {
469         ANS_LOGE("new dataWorker failed");
470         return;
471     }
472 
473     dataWorker->env = subscribeCallbackInfo_.env;
474     dataWorker->ref = subscribeCallbackInfo_.ref;
475 
476     uv_work_t *work = new (std::nothrow) uv_work_t;
477     if (work == nullptr) {
478         ANS_LOGE("new work failed");
479         delete dataWorker;
480         dataWorker = nullptr;
481         return;
482     }
483 
484     work->data = reinterpret_cast<void *>(dataWorker);
485 
486     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnConnected);
487     if (ret != 0) {
488         delete dataWorker;
489         dataWorker = nullptr;
490         delete work;
491         work = nullptr;
492     }
493 }
494 
UvQueueWorkOnDisconnected(uv_work_t * work,int status)495 void UvQueueWorkOnDisconnected(uv_work_t *work, int status)
496 {
497     ANS_LOGI("OnDisconnected uv_work_t start");
498 
499     if (work == nullptr) {
500         ANS_LOGE("work is null");
501         return;
502     }
503 
504     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(work->data);
505     if (dataWorkerData == nullptr) {
506         ANS_LOGE("dataWorkerData is null");
507         delete work;
508         work = nullptr;
509         return;
510     }
511 
512     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
513 
514     DelSubscriberInstancesInfo(dataWorkerData->env, dataWorkerData->subscriber);
515 
516     delete dataWorkerData;
517     dataWorkerData = nullptr;
518     delete work;
519 }
520 
OnDisconnected()521 void SubscriberInstance::OnDisconnected()
522 {
523     ANS_LOGI("enter");
524 
525     if (unsubscribeCallbackInfo_.ref == nullptr) {
526         ANS_LOGI("unsubscribe callback unset");
527         return;
528     }
529 
530     uv_loop_s *loop = nullptr;
531     napi_get_uv_event_loop(unsubscribeCallbackInfo_.env, &loop);
532     if (loop == nullptr) {
533         ANS_LOGE("loop instance is nullptr");
534         return;
535     }
536 
537     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
538     if (dataWorker == nullptr) {
539         ANS_LOGE("new dataWorker failed");
540         return;
541     }
542 
543     dataWorker->env = unsubscribeCallbackInfo_.env;
544     dataWorker->ref = unsubscribeCallbackInfo_.ref;
545     dataWorker->subscriber = this;
546 
547     uv_work_t *work = new (std::nothrow) uv_work_t;
548     if (work == nullptr) {
549         ANS_LOGE("new work failed");
550         delete dataWorker;
551         dataWorker = nullptr;
552         return;
553     }
554 
555     work->data = reinterpret_cast<void *>(dataWorker);
556 
557     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnDisconnected);
558     if (ret != 0) {
559         delete dataWorker;
560         dataWorker = nullptr;
561         delete work;
562         work = nullptr;
563     }
564 }
565 
UvQueueWorkOnDied(uv_work_t * work,int status)566 void UvQueueWorkOnDied(uv_work_t *work, int status)
567 {
568     ANS_LOGI("OnDied uv_work_t start");
569 
570     if (work == nullptr) {
571         ANS_LOGE("work is null");
572         return;
573     }
574     auto dataWorkerData = reinterpret_cast<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 }
589 
OnDied()590 void SubscriberInstance::OnDied()
591 {
592     ANS_LOGI("enter");
593 
594     if (dieCallbackInfo_.ref == nullptr) {
595         ANS_LOGE("die callback unset");
596         return;
597     }
598 
599     uv_loop_s *loop = nullptr;
600     napi_get_uv_event_loop(dieCallbackInfo_.env, &loop);
601     if (loop == nullptr) {
602         ANS_LOGE("loop instance is nullptr");
603         return;
604     }
605 
606     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
607     if (dataWorker == nullptr) {
608         ANS_LOGE("new dataWorker failed");
609         return;
610     }
611 
612     dataWorker->env = dieCallbackInfo_.env;
613     dataWorker->ref = dieCallbackInfo_.ref;
614 
615     uv_work_t *work = new (std::nothrow) uv_work_t;
616     if (work == nullptr) {
617         ANS_LOGE("new work failed");
618         delete dataWorker;
619         dataWorker = nullptr;
620         return;
621     }
622 
623     work->data = reinterpret_cast<void *>(dataWorker);
624 
625     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnDied);
626     if (ret != 0) {
627         delete dataWorker;
628         dataWorker = nullptr;
629         delete work;
630         work = nullptr;
631     }
632 }
633 
UvQueueWorkOnDoNotDisturbDateChange(uv_work_t * work,int status)634 void UvQueueWorkOnDoNotDisturbDateChange(uv_work_t *work, int status)
635 {
636     ANS_LOGI("OnDoNotDisturbDateChange uv_work_t start");
637 
638     if (work == nullptr) {
639         ANS_LOGE("work is null");
640         return;
641     }
642 
643     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(work->data);
644     if (dataWorkerData == nullptr) {
645         ANS_LOGE("dataWorkerData is null");
646         delete work;
647         work = nullptr;
648         return;
649     }
650 
651     napi_value result = nullptr;
652     napi_handle_scope scope;
653     napi_open_handle_scope(dataWorkerData->env, &scope);
654     napi_create_object(dataWorkerData->env, &result);
655 
656     if (!Common::SetDoNotDisturbDate(dataWorkerData->env, dataWorkerData->date, result)) {
657         result = Common::NapiGetNull(dataWorkerData->env);
658     }
659 
660     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
661     napi_close_handle_scope(dataWorkerData->env, scope);
662 
663     delete dataWorkerData;
664     dataWorkerData = nullptr;
665     delete work;
666 }
667 
OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> & date)668 void SubscriberInstance::OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> &date)
669 {
670     ANS_LOGI("enter");
671 
672     if (disturbDateCallbackInfo_.ref == nullptr) {
673         ANS_LOGI("disturbDateCallbackInfo_ callback unset");
674         return;
675     }
676 
677     if (date == nullptr) {
678         ANS_LOGE("date is null");
679         return;
680     }
681 
682     uv_loop_s *loop = nullptr;
683     napi_get_uv_event_loop(disturbDateCallbackInfo_.env, &loop);
684     if (loop == nullptr) {
685         ANS_LOGE("loop instance is nullptr");
686         return;
687     }
688 
689     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
690     if (dataWorker == nullptr) {
691         ANS_LOGE("new dataWorker failed");
692         return;
693     }
694 
695     dataWorker->date = *date;
696     dataWorker->env = disturbDateCallbackInfo_.env;
697     dataWorker->ref = disturbDateCallbackInfo_.ref;
698 
699     uv_work_t *work = new (std::nothrow) uv_work_t;
700     if (work == nullptr) {
701         ANS_LOGE("new work failed");
702         delete dataWorker;
703         dataWorker = nullptr;
704         return;
705     }
706 
707     work->data = reinterpret_cast<void *>(dataWorker);
708 
709     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnDoNotDisturbDateChange);
710     if (ret != 0) {
711         delete dataWorker;
712         dataWorker = nullptr;
713         delete work;
714         work = nullptr;
715     }
716 }
717 
UvQueueWorkOnEnabledNotificationChanged(uv_work_t * work,int status)718 void UvQueueWorkOnEnabledNotificationChanged(uv_work_t *work, int status)
719 {
720     ANS_LOGI("OnEnabledNotificationChanged uv_work_t start");
721 
722     if (work == nullptr) {
723         ANS_LOGE("work is null");
724         return;
725     }
726 
727     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(work->data);
728     if (dataWorkerData == nullptr) {
729         ANS_LOGE("dataWorkerData is null");
730         delete work;
731         work = nullptr;
732         return;
733     }
734 
735     napi_value result = nullptr;
736     napi_handle_scope scope;
737     napi_open_handle_scope(dataWorkerData->env, &scope);
738     napi_create_object(dataWorkerData->env, &result);
739 
740     if (!Common::SetEnabledNotificationCallbackData(dataWorkerData->env, dataWorkerData->callbackData, result)) {
741         result = Common::NapiGetNull(dataWorkerData->env);
742     }
743 
744     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
745     napi_close_handle_scope(dataWorkerData->env, scope);
746 
747     delete dataWorkerData;
748     dataWorkerData = nullptr;
749     delete work;
750 }
751 
OnEnabledNotificationChanged(const std::shared_ptr<EnabledNotificationCallbackData> & callbackData)752 void SubscriberInstance::OnEnabledNotificationChanged(
753     const std::shared_ptr<EnabledNotificationCallbackData> &callbackData)
754 {
755     ANS_LOGI("enter");
756 
757     if (enabledNotificationCallbackInfo_.ref == nullptr) {
758         ANS_LOGI("enabledNotificationCallbackInfo_ callback unset");
759         return;
760     }
761 
762     if (callbackData == nullptr) {
763         ANS_LOGE("callbackData is null");
764         return;
765     }
766 
767     uv_loop_s *loop = nullptr;
768     napi_get_uv_event_loop(enabledNotificationCallbackInfo_.env, &loop);
769     if (loop == nullptr) {
770         ANS_LOGE("loop instance is nullptr");
771         return;
772     }
773 
774     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
775     if (dataWorker == nullptr) {
776         ANS_LOGE("new dataWorker failed");
777         return;
778     }
779 
780     dataWorker->callbackData = *callbackData;
781     dataWorker->env = enabledNotificationCallbackInfo_.env;
782     dataWorker->ref = enabledNotificationCallbackInfo_.ref;
783 
784     uv_work_t *work = new (std::nothrow) uv_work_t;
785     if (work == nullptr) {
786         ANS_LOGE("new work failed");
787         delete dataWorker;
788         dataWorker = nullptr;
789         return;
790     }
791 
792     work->data = reinterpret_cast<void *>(dataWorker);
793 
794     int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnEnabledNotificationChanged);
795     if (ret != 0) {
796         delete dataWorker;
797         dataWorker = nullptr;
798         delete work;
799         work = nullptr;
800     }
801 }
802 
SetCancelCallbackInfo(const napi_env & env,const napi_ref & ref)803 void SubscriberInstance::SetCancelCallbackInfo(const napi_env &env, const napi_ref &ref)
804 {
805     canceCallbackInfo_.env = env;
806     canceCallbackInfo_.ref = ref;
807 }
808 
SetConsumeCallbackInfo(const napi_env & env,const napi_ref & ref)809 void SubscriberInstance::SetConsumeCallbackInfo(const napi_env &env, const napi_ref &ref)
810 {
811     consumeCallbackInfo_.env = env;
812     consumeCallbackInfo_.ref = ref;
813 }
814 
SetUpdateCallbackInfo(const napi_env & env,const napi_ref & ref)815 void SubscriberInstance::SetUpdateCallbackInfo(const napi_env &env, const napi_ref &ref)
816 {
817     updateCallbackInfo_.env = env;
818     updateCallbackInfo_.ref = ref;
819 }
820 
SetSubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)821 void SubscriberInstance::SetSubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
822 {
823     subscribeCallbackInfo_.env = env;
824     subscribeCallbackInfo_.ref = ref;
825 }
826 
SetUnsubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)827 void SubscriberInstance::SetUnsubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
828 {
829     unsubscribeCallbackInfo_.env = env;
830     unsubscribeCallbackInfo_.ref = ref;
831 }
832 
SetDieCallbackInfo(const napi_env & env,const napi_ref & ref)833 void SubscriberInstance::SetDieCallbackInfo(const napi_env &env, const napi_ref &ref)
834 {
835     dieCallbackInfo_.env = env;
836     dieCallbackInfo_.ref = ref;
837 }
838 
SetDisturbModeCallbackInfo(const napi_env & env,const napi_ref & ref)839 void SubscriberInstance::SetDisturbModeCallbackInfo(const napi_env &env, const napi_ref &ref)
840 {
841     disturbModeCallbackInfo_.env = env;
842     disturbModeCallbackInfo_.ref = ref;
843 }
844 
SetEnabledNotificationCallbackInfo(const napi_env & env,const napi_ref & ref)845 void SubscriberInstance::SetEnabledNotificationCallbackInfo(const napi_env &env, const napi_ref &ref)
846 {
847     enabledNotificationCallbackInfo_.env = env;
848     enabledNotificationCallbackInfo_.ref = ref;
849 }
850 
SetDisturbDateCallbackInfo(const napi_env & env,const napi_ref & ref)851 void SubscriberInstance::SetDisturbDateCallbackInfo(const napi_env &env, const napi_ref &ref)
852 {
853     disturbDateCallbackInfo_.env = env;
854     disturbDateCallbackInfo_.ref = ref;
855 }
856 
SetCallbackInfo(const napi_env & env,const std::string & type,const napi_ref & ref)857 void SubscriberInstance::SetCallbackInfo(const napi_env &env, const std::string &type, const napi_ref &ref)
858 {
859     if (type == CONSUME) {
860         SetConsumeCallbackInfo(env, ref);
861     } else if (type == CANCEL) {
862         SetCancelCallbackInfo(env, ref);
863     } else if (type == UPDATE) {
864         SetUpdateCallbackInfo(env, ref);
865     } else if (type == CONNECTED) {
866         SetSubscribeCallbackInfo(env, ref);
867     } else if (type == DIS_CONNECTED) {
868         SetUnsubscribeCallbackInfo(env, ref);
869     } else if (type == DIE) {
870         SetDieCallbackInfo(env, ref);
871     } else if (type == DISTURB_MODE_CHANGE) {
872         SetDisturbModeCallbackInfo(env, ref);
873     } else if (type == DISTURB_DATE_CHANGE) {
874         SetDisturbDateCallbackInfo(env, ref);
875     } else if (type == ENABLE_NOTIFICATION_CHANGED) {
876         SetEnabledNotificationCallbackInfo(env, ref);
877     } else {
878         ANS_LOGW("type is error");
879     }
880 }
881 
HasNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)882 bool HasNotificationSubscriber(const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
883 {
884     std::lock_guard<std::mutex> lock(mutex_);
885     for (auto vec : subscriberInstances_) {
886         napi_value callback = nullptr;
887         napi_get_reference_value(env, vec.ref, &callback);
888         bool isEquals = false;
889         napi_strict_equals(env, value, callback, &isEquals);
890         if (isEquals) {
891             subscriberInfo = vec;
892             return true;
893         }
894     }
895     return false;
896 }
897 
GetNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)898 napi_value GetNotificationSubscriber(
899     const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
900 {
901     ANS_LOGI("enter");
902     bool hasProperty = false;
903     napi_valuetype valuetype = napi_undefined;
904     napi_ref result = nullptr;
905 
906     subscriberInfo.subscriber = new (std::nothrow) SubscriberInstance();
907     if (subscriberInfo.subscriber == nullptr) {
908         ANS_LOGE("subscriber is null");
909         return nullptr;
910     }
911 
912     napi_create_reference(env, value, 1, &subscriberInfo.ref);
913 
914     // onConsume?:(data: SubscribeCallbackData) => void
915     NAPI_CALL(env, napi_has_named_property(env, value, "onConsume", &hasProperty));
916     if (hasProperty) {
917         napi_value nOnConsumed = nullptr;
918         napi_get_named_property(env, value, "onConsume", &nOnConsumed);
919         NAPI_CALL(env, napi_typeof(env, nOnConsumed, &valuetype));
920         if (valuetype != napi_function) {
921             ANS_LOGE("Wrong argument type. Function expected.");
922             return nullptr;
923         }
924         napi_create_reference(env, nOnConsumed, 1, &result);
925         subscriberInfo.subscriber->SetCallbackInfo(env, CONSUME, result);
926     }
927     // onCancel?:(data: SubscribeCallbackData) => void
928     NAPI_CALL(env, napi_has_named_property(env, value, "onCancel", &hasProperty));
929     if (hasProperty) {
930         napi_value nOnCanceled = nullptr;
931         napi_get_named_property(env, value, "onCancel", &nOnCanceled);
932         NAPI_CALL(env, napi_typeof(env, nOnCanceled, &valuetype));
933         if (valuetype != napi_function) {
934             ANS_LOGE("Wrong argument type. Function expected.");
935             return nullptr;
936         }
937         napi_create_reference(env, nOnCanceled, 1, &result);
938         subscriberInfo.subscriber->SetCallbackInfo(env, CANCEL, result);
939     }
940     // onUpdate?:(data: NotificationSortingMap) => void
941     NAPI_CALL(env, napi_has_named_property(env, value, "onUpdate", &hasProperty));
942     if (hasProperty) {
943         napi_value nOnUpdate = nullptr;
944         napi_get_named_property(env, value, "onUpdate", &nOnUpdate);
945         NAPI_CALL(env, napi_typeof(env, nOnUpdate, &valuetype));
946         if (valuetype != napi_function) {
947             ANS_LOGE("Wrong argument type. Function expected.");
948             return nullptr;
949         }
950         napi_create_reference(env, nOnUpdate, 1, &result);
951         subscriberInfo.subscriber->SetCallbackInfo(env, UPDATE, result);
952     }
953     // onConnect?:() => void
954     NAPI_CALL(env, napi_has_named_property(env, value, "onConnect", &hasProperty));
955     if (hasProperty) {
956         napi_value nOnConnected = nullptr;
957         napi_get_named_property(env, value, "onConnect", &nOnConnected);
958         NAPI_CALL(env, napi_typeof(env, nOnConnected, &valuetype));
959         if (valuetype != napi_function) {
960             ANS_LOGE("Wrong argument type. Function expected.");
961             return nullptr;
962         }
963         napi_create_reference(env, nOnConnected, 1, &result);
964         subscriberInfo.subscriber->SetCallbackInfo(env, CONNECTED, result);
965     }
966     // onDisconnect?:() => void
967     NAPI_CALL(env, napi_has_named_property(env, value, "onDisconnect", &hasProperty));
968     if (hasProperty) {
969         napi_value nOnDisConnect = nullptr;
970         napi_get_named_property(env, value, "onDisconnect", &nOnDisConnect);
971         NAPI_CALL(env, napi_typeof(env, nOnDisConnect, &valuetype));
972         if (valuetype != napi_function) {
973             ANS_LOGE("Wrong argument type. Function expected.");
974             return nullptr;
975         }
976         napi_create_reference(env, nOnDisConnect, 1, &result);
977         subscriberInfo.subscriber->SetCallbackInfo(env, DIS_CONNECTED, result);
978     }
979     // onDestroy?:() => void
980     NAPI_CALL(env, napi_has_named_property(env, value, "onDestroy", &hasProperty));
981     if (hasProperty) {
982         napi_value nOnDied = nullptr;
983         napi_get_named_property(env, value, "onDestroy", &nOnDied);
984         NAPI_CALL(env, napi_typeof(env, nOnDied, &valuetype));
985         if (valuetype != napi_function) {
986             ANS_LOGE("Wrong argument type. Function expected.");
987             return nullptr;
988         }
989         napi_create_reference(env, nOnDied, 1, &result);
990         subscriberInfo.subscriber->SetCallbackInfo(env, DIE, result);
991     }
992     // onDisturbModeChange?:(mode: notification.DoNotDisturbMode) => void
993     NAPI_CALL(env, napi_has_named_property(env, value, "onDisturbModeChange", &hasProperty));
994     if (hasProperty) {
995         napi_value nOnDisturbModeChanged = nullptr;
996         napi_get_named_property(env, value, "onDisturbModeChange", &nOnDisturbModeChanged);
997         NAPI_CALL(env, napi_typeof(env, nOnDisturbModeChanged, &valuetype));
998         if (valuetype != napi_function) {
999             ANS_LOGE("Wrong argument type. Function expected.");
1000             return nullptr;
1001         }
1002         napi_create_reference(env, nOnDisturbModeChanged, 1, &result);
1003         subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_MODE_CHANGE, result);
1004     }
1005 
1006     // onDoNotDisturbDateChange?:(mode: notification.DoNotDisturbDate) => void
1007     NAPI_CALL(env, napi_has_named_property(env, value, "onDoNotDisturbDateChange", &hasProperty));
1008     if (hasProperty) {
1009         napi_value nOnDisturbDateChanged = nullptr;
1010         napi_get_named_property(env, value, "onDoNotDisturbDateChange", &nOnDisturbDateChanged);
1011         NAPI_CALL(env, napi_typeof(env, nOnDisturbDateChanged, &valuetype));
1012         if (valuetype != napi_function) {
1013             ANS_LOGE("Wrong argument type. Function expected.");
1014             return nullptr;
1015         }
1016         napi_create_reference(env, nOnDisturbDateChanged, 1, &result);
1017         subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_DATE_CHANGE, result);
1018     }
1019 
1020     // onEnabledNotificationChanged?:(data: notification.EnabledNotificationCallbackData) => void
1021     NAPI_CALL(env, napi_has_named_property(env, value, "onEnabledNotificationChanged", &hasProperty));
1022     if (hasProperty) {
1023         napi_value nOnEnabledNotificationChanged = nullptr;
1024         napi_get_named_property(env, value, "onEnabledNotificationChanged", &nOnEnabledNotificationChanged);
1025         NAPI_CALL(env, napi_typeof(env, nOnEnabledNotificationChanged, &valuetype));
1026         if (valuetype != napi_function) {
1027             ANS_LOGE("Wrong argument type. Function expected.");
1028             return nullptr;
1029         }
1030         napi_create_reference(env, nOnEnabledNotificationChanged, 1, &result);
1031         subscriberInfo.subscriber->SetCallbackInfo(env, ENABLE_NOTIFICATION_CHANGED, result);
1032     }
1033 
1034     return Common::NapiGetNull(env);
1035 }
1036 
AddSubscriberInstancesInfo(const napi_env & env,const SubscriberInstancesInfo & subscriberInfo)1037 bool AddSubscriberInstancesInfo(const napi_env &env, const SubscriberInstancesInfo &subscriberInfo)
1038 {
1039     ANS_LOGI("enter");
1040     if (subscriberInfo.ref == nullptr) {
1041         ANS_LOGE("subscriberInfo.ref is null");
1042         return false;
1043     }
1044     if (subscriberInfo.subscriber == nullptr) {
1045         ANS_LOGE("subscriberInfo.subscriber is null");
1046         return false;
1047     }
1048     std::lock_guard<std::mutex> lock(mutex_);
1049     subscriberInstances_.emplace_back(subscriberInfo);
1050 
1051     return true;
1052 }
1053 
DelSubscriberInstancesInfo(const napi_env & env,const SubscriberInstance * subscriber)1054 bool DelSubscriberInstancesInfo(const napi_env &env, const SubscriberInstance *subscriber)
1055 {
1056     ANS_LOGI("enter");
1057     if (subscriber == nullptr) {
1058         ANS_LOGE("subscriber is null");
1059         return false;
1060     }
1061 
1062     std::lock_guard<std::mutex> lock(mutex_);
1063     for (auto it = subscriberInstances_.begin(); it != subscriberInstances_.end(); ++it) {
1064         if ((*it).subscriber == subscriber) {
1065             if ((*it).ref != nullptr) {
1066                 napi_delete_reference(env, (*it).ref);
1067             }
1068             DelDeletingSubscriber((*it).subscriber);
1069             delete (*it).subscriber;
1070             (*it).subscriber = nullptr;
1071             subscriberInstances_.erase(it);
1072             return true;
1073         }
1074     }
1075     return false;
1076 }
ParseParameters(const napi_env & env,const napi_callback_info & info,NotificationSubscribeInfo & subscriberInfo,SubscriberInstance * & subscriber,napi_ref & callback)1077 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info,
1078     NotificationSubscribeInfo &subscriberInfo, SubscriberInstance *&subscriber, napi_ref &callback)
1079 {
1080     ANS_LOGI("enter");
1081 
1082     size_t argc = SUBSRIBE_MAX_PARA;
1083     napi_value argv[SUBSRIBE_MAX_PARA] = {nullptr};
1084     napi_value thisVar = nullptr;
1085     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
1086     if (argc < 1) {
1087         ANS_LOGE("Wrong number of arguments");
1088         return nullptr;
1089     }
1090 
1091     napi_valuetype valuetype = napi_undefined;
1092 
1093     // argv[0]:subscriber
1094     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
1095     if (valuetype != napi_object) {
1096         ANS_LOGE("Wrong argument type for arg0. NotificationSubscriber object expected.");
1097         return nullptr;
1098     }
1099 
1100     SubscriberInstancesInfo subscriberInstancesInfo;
1101     if (!HasNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo)) {
1102         if (GetNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo) == nullptr) {
1103             ANS_LOGE("NotificationSubscriber parse failed");
1104             if (subscriberInstancesInfo.subscriber) {
1105                 delete subscriberInstancesInfo.subscriber;
1106                 subscriberInstancesInfo.subscriber = nullptr;
1107             }
1108             return nullptr;
1109         }
1110         if (!AddSubscriberInstancesInfo(env, subscriberInstancesInfo)) {
1111             ANS_LOGE("AddSubscriberInstancesInfo add failed");
1112             if (subscriberInstancesInfo.subscriber) {
1113                 delete subscriberInstancesInfo.subscriber;
1114                 subscriberInstancesInfo.subscriber = nullptr;
1115             }
1116             return nullptr;
1117         }
1118     }
1119     subscriber = subscriberInstancesInfo.subscriber;
1120 
1121     // argv[1]:callback or NotificationSubscribeInfo
1122     if (argc >= SUBSRIBE_MAX_PARA - 1) {
1123         NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
1124         if ((valuetype != napi_function) && (valuetype != napi_object)) {
1125             ANS_LOGE("Wrong argument type for arg1. Function or NotificationSubscribeInfo object expected.");
1126             return nullptr;
1127         }
1128         if (valuetype == napi_function) {
1129             napi_create_reference(env, argv[PARAM1], 1, &callback);
1130         } else {
1131             if (Common::GetNotificationSubscriberInfo(env, argv[PARAM1], subscriberInfo) == nullptr) {
1132                 ANS_LOGE("NotificationSubscribeInfo parse failed");
1133                 return nullptr;
1134             }
1135         }
1136     }
1137 
1138     // argv[2]:callback
1139     if (argc >= SUBSRIBE_MAX_PARA) {
1140         NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
1141         if (valuetype != napi_function) {
1142             ANS_LOGE("Wrong argument type. Function expected.");
1143             return nullptr;
1144         }
1145         napi_create_reference(env, argv[PARAM2], 1, &callback);
1146     }
1147 
1148     return Common::NapiGetNull(env);
1149 }
1150 
Subscribe(napi_env env,napi_callback_info info)1151 napi_value Subscribe(napi_env env, napi_callback_info info)
1152 {
1153     ANS_LOGI("enter");
1154 
1155     napi_ref callback = nullptr;
1156     SubscriberInstance *objectInfo = nullptr;
1157     NotificationSubscribeInfo subscriberInfo;
1158     if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
1159         if (objectInfo) {
1160             delete objectInfo;
1161             objectInfo = nullptr;
1162         }
1163         return Common::NapiGetUndefined(env);
1164     }
1165 
1166     AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
1167         .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
1168     };
1169     if (!asynccallbackinfo) {
1170         if (objectInfo) {
1171             delete objectInfo;
1172             objectInfo = nullptr;
1173         }
1174         return Common::JSParaError(env, callback);
1175     }
1176     napi_value promise = nullptr;
1177     Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
1178 
1179     napi_value resourceName = nullptr;
1180     napi_create_string_latin1(env, "subscribeNotification", NAPI_AUTO_LENGTH, &resourceName);
1181     // Asynchronous function call
1182     napi_create_async_work(env,
1183         nullptr,
1184         resourceName,
1185         [](napi_env env, void *data) {
1186             ANS_LOGI("Subscribe napi_create_async_work start");
1187             if (!data) {
1188                 ANS_LOGE("Invalid asynccallbackinfo!");
1189                 return;
1190             }
1191             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
1192             if (asynccallbackinfo) {
1193                 if (asynccallbackinfo->subscriberInfo.hasSubscribeInfo) {
1194                     ANS_LOGI("Subscribe with NotificationSubscribeInfo");
1195                     OHOS::Notification::NotificationSubscribeInfo subscribeInfo;
1196                     subscribeInfo.AddAppNames(asynccallbackinfo->subscriberInfo.bundleNames);
1197                     subscribeInfo.AddAppUserId(asynccallbackinfo->subscriberInfo.userId);
1198                     asynccallbackinfo->info.errorCode =
1199                         NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo), subscribeInfo);
1200                 } else {
1201                     asynccallbackinfo->info.errorCode =
1202                         NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo));
1203                 }
1204             }
1205         },
1206         [](napi_env env, napi_status status, void *data) {
1207             ANS_LOGI("Subscribe napi_create_async_work end");
1208             if (!data) {
1209                 ANS_LOGE("Invalid asynccallbackinfo!");
1210                 return;
1211             }
1212             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
1213             if (asynccallbackinfo) {
1214                 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
1215 
1216                 if (asynccallbackinfo->info.callback != nullptr) {
1217                     napi_delete_reference(env, asynccallbackinfo->info.callback);
1218                 }
1219                 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
1220 
1221                 delete asynccallbackinfo;
1222                 asynccallbackinfo = nullptr;
1223             }
1224         },
1225         (void *)asynccallbackinfo,
1226         &asynccallbackinfo->asyncWork);
1227 
1228     napi_status status = napi_queue_async_work(env, asynccallbackinfo->asyncWork);
1229     if (status != napi_ok) {
1230         ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
1231         if (asynccallbackinfo->info.callback != nullptr) {
1232             napi_delete_reference(env, asynccallbackinfo->info.callback);
1233         }
1234         napi_delete_async_work(env, asynccallbackinfo->asyncWork);
1235         delete asynccallbackinfo;
1236         asynccallbackinfo = nullptr;
1237         return Common::JSParaError(env, callback);
1238     }
1239 
1240     if (asynccallbackinfo->info.isCallback) {
1241         return Common::NapiGetNull(env);
1242     } else {
1243         return promise;
1244     }
1245 }
1246 
AddDeletingSubscriber(SubscriberInstance * subscriber)1247 bool AddDeletingSubscriber(SubscriberInstance *subscriber)
1248 {
1249     std::lock_guard<std::mutex> lock(delMutex_);
1250     auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1251     if (iter != DeletingSubscriber.end()) {
1252         return false;
1253     }
1254 
1255     DeletingSubscriber.push_back(subscriber);
1256     return true;
1257 }
1258 
DelDeletingSubscriber(SubscriberInstance * subscriber)1259 void DelDeletingSubscriber(SubscriberInstance *subscriber)
1260 {
1261     std::lock_guard<std::mutex> lock(delMutex_);
1262     auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1263     if (iter != DeletingSubscriber.end()) {
1264         DeletingSubscriber.erase(iter);
1265     }
1266 }
1267 }  // namespace NotificationNapi
1268 }  // namespace OHOS