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