/* * Copyright (c) 2021-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "notification_subscriber.h" #include "notification_constant.h" #include "hitrace_meter_adapter.h" #include "iservice_registry.h" #include "system_ability_definition.h" namespace OHOS { namespace Notification { NotificationSubscriber::NotificationSubscriber() { impl_ = new (std::nothrow) SubscriberImpl(*this); deviceType_ = NotificationConstant::CURRENT_DEVICE_TYPE; }; NotificationSubscriber::~NotificationSubscriber() { if (impl_ != nullptr) { impl_->OnSubscriberDestory(); } } void NotificationSubscriber::SetDeviceType(const std::string &deviceType) { deviceType_ = deviceType; } std::string NotificationSubscriber::GetDeviceType() const { return deviceType_; } #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED bool NotificationSubscriber::ProcessSyncDecision( const std::string &deviceType, std::shared_ptr ¬ification) const { sptr request = notification->GetNotificationRequestPoint(); if (request == nullptr) { ANS_LOGE("No need to consume cause invalid reqeuest."); return false; } auto flagsMap = request->GetDeviceFlags(); if (flagsMap == nullptr || flagsMap->size() <= 0) { return true; } auto flagIter = flagsMap->find(deviceType); if (flagIter != flagsMap->end() && flagIter->second != nullptr) { ANS_LOGI("SetFlags-before filte, notificationKey = %{public}s flagIter \ flags = %{public}d, deviceType:%{public}s", request->GetKey().c_str(), flagIter->second->GetReminderFlags(), deviceType.c_str()); std::shared_ptr tempFlags = request->GetFlags(); tempFlags->SetSoundEnabled(DowngradeReminder(tempFlags->IsSoundEnabled(), flagIter->second->IsSoundEnabled())); tempFlags->SetVibrationEnabled( DowngradeReminder(tempFlags->IsVibrationEnabled(), flagIter->second->IsVibrationEnabled())); tempFlags->SetLockScreenVisblenessEnabled( tempFlags->IsLockScreenVisblenessEnabled() && flagIter->second->IsLockScreenVisblenessEnabled()); tempFlags->SetBannerEnabled( tempFlags->IsBannerEnabled() && flagIter->second->IsBannerEnabled()); tempFlags->SetLightScreenEnabled( tempFlags->IsLightScreenEnabled() && flagIter->second->IsLightScreenEnabled()); request->SetFlags(tempFlags); ANS_LOGI("SetFlags-after filte, notificationKey = %{public}s flags = %{public}d", request->GetKey().c_str(), tempFlags->GetReminderFlags()); return true; } if (deviceType.size() <= 0 || deviceType.compare(NotificationConstant::CURRENT_DEVICE_TYPE) == 0) { return true; } ANS_LOGD("No need to consume cause cannot find deviceFlags. deviceType: %{public}s.", deviceType.c_str()); return false; } NotificationConstant::FlagStatus NotificationSubscriber::DowngradeReminder( const NotificationConstant::FlagStatus &oldFlags, const NotificationConstant::FlagStatus &judgeFlags) const { if (judgeFlags == NotificationConstant::FlagStatus::NONE || oldFlags == NotificationConstant::FlagStatus::NONE) { return NotificationConstant::FlagStatus::NONE; } if (judgeFlags > oldFlags) { return judgeFlags; } else { return oldFlags; } } #endif const sptr NotificationSubscriber::GetImpl() const { return impl_; } NotificationSubscriber::SubscriberImpl::SubscriberImpl(NotificationSubscriber &subscriber) : subscriber_(subscriber) { recipient_ = new (std::nothrow) DeathRecipient(*this); }; void NotificationSubscriber::SubscriberImpl::OnSubscriberDestory() { isSubscriberDestory_.store(true); } void NotificationSubscriber::SubscriberImpl::OnConnected() { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); sptr proxy = GetAnsManagerProxy(); if (proxy != nullptr) { proxy->AsObject()->AddDeathRecipient(recipient_); ANS_LOGD("%s, Add death recipient.", __func__); } subscriber_.OnConnected(); } void NotificationSubscriber::SubscriberImpl::OnDisconnected() { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); sptr proxy = GetAnsManagerProxy(); if (proxy != nullptr) { proxy->AsObject()->RemoveDeathRecipient(recipient_); ANS_LOGD("%s, Remove death recipient.", __func__); } subscriber_.OnDisconnected(); } void NotificationSubscriber::SubscriberImpl::OnConsumed( const sptr ¬ification, const sptr ¬ificationMap) { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); std::shared_ptr sharedNotification = std::make_shared(*notification); #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED if (!subscriber_.ProcessSyncDecision(subscriber_.GetDeviceType(), sharedNotification)) { return; } #endif subscriber_.OnConsumed( sharedNotification, std::make_shared(*notificationMap)); } void NotificationSubscriber::SubscriberImpl::OnConsumedList(const std::vector> ¬ifications, const sptr ¬ificationMap) { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); for (auto notification : notifications) { OnConsumed(notification, notificationMap); } } void NotificationSubscriber::SubscriberImpl::OnCanceled( const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); if (notificationMap == nullptr) { subscriber_.OnCanceled(std::make_shared(*notification), std::make_shared(), deleteReason); } else { subscriber_.OnCanceled(std::make_shared(*notification), std::make_shared(*notificationMap), deleteReason); } } void NotificationSubscriber::SubscriberImpl::OnBatchCanceled(const std::vector> ¬ifications, const sptr ¬ificationMap, int32_t deleteReason) { if (isSubscriberDestory_.load()) { return; } std::vector> notificationList; for (auto notification : notifications) { notificationList.emplace_back(std::make_shared(*notification)); } if (notificationMap == nullptr) { subscriber_.OnBatchCanceled(notificationList, std::make_shared(), deleteReason); } else { subscriber_.OnBatchCanceled(notificationList, std::make_shared(*notificationMap), deleteReason); } } void NotificationSubscriber::SubscriberImpl::OnCanceledList(const std::vector> ¬ifications, const sptr ¬ificationMap, int32_t deleteReason) { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); if (subscriber_.HasOnBatchCancelCallback()) { OnBatchCanceled(notifications, notificationMap, deleteReason); return; } for (auto notification : notifications) { OnCanceled(notification, notificationMap, deleteReason); } } void NotificationSubscriber::SubscriberImpl::OnUpdated(const sptr ¬ificationMap) { if (isSubscriberDestory_.load()) { return; } subscriber_.OnUpdate(std::make_shared(*notificationMap)); } void NotificationSubscriber::SubscriberImpl::OnDoNotDisturbDateChange(const sptr &date) { if (isSubscriberDestory_.load()) { return; } subscriber_.OnDoNotDisturbDateChange(std::make_shared(*date)); } void NotificationSubscriber::SubscriberImpl::OnEnabledNotificationChanged( const sptr &callbackData) { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); subscriber_.OnEnabledNotificationChanged(std::make_shared(*callbackData)); } void NotificationSubscriber::SubscriberImpl::OnBadgeChanged(const sptr &badgeData) { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); subscriber_.OnBadgeChanged(std::make_shared(*badgeData)); } void NotificationSubscriber::SubscriberImpl::OnBadgeEnabledChanged( const sptr &callbackData) { if (isSubscriberDestory_.load()) { return; } HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); subscriber_.OnBadgeEnabledChanged(callbackData); } sptr NotificationSubscriber::SubscriberImpl::GetAnsManagerProxy() { sptr systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (!systemAbilityManager) { return nullptr; } sptr remoteObject = systemAbilityManager->GetSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID); if (!remoteObject) { return nullptr; } sptr proxy = iface_cast(remoteObject); if ((proxy == nullptr) || (proxy->AsObject() == nullptr)) { return nullptr; } return proxy; } NotificationSubscriber::SubscriberImpl::DeathRecipient::DeathRecipient(SubscriberImpl &subscriberImpl) : subscriberImpl_(subscriberImpl) {}; NotificationSubscriber::SubscriberImpl::DeathRecipient::~DeathRecipient() {}; void NotificationSubscriber::SubscriberImpl::DeathRecipient::OnRemoteDied(const wptr &object) { subscriberImpl_.subscriber_.OnDied(); } } // namespace Notification } // namespace OHOS