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
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
407 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
408 if (dataWorker == nullptr) {
409 ANS_LOGE("new dataWorker failed");
410 return;
411 }
412
413 dataWorker->request = request;
414 dataWorker->sortingMap = sortingMap;
415 dataWorker->env = consumeCallbackInfo_.env;
416 dataWorker->ref = consumeCallbackInfo_.ref;
417 dataWorker->type = Type::CONSUME;
418 napi_acquire_threadsafe_function(tsfn_);
419 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
420 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
421 }
422
ThreadSafeOnUpdate(napi_env env,napi_value jsCallback,void * context,void * data)423 void ThreadSafeOnUpdate(napi_env env, napi_value jsCallback, void* context, void* data)
424 {
425 ANS_LOGI("OnUpdate thread safe start");
426
427 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
428 if (dataWorkerData == nullptr) {
429 ANS_LOGE("dataWorkerData is nullptr");
430 return;
431 }
432 napi_value result = nullptr;
433 napi_handle_scope scope;
434 napi_open_handle_scope(dataWorkerData->env, &scope);
435 if (scope == nullptr) {
436 ANS_LOGE("Scope is null");
437 return;
438 }
439 napi_create_object(dataWorkerData->env, &result);
440 if (!Common::SetNotificationSortingMap(dataWorkerData->env, dataWorkerData->sortingMap, result)) {
441 ANS_LOGE("Failed to convert data to JS");
442 } else {
443 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
444 }
445 napi_close_handle_scope(dataWorkerData->env, scope);
446
447 delete dataWorkerData;
448 dataWorkerData = nullptr;
449 }
450
OnUpdate(const std::shared_ptr<NotificationSortingMap> & sortingMap)451 void SubscriberInstance::OnUpdate(const std::shared_ptr<NotificationSortingMap> &sortingMap)
452 {
453 ANS_LOGD("enter");
454
455 if (updateCallbackInfo_.ref == nullptr || updateCallbackInfo_.env == nullptr) {
456 ANS_LOGI("update callback or env unset");
457 return;
458 }
459
460 if (sortingMap == nullptr) {
461 ANS_LOGE("sortingMap is null");
462 return;
463 }
464 ANS_LOGI("OnUpdate sortingMap size = %{public}zu", sortingMap->GetKey().size());
465
466 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
467 if (dataWorker == nullptr) {
468 ANS_LOGE("new dataWorker failed");
469 return;
470 }
471
472 dataWorker->sortingMap = sortingMap;
473 dataWorker->env = updateCallbackInfo_.env;
474 dataWorker->ref = updateCallbackInfo_.ref;
475 dataWorker->type = Type::UPDATE;
476
477 napi_acquire_threadsafe_function(tsfn_);
478 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
479 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
480 }
481
ThreadSafeOnConnected(napi_env env,napi_value jsCallback,void * context,void * data)482 void ThreadSafeOnConnected(napi_env env, napi_value jsCallback, void* context, void* data)
483 {
484 ANS_LOGD("OnConnected thread safe start");
485 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
486 if (dataWorkerData == nullptr) {
487 ANS_LOGE("dataWorkerData is nullptr.");
488 return;
489 }
490
491 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
492
493 delete dataWorkerData;
494 dataWorkerData = nullptr;
495 }
496
OnConnected()497 void SubscriberInstance::OnConnected()
498 {
499 ANS_LOGD("enter");
500
501 if (subscribeCallbackInfo_.ref == nullptr || subscribeCallbackInfo_.env == nullptr) {
502 ANS_LOGI("subscribe callback or env unset");
503 return;
504 }
505
506 if (tsfn_ == nullptr) {
507 ANS_LOGI("subscribe tsfn is null");
508 return;
509 }
510
511 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
512 if (dataWorker == nullptr) {
513 ANS_LOGE("new dataWorker failed");
514 return;
515 }
516
517 dataWorker->env = subscribeCallbackInfo_.env;
518 dataWorker->ref = subscribeCallbackInfo_.ref;
519 dataWorker->type = Type::CONNECTED;
520
521 napi_acquire_threadsafe_function(tsfn_);
522 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
523 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
524 }
525
ThreadSafeOnDisconnected(napi_env env,napi_value jsCallback,void * context,void * data)526 void ThreadSafeOnDisconnected(napi_env env, napi_value jsCallback, void* context, void* data)
527 {
528 ANS_LOGI("OnDisconnected thread safe start");
529
530 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
531 if (dataWorkerData == nullptr) {
532 ANS_LOGE("Failed to create dataWorkerData.");
533 return;
534 }
535
536 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
537 DelSubscriberInstancesInfo(dataWorkerData->env, dataWorkerData->subscriber);
538 delete dataWorkerData;
539 dataWorkerData = nullptr;
540 }
541
OnDisconnected()542 void SubscriberInstance::OnDisconnected()
543 {
544 ANS_LOGD("enter");
545
546 if (unsubscribeCallbackInfo_.ref == nullptr) {
547 ANS_LOGI("unsubscribe callback unset");
548 return;
549 }
550
551 if (tsfn_ == nullptr) {
552 ANS_LOGI("unsubscribe tsfn is null");
553 return;
554 }
555
556 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
557 if (dataWorker == nullptr) {
558 ANS_LOGE("new dataWorker failed");
559 return;
560 }
561
562 dataWorker->env = unsubscribeCallbackInfo_.env;
563 dataWorker->ref = unsubscribeCallbackInfo_.ref;
564 dataWorker->subscriber = std::static_pointer_cast<SubscriberInstance>(shared_from_this());
565 dataWorker->type = Type::DIS_CONNECTED;
566
567 napi_acquire_threadsafe_function(tsfn_);
568 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
569 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
570 }
571
ThreadSafeOnDestroy(napi_env env,napi_value jsCallback,void * context,void * data)572 void ThreadSafeOnDestroy(napi_env env, napi_value jsCallback, void* context, void* data)
573 {
574 ANS_LOGI("OnDied thread safe start");
575
576 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
577 if (dataWorkerData == nullptr) {
578 ANS_LOGE("dataWorkerData is null");
579 return;
580 }
581
582 Common::SetCallback(
583 dataWorkerData->env, dataWorkerData->ref, Common::NapiGetNull(dataWorkerData->env));
584
585 delete dataWorkerData;
586 dataWorkerData = nullptr;
587 }
588
OnDied()589 void SubscriberInstance::OnDied()
590 {
591 ANS_LOGD("enter");
592
593 if (dieCallbackInfo_.ref == nullptr) {
594 ANS_LOGE("die callback unset");
595 return;
596 }
597
598 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
599 if (dataWorker == nullptr) {
600 ANS_LOGE("new dataWorker failed");
601 return;
602 }
603
604 dataWorker->env = dieCallbackInfo_.env;
605 dataWorker->ref = dieCallbackInfo_.ref;
606 dataWorker->type = Type::DIE;
607
608 napi_acquire_threadsafe_function(tsfn_);
609 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
610 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
611 }
612
ThreadSafeOnDoNotDisturbDateChange(napi_env env,napi_value jsCallback,void * context,void * data)613 void ThreadSafeOnDoNotDisturbDateChange(napi_env env, napi_value jsCallback, void* context, void* data)
614 {
615 ANS_LOGI("OnDoNotDisturbDateChange thread safe start");
616
617 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
618 if (dataWorkerData == nullptr) {
619 ANS_LOGE("Data worker data is null.");
620 return;
621 }
622
623 napi_value result = nullptr;
624 napi_handle_scope scope;
625 napi_open_handle_scope(dataWorkerData->env, &scope);
626 if (scope == nullptr) {
627 ANS_LOGE("Scope is null");
628 return;
629 }
630 napi_create_object(dataWorkerData->env, &result);
631
632 if (!Common::SetDoNotDisturbDate(dataWorkerData->env, dataWorkerData->date, result)) {
633 result = Common::NapiGetNull(dataWorkerData->env);
634 }
635
636 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
637 napi_close_handle_scope(dataWorkerData->env, scope);
638
639 delete dataWorkerData;
640 dataWorkerData = nullptr;
641 }
642
OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> & date)643 void SubscriberInstance::OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> &date)
644 {
645 ANS_LOGD("enter");
646
647 onDoNotDisturbChanged(date);
648
649 if (disturbDateCallbackInfo_.ref == nullptr || disturbDateCallbackInfo_.env == nullptr) {
650 ANS_LOGI("disturbDateCallbackInfo_ callback or env unset");
651 return;
652 }
653
654 if (date == nullptr) {
655 ANS_LOGE("date is null");
656 return;
657 }
658
659 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
660 if (dataWorker == nullptr) {
661 ANS_LOGE("new dataWorker failed");
662 return;
663 }
664
665 dataWorker->date = *date;
666 dataWorker->env = disturbDateCallbackInfo_.env;
667 dataWorker->ref = disturbDateCallbackInfo_.ref;
668 dataWorker->type = Type::DISTURB_DATE_CHANGE;
669
670 napi_acquire_threadsafe_function(tsfn_);
671 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
672 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
673 }
674
675
ThreadSafeOnDoNotDisturbChanged(napi_env env,napi_value jsCallback,void * context,void * data)676 void ThreadSafeOnDoNotDisturbChanged(napi_env env, napi_value jsCallback, void* context, void* data)
677 {
678 ANS_LOGI("OnDoNotDisturbChanged thread safe start");
679
680 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
681 if (dataWorkerData == nullptr) {
682 ANS_LOGE("Data worker data is null.");
683 return;
684 }
685
686 napi_value result = nullptr;
687 napi_handle_scope scope;
688 napi_open_handle_scope(dataWorkerData->env, &scope);
689 napi_create_object(dataWorkerData->env, &result);
690
691 if (!Common::SetDoNotDisturbDate(dataWorkerData->env, dataWorkerData->date, result)) {
692 result = Common::NapiGetNull(dataWorkerData->env);
693 }
694
695 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
696 napi_close_handle_scope(dataWorkerData->env, scope);
697
698 delete dataWorkerData;
699 dataWorkerData = nullptr;
700 }
701
onDoNotDisturbChanged(const std::shared_ptr<NotificationDoNotDisturbDate> & date)702 void SubscriberInstance::onDoNotDisturbChanged(const std::shared_ptr<NotificationDoNotDisturbDate>& date)
703 {
704 ANS_LOGD("enter");
705
706 if (disturbChangedCallbackInfo_.ref == nullptr || disturbChangedCallbackInfo_.env == nullptr) {
707 ANS_LOGE("disturbChangedCallbackInfo_ callback or env unset");
708 return;
709 }
710
711 if (date == nullptr) {
712 ANS_LOGE("date is null");
713 return;
714 }
715
716 NotificationReceiveDataWorker* dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
717 if (dataWorker == nullptr) {
718 ANS_LOGE("new dataWorker failed");
719 return;
720 }
721
722 dataWorker->date = *date;
723 dataWorker->env = disturbChangedCallbackInfo_.env;
724 dataWorker->ref = disturbChangedCallbackInfo_.ref;
725 dataWorker->type = Type::DISTURB_CHANGED;
726
727 napi_acquire_threadsafe_function(tsfn_);
728 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
729 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
730 }
731
ThreadSafeOnEnabledNotificationChanged(napi_env env,napi_value jsCallback,void * context,void * data)732 void ThreadSafeOnEnabledNotificationChanged(napi_env env, napi_value jsCallback, void* context, void* data)
733 {
734 ANS_LOGI("OnEnabledNotificationChanged thread safe start");
735
736 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
737 if (dataWorkerData == nullptr) {
738 ANS_LOGE("Data worker data is null.");
739 return;
740 }
741
742 napi_value result = nullptr;
743 napi_handle_scope scope;
744 napi_open_handle_scope(dataWorkerData->env, &scope);
745 if (scope == nullptr) {
746 ANS_LOGE("Scope is null");
747 return;
748 }
749 napi_create_object(dataWorkerData->env, &result);
750
751 if (!Common::SetEnabledNotificationCallbackData(dataWorkerData->env, dataWorkerData->callbackData, result)) {
752 result = Common::NapiGetNull(dataWorkerData->env);
753 }
754
755 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
756 napi_close_handle_scope(dataWorkerData->env, scope);
757
758 delete dataWorkerData;
759 dataWorkerData = nullptr;
760 }
761
OnEnabledNotificationChanged(const std::shared_ptr<EnabledNotificationCallbackData> & callbackData)762 void SubscriberInstance::OnEnabledNotificationChanged(
763 const std::shared_ptr<EnabledNotificationCallbackData> &callbackData)
764 {
765 ANS_LOGD("enter");
766
767 if (enabledNotificationCallbackInfo_.ref == nullptr || enabledNotificationCallbackInfo_.env == nullptr) {
768 ANS_LOGI("enabledNotificationCallbackInfo_ callback or env unset");
769 return;
770 }
771
772 if (callbackData == nullptr) {
773 ANS_LOGE("callbackData is null");
774 return;
775 }
776
777 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
778 if (dataWorker == nullptr) {
779 ANS_LOGE("new dataWorker failed");
780 return;
781 }
782
783 dataWorker->callbackData = *callbackData;
784 dataWorker->env = enabledNotificationCallbackInfo_.env;
785 dataWorker->ref = enabledNotificationCallbackInfo_.ref;
786 dataWorker->type = Type::ENABLE_NOTIFICATION_CHANGED;
787
788 napi_acquire_threadsafe_function(tsfn_);
789 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
790 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
791 }
792
ThreadSafeOnBadgeChanged(napi_env env,napi_value jsCallback,void * context,void * data)793 void ThreadSafeOnBadgeChanged(napi_env env, napi_value jsCallback, void* context, void* data)
794 {
795 ANS_LOGI("OnBadgeChanged thread safe start");
796
797 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
798 if (dataWorkerData == nullptr) {
799 ANS_LOGE("dataWorkerData is null");
800 return;
801 }
802
803 napi_value result = nullptr;
804 napi_handle_scope scope;
805 napi_open_handle_scope(dataWorkerData->env, &scope);
806 if (scope == nullptr) {
807 ANS_LOGE("Scope is null");
808 return;
809 }
810 napi_create_object(dataWorkerData->env, &result);
811
812 if (!Common::SetBadgeCallbackData(dataWorkerData->env, dataWorkerData->badge, result)) {
813 result = Common::NapiGetNull(dataWorkerData->env);
814 }
815
816 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
817 napi_close_handle_scope(dataWorkerData->env, scope);
818
819 delete dataWorkerData;
820 dataWorkerData = nullptr;
821 }
822
OnBadgeChanged(const std::shared_ptr<BadgeNumberCallbackData> & badgeData)823 void SubscriberInstance::OnBadgeChanged(
824 const std::shared_ptr<BadgeNumberCallbackData> &badgeData)
825 {
826 ANS_LOGD("enter");
827
828 if (setBadgeCallbackInfo_.ref == nullptr || setBadgeCallbackInfo_.env == nullptr) {
829 return;
830 }
831
832 if (badgeData == nullptr) {
833 ANS_LOGE("badgeData is null");
834 return;
835 }
836
837 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
838 if (dataWorker == nullptr) {
839 ANS_LOGE("new dataWorker failed");
840 return;
841 }
842
843 dataWorker->badge = *badgeData;
844 dataWorker->env = setBadgeCallbackInfo_.env;
845 dataWorker->ref = setBadgeCallbackInfo_.ref;
846 dataWorker->type = Type::BADGE_CHANGED;
847
848 napi_acquire_threadsafe_function(tsfn_);
849 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
850 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
851 }
852
ThreadSafeOnBadgeEnabledChanged(napi_env env,napi_value jsCallback,void * context,void * data)853 void ThreadSafeOnBadgeEnabledChanged(napi_env env, napi_value jsCallback, void* context, void* data)
854 {
855 ANS_LOGI("OnBadgeEnabledChanged thread safe start.");
856
857 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
858 if (dataWorkerData == nullptr) {
859 ANS_LOGE("Data worker is null.");
860 return;
861 }
862
863 napi_value result = nullptr;
864 napi_handle_scope scope;
865 napi_open_handle_scope(dataWorkerData->env, &scope);
866 if (scope == nullptr) {
867 ANS_LOGE("Scope is null");
868 return;
869 }
870 napi_create_object(dataWorkerData->env, &result);
871 if (!Common::SetEnabledNotificationCallbackData(dataWorkerData->env, dataWorkerData->callbackData, result)) {
872 result = Common::NapiGetNull(dataWorkerData->env);
873 }
874
875 Common::SetCallback(dataWorkerData->env, dataWorkerData->ref, result);
876 napi_close_handle_scope(dataWorkerData->env, scope);
877
878 delete dataWorkerData;
879 dataWorkerData = nullptr;
880 }
881
OnBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> & callbackData)882 void SubscriberInstance::OnBadgeEnabledChanged(
883 const sptr<EnabledNotificationCallbackData> &callbackData)
884 {
885 if (setBadgeEnabledCallbackInfo_.ref == nullptr) {
886 ANS_LOGE("Set badge enabled callback info is null.");
887 return;
888 }
889 if (callbackData == nullptr) {
890 ANS_LOGE("Callback data is null.");
891 return;
892 }
893
894 NotificationReceiveDataWorker *dataWorker = new (std::nothrow) NotificationReceiveDataWorker();
895 if (dataWorker == nullptr) {
896 ANS_LOGE("Create new data worker failed.");
897 return;
898 }
899
900 dataWorker->callbackData = *callbackData;
901 dataWorker->env = setBadgeEnabledCallbackInfo_.env;
902 dataWorker->ref = setBadgeEnabledCallbackInfo_.ref;
903 dataWorker->type = Type::BADGE_ENABLED_CHANGED;
904
905 napi_acquire_threadsafe_function(tsfn_);
906 napi_call_threadsafe_function(tsfn_, dataWorker, napi_tsfn_nonblocking);
907 napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
908 }
909
SetThreadSafeFunction(const napi_threadsafe_function & tsfn)910 void SubscriberInstance::SetThreadSafeFunction(const napi_threadsafe_function &tsfn)
911 {
912 tsfn_ = tsfn;
913 }
914
SetCancelCallbackInfo(const napi_env & env,const napi_ref & ref)915 void SubscriberInstance::SetCancelCallbackInfo(const napi_env &env, const napi_ref &ref)
916 {
917 canceCallbackInfo_.env = env;
918 canceCallbackInfo_.ref = ref;
919 }
920
SetConsumeCallbackInfo(const napi_env & env,const napi_ref & ref)921 void SubscriberInstance::SetConsumeCallbackInfo(const napi_env &env, const napi_ref &ref)
922 {
923 consumeCallbackInfo_.env = env;
924 consumeCallbackInfo_.ref = ref;
925 }
926
SetUpdateCallbackInfo(const napi_env & env,const napi_ref & ref)927 void SubscriberInstance::SetUpdateCallbackInfo(const napi_env &env, const napi_ref &ref)
928 {
929 updateCallbackInfo_.env = env;
930 updateCallbackInfo_.ref = ref;
931 }
932
SetSubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)933 void SubscriberInstance::SetSubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
934 {
935 subscribeCallbackInfo_.env = env;
936 subscribeCallbackInfo_.ref = ref;
937 }
938
SetUnsubscribeCallbackInfo(const napi_env & env,const napi_ref & ref)939 void SubscriberInstance::SetUnsubscribeCallbackInfo(const napi_env &env, const napi_ref &ref)
940 {
941 unsubscribeCallbackInfo_.env = env;
942 unsubscribeCallbackInfo_.ref = ref;
943 }
944
SetDieCallbackInfo(const napi_env & env,const napi_ref & ref)945 void SubscriberInstance::SetDieCallbackInfo(const napi_env &env, const napi_ref &ref)
946 {
947 dieCallbackInfo_.env = env;
948 dieCallbackInfo_.ref = ref;
949 }
950
SetDisturbModeCallbackInfo(const napi_env & env,const napi_ref & ref)951 void SubscriberInstance::SetDisturbModeCallbackInfo(const napi_env &env, const napi_ref &ref)
952 {
953 disturbModeCallbackInfo_.env = env;
954 disturbModeCallbackInfo_.ref = ref;
955 }
956
SetEnabledNotificationCallbackInfo(const napi_env & env,const napi_ref & ref)957 void SubscriberInstance::SetEnabledNotificationCallbackInfo(const napi_env &env, const napi_ref &ref)
958 {
959 enabledNotificationCallbackInfo_.env = env;
960 enabledNotificationCallbackInfo_.ref = ref;
961 }
962
SetDisturbDateCallbackInfo(const napi_env & env,const napi_ref & ref)963 void SubscriberInstance::SetDisturbDateCallbackInfo(const napi_env &env, const napi_ref &ref)
964 {
965 disturbDateCallbackInfo_.env = env;
966 disturbDateCallbackInfo_.ref = ref;
967 }
968
SetDisturbChangedCallbackInfo(const napi_env & env,const napi_ref & ref)969 void SubscriberInstance::SetDisturbChangedCallbackInfo(const napi_env &env, const napi_ref &ref)
970 {
971 disturbChangedCallbackInfo_.env = env;
972 disturbChangedCallbackInfo_.ref = ref;
973 }
974
SetBadgeCallbackInfo(const napi_env & env,const napi_ref & ref)975 void SubscriberInstance::SetBadgeCallbackInfo(const napi_env &env, const napi_ref &ref)
976 {
977 setBadgeCallbackInfo_.env = env;
978 setBadgeCallbackInfo_.ref = ref;
979 }
980
981
SetBadgeEnabledCallbackInfo(const napi_env & env,const napi_ref & ref)982 void SubscriberInstance::SetBadgeEnabledCallbackInfo(const napi_env &env, const napi_ref &ref)
983 {
984 setBadgeEnabledCallbackInfo_.env = env;
985 setBadgeEnabledCallbackInfo_.ref = ref;
986 }
987
SetBatchCancelCallbackInfo(const napi_env & env,const napi_ref & ref)988 void SubscriberInstance::SetBatchCancelCallbackInfo(const napi_env &env, const napi_ref &ref)
989 {
990 batchCancelCallbackInfo_.env = env;
991 batchCancelCallbackInfo_.ref = ref;
992 }
993
SetCallbackInfo(const napi_env & env,const std::string & type,const napi_ref & ref)994 void SubscriberInstance::SetCallbackInfo(const napi_env &env, const std::string &type, const napi_ref &ref)
995 {
996 if (type == CONSUME) {
997 SetConsumeCallbackInfo(env, ref);
998 } else if (type == CANCEL) {
999 SetCancelCallbackInfo(env, ref);
1000 } else if (type == UPDATE) {
1001 SetUpdateCallbackInfo(env, ref);
1002 } else if (type == CONNECTED) {
1003 SetSubscribeCallbackInfo(env, ref);
1004 } else if (type == DIS_CONNECTED) {
1005 SetUnsubscribeCallbackInfo(env, ref);
1006 } else if (type == DIE) {
1007 SetDieCallbackInfo(env, ref);
1008 } else if (type == DISTURB_MODE_CHANGE) {
1009 SetDisturbModeCallbackInfo(env, ref);
1010 } else if (type == DISTURB_DATE_CHANGE) {
1011 SetDisturbDateCallbackInfo(env, ref);
1012 } else if (type == DISTURB_CHANGED) {
1013 SetDisturbChangedCallbackInfo(env, ref);
1014 } else if (type == ENABLE_NOTIFICATION_CHANGED) {
1015 SetEnabledNotificationCallbackInfo(env, ref);
1016 } else if (type == BADGE_CHANGED) {
1017 SetBadgeCallbackInfo(env, ref);
1018 } else if (type == BADGE_ENABLED_CHANGED) {
1019 SetBadgeEnabledCallbackInfo(env, ref);
1020 } else if (type == BATCH_CANCEL) {
1021 SetBatchCancelCallbackInfo(env, ref);
1022 } else {
1023 ANS_LOGW("type is error");
1024 }
1025 }
1026
HasNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)1027 bool HasNotificationSubscriber(const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
1028 {
1029 std::lock_guard<std::mutex> lock(mutex_);
1030 for (auto vec : subscriberInstances_) {
1031 napi_value callback = nullptr;
1032 napi_get_reference_value(env, vec.ref, &callback);
1033 bool isEquals = false;
1034 napi_strict_equals(env, value, callback, &isEquals);
1035 if (isEquals) {
1036 subscriberInfo = vec;
1037 return true;
1038 }
1039 }
1040 return false;
1041 }
1042
1043 void ThreadFinished(napi_env env, void* data, [[maybe_unused]] void* context)
1044 {
1045 ANS_LOGD("ThreadFinished");
1046 }
1047
ThreadSafeCommon(napi_env env,napi_value jsCallback,void * context,void * data)1048 void ThreadSafeCommon(napi_env env, napi_value jsCallback, void* context, void* data)
1049 {
1050 ANS_LOGI("common thread safe start");
1051 auto dataWorkerData = reinterpret_cast<NotificationReceiveDataWorker *>(data);
1052 switch (dataWorkerData->type) {
1053 case Type::CANCEL:
1054 ThreadSafeOnCancel(env, jsCallback, context, data);
1055 break;
1056 case Type::BATCH_CANCEL:
1057 ThreadSafeOnBatchCancel(env, jsCallback, context, data);
1058 break;
1059 case Type::CONSUME:
1060 ThreadSafeOnConsumed(env, jsCallback, context, data);
1061 break;
1062 case Type::UPDATE:
1063 ThreadSafeOnUpdate(env, jsCallback, context, data);
1064 break;
1065 case Type::CONNECTED:
1066 ThreadSafeOnConnected(env, jsCallback, context, data);
1067 break;
1068 case Type::DIS_CONNECTED:
1069 ThreadSafeOnDisconnected(env, jsCallback, context, data);
1070 break;
1071 case Type::DIE:
1072 ThreadSafeOnDestroy(env, jsCallback, context, data);
1073 break;
1074 case Type::DISTURB_DATE_CHANGE:
1075 ThreadSafeOnDoNotDisturbDateChange(env, jsCallback, context, data);
1076 break;
1077 case Type::DISTURB_CHANGED:
1078 ThreadSafeOnDoNotDisturbChanged(env, jsCallback, context, data);
1079 break;
1080 case Type::ENABLE_NOTIFICATION_CHANGED:
1081 ThreadSafeOnEnabledNotificationChanged(env, jsCallback, context, data);
1082 break;
1083 case Type::BADGE_CHANGED:
1084 ThreadSafeOnBadgeChanged(env, jsCallback, context, data);
1085 break;
1086 case Type::BADGE_ENABLED_CHANGED:
1087 ThreadSafeOnBadgeEnabledChanged(env, jsCallback, context, data);
1088 break;
1089 default:
1090 break;
1091 }
1092 }
1093
GetNotificationSubscriber(const napi_env & env,const napi_value & value,SubscriberInstancesInfo & subscriberInfo)1094 napi_value GetNotificationSubscriber(
1095 const napi_env &env, const napi_value &value, SubscriberInstancesInfo &subscriberInfo)
1096 {
1097 ANS_LOGD("enter");
1098 bool hasProperty = false;
1099 napi_valuetype valuetype = napi_undefined;
1100 napi_ref result = nullptr;
1101
1102 subscriberInfo.subscriber = std::make_shared<SubscriberInstance>();
1103 if (subscriberInfo.subscriber == nullptr) {
1104 ANS_LOGE("subscriber is null");
1105 std::string msg = "Mandatory parameters are left unspecified. subscriber is null";
1106 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1107 return nullptr;
1108 }
1109
1110 napi_create_reference(env, value, 1, &subscriberInfo.ref);
1111
1112 napi_value resourceName = nullptr;
1113 napi_create_string_latin1(env, "tsfn", NAPI_AUTO_LENGTH, &resourceName);
1114 napi_threadsafe_function tsfn = nullptr;
1115 napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 0, 1, subscriberInfo.ref,
1116 ThreadFinished, nullptr, ThreadSafeCommon, &tsfn);
1117 subscriberInfo.subscriber->SetThreadSafeFunction(tsfn);
1118
1119 // onConsume?:(data: SubscribeCallbackData) => void
1120 NAPI_CALL(env, napi_has_named_property(env, value, "onConsume", &hasProperty));
1121 if (hasProperty) {
1122 napi_value nOnConsumed = nullptr;
1123 napi_get_named_property(env, value, "onConsume", &nOnConsumed);
1124 NAPI_CALL(env, napi_typeof(env, nOnConsumed, &valuetype));
1125 if (valuetype != napi_function) {
1126 ANS_LOGE("Wrong argument type. Function expected.");
1127 std::string msg = "Incorrect parameter types.The type of param must be function.";
1128 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1129 return nullptr;
1130 }
1131 napi_create_reference(env, nOnConsumed, 1, &result);
1132 subscriberInfo.subscriber->SetCallbackInfo(env, CONSUME, result);
1133 }
1134 // onCancel?:(data: SubscribeCallbackData) => void
1135 NAPI_CALL(env, napi_has_named_property(env, value, "onCancel", &hasProperty));
1136 if (hasProperty) {
1137 napi_value nOnCanceled = nullptr;
1138 napi_get_named_property(env, value, "onCancel", &nOnCanceled);
1139 NAPI_CALL(env, napi_typeof(env, nOnCanceled, &valuetype));
1140 if (valuetype != napi_function) {
1141 ANS_LOGE("Wrong argument type. Function expected.");
1142 std::string msg = "Incorrect parameter types.The type of param must be function.";
1143 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1144 return nullptr;
1145 }
1146 napi_create_reference(env, nOnCanceled, 1, &result);
1147 subscriberInfo.subscriber->SetCallbackInfo(env, CANCEL, result);
1148 }
1149 // onUpdate?:(data: NotificationSortingMap) => void
1150 NAPI_CALL(env, napi_has_named_property(env, value, "onUpdate", &hasProperty));
1151 if (hasProperty) {
1152 napi_value nOnUpdate = nullptr;
1153 napi_get_named_property(env, value, "onUpdate", &nOnUpdate);
1154 NAPI_CALL(env, napi_typeof(env, nOnUpdate, &valuetype));
1155 if (valuetype != napi_function) {
1156 ANS_LOGE("Wrong argument type. Function expected.");
1157 std::string msg = "Incorrect parameter types.The type of param must be function.";
1158 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1159 return nullptr;
1160 }
1161 napi_create_reference(env, nOnUpdate, 1, &result);
1162 subscriberInfo.subscriber->SetCallbackInfo(env, UPDATE, result);
1163 }
1164 // onConnect?:() => void
1165 NAPI_CALL(env, napi_has_named_property(env, value, "onConnect", &hasProperty));
1166 if (hasProperty) {
1167 napi_value nOnConnected = nullptr;
1168 napi_get_named_property(env, value, "onConnect", &nOnConnected);
1169 NAPI_CALL(env, napi_typeof(env, nOnConnected, &valuetype));
1170 if (valuetype != napi_function) {
1171 ANS_LOGE("Wrong argument type. Function expected.");
1172 std::string msg = "Incorrect parameter types.The type of param must be function.";
1173 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1174 return nullptr;
1175 }
1176 napi_create_reference(env, nOnConnected, 1, &result);
1177 subscriberInfo.subscriber->SetCallbackInfo(env, CONNECTED, result);
1178 }
1179 // onDisconnect?:() => void
1180 NAPI_CALL(env, napi_has_named_property(env, value, "onDisconnect", &hasProperty));
1181 if (hasProperty) {
1182 napi_value nOnDisConnect = nullptr;
1183 napi_get_named_property(env, value, "onDisconnect", &nOnDisConnect);
1184 NAPI_CALL(env, napi_typeof(env, nOnDisConnect, &valuetype));
1185 if (valuetype != napi_function) {
1186 ANS_LOGE("Wrong argument type. Function expected.");
1187 std::string msg = "Incorrect parameter types.The type of param must be function.";
1188 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1189 return nullptr;
1190 }
1191 napi_create_reference(env, nOnDisConnect, 1, &result);
1192 subscriberInfo.subscriber->SetCallbackInfo(env, DIS_CONNECTED, result);
1193 }
1194 // onDestroy?:() => void
1195 NAPI_CALL(env, napi_has_named_property(env, value, "onDestroy", &hasProperty));
1196 if (hasProperty) {
1197 napi_value nOnDied = nullptr;
1198 napi_get_named_property(env, value, "onDestroy", &nOnDied);
1199 NAPI_CALL(env, napi_typeof(env, nOnDied, &valuetype));
1200 if (valuetype != napi_function) {
1201 ANS_LOGE("Wrong argument type. Function expected.");
1202 std::string msg = "Incorrect parameter types.The type of param must be function.";
1203 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1204 return nullptr;
1205 }
1206 napi_create_reference(env, nOnDied, 1, &result);
1207 subscriberInfo.subscriber->SetCallbackInfo(env, DIE, result);
1208 }
1209 // onDisturbModeChange?:(mode: notification.DoNotDisturbMode) => void
1210 NAPI_CALL(env, napi_has_named_property(env, value, "onDisturbModeChange", &hasProperty));
1211 if (hasProperty) {
1212 napi_value nOnDisturbModeChanged = nullptr;
1213 napi_get_named_property(env, value, "onDisturbModeChange", &nOnDisturbModeChanged);
1214 NAPI_CALL(env, napi_typeof(env, nOnDisturbModeChanged, &valuetype));
1215 if (valuetype != napi_function) {
1216 ANS_LOGE("Wrong argument type. Function expected.");
1217 std::string msg = "Incorrect parameter types.The type of param must be function.";
1218 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1219 return nullptr;
1220 }
1221 napi_create_reference(env, nOnDisturbModeChanged, 1, &result);
1222 subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_MODE_CHANGE, result);
1223 }
1224
1225 // onDoNotDisturbDateChange?:(mode: notification.DoNotDisturbDate) => void
1226 NAPI_CALL(env, napi_has_named_property(env, value, "onDoNotDisturbDateChange", &hasProperty));
1227 if (hasProperty) {
1228 napi_value nOnDisturbDateChanged = nullptr;
1229 napi_get_named_property(env, value, "onDoNotDisturbDateChange", &nOnDisturbDateChanged);
1230 NAPI_CALL(env, napi_typeof(env, nOnDisturbDateChanged, &valuetype));
1231 if (valuetype != napi_function) {
1232 ANS_LOGE("Wrong argument type. Function expected.");
1233 std::string msg = "Incorrect parameter types.The type of param must be function.";
1234 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1235 return nullptr;
1236 }
1237 napi_create_reference(env, nOnDisturbDateChanged, 1, &result);
1238 subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_DATE_CHANGE, result);
1239 }
1240
1241 // onDoNotDisturbChanged?:(mode: notificationManager.DoNotDisturbDate) => void
1242 NAPI_CALL(env, napi_has_named_property(env, value, "onDoNotDisturbChanged", &hasProperty));
1243 if (hasProperty) {
1244 napi_value nOnDoNotDisturbChanged = nullptr;
1245 napi_get_named_property(env, value, "onDoNotDisturbChanged", &nOnDoNotDisturbChanged);
1246 NAPI_CALL(env, napi_typeof(env, nOnDoNotDisturbChanged, &valuetype));
1247 if (valuetype != napi_function) {
1248 ANS_LOGE("Wrong argument type. Function expected.");
1249 std::string msg = "Incorrect parameter types.The type of param must be function.";
1250 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1251 return nullptr;
1252 }
1253 napi_create_reference(env, nOnDoNotDisturbChanged, 1, &result);
1254 subscriberInfo.subscriber->SetCallbackInfo(env, DISTURB_CHANGED, result);
1255 }
1256
1257 // onEnabledNotificationChanged?:(data: notification.EnabledNotificationCallbackData) => void
1258 NAPI_CALL(env, napi_has_named_property(env, value, "onEnabledNotificationChanged", &hasProperty));
1259 if (hasProperty) {
1260 napi_value nOnEnabledNotificationChanged = nullptr;
1261 napi_get_named_property(env, value, "onEnabledNotificationChanged", &nOnEnabledNotificationChanged);
1262 NAPI_CALL(env, napi_typeof(env, nOnEnabledNotificationChanged, &valuetype));
1263 if (valuetype != napi_function) {
1264 ANS_LOGE("Wrong argument type. Function expected.");
1265 std::string msg = "Incorrect parameter types.The type of param must be function.";
1266 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1267 return nullptr;
1268 }
1269 napi_create_reference(env, nOnEnabledNotificationChanged, 1, &result);
1270 subscriberInfo.subscriber->SetCallbackInfo(env, ENABLE_NOTIFICATION_CHANGED, result);
1271 }
1272
1273 // onBadgeChanged?:(data: BadgeNumberCallbackData) => void
1274 NAPI_CALL(env, napi_has_named_property(env, value, "onBadgeChanged", &hasProperty));
1275 if (hasProperty) {
1276 napi_value nOnBadgeChanged = nullptr;
1277 napi_get_named_property(env, value, "onBadgeChanged", &nOnBadgeChanged);
1278 NAPI_CALL(env, napi_typeof(env, nOnBadgeChanged, &valuetype));
1279 if (valuetype != napi_function) {
1280 ANS_LOGE("Wrong argument type. Function expected.");
1281 std::string msg = "Incorrect parameter types.The type of param must be function.";
1282 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1283 return nullptr;
1284 }
1285 napi_create_reference(env, nOnBadgeChanged, 1, &result);
1286 subscriberInfo.subscriber->SetCallbackInfo(env, BADGE_CHANGED, result);
1287 }
1288
1289 // onBadgeEnabledChanged?:(data: EnabledNotificationCallbackData) => void
1290 NAPI_CALL(env, napi_has_named_property(env, value, "onBadgeEnabledChanged", &hasProperty));
1291 if (hasProperty) {
1292 napi_value nOnBadgeEnabledChanged = nullptr;
1293 napi_get_named_property(env, value, "onBadgeEnabledChanged", &nOnBadgeEnabledChanged);
1294 NAPI_CALL(env, napi_typeof(env, nOnBadgeEnabledChanged, &valuetype));
1295 if (valuetype != napi_function) {
1296 ANS_LOGE("Wrong argument type. Function expected.");
1297 std::string msg = "Incorrect parameter types.The type of param must be function.";
1298 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1299 return nullptr;
1300 }
1301 napi_create_reference(env, nOnBadgeEnabledChanged, 1, &result);
1302 subscriberInfo.subscriber->SetCallbackInfo(env, BADGE_ENABLED_CHANGED, result);
1303 }
1304
1305 // onBatchCancel?:(data: Array<SubscribeCallbackData>) => void
1306 NAPI_CALL(env, napi_has_named_property(env, value, "onBatchCancel", &hasProperty));
1307 if (hasProperty) {
1308 napi_value onBatchCancel = nullptr;
1309 napi_get_named_property(env, value, "onBatchCancel", &onBatchCancel);
1310 NAPI_CALL(env, napi_typeof(env, onBatchCancel, &valuetype));
1311 if (valuetype != napi_function) {
1312 ANS_LOGE("Wrong argument type. Function expected.");
1313 std::string msg = "Incorrect parameter types.The type of param must be function.";
1314 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1315 return nullptr;
1316 }
1317 napi_create_reference(env, onBatchCancel, 1, &result);
1318 subscriberInfo.subscriber->SetCallbackInfo(env, BATCH_CANCEL, result);
1319 }
1320
1321 return Common::NapiGetNull(env);
1322 }
1323
AddSubscriberInstancesInfo(const napi_env & env,const SubscriberInstancesInfo & subscriberInfo)1324 bool AddSubscriberInstancesInfo(const napi_env &env, const SubscriberInstancesInfo &subscriberInfo)
1325 {
1326 ANS_LOGD("enter");
1327 if (subscriberInfo.ref == nullptr) {
1328 ANS_LOGE("subscriberInfo.ref is null");
1329 return false;
1330 }
1331 if (subscriberInfo.subscriber == nullptr) {
1332 ANS_LOGE("subscriberInfo.subscriber is null");
1333 return false;
1334 }
1335 std::lock_guard<std::mutex> lock(mutex_);
1336 subscriberInstances_.emplace_back(subscriberInfo);
1337
1338 return true;
1339 }
1340
DelSubscriberInstancesInfo(const napi_env & env,const std::shared_ptr<SubscriberInstance> subscriber)1341 bool DelSubscriberInstancesInfo(const napi_env &env, const std::shared_ptr<SubscriberInstance> subscriber)
1342 {
1343 ANS_LOGD("enter");
1344 if (subscriber == nullptr) {
1345 ANS_LOGE("subscriber is null");
1346 return false;
1347 }
1348 std::lock_guard<std::mutex> lock(delMutex_);
1349 auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1350 if (iter != DeletingSubscriber.end()) {
1351 DeletingSubscriber.erase(iter);
1352 std::lock_guard<std::mutex> lock(mutex_);
1353 for (auto it = subscriberInstances_.begin(); it != subscriberInstances_.end(); ++it) {
1354 if ((*it).subscriber == subscriber) {
1355 if ((*it).ref != nullptr) {
1356 napi_delete_reference(env, (*it).ref);
1357 }
1358 subscriberInstances_.erase(it);
1359 return true;
1360 }
1361 }
1362 }
1363 return false;
1364 }
1365
ParseParameters(const napi_env & env,const napi_callback_info & info,NotificationSubscribeInfo & subscriberInfo,std::shared_ptr<SubscriberInstance> & subscriber,napi_ref & callback)1366 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info,
1367 NotificationSubscribeInfo &subscriberInfo, std::shared_ptr<SubscriberInstance> &subscriber, napi_ref &callback)
1368 {
1369 ANS_LOGD("enter");
1370
1371 size_t argc = SUBSRIBE_MAX_PARA;
1372 napi_value argv[SUBSRIBE_MAX_PARA] = {nullptr};
1373 napi_value thisVar = nullptr;
1374 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
1375 if (argc < 1) {
1376 ANS_LOGE("Wrong number of arguments");
1377 Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED);
1378 return nullptr;
1379 }
1380
1381 napi_valuetype valuetype = napi_undefined;
1382
1383 // argv[0]:subscriber
1384 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
1385 if (valuetype != napi_object) {
1386 ANS_LOGE("Wrong argument type for arg0. NotificationSubscriber object expected.");
1387 std::string msg = "Incorrect parameter types.The type of param must be NotificationSubscriber.";
1388 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
1389 return nullptr;
1390 }
1391
1392 SubscriberInstancesInfo subscriberInstancesInfo;
1393 if (!HasNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo)) {
1394 if (GetNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo) == nullptr) {
1395 ANS_LOGE("NotificationSubscriber parse failed");
1396 return nullptr;
1397 }
1398 if (!AddSubscriberInstancesInfo(env, subscriberInstancesInfo)) {
1399 ANS_LOGE("AddSubscriberInstancesInfo add failed");
1400 return nullptr;
1401 }
1402 }
1403 subscriber = subscriberInstancesInfo.subscriber;
1404
1405 // argv[1]:callback or NotificationSubscribeInfo
1406 if (argc >= SUBSRIBE_MAX_PARA - 1) {
1407 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
1408 if ((valuetype != napi_function) && (valuetype != napi_object)) {
1409 ANS_LOGE("Wrong argument type for arg1."
1410 "Function or NotificationSubscribeInfo object expected. Excute promise");
1411 return Common::NapiGetNull(env);
1412 }
1413 if (valuetype == napi_function) {
1414 napi_create_reference(env, argv[PARAM1], 1, &callback);
1415 } else {
1416 if (Common::GetNotificationSubscriberInfo(env, argv[PARAM1], subscriberInfo) == nullptr) {
1417 ANS_LOGE("NotificationSubscribeInfo parse failed");
1418 return nullptr;
1419 }
1420 }
1421 }
1422
1423 // argv[2]:callback
1424 if (argc >= SUBSRIBE_MAX_PARA) {
1425 NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
1426 if (valuetype != napi_function) {
1427 ANS_LOGE("Callback is not function enforce promise.");
1428 return Common::NapiGetNull(env);
1429 }
1430 napi_create_reference(env, argv[PARAM2], 1, &callback);
1431 }
1432
1433 return Common::NapiGetNull(env);
1434 }
1435
Subscribe(napi_env env,napi_callback_info info)1436 napi_value Subscribe(napi_env env, napi_callback_info info)
1437 {
1438 ANS_LOGD("enter");
1439
1440 napi_ref callback = nullptr;
1441 std::shared_ptr<SubscriberInstance> objectInfo = nullptr;
1442 NotificationSubscribeInfo subscriberInfo;
1443 if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
1444 ANS_LOGD("ParseParameters is nullptr.");
1445 return Common::NapiGetUndefined(env);
1446 }
1447
1448 AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
1449 .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
1450 };
1451 if (!asynccallbackinfo) {
1452 ANS_LOGD("Asynccallbackinfo is nullptr.");
1453 return Common::JSParaError(env, callback);
1454 }
1455 napi_value promise = nullptr;
1456 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
1457
1458 ANS_LOGD("Create subscribeNotification string.");
1459 napi_value resourceName = nullptr;
1460 napi_create_string_latin1(env, "subscribeNotification", NAPI_AUTO_LENGTH, &resourceName);
1461 // Asynchronous function call
1462 napi_create_async_work(env,
1463 nullptr,
1464 resourceName,
1465 [](napi_env env, void *data) {
1466 ANS_LOGD("Subscribe work excuted.");
1467 if (!data) {
1468 ANS_LOGE("Invalid asynccallbackinfo!");
1469 return;
1470 }
1471 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
1472 if (asynccallbackinfo) {
1473 if (asynccallbackinfo->subscriberInfo.hasSubscribeInfo) {
1474 ANS_LOGD("Subscribe with NotificationSubscribeInfo excute.");
1475 OHOS::Notification::NotificationSubscribeInfo subscribeInfo;
1476 subscribeInfo.AddAppNames(asynccallbackinfo->subscriberInfo.bundleNames);
1477 subscribeInfo.AddAppUserId(asynccallbackinfo->subscriberInfo.userId);
1478 asynccallbackinfo->info.errorCode =
1479 NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo), subscribeInfo);
1480 } else {
1481 ANS_LOGD("SubscribeNotification execute.");
1482 asynccallbackinfo->info.errorCode =
1483 NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo));
1484 }
1485 }
1486 },
1487 [](napi_env env, napi_status status, void *data) {
1488 ANS_LOGD("Subscribe work complete.");
1489 if (!data) {
1490 ANS_LOGE("Invalid asynccallbackinfo!");
1491 return;
1492 }
1493 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
1494 if (asynccallbackinfo) {
1495 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
1496 if (asynccallbackinfo->info.callback != nullptr) {
1497 ANS_LOGD("Delete subscribe callback reference.");
1498 napi_delete_reference(env, asynccallbackinfo->info.callback);
1499 }
1500 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
1501 delete asynccallbackinfo;
1502 asynccallbackinfo = nullptr;
1503 }
1504 ANS_LOGD("Subscribe work complete end.");
1505 },
1506 (void *)asynccallbackinfo,
1507 &asynccallbackinfo->asyncWork);
1508
1509 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
1510
1511 if (asynccallbackinfo->info.isCallback) {
1512 ANS_LOGD("subscribe callback is nullptr.");
1513 return Common::NapiGetNull(env);
1514 } else {
1515 return promise;
1516 }
1517 }
1518
AddDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)1519 bool AddDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)
1520 {
1521 std::lock_guard<std::mutex> lock(delMutex_);
1522 auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1523 if (iter != DeletingSubscriber.end()) {
1524 return false;
1525 }
1526
1527 DeletingSubscriber.push_back(subscriber);
1528 return true;
1529 }
1530
DelDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)1531 void DelDeletingSubscriber(std::shared_ptr<SubscriberInstance> subscriber)
1532 {
1533 std::lock_guard<std::mutex> lock(delMutex_);
1534 auto iter = std::find(DeletingSubscriber.begin(), DeletingSubscriber.end(), subscriber);
1535 if (iter != DeletingSubscriber.end()) {
1536 DeletingSubscriber.erase(iter);
1537 }
1538 }
1539 } // namespace NotificationNapi
1540 } // namespace OHOS