• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 #include "ans_inner_errors.h"
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 DISTURB_CHANGED = "onDoNotDisturbChanged";
34 const std::string ENABLE_NOTIFICATION_CHANGED = "OnEnabledNotificationChanged";
35 const std::string BADGE_CHANGED = "OnBadgeChanged";
36 const std::string BADGE_ENABLED_CHANGED = "OnBadgeEnabledChanged";
37 const std::string BATCH_CANCEL = "onBatchCancel";
38 
39 enum class Type {
40     UNKNOWN,
41     CANCEL,
42     BATCH_CANCEL,
43     CONSUME,
44     UPDATE,
45     CONNECTED,
46     DIS_CONNECTED,
47     DIE,
48     DISTURB_DATE_CHANGE,
49     DISTURB_CHANGED,
50     ENABLE_NOTIFICATION_CHANGED,
51     BADGE_CHANGED,
52     BADGE_ENABLED_CHANGED
53 };
54 
55 struct NotificationReceiveDataWorker {
56     napi_env env = nullptr;
57     napi_ref ref = nullptr;
58     std::shared_ptr<OHOS::Notification::Notification> request;
59     std::vector<std::shared_ptr<OHOS::Notification::Notification>> requestList;
60     std::shared_ptr<NotificationSortingMap> sortingMap;
61     NotificationDoNotDisturbDate date;
62     EnabledNotificationCallbackData callbackData;
63     BadgeNumberCallbackData badge;
64     int32_t deleteReason = 0;
65     int32_t result = 0;
66     int32_t disturbMode = 0;
67     std::shared_ptr<SubscriberInstance> subscriber = nullptr;
68     Type type;
69 };
70 
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)71 napi_value SetSubscribeCallbackData(const napi_env &env,
72     const std::shared_ptr<OHOS::Notification::Notification> &request,
73     const std::shared_ptr<NotificationSortingMap> &sortingMap, int32_t deleteReason, napi_value &result)
74 {
75     ANS_LOGD("enter");
76     if (request == nullptr) {
77         ANS_LOGE("request is null");
78         return Common::NapiGetBoolean(env, false);
79     }
80 
81     if (sortingMap == nullptr) {
82         ANS_LOGE("sortingMap is null");
83         return Common::NapiGetBoolean(env, false);
84     }
85 
86     // request: NotificationRequest
87     napi_value requestResult = nullptr;
88     napi_create_object(env, &requestResult);
89     if (!Common::SetNotification(env, request.get(), requestResult)) {
90         ANS_LOGE("SetNotification call failed");
91         return Common::NapiGetBoolean(env, false);
92     }
93     napi_set_named_property(env, result, "request", requestResult);
94 
95     // sortingMap?: NotificationSortingMap
96     napi_value sortingMapResult = nullptr;
97     napi_create_object(env, &sortingMapResult);
98     if (!Common::SetNotificationSortingMap(env, sortingMap, sortingMapResult)) {
99         ANS_LOGE("SetNotificationSortingMap call failed");
100         return Common::NapiGetBoolean(env, false);
101     }
102     napi_set_named_property(env, result, "sortingMap", sortingMapResult);
103 
104     // reason?: number
105     if (deleteReason != NO_DELETE_REASON) {
106         napi_value value = nullptr;
107         int32_t outReason = 0;
108         if (!AnsEnumUtil::ReasonCToJS(deleteReason, outReason)) {
109             return Common::NapiGetBoolean(env, false);
110         }
111         napi_create_int32(env, outReason, &value);
112         napi_set_named_property(env, result, "reason", value);
113     }
114 
115     // sound?: string
116     napi_value soundResult = nullptr;
117     std::string sound;
118     if (request->EnableSound()) {
119         sound = request->GetSound().ToString();
120     }
121     napi_create_string_utf8(env, sound.c_str(), NAPI_AUTO_LENGTH, &soundResult);
122     napi_set_named_property(env, result, "sound", soundResult);
123 
124     // vibrationValues?: Array<number>
125     napi_value arr = nullptr;
126     napi_create_array(env, &arr);
127     if (request->EnableVibrate()) {
128         uint32_t count = 0;
129         for (auto vec : request->GetVibrationStyle()) {
130             napi_value nVibrationValue = nullptr;
131             napi_create_int64(env, vec, &nVibrationValue);
132             napi_set_element(env, arr, count, nVibrationValue);
133             count++;
134         }
135     }
136     napi_set_named_property(env, result, "vibrationValues", arr);
137 
138     return Common::NapiGetBoolean(env, true);
139 }
140 
SubscriberInstance()141 SubscriberInstance::SubscriberInstance()
142 {}
143 
~SubscriberInstance()144 SubscriberInstance::~SubscriberInstance()
145 {
146     if (unsubscribeCallbackInfo_.tsfn != nullptr) {
147         napi_release_threadsafe_function(unsubscribeCallbackInfo_.tsfn, napi_tsfn_abort);
148     }
149     if (canceCallbackInfo_.ref != nullptr) {
150         napi_delete_reference(canceCallbackInfo_.env, canceCallbackInfo_.ref);
151     }
152     if (consumeCallbackInfo_.ref != nullptr) {
153         napi_delete_reference(consumeCallbackInfo_.env, consumeCallbackInfo_.ref);
154     }
155     if (updateCallbackInfo_.ref != nullptr) {
156         napi_delete_reference(updateCallbackInfo_.env, updateCallbackInfo_.ref);
157     }
158     if (subscribeCallbackInfo_.ref != nullptr) {
159         napi_delete_reference(subscribeCallbackInfo_.env, subscribeCallbackInfo_.ref);
160     }
161     if (unsubscribeCallbackInfo_.ref != nullptr) {
162         napi_delete_reference(unsubscribeCallbackInfo_.env, unsubscribeCallbackInfo_.ref);
163     }
164     if (dieCallbackInfo_.ref != nullptr) {
165         napi_delete_reference(dieCallbackInfo_.env, dieCallbackInfo_.ref);
166     }
167     if (disturbModeCallbackInfo_.ref != nullptr) {
168         napi_delete_reference(disturbModeCallbackInfo_.env, disturbModeCallbackInfo_.ref);
169     }
170     if (enabledNotificationCallbackInfo_.ref != nullptr) {
171         napi_delete_reference(enabledNotificationCallbackInfo_.env, enabledNotificationCallbackInfo_.ref);
172     }
173     if (batchCancelCallbackInfo_.ref != nullptr) {
174         napi_delete_reference(batchCancelCallbackInfo_.env, batchCancelCallbackInfo_.ref);
175     }
176 }
177 
ThreadSafeOnCancel(napi_env env,napi_value jsCallback,void * context,void * data)178 void ThreadSafeOnCancel(napi_env env, napi_value jsCallback, void* context, void* data)
179 {
180     ANS_LOGI("OnCanceled thread safe start");
181 
182     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
183     if (dataWorkerData == nullptr) {
184         ANS_LOGE("Create dataWorkerData failed.");
185         return;
186     }
187 
188     napi_value result = nullptr;
189     napi_handle_scope scope;
190     napi_open_handle_scope(dataWorkerData->env, &scope);
191     if (scope == nullptr) {
192         ANS_LOGE("Scope is null");
193         return;
194     }
195     napi_create_object(dataWorkerData->env, &result);
196     if (!SetSubscribeCallbackData(dataWorkerData->env,
197         dataWorkerData->request,
198         dataWorkerData->sortingMap,
199         dataWorkerData->deleteReason,
200         result)) {
201         ANS_LOGE("Failed to convert data to JS");
202     } else {
203         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
204     }
205     napi_close_handle_scope(dataWorkerData->env, scope);
206 
207     delete dataWorkerData;
208     dataWorkerData = nullptr;
209 }
210 
OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap,int32_t deleteReason)211 void SubscriberInstance::OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> &request,
212     const std::shared_ptr<NotificationSortingMap> &sortingMap, int32_t deleteReason)
213 {
214     ANS_LOGD("enter");
215 
216     if (canceCallbackInfo_.ref == nullptr || canceCallbackInfo_.env == nullptr) {
217         ANS_LOGI("cancel callback or env unset");
218         return;
219     }
220 
221     if (request == nullptr) {
222         ANS_LOGE("request is null");
223         return;
224     }
225 
226     if (sortingMap == nullptr) {
227         ANS_LOGE("sortingMap is null");
228         return;
229     }
230     ANS_LOGI("OnCanceled NotificationKey = %{public}s. sortingMap size = %{public}zu. deleteReason = %{public}d",
231         request->GetKey().c_str(), sortingMap->GetKey().size(), deleteReason);
232 
233     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
234     if (dataWorker == nullptr) {
235         ANS_LOGE("DataWorker is nullptr.");
236         return;
237     }
238 
239     dataWorker->request = request;
240     dataWorker->sortingMap = sortingMap;
241     dataWorker->deleteReason = deleteReason;
242     dataWorker->env = canceCallbackInfo_.env;
243     dataWorker->ref = canceCallbackInfo_.ref;
244     dataWorker->type = Type::CANCEL;
245 
246     napi_acquire_threadsafe_function(canceCallbackInfo_.tsfn);
247     napi_call_threadsafe_function(canceCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
248     napi_release_threadsafe_function(canceCallbackInfo_.tsfn, napi_tsfn_release);
249 }
250 
ThreadSafeOnBatchCancel(napi_env env,napi_value jsCallback,void * context,void * data)251 void ThreadSafeOnBatchCancel(napi_env env, napi_value jsCallback, void* context, void* data)
252 {
253     ANS_LOGI("OnBatchCancel thread safe start");
254 
255     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
256     if (dataWorkerData == nullptr) {
257         ANS_LOGE("Create dataWorkerData failed.");
258         return;
259     }
260 
261     napi_value resultArray = nullptr;
262     napi_handle_scope scope;
263     napi_open_handle_scope(dataWorkerData->env, &scope);
264     if (scope == nullptr) {
265         ANS_LOGE("Scope is null");
266         return;
267     }
268     napi_create_array(dataWorkerData->env, &resultArray);
269     int index = 0;
270     for (auto request : dataWorkerData->requestList) {
271         napi_value result = nullptr;
272         napi_create_object(dataWorkerData->env, &result);
273         if (SetSubscribeCallbackData(dataWorkerData->env, request,
274             dataWorkerData->sortingMap, dataWorkerData->deleteReason, result)) {
275             napi_set_element(dataWorkerData->env, resultArray, index, result);
276             index++;
277         }
278     }
279     uint32_t elementCount = 0;
280     napi_get_array_length(dataWorkerData->env, resultArray, &elementCount);
281     ANS_LOGI("notification array length: %{public}d ", elementCount);
282     if (elementCount > 0) {
283         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, resultArray);
284     }
285 
286     napi_close_handle_scope(dataWorkerData->env, scope);
287 
288     delete dataWorkerData;
289     dataWorkerData = nullptr;
290 }
291 
OnBatchCanceled(const std::vector<std::shared_ptr<OHOS::Notification::Notification>> & requestList,const std::shared_ptr<NotificationSortingMap> & sortingMap,int32_t deleteReason)292 void SubscriberInstance::OnBatchCanceled(const std::vector<std::shared_ptr<OHOS::Notification::Notification>>
293     &requestList, const std::shared_ptr<NotificationSortingMap> &sortingMap, int32_t deleteReason)
294 {
295     ANS_LOGI("OnBatchCancel");
296     if (batchCancelCallbackInfo_.ref == nullptr || batchCancelCallbackInfo_.env == nullptr) {
297         ANS_LOGI("batchCancelCallbackInfo_ callback or env unset");
298         return;
299     }
300     if (requestList.empty()) {
301         ANS_LOGE("requestList is empty");
302         return;
303     }
304     if (sortingMap == nullptr) {
305         ANS_LOGE("sortingMap is null");
306         return;
307     }
308     ANS_LOGI("OnBatchCancel sortingMap size = %{public}zu", sortingMap->GetKey().size());
309     ANS_LOGI("OnBatchCancel deleteReason = %{public}d", deleteReason);
310     std::string notificationKeys = "";
311     for (auto notification : requestList) {
312         notificationKeys.append(notification->GetKey()).append("-");
313     }
314     ANS_LOGI("OnBatchCancel. cancel keys = %{public}s", notificationKeys.c_str());
315 
316     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
317     if (dataWorker == nullptr) {
318         ANS_LOGE("DataWorker is nullptr.");
319         return;
320     }
321     dataWorker->requestList = requestList;
322     dataWorker->sortingMap = sortingMap;
323     dataWorker->deleteReason = deleteReason;
324     dataWorker->env = batchCancelCallbackInfo_.env;
325     dataWorker->ref = batchCancelCallbackInfo_.ref;
326     dataWorker->type = Type::BATCH_CANCEL;
327 
328     napi_acquire_threadsafe_function(batchCancelCallbackInfo_.tsfn);
329     napi_call_threadsafe_function(batchCancelCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
330     napi_release_threadsafe_function(batchCancelCallbackInfo_.tsfn, napi_tsfn_release);
331     return;
332 }
333 
HasOnBatchCancelCallback()334 bool SubscriberInstance::HasOnBatchCancelCallback()
335 {
336     if (batchCancelCallbackInfo_.ref == nullptr) {
337         ANS_LOGI("batchCancelCallbackInfo_ callback unset");
338         return false;
339     }
340     return true;
341 }
342 
ThreadSafeOnConsumed(napi_env env,napi_value jsCallback,void * context,void * data)343 void ThreadSafeOnConsumed(napi_env env, napi_value jsCallback, void* context, void* data)
344 {
345     ANS_LOGI("OnConsumed thread safe start");
346 
347     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
348     if (dataWorkerData == nullptr) {
349         ANS_LOGD("dataWorkerData is null.");
350         return;
351     }
352     napi_value result = nullptr;
353     napi_handle_scope scope;
354     napi_open_handle_scope(dataWorkerData->env, &scope);
355     if (scope == nullptr) {
356         ANS_LOGE("Scope is null");
357         return;
358     }
359     napi_create_object(dataWorkerData->env, &result);
360     if (!SetSubscribeCallbackData(dataWorkerData->env,
361         dataWorkerData->request,
362         dataWorkerData->sortingMap,
363         NO_DELETE_REASON,
364         result)) {
365         ANS_LOGE("Convert data to JS fail.");
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 }
374 
OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap)375 void SubscriberInstance::OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> &request,
376     const std::shared_ptr<NotificationSortingMap> &sortingMap)
377 {
378     ANS_LOGD("enter");
379 
380     if (consumeCallbackInfo_.ref == nullptr || consumeCallbackInfo_.env == nullptr) {
381         ANS_LOGI("consume callback or env unset");
382         return;
383     }
384 
385     if (consumeCallbackInfo_.tsfn == nullptr) {
386         ANS_LOGI("consume tsfn is null");
387         return;
388     }
389 
390     if (request == nullptr) {
391         ANS_LOGE("request is nullptr.");
392         return;
393     }
394 
395     if (sortingMap == nullptr) {
396         ANS_LOGE("sortingMap is nullptr.");
397         return;
398     }
399     auto notificationFlags = request->GetNotificationRequest().GetFlags();
400     ANS_LOGI("OnConsumed Notification key = %{public}s, sortingMap size = %{public}zu, notificationFlag = %{public}s",
401         request->GetKey().c_str(), sortingMap->GetKey().size(),
402         notificationFlags == nullptr ? "null" : notificationFlags->Dump().c_str());
403     ANS_LOGD("OnConsumed Notification info is %{public}s", request->GetNotificationRequest().Dump().c_str());
404 
405     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
406     if (dataWorker == nullptr) {
407         ANS_LOGE("new dataWorker failed");
408         return;
409     }
410 
411     dataWorker->request = request;
412     dataWorker->sortingMap = sortingMap;
413     dataWorker->env = consumeCallbackInfo_.env;
414     dataWorker->ref = consumeCallbackInfo_.ref;
415     dataWorker->type = Type::CONSUME;
416 
417     napi_acquire_threadsafe_function(consumeCallbackInfo_.tsfn);
418     napi_call_threadsafe_function(consumeCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
419     napi_release_threadsafe_function(consumeCallbackInfo_.tsfn, napi_tsfn_release);
420 }
421 
ThreadSafeOnUpdate(napi_env env,napi_value jsCallback,void * context,void * data)422 void ThreadSafeOnUpdate(napi_env env, napi_value jsCallback, void* context, void* data)
423 {
424     ANS_LOGI("OnUpdate thread safe start");
425 
426     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
427     if (dataWorkerData == nullptr) {
428         ANS_LOGE("dataWorkerData is nullptr");
429         return;
430     }
431     napi_value result = nullptr;
432     napi_handle_scope scope;
433     napi_open_handle_scope(dataWorkerData->env, &scope);
434     if (scope == nullptr) {
435         ANS_LOGE("Scope is null");
436         return;
437     }
438     napi_create_object(dataWorkerData->env, &result);
439     if (!Common::SetNotificationSortingMap(dataWorkerData->env, dataWorkerData->sortingMap, result)) {
440         ANS_LOGE("Failed to convert data to JS");
441     } else {
442         Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
443     }
444     napi_close_handle_scope(dataWorkerData->env, scope);
445 
446     delete dataWorkerData;
447     dataWorkerData = nullptr;
448 }
449 
OnUpdate(const std::shared_ptr<NotificationSortingMap> & sortingMap)450 void SubscriberInstance::OnUpdate(const std::shared_ptr<NotificationSortingMap> &sortingMap)
451 {
452     ANS_LOGD("enter");
453 
454     if (updateCallbackInfo_.ref == nullptr || updateCallbackInfo_.env == nullptr) {
455         ANS_LOGI("update callback or env unset");
456         return;
457     }
458 
459     if (sortingMap == nullptr) {
460         ANS_LOGE("sortingMap is null");
461         return;
462     }
463     ANS_LOGI("OnUpdate sortingMap size = %{public}zu", sortingMap->GetKey().size());
464 
465     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
466     if (dataWorker == nullptr) {
467         ANS_LOGE("new dataWorker failed");
468         return;
469     }
470 
471     dataWorker->sortingMap = sortingMap;
472     dataWorker->env = updateCallbackInfo_.env;
473     dataWorker->ref = updateCallbackInfo_.ref;
474     dataWorker->type = Type::UPDATE;
475 
476     napi_acquire_threadsafe_function(updateCallbackInfo_.tsfn);
477     napi_call_threadsafe_function(updateCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
478     napi_release_threadsafe_function(updateCallbackInfo_.tsfn, napi_tsfn_release);
479 }
480 
ThreadSafeOnConnected(napi_env env,napi_value jsCallback,void * context,void * data)481 void ThreadSafeOnConnected(napi_env env, napi_value jsCallback, void* context, void* data)
482 {
483     ANS_LOGD("OnConnected thread safe start");
484     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
485     if (dataWorkerData == nullptr) {
486         ANS_LOGE("dataWorkerData is nullptr.");
487         return;
488     }
489 
490     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
491 
492     delete dataWorkerData;
493     dataWorkerData = nullptr;
494 }
495 
OnConnected()496 void SubscriberInstance::OnConnected()
497 {
498     ANS_LOGD("enter");
499 
500     if (subscribeCallbackInfo_.ref == nullptr || subscribeCallbackInfo_.env == nullptr) {
501         ANS_LOGI("subscribe callback or env unset");
502         return;
503     }
504 
505     if (subscribeCallbackInfo_.tsfn == nullptr) {
506         ANS_LOGI("subscribe tsfn is null");
507         return;
508     }
509 
510     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
511     if (dataWorker == nullptr) {
512         ANS_LOGE("new dataWorker failed");
513         return;
514     }
515 
516     dataWorker->env = subscribeCallbackInfo_.env;
517     dataWorker->ref = subscribeCallbackInfo_.ref;
518     dataWorker->type = Type::CONNECTED;
519 
520     napi_acquire_threadsafe_function(subscribeCallbackInfo_.tsfn);
521     napi_call_threadsafe_function(subscribeCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
522     napi_release_threadsafe_function(subscribeCallbackInfo_.tsfn, napi_tsfn_release);
523 }
524 
ThreadSafeOnDisconnected(napi_env env,napi_value jsCallback,void * context,void * data)525 void ThreadSafeOnDisconnected(napi_env env, napi_value jsCallback, void* context, void* data)
526 {
527     ANS_LOGI("OnDisconnected thread safe start");
528 
529     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
530     if (dataWorkerData == nullptr) {
531         ANS_LOGE("Failed to create dataWorkerData.");
532         return;
533     }
534 
535     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
536     DelSubscriberInstancesInfo(dataWorkerData->env, dataWorkerData->subscriber);
537     delete dataWorkerData;
538     dataWorkerData = nullptr;
539 }
540 
OnDisconnected()541 void SubscriberInstance::OnDisconnected()
542 {
543     ANS_LOGD("enter");
544 
545     if (unsubscribeCallbackInfo_.ref == nullptr) {
546         ANS_LOGI("unsubscribe callback unset");
547         return;
548     }
549 
550     if (unsubscribeCallbackInfo_.tsfn == nullptr) {
551         ANS_LOGI("unsubscribe tsfn is null");
552         return;
553     }
554 
555     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
556     if (dataWorker == nullptr) {
557         ANS_LOGE("new dataWorker failed");
558         return;
559     }
560 
561     dataWorker->env = unsubscribeCallbackInfo_.env;
562     dataWorker->ref = unsubscribeCallbackInfo_.ref;
563     dataWorker->subscriber = shared_from_this();
564     dataWorker->type = Type::DIS_CONNECTED;
565 
566     napi_acquire_threadsafe_function(unsubscribeCallbackInfo_.tsfn);
567     napi_call_threadsafe_function(unsubscribeCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
568     napi_release_threadsafe_function(unsubscribeCallbackInfo_.tsfn, napi_tsfn_release);
569 }
570 
ThreadSafeOnDestroy(napi_env env,napi_value jsCallback,void * context,void * data)571 void ThreadSafeOnDestroy(napi_env env, napi_value jsCallback, void* context, void* data)
572 {
573     ANS_LOGI("OnDied thread safe start");
574 
575     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
576     if (dataWorkerData == nullptr) {
577         ANS_LOGE("dataWorkerData is null");
578         return;
579     }
580 
581     Common::SetCallback(
582         dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
583 
584     delete dataWorkerData;
585     dataWorkerData = nullptr;
586 }
587 
OnDied()588 void SubscriberInstance::OnDied()
589 {
590     ANS_LOGD("enter");
591 
592     if (dieCallbackInfo_.ref == nullptr) {
593         ANS_LOGE("die callback unset");
594         return;
595     }
596 
597     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
598     if (dataWorker == nullptr) {
599         ANS_LOGE("new dataWorker failed");
600         return;
601     }
602 
603     dataWorker->env = dieCallbackInfo_.env;
604     dataWorker->ref = dieCallbackInfo_.ref;
605     dataWorker->type = Type::DIE;
606 
607     napi_acquire_threadsafe_function(dieCallbackInfo_.tsfn);
608     napi_call_threadsafe_function(dieCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
609     napi_release_threadsafe_function(dieCallbackInfo_.tsfn, napi_tsfn_release);
610 }
611 
ThreadSafeOnDoNotDisturbDateChange(napi_env env,napi_value jsCallback,void * context,void * data)612 void ThreadSafeOnDoNotDisturbDateChange(napi_env env, napi_value jsCallback, void* context, void* data)
613 {
614     ANS_LOGI("OnDoNotDisturbDateChange thread safe start");
615 
616     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
617     if (dataWorkerData == nullptr) {
618         ANS_LOGE("Data worker data is null.");
619         return;
620     }
621 
622     napi_value result = nullptr;
623     napi_handle_scope scope;
624     napi_open_handle_scope(dataWorkerData->env, &scope);
625     if (scope == nullptr) {
626         ANS_LOGE("Scope is null");
627         return;
628     }
629     napi_create_object(dataWorkerData->env, &result);
630 
631     if (!Common::SetDoNotDisturbDate(dataWorkerData->env, dataWorkerData->date, result)) {
632         result = Common::NapiGetNull(dataWorkerData->env);
633     }
634 
635     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
636     napi_close_handle_scope(dataWorkerData->env, scope);
637 
638     delete dataWorkerData;
639     dataWorkerData = nullptr;
640 }
641 
OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> & date)642 void SubscriberInstance::OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> &date)
643 {
644     ANS_LOGD("enter");
645 
646     onDoNotDisturbChanged(date);
647 
648     if (disturbDateCallbackInfo_.ref == nullptr || disturbDateCallbackInfo_.env == nullptr) {
649         ANS_LOGI("disturbDateCallbackInfo_ callback or env unset");
650         return;
651     }
652 
653     if (date == nullptr) {
654         ANS_LOGE("date is null");
655         return;
656     }
657 
658     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
659     if (dataWorker == nullptr) {
660         ANS_LOGE("new dataWorker failed");
661         return;
662     }
663 
664     dataWorker->date = *date;
665     dataWorker->env = disturbDateCallbackInfo_.env;
666     dataWorker->ref = disturbDateCallbackInfo_.ref;
667     dataWorker->type = Type::DISTURB_DATE_CHANGE;
668 
669     napi_acquire_threadsafe_function(disturbDateCallbackInfo_.tsfn);
670     napi_call_threadsafe_function(disturbDateCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
671     napi_release_threadsafe_function(disturbDateCallbackInfo_.tsfn, napi_tsfn_release);
672 }
673 
674 
ThreadSafeOnDoNotDisturbChanged(napi_env env,napi_value jsCallback,void * context,void * data)675 void ThreadSafeOnDoNotDisturbChanged(napi_env env, napi_value jsCallback, void* context, void* data)
676 {
677     ANS_LOGI("OnDoNotDisturbChanged thread safe start");
678 
679     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
680     if (dataWorkerData == nullptr) {
681         ANS_LOGE("Data worker data is null.");
682         return;
683     }
684 
685     napi_value result = nullptr;
686     napi_handle_scope scope;
687     napi_open_handle_scope(dataWorkerData->env, &scope);
688     napi_create_object(dataWorkerData->env, &result);
689 
690     if (!Common::SetDoNotDisturbDate(dataWorkerData->env, dataWorkerData->date, result)) {
691         result = Common::NapiGetNull(dataWorkerData->env);
692     }
693 
694     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
695     napi_close_handle_scope(dataWorkerData->env, scope);
696 
697     delete dataWorkerData;
698     dataWorkerData = nullptr;
699 }
700 
onDoNotDisturbChanged(const std::shared_ptr<NotificationDoNotDisturbDate> & date)701 void SubscriberInstance::onDoNotDisturbChanged(const std::shared_ptr<NotificationDoNotDisturbDate>& date)
702 {
703     ANS_LOGD("enter");
704 
705     if (disturbChangedCallbackInfo_.ref == nullptr || disturbChangedCallbackInfo_.env == nullptr) {
706         ANS_LOGE("disturbChangedCallbackInfo_ callback or env unset");
707         return;
708     }
709 
710     if (date == nullptr) {
711         ANS_LOGE("date is null");
712         return;
713     }
714 
715     NotificationReceiveDataWorker* dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
716     if (dataWorker == nullptr) {
717         ANS_LOGE("new dataWorker failed");
718         return;
719     }
720 
721     dataWorker->date = *date;
722     dataWorker->env = disturbChangedCallbackInfo_.env;
723     dataWorker->ref = disturbChangedCallbackInfo_.ref;
724     dataWorker->type = Type::DISTURB_CHANGED;
725 
726     napi_acquire_threadsafe_function(disturbChangedCallbackInfo_.tsfn);
727     napi_call_threadsafe_function(disturbChangedCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
728     napi_release_threadsafe_function(disturbChangedCallbackInfo_.tsfn, napi_tsfn_release);
729 }
730 
ThreadSafeOnEnabledNotificationChanged(napi_env env,napi_value jsCallback,void * context,void * data)731 void ThreadSafeOnEnabledNotificationChanged(napi_env env, napi_value jsCallback, void* context, void* data)
732 {
733     ANS_LOGI("OnEnabledNotificationChanged thread safe start");
734 
735     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
736     if (dataWorkerData == nullptr) {
737         ANS_LOGE("Data worker data is null.");
738         return;
739     }
740 
741     napi_value result = nullptr;
742     napi_handle_scope scope;
743     napi_open_handle_scope(dataWorkerData->env, &scope);
744     if (scope == nullptr) {
745         ANS_LOGE("Scope is null");
746         return;
747     }
748     napi_create_object(dataWorkerData->env, &result);
749 
750     if (!Common::SetEnabledNotificationCallbackData(dataWorkerData->env, dataWorkerData->callbackData, result)) {
751         result = Common::NapiGetNull(dataWorkerData->env);
752     }
753 
754     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
755     napi_close_handle_scope(dataWorkerData->env, scope);
756 
757     delete dataWorkerData;
758     dataWorkerData = nullptr;
759 }
760 
OnEnabledNotificationChanged(const std::shared_ptr<EnabledNotificationCallbackData> & callbackData)761 void SubscriberInstance::OnEnabledNotificationChanged(
762     const std::shared_ptr<EnabledNotificationCallbackData> &callbackData)
763 {
764     ANS_LOGD("enter");
765 
766     if (enabledNotificationCallbackInfo_.ref == nullptr || enabledNotificationCallbackInfo_.env == nullptr) {
767         ANS_LOGI("enabledNotificationCallbackInfo_ callback or env unset");
768         return;
769     }
770 
771     if (callbackData == nullptr) {
772         ANS_LOGE("callbackData is null");
773         return;
774     }
775 
776     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
777     if (dataWorker == nullptr) {
778         ANS_LOGE("new dataWorker failed");
779         return;
780     }
781 
782     dataWorker->callbackData = *callbackData;
783     dataWorker->env = enabledNotificationCallbackInfo_.env;
784     dataWorker->ref = enabledNotificationCallbackInfo_.ref;
785     dataWorker->type = Type::ENABLE_NOTIFICATION_CHANGED;
786 
787     napi_acquire_threadsafe_function(enabledNotificationCallbackInfo_.tsfn);
788     napi_call_threadsafe_function(enabledNotificationCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
789     napi_release_threadsafe_function(enabledNotificationCallbackInfo_.tsfn, napi_tsfn_release);
790 }
791 
ThreadSafeOnBadgeChanged(napi_env env,napi_value jsCallback,void * context,void * data)792 void ThreadSafeOnBadgeChanged(napi_env env, napi_value jsCallback, void* context, void* data)
793 {
794     ANS_LOGI("OnBadgeChanged thread safe start");
795 
796     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
797     if (dataWorkerData == nullptr) {
798         ANS_LOGE("dataWorkerData is null");
799         return;
800     }
801 
802     napi_value result = nullptr;
803     napi_handle_scope scope;
804     napi_open_handle_scope(dataWorkerData->env, &scope);
805     if (scope == nullptr) {
806         ANS_LOGE("Scope is null");
807         return;
808     }
809     napi_create_object(dataWorkerData->env, &result);
810 
811     if (!Common::SetBadgeCallbackData(dataWorkerData->env, dataWorkerData->badge, result)) {
812         result = Common::NapiGetNull(dataWorkerData->env);
813     }
814 
815     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
816     napi_close_handle_scope(dataWorkerData->env, scope);
817 
818     delete dataWorkerData;
819     dataWorkerData = nullptr;
820 }
821 
OnBadgeChanged(const std::shared_ptr<BadgeNumberCallbackData> & badgeData)822 void SubscriberInstance::OnBadgeChanged(
823     const std::shared_ptr<BadgeNumberCallbackData> &badgeData)
824 {
825     ANS_LOGD("enter");
826 
827     if (setBadgeCallbackInfo_.ref == nullptr || setBadgeCallbackInfo_.env == nullptr) {
828         return;
829     }
830 
831     if (badgeData == nullptr) {
832         ANS_LOGE("badgeData is null");
833         return;
834     }
835 
836     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
837     if (dataWorker == nullptr) {
838         ANS_LOGE("new dataWorker failed");
839         return;
840     }
841 
842     dataWorker->badge = *badgeData;
843     dataWorker->env = setBadgeCallbackInfo_.env;
844     dataWorker->ref = setBadgeCallbackInfo_.ref;
845     dataWorker->type = Type::BADGE_CHANGED;
846 
847     napi_acquire_threadsafe_function(setBadgeCallbackInfo_.tsfn);
848     napi_call_threadsafe_function(setBadgeCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
849     napi_release_threadsafe_function(setBadgeCallbackInfo_.tsfn, napi_tsfn_release);
850 }
851 
ThreadSafeOnBadgeEnabledChanged(napi_env env,napi_value jsCallback,void * context,void * data)852 void ThreadSafeOnBadgeEnabledChanged(napi_env env, napi_value jsCallback, void* context, void* data)
853 {
854     ANS_LOGI("OnBadgeEnabledChanged thread safe start.");
855 
856     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
857     if (dataWorkerData == nullptr) {
858         ANS_LOGE("Data worker is null.");
859         return;
860     }
861 
862     napi_value result = nullptr;
863     napi_handle_scope scope;
864     napi_open_handle_scope(dataWorkerData->env, &scope);
865     if (scope == nullptr) {
866         ANS_LOGE("Scope is null");
867         return;
868     }
869     napi_create_object(dataWorkerData->env, &result);
870     if (!Common::SetEnabledNotificationCallbackData(dataWorkerData->env, dataWorkerData->callbackData, result)) {
871         result = Common::NapiGetNull(dataWorkerData->env);
872     }
873 
874     Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
875     napi_close_handle_scope(dataWorkerData->env, scope);
876 
877     delete dataWorkerData;
878     dataWorkerData = nullptr;
879 }
880 
OnBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> & callbackData)881 void SubscriberInstance::OnBadgeEnabledChanged(
882     const sptr<EnabledNotificationCallbackData> &callbackData)
883 {
884     if (setBadgeEnabledCallbackInfo_.ref == nullptr) {
885         ANS_LOGE("Set badge enabled callback info is null.");
886         return;
887     }
888     if (callbackData == nullptr) {
889         ANS_LOGE("Callback data is null.");
890         return;
891     }
892 
893     NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
894     if (dataWorker == nullptr) {
895         ANS_LOGE("Create new data worker failed.");
896         return;
897     }
898 
899     dataWorker->callbackData = *callbackData;
900     dataWorker->env = setBadgeEnabledCallbackInfo_.env;
901     dataWorker->ref = setBadgeEnabledCallbackInfo_.ref;
902     dataWorker->type = Type::BADGE_ENABLED_CHANGED;
903 
904     napi_acquire_threadsafe_function(setBadgeEnabledCallbackInfo_.tsfn);
905     napi_call_threadsafe_function(setBadgeEnabledCallbackInfo_.tsfn, dataWorker, napi_tsfn_nonblocking);
906     napi_release_threadsafe_function(setBadgeEnabledCallbackInfo_.tsfn, napi_tsfn_release);
907 }
908 
SetCancelCallbackInfo(const napi_env & env,const napi_ref & ref)909 void SubscriberInstance::SetCancelCallbackInfo(const napi_env &env, const napi_ref &ref)
910 {
911     canceCallbackInfo_.env = env;
912     canceCallbackInfo_.ref = ref;
913 }
914 
SetCancelCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)915 void SubscriberInstance::SetCancelCallbackInfo(const napi_env &env, const napi_ref &ref,
916     const napi_threadsafe_function &tsfn)
917 {
918     canceCallbackInfo_.env = env;
919     canceCallbackInfo_.ref = ref;
920     canceCallbackInfo_.tsfn = tsfn;
921 }
922 
SetConsumeCallbackInfo(const napi_env & env,const napi_ref & ref)923 void SubscriberInstance::SetConsumeCallbackInfo(const napi_env &env, const napi_ref &ref)
924 {
925     consumeCallbackInfo_.env = env;
926     consumeCallbackInfo_.ref = ref;
927 }
928 
SetConsumeCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)929 void SubscriberInstance::SetConsumeCallbackInfo(const napi_env &env, const napi_ref &ref,
930     const napi_threadsafe_function &tsfn)
931 {
932     consumeCallbackInfo_.env = env;
933     consumeCallbackInfo_.ref = ref;
934     consumeCallbackInfo_.tsfn = tsfn;
935 }
936 
SetUpdateCallbackInfo(const napi_env & env,const napi_ref & ref)937 void SubscriberInstance::SetUpdateCallbackInfo(const napi_env &env, const napi_ref &ref)
938 {
939     updateCallbackInfo_.env = env;
940     updateCallbackInfo_.ref = ref;
941 }
942 
SetUpdateCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)943 void SubscriberInstance::SetUpdateCallbackInfo(const napi_env &env, const napi_ref &ref,
944     const napi_threadsafe_function &tsfn)
945 {
946     updateCallbackInfo_.env = env;
947     updateCallbackInfo_.ref = ref;
948     updateCallbackInfo_.tsfn = tsfn;
949 }
950 
SetSubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)951 void SubscriberInstance::SetSubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
952 {
953     subscribeCallbackInfo_.env = env;
954     subscribeCallbackInfo_.ref = ref;
955 }
956 
SetSubscribeCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)957 void SubscriberInstance::SetSubscribeCallbackInfo(const napi_env &env, const napi_ref &ref,
958     const napi_threadsafe_function &tsfn)
959 {
960     subscribeCallbackInfo_.env = env;
961     subscribeCallbackInfo_.ref = ref;
962     subscribeCallbackInfo_.tsfn = tsfn;
963 }
964 
SetUnsubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)965 void SubscriberInstance::SetUnsubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
966 {
967     unsubscribeCallbackInfo_.env = env;
968     unsubscribeCallbackInfo_.ref = ref;
969 }
970 
SetUnsubscribeCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)971 void SubscriberInstance::SetUnsubscribeCallbackInfo(const napi_env &env, const napi_ref &ref,
972     const napi_threadsafe_function &tsfn)
973 {
974     unsubscribeCallbackInfo_.env = env;
975     unsubscribeCallbackInfo_.ref = ref;
976     unsubscribeCallbackInfo_.tsfn = tsfn;
977 }
978 
SetDieCallbackInfo(const napi_env & env,const napi_ref & ref)979 void SubscriberInstance::SetDieCallbackInfo(const napi_env &env, const napi_ref &ref)
980 {
981     dieCallbackInfo_.env = env;
982     dieCallbackInfo_.ref = ref;
983 }
984 
SetDieCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)985 void SubscriberInstance::SetDieCallbackInfo(const napi_env &env, const napi_ref &ref,
986     const napi_threadsafe_function &tsfn)
987 {
988     dieCallbackInfo_.env = env;
989     dieCallbackInfo_.ref = ref;
990     dieCallbackInfo_.tsfn = tsfn;
991 }
992 
SetDisturbModeCallbackInfo(const napi_env & env,const napi_ref & ref)993 void SubscriberInstance::SetDisturbModeCallbackInfo(const napi_env &env, const napi_ref &ref)
994 {
995     disturbModeCallbackInfo_.env = env;
996     disturbModeCallbackInfo_.ref = ref;
997 }
998 
SetDisturbModeCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)999 void SubscriberInstance::SetDisturbModeCallbackInfo(const napi_env &env, const napi_ref &ref,
1000     const napi_threadsafe_function &tsfn)
1001 {
1002     disturbModeCallbackInfo_.env = env;
1003     disturbModeCallbackInfo_.ref = ref;
1004     disturbModeCallbackInfo_.tsfn = tsfn;
1005 }
1006 
SetEnabledNotificationCallbackInfo(const napi_env & env,const napi_ref & ref)1007 void SubscriberInstance::SetEnabledNotificationCallbackInfo(const napi_env &env, const napi_ref &ref)
1008 {
1009     enabledNotificationCallbackInfo_.env = env;
1010     enabledNotificationCallbackInfo_.ref = ref;
1011 }
1012 
SetEnabledNotificationCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)1013 void SubscriberInstance::SetEnabledNotificationCallbackInfo(const napi_env &env, const napi_ref &ref,
1014     const napi_threadsafe_function &tsfn)
1015 {
1016     enabledNotificationCallbackInfo_.env = env;
1017     enabledNotificationCallbackInfo_.ref = ref;
1018     enabledNotificationCallbackInfo_.tsfn = tsfn;
1019 }
1020 
SetDisturbDateCallbackInfo(const napi_env & env,const napi_ref & ref)1021 void SubscriberInstance::SetDisturbDateCallbackInfo(const napi_env &env, const napi_ref &ref)
1022 {
1023     disturbDateCallbackInfo_.env = env;
1024     disturbDateCallbackInfo_.ref = ref;
1025 }
1026 
SetDisturbDateCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)1027 void SubscriberInstance::SetDisturbDateCallbackInfo(const napi_env &env, const napi_ref &ref,
1028     const napi_threadsafe_function &tsfn)
1029 {
1030     disturbDateCallbackInfo_.env = env;
1031     disturbDateCallbackInfo_.ref = ref;
1032     disturbDateCallbackInfo_.tsfn = tsfn;
1033 }
1034 
SetDisturbChangedCallbackInfo(const napi_env & env,const napi_ref & ref)1035 void SubscriberInstance::SetDisturbChangedCallbackInfo(const napi_env &env, const napi_ref &ref)
1036 {
1037     disturbChangedCallbackInfo_.env = env;
1038     disturbChangedCallbackInfo_.ref = ref;
1039 }
1040 
SetDisturbChangedCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)1041 void SubscriberInstance::SetDisturbChangedCallbackInfo(const napi_env &env, const napi_ref &ref,
1042     const napi_threadsafe_function &tsfn)
1043 {
1044     disturbChangedCallbackInfo_.env = env;
1045     disturbChangedCallbackInfo_.ref = ref;
1046     disturbChangedCallbackInfo_.tsfn = tsfn;
1047 }
1048 
SetBadgeCallbackInfo(const napi_env & env,const napi_ref & ref)1049 void SubscriberInstance::SetBadgeCallbackInfo(const napi_env &env, const napi_ref &ref)
1050 {
1051     setBadgeCallbackInfo_.env = env;
1052     setBadgeCallbackInfo_.ref = ref;
1053 }
1054 
SetBadgeCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)1055 void SubscriberInstance::SetBadgeCallbackInfo(const napi_env &env, const napi_ref &ref,
1056     const napi_threadsafe_function &tsfn)
1057 {
1058     setBadgeCallbackInfo_.env = env;
1059     setBadgeCallbackInfo_.ref = ref;
1060     setBadgeCallbackInfo_.tsfn = tsfn;
1061 }
1062 
SetBadgeEnabledCallbackInfo(const napi_env & env,const napi_ref & ref)1063 void SubscriberInstance::SetBadgeEnabledCallbackInfo(const napi_env &env, const napi_ref &ref)
1064 {
1065     setBadgeEnabledCallbackInfo_.env = env;
1066     setBadgeEnabledCallbackInfo_.ref = ref;
1067 }
1068 
SetBadgeEnabledCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)1069 void SubscriberInstance::SetBadgeEnabledCallbackInfo(const napi_env &env, const napi_ref &ref,
1070     const napi_threadsafe_function &tsfn)
1071 {
1072     setBadgeEnabledCallbackInfo_.env = env;
1073     setBadgeEnabledCallbackInfo_.ref = ref;
1074     setBadgeEnabledCallbackInfo_.tsfn = tsfn;
1075 }
1076 
SetBatchCancelCallbackInfo(const napi_env & env,const napi_ref & ref)1077 void SubscriberInstance::SetBatchCancelCallbackInfo(const napi_env &env, const napi_ref &ref)
1078 {
1079     batchCancelCallbackInfo_.env = env;
1080     batchCancelCallbackInfo_.ref = ref;
1081 }
1082 
SetBatchCancelCallbackInfo(const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)1083 void SubscriberInstance::SetBatchCancelCallbackInfo(const napi_env &env, const napi_ref &ref,
1084     const napi_threadsafe_function &tsfn)
1085 {
1086     batchCancelCallbackInfo_.env = env;
1087     batchCancelCallbackInfo_.ref = ref;
1088     batchCancelCallbackInfo_.tsfn = tsfn;
1089 }
1090 
1091 
SetCallbackInfo(const napi_env & env,const std::string & type,const napi_ref & ref)1092 void SubscriberInstance::SetCallbackInfo(const napi_env &env, const std::string &type, const napi_ref &ref)
1093 {
1094     if (type == CONSUME) {
1095         SetConsumeCallbackInfo(env, ref);
1096     } else if (type == CANCEL) {
1097         SetCancelCallbackInfo(env, ref);
1098     } else if (type == UPDATE) {
1099         SetUpdateCallbackInfo(env, ref);
1100     } else if (type == CONNECTED) {
1101         SetSubscribeCallbackInfo(env, ref);
1102     } else if (type == DIS_CONNECTED) {
1103         SetUnsubscribeCallbackInfo(env, ref);
1104     } else if (type == DIE) {
1105         SetDieCallbackInfo(env, ref);
1106     } else if (type == DISTURB_MODE_CHANGE) {
1107         SetDisturbModeCallbackInfo(env, ref);
1108     } else if (type == DISTURB_DATE_CHANGE) {
1109         SetDisturbDateCallbackInfo(env, ref);
1110     } else if (type == DISTURB_CHANGED) {
1111         SetDisturbChangedCallbackInfo(env, ref);
1112     } else if (type == ENABLE_NOTIFICATION_CHANGED) {
1113         SetEnabledNotificationCallbackInfo(env, ref);
1114     } else if (type == BADGE_CHANGED) {
1115         SetBadgeCallbackInfo(env, ref);
1116     } else if (type == BADGE_ENABLED_CHANGED) {
1117         SetBadgeEnabledCallbackInfo(env, ref);
1118     } else if (type == BATCH_CANCEL) {
1119         SetBatchCancelCallbackInfo(env, ref);
1120     } else {
1121         ANS_LOGW("type is error");
1122     }
1123 }
1124 
1125 
SetCallbackInfo(const std::string & type,const napi_env & env,const napi_ref & ref,const napi_threadsafe_function & tsfn)1126 void SubscriberInstance::SetCallbackInfo(const std::string &type, const napi_env &env, const napi_ref &ref,
1127     const napi_threadsafe_function &tsfn)
1128 {
1129     if (type == CONSUME) {
1130         SetConsumeCallbackInfo(env, ref, tsfn);
1131     } else if (type == CANCEL) {
1132         SetCancelCallbackInfo(env, ref, tsfn);
1133     } else if (type == UPDATE) {
1134         SetUpdateCallbackInfo(env, ref, tsfn);
1135     } else if (type == CONNECTED) {
1136         SetSubscribeCallbackInfo(env, ref, tsfn);
1137     } else if (type == DIS_CONNECTED) {
1138         SetUnsubscribeCallbackInfo(env, ref, tsfn);
1139     } else if (type == DIE) {
1140         SetDieCallbackInfo(env, ref, tsfn);
1141     } else if (type == DISTURB_MODE_CHANGE) {
1142         SetDisturbModeCallbackInfo(env, ref, tsfn);
1143     } else if (type == DISTURB_DATE_CHANGE) {
1144         SetDisturbDateCallbackInfo(env, ref, tsfn);
1145     } else if (type == DISTURB_CHANGED) {
1146         SetDisturbChangedCallbackInfo(env, ref, tsfn);
1147     } else if (type == ENABLE_NOTIFICATION_CHANGED) {
1148         SetEnabledNotificationCallbackInfo(env, ref, tsfn);
1149     } else if (type == BADGE_CHANGED) {
1150         SetBadgeCallbackInfo(env, ref, tsfn);
1151     } else if (type == BADGE_ENABLED_CHANGED) {
1152         SetBadgeEnabledCallbackInfo(env, ref, tsfn);
1153     } else if (type == BATCH_CANCEL) {
1154         SetBatchCancelCallbackInfo(env, ref, tsfn);
1155     } else {
1156         ANS_LOGW("type is error");
1157     }
1158 }
1159 
HasNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)1160 bool HasNotificationSubscriber(const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
1161 {
1162     std::lock_guard<std::mutex> lock(mutex_);
1163     for (auto vec : subscriberInstances_) {
1164         napi_value callback = nullptr;
1165         napi_get_reference_value(env, vec.ref, &callback);
1166         bool isEquals = false;
1167         napi_strict_equals(env, value, callback, &isEquals);
1168         if (isEquals) {
1169             subscriberInfo = vec;
1170             return true;
1171         }
1172     }
1173     return false;
1174 }
1175 
ThreadFinished(napi_env env,void * data,void * context)1176 void ThreadFinished(napi_env env, void* data, [[maybe_unused]] void* context)
1177 {
1178     ANS_LOGD("ThreadFinished");
1179 }
1180 
ThreadSafeCommon(napi_env env,napi_value jsCallback,void * context,void * data)1181 void ThreadSafeCommon(napi_env env, napi_value jsCallback, void* context, void* data)
1182 {
1183     ANS_LOGI("common thread safe start");
1184     auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
1185     switch (dataWorkerData->type) {
1186         case Type::CANCEL:
1187             ThreadSafeOnCancel(env, jsCallback, context, data);
1188             break;
1189         case Type::BATCH_CANCEL:
1190             ThreadSafeOnBatchCancel(env, jsCallback, context, data);
1191             break;
1192         case Type::CONSUME:
1193             ThreadSafeOnConsumed(env, jsCallback, context, data);
1194             break;
1195         case Type::UPDATE:
1196             ThreadSafeOnUpdate(env, jsCallback, context, data);
1197             break;
1198         case Type::CONNECTED:
1199             ThreadSafeOnConnected(env, jsCallback, context, data);
1200             break;
1201         case Type::DIS_CONNECTED:
1202             ThreadSafeOnDisconnected(env, jsCallback, context, data);
1203             break;
1204         case Type::DIE:
1205             ThreadSafeOnDestroy(env, jsCallback, context, data);
1206             break;
1207         case Type::DISTURB_DATE_CHANGE:
1208             ThreadSafeOnDoNotDisturbDateChange(env, jsCallback, context, data);
1209             break;
1210         case Type::DISTURB_CHANGED:
1211             ThreadSafeOnDoNotDisturbChanged(env, jsCallback, context, data);
1212             break;
1213         case Type::ENABLE_NOTIFICATION_CHANGED:
1214             ThreadSafeOnEnabledNotificationChanged(env, jsCallback, context, data);
1215             break;
1216         case Type::BADGE_CHANGED:
1217             ThreadSafeOnBadgeChanged(env, jsCallback, context, data);
1218             break;
1219         case Type::BADGE_ENABLED_CHANGED:
1220             ThreadSafeOnBadgeEnabledChanged(env, jsCallback, context, data);
1221             break;
1222         default:
1223             break;
1224     }
1225 }
1226 
GetNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)1227 napi_value GetNotificationSubscriber(
1228     const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
1229 {
1230     ANS_LOGD("enter");
1231     bool hasProperty = false;
1232     napi_valuetype valuetype = napi_undefined;
1233     napi_ref result = nullptr;
1234 
1235     subscriberInfo.subscriber = std::make_shared<SubscriberInstance>();
1236     if (subscriberInfo.subscriber == nullptr) {
1237         ANS_LOGE("subscriber is null");
1238         std::string msg = "Mandatory parameters are left unspecified. subscriber is null";
1239         Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1240         return nullptr;
1241     }
1242 
1243     napi_create_reference(env, value, 1, &subscriberInfo.ref);
1244 
1245     napi_value resourceName = nullptr;
1246     napi_create_string_latin1(env, "tsfn", NAPI_AUTO_LENGTH, &resourceName);
1247     napi_threadsafe_function tsfn = nullptr;
1248     napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 0, 1, subscriberInfo.ref,
1249         ThreadFinished, nullptr, ThreadSafeCommon, &tsfn);
1250 
1251     // onConsume?:(data: SubscribeCallbackData) => void
1252     NAPI_CALL(env, napi_has_named_property(env, value, "onConsume", &hasProperty));
1253     if (hasProperty) {
1254         napi_value nOnConsumed = nullptr;
1255         napi_get_named_property(env, value, "onConsume", &nOnConsumed);
1256         NAPI_CALL(env, napi_typeof(env, nOnConsumed, &valuetype));
1257         if (valuetype != napi_function) {
1258             ANS_LOGE("Wrong argument type. Function expected.");
1259             std::string msg = "Incorrect parameter types.The type of param must be function.";
1260             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1261             return nullptr;
1262         }
1263         napi_create_reference(env, nOnConsumed, 1, &result);
1264         subscriberInfo.subscriber->SetCallbackInfo(CONSUME, env, result, tsfn);
1265     }
1266     // onCancel?:(data: SubscribeCallbackData) => void
1267     NAPI_CALL(env, napi_has_named_property(env, value, "onCancel", &hasProperty));
1268     if (hasProperty) {
1269         napi_value nOnCanceled = nullptr;
1270         napi_get_named_property(env, value, "onCancel", &nOnCanceled);
1271         NAPI_CALL(env, napi_typeof(env, nOnCanceled, &valuetype));
1272         if (valuetype != napi_function) {
1273             ANS_LOGE("Wrong argument type. Function expected.");
1274             std::string msg = "Incorrect parameter types.The type of param must be function.";
1275             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1276             return nullptr;
1277         }
1278         napi_create_reference(env, nOnCanceled, 1, &result);
1279         subscriberInfo.subscriber->SetCallbackInfo(CANCEL, env, result, tsfn);
1280     }
1281     // onUpdate?:(data: NotificationSortingMap) => void
1282     NAPI_CALL(env, napi_has_named_property(env, value, "onUpdate", &hasProperty));
1283     if (hasProperty) {
1284         napi_value nOnUpdate = nullptr;
1285         napi_get_named_property(env, value, "onUpdate", &nOnUpdate);
1286         NAPI_CALL(env, napi_typeof(env, nOnUpdate, &valuetype));
1287         if (valuetype != napi_function) {
1288             ANS_LOGE("Wrong argument type. Function expected.");
1289             std::string msg = "Incorrect parameter types.The type of param must be function.";
1290             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1291             return nullptr;
1292         }
1293         napi_create_reference(env, nOnUpdate, 1, &result);
1294         subscriberInfo.subscriber->SetCallbackInfo(UPDATE, env, result, tsfn);
1295     }
1296     // onConnect?:() => void
1297     NAPI_CALL(env, napi_has_named_property(env, value, "onConnect", &hasProperty));
1298     if (hasProperty) {
1299         napi_value nOnConnected = nullptr;
1300         napi_get_named_property(env, value, "onConnect", &nOnConnected);
1301         NAPI_CALL(env, napi_typeof(env, nOnConnected, &valuetype));
1302         if (valuetype != napi_function) {
1303             ANS_LOGE("Wrong argument type. Function expected.");
1304             std::string msg = "Incorrect parameter types.The type of param must be function.";
1305             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1306             return nullptr;
1307         }
1308         napi_create_reference(env, nOnConnected, 1, &result);
1309         subscriberInfo.subscriber->SetCallbackInfo(CONNECTED, env, result, tsfn);
1310     }
1311     // onDisconnect?:() => void
1312     NAPI_CALL(env, napi_has_named_property(env, value, "onDisconnect", &hasProperty));
1313     if (hasProperty) {
1314         napi_value nOnDisConnect = nullptr;
1315         napi_get_named_property(env, value, "onDisconnect", &nOnDisConnect);
1316         NAPI_CALL(env, napi_typeof(env, nOnDisConnect, &valuetype));
1317         if (valuetype != napi_function) {
1318             ANS_LOGE("Wrong argument type. Function expected.");
1319             std::string msg = "Incorrect parameter types.The type of param must be function.";
1320             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1321             return nullptr;
1322         }
1323         napi_create_reference(env, nOnDisConnect, 1, &result);
1324         subscriberInfo.subscriber->SetCallbackInfo(DIS_CONNECTED, env, result, tsfn);
1325     }
1326     // onDestroy?:() => void
1327     NAPI_CALL(env, napi_has_named_property(env, value, "onDestroy", &hasProperty));
1328     if (hasProperty) {
1329         napi_value nOnDied = nullptr;
1330         napi_get_named_property(env, value, "onDestroy", &nOnDied);
1331         NAPI_CALL(env, napi_typeof(env, nOnDied, &valuetype));
1332         if (valuetype != napi_function) {
1333             ANS_LOGE("Wrong argument type. Function expected.");
1334             std::string msg = "Incorrect parameter types.The type of param must be function.";
1335             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1336             return nullptr;
1337         }
1338         napi_create_reference(env, nOnDied, 1, &result);
1339         subscriberInfo.subscriber->SetCallbackInfo(DIE, env, result, tsfn);
1340     }
1341     // onDisturbModeChange?:(mode: notification.DoNotDisturbMode) => void
1342     NAPI_CALL(env, napi_has_named_property(env, value, "onDisturbModeChange", &hasProperty));
1343     if (hasProperty) {
1344         napi_value nOnDisturbModeChanged = nullptr;
1345         napi_get_named_property(env, value, "onDisturbModeChange", &nOnDisturbModeChanged);
1346         NAPI_CALL(env, napi_typeof(env, nOnDisturbModeChanged, &valuetype));
1347         if (valuetype != napi_function) {
1348             ANS_LOGE("Wrong argument type. Function expected.");
1349             std::string msg = "Incorrect parameter types.The type of param must be function.";
1350             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1351             return nullptr;
1352         }
1353         napi_create_reference(env, nOnDisturbModeChanged, 1, &result);
1354         subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_MODE_CHANGE, result);
1355     }
1356 
1357     // onDoNotDisturbDateChange?:(mode: notification.DoNotDisturbDate) => void
1358     NAPI_CALL(env, napi_has_named_property(env, value, "onDoNotDisturbDateChange", &hasProperty));
1359     if (hasProperty) {
1360         napi_value nOnDisturbDateChanged = nullptr;
1361         napi_get_named_property(env, value, "onDoNotDisturbDateChange", &nOnDisturbDateChanged);
1362         NAPI_CALL(env, napi_typeof(env, nOnDisturbDateChanged, &valuetype));
1363         if (valuetype != napi_function) {
1364             ANS_LOGE("Wrong argument type. Function expected.");
1365             std::string msg = "Incorrect parameter types.The type of param must be function.";
1366             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1367             return nullptr;
1368         }
1369         napi_create_reference(env, nOnDisturbDateChanged, 1, &result);
1370         subscriberInfo.subscriber->SetCallbackInfo(DISTURB_DATE_CHANGE, env, result, tsfn);
1371     }
1372 
1373     // onDoNotDisturbChanged?:(mode: notificationManager.DoNotDisturbDate) => void
1374     NAPI_CALL(env, napi_has_named_property(env, value, "onDoNotDisturbChanged", &hasProperty));
1375     if (hasProperty) {
1376         napi_value nOnDoNotDisturbChanged = nullptr;
1377         napi_get_named_property(env, value, "onDoNotDisturbChanged", &nOnDoNotDisturbChanged);
1378         NAPI_CALL(env, napi_typeof(env, nOnDoNotDisturbChanged, &valuetype));
1379         if (valuetype != napi_function) {
1380             ANS_LOGE("Wrong argument type. Function expected.");
1381             std::string msg = "Incorrect parameter types.The type of param must be function.";
1382             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1383             return nullptr;
1384         }
1385         napi_create_reference(env, nOnDoNotDisturbChanged, 1, &result);
1386         subscriberInfo.subscriber->SetCallbackInfo(DISTURB_CHANGED, env, result, tsfn);
1387     }
1388 
1389     // onEnabledNotificationChanged?:(data: notification.EnabledNotificationCallbackData) => void
1390     NAPI_CALL(env, napi_has_named_property(env, value, "onEnabledNotificationChanged", &hasProperty));
1391     if (hasProperty) {
1392         napi_value nOnEnabledNotificationChanged = nullptr;
1393         napi_get_named_property(env, value, "onEnabledNotificationChanged", &nOnEnabledNotificationChanged);
1394         NAPI_CALL(env, napi_typeof(env, nOnEnabledNotificationChanged, &valuetype));
1395         if (valuetype != napi_function) {
1396             ANS_LOGE("Wrong argument type. Function expected.");
1397             std::string msg = "Incorrect parameter types.The type of param must be function.";
1398             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1399             return nullptr;
1400         }
1401         napi_create_reference(env, nOnEnabledNotificationChanged, 1, &result);
1402         subscriberInfo.subscriber->SetCallbackInfo(ENABLE_NOTIFICATION_CHANGED, env, result, tsfn);
1403     }
1404 
1405     // onBadgeChanged?:(data: BadgeNumberCallbackData) => void
1406     NAPI_CALL(env, napi_has_named_property(env, value, "onBadgeChanged", &hasProperty));
1407     if (hasProperty) {
1408         napi_value nOnBadgeChanged = nullptr;
1409         napi_get_named_property(env, value, "onBadgeChanged", &nOnBadgeChanged);
1410         NAPI_CALL(env, napi_typeof(env, nOnBadgeChanged, &valuetype));
1411         if (valuetype != napi_function) {
1412             ANS_LOGE("Wrong argument type. Function expected.");
1413             std::string msg = "Incorrect parameter types.The type of param must be function.";
1414             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1415             return nullptr;
1416         }
1417         napi_create_reference(env, nOnBadgeChanged, 1, &result);
1418         subscriberInfo.subscriber->SetCallbackInfo(BADGE_CHANGED, env, result, tsfn);
1419     }
1420 
1421     // onBadgeEnabledChanged?:(data: EnabledNotificationCallbackData) => void
1422     NAPI_CALL(env, napi_has_named_property(env, value, "onBadgeEnabledChanged", &hasProperty));
1423     if (hasProperty) {
1424         napi_value nOnBadgeEnabledChanged = nullptr;
1425         napi_get_named_property(env, value, "onBadgeEnabledChanged", &nOnBadgeEnabledChanged);
1426         NAPI_CALL(env, napi_typeof(env, nOnBadgeEnabledChanged, &valuetype));
1427         if (valuetype != napi_function) {
1428             ANS_LOGE("Wrong argument type. Function expected.");
1429             std::string msg = "Incorrect parameter types.The type of param must be function.";
1430             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1431             return nullptr;
1432         }
1433         napi_create_reference(env, nOnBadgeEnabledChanged, 1, &result);
1434         subscriberInfo.subscriber->SetCallbackInfo(BADGE_ENABLED_CHANGED, env, result, tsfn);
1435     }
1436 
1437     // onBatchCancel?:(data: Array<SubscribeCallbackData>) => void
1438     NAPI_CALL(env, napi_has_named_property(env, value, "onBatchCancel", &hasProperty));
1439     if (hasProperty) {
1440         napi_value onBatchCancel = nullptr;
1441         napi_get_named_property(env, value, "onBatchCancel", &onBatchCancel);
1442         NAPI_CALL(env, napi_typeof(env, onBatchCancel, &valuetype));
1443         if (valuetype != napi_function) {
1444             ANS_LOGE("Wrong argument type. Function expected.");
1445             std::string msg = "Incorrect parameter types.The type of param must be function.";
1446             Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1447             return nullptr;
1448         }
1449         napi_create_reference(env, onBatchCancel, 1, &result);
1450         subscriberInfo.subscriber->SetCallbackInfo(BATCH_CANCEL, env, result, tsfn);
1451     }
1452 
1453     return Common::NapiGetNull(env);
1454 }
1455 
AddSubscriberInstancesInfo(const napi_env & env,const SubscriberInstancesInfo & subscriberInfo)1456 bool AddSubscriberInstancesInfo(const napi_env &env, const SubscriberInstancesInfo &subscriberInfo)
1457 {
1458     ANS_LOGD("enter");
1459     if (subscriberInfo.ref == nullptr) {
1460         ANS_LOGE("subscriberInfo.ref is null");
1461         return false;
1462     }
1463     if (subscriberInfo.subscriber == nullptr) {
1464         ANS_LOGE("subscriberInfo.subscriber is null");
1465         return false;
1466     }
1467     std::lock_guard<std::mutex> lock(mutex_);
1468     subscriberInstances_.emplace_back(subscriberInfo);
1469 
1470     return true;
1471 }
1472 
DelSubscriberInstancesInfo(const napi_env & env,const std::shared_ptr<SubscriberInstance> subscriber)1473 bool DelSubscriberInstancesInfo(const napi_env &env, const std::shared_ptr<SubscriberInstance> subscriber)
1474 {
1475     ANS_LOGD("enter");
1476     if (subscriber == nullptr) {
1477         ANS_LOGE("subscriber is null");
1478         return false;
1479     }
1480     std::lock_guard<std::mutex> lock(delMutex_);
1481     auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1482     if (iter != DeletingSubscriber.end()) {
1483         DeletingSubscriber.erase(iter);
1484         std::lock_guard<std::mutex> lock(mutex_);
1485         for (auto it = subscriberInstances_.begin(); it != subscriberInstances_.end(); ++it) {
1486             if ((*it).subscriber == subscriber) {
1487                 if ((*it).ref != nullptr) {
1488                     napi_delete_reference(env, (*it).ref);
1489                 }
1490                 subscriberInstances_.erase(it);
1491                 return true;
1492             }
1493         }
1494     }
1495     return false;
1496 }
ParseParameters(const napi_env & env,const napi_callback_info & info,NotificationSubscribeInfo & subscriberInfo,std::shared_ptr<SubscriberInstance> & subscriber,napi_ref & callback)1497 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info,
1498     NotificationSubscribeInfo &subscriberInfo, std::shared_ptr<SubscriberInstance> &subscriber, napi_ref &callback)
1499 {
1500     ANS_LOGD("enter");
1501 
1502     size_t argc = SUBSRIBE_MAX_PARA;
1503     napi_value argv[SUBSRIBE_MAX_PARA] = {nullptr};
1504     napi_value thisVar = nullptr;
1505     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
1506     if (argc < 1) {
1507         ANS_LOGE("Wrong number of arguments");
1508         Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED);
1509         return nullptr;
1510     }
1511 
1512     napi_valuetype valuetype = napi_undefined;
1513 
1514     // argv[0]:subscriber
1515     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
1516     if (valuetype != napi_object) {
1517         ANS_LOGE("Wrong argument type for arg0. NotificationSubscriber object expected.");
1518         std::string msg = "Incorrect parameter types.The type of param must be NotificationSubscriber.";
1519         Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1520         return nullptr;
1521     }
1522 
1523     SubscriberInstancesInfo subscriberInstancesInfo;
1524     if (!HasNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo)) {
1525         if (GetNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo) == nullptr) {
1526             ANS_LOGE("NotificationSubscriber parse failed");
1527             return nullptr;
1528         }
1529         if (!AddSubscriberInstancesInfo(env, subscriberInstancesInfo)) {
1530             ANS_LOGE("AddSubscriberInstancesInfo add failed");
1531             return nullptr;
1532         }
1533     }
1534     subscriber = subscriberInstancesInfo.subscriber;
1535 
1536     // argv[1]:callback or NotificationSubscribeInfo
1537     if (argc >= SUBSRIBE_MAX_PARA - 1) {
1538         NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
1539         if ((valuetype != napi_function) && (valuetype != napi_object)) {
1540             ANS_LOGE("Wrong argument type for arg1."
1541                 "Function or NotificationSubscribeInfo object expected. Excute promise");
1542             return Common::NapiGetNull(env);
1543         }
1544         if (valuetype == napi_function) {
1545             napi_create_reference(env, argv[PARAM1], 1, &callback);
1546         } else {
1547             if (Common::GetNotificationSubscriberInfo(env, argv[PARAM1], subscriberInfo) == nullptr) {
1548                 ANS_LOGE("NotificationSubscribeInfo parse failed");
1549                 return nullptr;
1550             }
1551         }
1552     }
1553 
1554     // argv[2]:callback
1555     if (argc >= SUBSRIBE_MAX_PARA) {
1556         NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
1557         if (valuetype != napi_function) {
1558             ANS_LOGE("Callback is not function enforce promise.");
1559             return Common::NapiGetNull(env);
1560         }
1561         napi_create_reference(env, argv[PARAM2], 1, &callback);
1562     }
1563 
1564     return Common::NapiGetNull(env);
1565 }
1566 
Subscribe(napi_env env,napi_callback_info info)1567 napi_value Subscribe(napi_env env, napi_callback_info info)
1568 {
1569     ANS_LOGD("enter");
1570 
1571     napi_ref callback = nullptr;
1572     std::shared_ptr<SubscriberInstance> objectInfo = nullptr;
1573     NotificationSubscribeInfo subscriberInfo;
1574     if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
1575         ANS_LOGD("ParseParameters is nullptr.");
1576         return Common::NapiGetUndefined(env);
1577     }
1578 
1579     AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
1580         .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
1581     };
1582     if (!asynccallbackinfo) {
1583         ANS_LOGD("Asynccallbackinfo is nullptr.");
1584         return Common::JSParaError(env, callback);
1585     }
1586     napi_value promise = nullptr;
1587     Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
1588 
1589     ANS_LOGD("Create subscribeNotification string.");
1590     napi_value resourceName = nullptr;
1591     napi_create_string_latin1(env, "subscribeNotification", NAPI_AUTO_LENGTH, &resourceName);
1592     // Asynchronous function call
1593     napi_create_async_work(env,
1594         nullptr,
1595         resourceName,
1596         [](napi_env env, void *data) {
1597             ANS_LOGD("Subscribe work excuted.");
1598             if (!data) {
1599                 ANS_LOGE("Invalid asynccallbackinfo!");
1600                 return;
1601             }
1602             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
1603             if (asynccallbackinfo) {
1604                 if (asynccallbackinfo->subscriberInfo.hasSubscribeInfo) {
1605                     ANS_LOGD("Subscribe with NotificationSubscribeInfo excute.");
1606                     OHOS::Notification::NotificationSubscribeInfo subscribeInfo;
1607                     subscribeInfo.AddAppNames(asynccallbackinfo->subscriberInfo.bundleNames);
1608                     subscribeInfo.AddAppUserId(asynccallbackinfo->subscriberInfo.userId);
1609                     asynccallbackinfo->info.errorCode =
1610                         NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo), subscribeInfo);
1611                 } else {
1612                     ANS_LOGD("SubscribeNotification execute.");
1613                     asynccallbackinfo->info.errorCode =
1614                         NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo));
1615                 }
1616             }
1617         },
1618         [](napi_env env, napi_status status, void *data) {
1619             ANS_LOGD("Subscribe work complete.");
1620             if (!data) {
1621                 ANS_LOGE("Invalid asynccallbackinfo!");
1622                 return;
1623             }
1624             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
1625             if (asynccallbackinfo) {
1626                 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
1627                 if (asynccallbackinfo->info.callback != nullptr) {
1628                     ANS_LOGD("Delete subscribe callback reference.");
1629                     napi_delete_reference(env, asynccallbackinfo->info.callback);
1630                 }
1631                 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
1632                 delete asynccallbackinfo;
1633                 asynccallbackinfo = nullptr;
1634             }
1635             ANS_LOGD("Subscribe work complete end.");
1636         },
1637         (void *)asynccallbackinfo,
1638         &asynccallbackinfo->asyncWork);
1639 
1640     napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
1641 
1642     if (asynccallbackinfo->info.isCallback) {
1643         ANS_LOGD("subscribe callback is nullptr.");
1644         return Common::NapiGetNull(env);
1645     } else {
1646         return promise;
1647     }
1648 }
1649 
AddDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)1650 bool AddDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)
1651 {
1652     std::lock_guard<std::mutex> lock(delMutex_);
1653     auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1654     if (iter != DeletingSubscriber.end()) {
1655         return false;
1656     }
1657 
1658     DeletingSubscriber.push_back(subscriber);
1659     return true;
1660 }
1661 
DelDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)1662 void DelDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)
1663 {
1664     std::lock_guard<std::mutex> lock(delMutex_);
1665     auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1666     if (iter != DeletingSubscriber.end()) {
1667         DeletingSubscriber.erase(iter);
1668     }
1669 }
1670 }  // namespace NotificationNapi
1671 }  // namespace OHOS