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