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