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