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