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