/* * Copyright (c) 2021-2025 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 "ans_trace_wrapper.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() {} void NotificationSubscriber::SetDeviceType(const std::string &deviceType) { deviceType_ = deviceType; } std::string NotificationSubscriber::GetDeviceType() const { return deviceType_; } bool NotificationSubscriber::SyncLiveViewVoip( 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; } if (request->GetClassification() == NotificationConstant::ANS_VOIP && request->GetSlotType() == NotificationConstant::LIVE_VIEW && (deviceType == CURRENT_DEVICE_TYPE || deviceType == NotificationConstant::LITEWEARABLE_DEVICE_TYPE || deviceType == NotificationConstant::HEADSET_DEVICE_TYPE || deviceType == NotificationConstant::WEARABLE_DEVICE_TYPE)) { return true; } return false; } #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("null request"); 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) { request->SetFlags(flagIter->second); ANS_LOGI("SetFlags-final, notificationKey = %{public}s flags = %{public}d deviceType: %{public}s.", request->GetKey().c_str(), request->GetFlags()->GetReminderFlags(), deviceType.c_str()); return true; } if (deviceType.size() <= 0 || deviceType.compare(NotificationConstant::CURRENT_DEVICE_TYPE) == 0) { return true; } ANS_LOGE("Cannot find deviceFlags,notificationKey = %{public}s, deviceType: %{public}s.", request->GetKey().c_str(), 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); }; ErrCode NotificationSubscriber::SubscriberImpl::OnConnected() { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); sptr proxy = GetAnsManagerProxy(); if (proxy != nullptr) { proxy->AsObject()->AddDeathRecipient(recipient_); ANS_LOGD("%s, Add death recipient.", __func__); } subscriber_.OnConnected(); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnDisconnected() { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); sptr proxy = GetAnsManagerProxy(); if (proxy != nullptr) { proxy->AsObject()->RemoveDeathRecipient(recipient_); ANS_LOGD("%s, Remove death recipient.", __func__); } subscriber_.OnDisconnected(); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnConsumed( const sptr ¬ification, const sptr ¬ificationMap) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); if (notificationMap == nullptr) { ANS_LOGE("null notificationMap"); return ERR_INVALID_DATA; } std::shared_ptr sharedNotification = std::make_shared(*notification); auto deviceType = subscriber_.GetDeviceType(); if (subscriber_.SyncLiveViewVoip(deviceType, sharedNotification)) { ANS_LOGI("Sync LIVE_VIEW VOIP."); } #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED else if (!subscriber_.ProcessSyncDecision(deviceType, sharedNotification)) { return ERR_OK; } #endif subscriber_.OnConsumed( sharedNotification, std::make_shared(*notificationMap)); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnConsumed(const sptr ¬ification) { return OnConsumed(notification, nullptr); } ErrCode NotificationSubscriber::SubscriberImpl::OnConsumedWithMaxCapacity( const sptr ¬ification, const sptr ¬ificationMap) { return OnConsumed(notification, notificationMap); } ErrCode NotificationSubscriber::SubscriberImpl::OnConsumedWithMaxCapacity(const sptr ¬ification) { return OnConsumed(notification, nullptr); } ErrCode NotificationSubscriber::SubscriberImpl::OnConsumedList(const std::vector> ¬ifications, const sptr ¬ificationMap) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); for (auto notification : notifications) { OnConsumed(notification, notificationMap); } return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnConsumedList(const std::vector> ¬ifications) { return OnConsumedList(notifications, nullptr); } ErrCode NotificationSubscriber::SubscriberImpl::OnCanceled( const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); 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); } return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnCanceled( const sptr ¬ification, int32_t deleteReason) { return OnCanceled(notification, nullptr, deleteReason); } ErrCode NotificationSubscriber::SubscriberImpl::OnCanceledWithMaxCapacity( const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) { return OnCanceled(notification, notificationMap, deleteReason); } ErrCode NotificationSubscriber::SubscriberImpl::OnCanceledWithMaxCapacity( const sptr ¬ification, int32_t deleteReason) { return OnCanceled(notification, nullptr, deleteReason); } void NotificationSubscriber::SubscriberImpl::OnBatchCanceled(const std::vector> ¬ifications, const sptr ¬ificationMap, int32_t deleteReason) { 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); } } ErrCode NotificationSubscriber::SubscriberImpl::OnCanceledList(const std::vector> ¬ifications, const sptr ¬ificationMap, int32_t deleteReason) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); if (subscriber_.HasOnBatchCancelCallback()) { OnBatchCanceled(notifications, notificationMap, deleteReason); return ERR_OK; } for (auto notification : notifications) { OnCanceled(notification, notificationMap, deleteReason); } return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnCanceledList( const std::vector> ¬ifications, int32_t deleteReason) { return OnCanceledList(notifications, nullptr, deleteReason); } ErrCode NotificationSubscriber::SubscriberImpl::OnUpdated(const sptr ¬ificationMap) { subscriber_.OnUpdate(std::make_shared(*notificationMap)); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnDoNotDisturbDateChange(const sptr &date) { subscriber_.OnDoNotDisturbDateChange(std::make_shared(*date)); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnEnabledNotificationChanged( const sptr &callbackData) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); subscriber_.OnEnabledNotificationChanged(std::make_shared(*callbackData)); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnBadgeChanged(const sptr &badgeData) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); subscriber_.OnBadgeChanged(std::make_shared(*badgeData)); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnBadgeEnabledChanged( const sptr &callbackData) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); subscriber_.OnBadgeEnabledChanged(callbackData); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnApplicationInfoNeedChanged( const std::string& bundleName) { NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); subscriber_.OnApplicationInfoNeedChanged(bundleName); return ERR_OK; } ErrCode NotificationSubscriber::SubscriberImpl::OnOperationResponse( const sptr &operationInfo, int32_t& funcResult) { return subscriber_.OnOperationResponse(std::make_shared(*operationInfo)); } 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