diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index c39458f3d7e94493f276a182e77543997e228bb9..6d47e9660d82571d9e1fec4fae60f45008075306 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -678,6 +678,20 @@ public: void OnResourceRemove(int32_t userId); void OnBundleDataCleared(const sptr &bundleOption); + /** + * @brief Obtains the event of bundle install. + * + * @param bundleOption Indicates the bundle info. + */ + void OnBundleDataAdd(const sptr &bundleOption); + + /** + * @brief Obtains the event of bundle update. + * + * @param bundleOption Indicates the bundle info. + */ + void OnBundleDataUpdate(const sptr &bundleOption); + // Distributed KvStore /** @@ -732,6 +746,11 @@ public: */ void ResetPushCallbackProxy(); + /** + * @brief Init The Default Installation Package Notification Enabled. + */ + void InitNotificationEnableList(); + private: struct RecentInfo; AdvancedNotificationService(); @@ -836,7 +855,8 @@ private: void SelfClean(); ErrCode SetDefaultNotificationEnabled( const sptr &bundleOption, bool enabled); - + ErrCode CheckNotificationEnableStatus(bool ¬ificationEnable); + ErrCode PublishPreparedNotificationInner(const sptr &request); private: static sptr instance_; static std::mutex instanceMutex_; diff --git a/services/ans/include/bundle_manager_helper.h b/services/ans/include/bundle_manager_helper.h index 2bde977c3770e9140ebbd22f9a53f88bfebec128..ed3cda547dcd74e725d9a345171173eaa7833302 100644 --- a/services/ans/include/bundle_manager_helper.h +++ b/services/ans/include/bundle_manager_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -86,6 +86,16 @@ public: bool GetDistributedNotificationEnabled(const std::string &bundleName, const int32_t userId); #endif + /** + * @brief Obtains BundleInfo of all bundles available in the system through the proxy object. + * @param flag Indicates the flag used to specify information contained in the BundleInfo that will be returned. + * @param bundleInfos Indicates all of the obtained BundleInfo objects. + * @param userId Indicates the user ID. + * @return Returns true if the BundleInfos is successfully obtained, returns false otherwise. + */ + bool GetBundleInfos( + const AppExecFwk::BundleFlag flag, std::vector &bundleInfos, int32_t userId); + private: void Connect(); void Disconnect(); diff --git a/services/ans/include/interface_system_event.h b/services/ans/include/interface_system_event.h index 7be3c05d803e62da8270d4193224db202444aa18..ad2dbac195231da8be246dd30fbb53e148de1b9a 100644 --- a/services/ans/include/interface_system_event.h +++ b/services/ans/include/interface_system_event.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -31,6 +31,8 @@ struct ISystemEvent { #endif std::function onResourceRemove; std::function &)> onBundleDataCleared; + std::function &)> onBundleAdd; + std::function &)> onBundleUpdate; }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/include/preferences_constant.h b/services/ans/include/preferences_constant.h index 034cc65d538bea01278e20ca0f244abcf099af0e..7e3de52ce071376783ae58c68aff6fa6fc66990f 100644 --- a/services/ans/include/preferences_constant.h +++ b/services/ans/include/preferences_constant.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -58,6 +58,7 @@ enum class BundleType { BUNDLE_SHOW_BADGE_TYPE, BUNDLE_BADGE_TOTAL_NUM_TYPE, BUNDLE_ENABLE_NOTIFICATION_TYPE, + BUNDLE_ENABLE_NOTIFICATION_USER_OPTION, BUNDLE_POPPED_DIALOG_TYPE, }; } // namespace Notification diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 88bf369f2d0bbfb31318f8a332e71b8440254c6e..e571129316485559869f735a63f1cf45a0df169b 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -81,6 +81,7 @@ constexpr int32_t DIALOG_DEFAULT_HEIGHT = 240; constexpr int32_t WINDOW_DEFAULT_WIDTH = 720; constexpr int32_t WINDOW_DEFAULT_HEIGHT = 1280; constexpr int32_t UI_HALF = 2; +constexpr int32_t MAIN_USER_ID = 100; constexpr char HIDUMPER_HELP_MSG[] = "Usage:dump [options]\n" @@ -301,6 +302,8 @@ AdvancedNotificationService::AdvancedNotificationService() #endif std::bind(&AdvancedNotificationService::OnResourceRemove, this, std::placeholders::_1), std::bind(&AdvancedNotificationService::OnBundleDataCleared, this, std::placeholders::_1), + std::bind(&AdvancedNotificationService::OnBundleDataAdd, this, std::placeholders::_1), + std::bind(&AdvancedNotificationService::OnBundleDataUpdate, this, std::placeholders::_1), }; systemEventObserver_ = std::make_shared(iSystemEvent); @@ -589,7 +592,19 @@ ErrCode AdvancedNotificationService::Publish(const std::string &label, const spt } do { + bool notificationEnable = false; if (request->GetReceiverUserId() != SUBSCRIBE_USER_INIT) { + result = CheckNotificationEnableStatus(notificationEnable); + if (result != ERR_OK) { + result = ERR_ANS_INVALID_BUNDLE; + ANS_LOGE("Bundle notification enable not found!"); + break; + } + if (notificationEnable) { + result = PublishPreparedNotificationInner(request); + break; + } + if (!AccessTokenHelper::IsSystemApp()) { result = ERR_ANS_NON_SYSTEM_APP; break; @@ -607,21 +622,9 @@ ErrCode AdvancedNotificationService::Publish(const std::string &label, const spt break; } - sptr bundleOption; - result = PrepareNotificationInfo(request, bundleOption); + result = PublishPreparedNotificationInner(request); if (result != ERR_OK) { - break; - } - - if (IsNeedPushCheck(request->GetSlotType())) { - result = PushCheck(request); - } - if (result != ERR_OK) { - break; - } - result = PublishPreparedNotification(request, bundleOption); - if (result != ERR_OK) { - break; + ANS_LOGE("Notification inner error code: %{public}d", result); } } while (0); @@ -2479,6 +2482,103 @@ void AdvancedNotificationService::OnBundleRemoved(const sptr &bundleOption) +{ + if (bundleOption == nullptr) { + ANS_LOGE("Bundle option sptr is null!"); + return; + } + if (bundleOption->GetBundleName().empty()) { + ANS_LOGE("Bundle name empty!"); + return; + } + + auto bundleInstall = [bundleOption]() { + if (bundleOption == nullptr) { + ANS_LOGE("Bundle option sptr is null!"); + return; + } + + AppExecFwk::BundleInfo bundleInfo; + int32_t callingUserId = -1; + AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(bundleOption->GetUid(), callingUserId); + auto bundleMgr = BundleManagerHelper::GetInstance(); + if (bundleMgr == nullptr) { + ANS_LOGE("bundleMgr instance error!"); + return; + } + if (!bundleMgr->GetBundleInfoByBundleName(bundleOption->GetBundleName(), callingUserId, bundleInfo)) { + ANS_LOGE("Get bundle info error!"); + return; + } + + auto errCode = NotificationPreferences::GetInstance().SetNotificationsEnabledForBundle( + bundleOption, bundleInfo.applicationInfo.allowEnableNotification); + if (errCode != ERR_OK) { + ANS_LOGE("Set notification enable error! code: %{public}d", errCode); + } + }; + + notificationSvrQueue_ != nullptr ? notificationSvrQueue_->submit(bundleInstall) : bundleInstall(); +} + +void AdvancedNotificationService::OnBundleDataUpdate(const sptr &bundleOption) +{ + if (bundleOption == nullptr) { + ANS_LOGE("Bundle option sptr is null!"); + return; + } + if (bundleOption->GetBundleName().empty()) { + ANS_LOGE("Bundle name empty!"); + return; + } + + auto bundleUpdate = [bundleOption]() { + if (bundleOption == nullptr) { + ANS_LOGE("Bundle option sptr is null!"); + return; + } + + AppExecFwk::BundleInfo bundleInfo; + int32_t callingUserId = -1; + AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(bundleOption->GetUid(), callingUserId); + auto bundleMgr = BundleManagerHelper::GetInstance(); + if (bundleMgr == nullptr) { + ANS_LOGE("bundleMgr instance error!"); + return; + } + if (!bundleMgr->GetBundleInfoByBundleName(bundleOption->GetBundleName(), callingUserId, bundleInfo)) { + ANS_LOGE("Get bundle info error!"); + return; + } + + bool hasPopped = false; + auto errCode = NotificationPreferences::GetInstance().GetHasPoppedDialog(bundleOption, hasPopped); + if (errCode != ERR_OK) { + ANS_LOGD("Get notification user option fail, need to insert data"); + errCode = NotificationPreferences::GetInstance().SetNotificationsEnabledForBundle( + bundleOption, bundleInfo.applicationInfo.allowEnableNotification); + if (errCode != ERR_OK) { + ANS_LOGE("Set notification enable error! code: %{public}d", errCode); + } + return; + } + + if (hasPopped) { + ANS_LOGI("The user has made changes, subject to the user's selection"); + return; + } + + errCode = NotificationPreferences::GetInstance().SetNotificationsEnabledForBundle( + bundleOption, bundleInfo.applicationInfo.allowEnableNotification); + if (errCode != ERR_OK) { + ANS_LOGE("Set notification enable error! code: %{public}d", errCode); + } + }; + + notificationSvrQueue_ != nullptr ? notificationSvrQueue_->submit(bundleUpdate) : bundleUpdate(); +} + #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED void AdvancedNotificationService::OnScreenOn() { @@ -4767,6 +4867,100 @@ void AdvancedNotificationService::SendNotificationsOnCanceled(std::vector activeUserId; + AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUserId); + if (activeUserId.empty()) { + activeUserId.push_back(MAIN_USER_ID); + } + AppExecFwk::BundleFlag flag = AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT; + std::vector bundleInfos; + for (auto &itemUser: activeUserId) { + std::vector infos; + if (!bundleMgr->GetBundleInfos(flag, infos, itemUser)) { + ANS_LOGW("Get bundle infos error"); + continue; + } + bundleInfos.insert(bundleInfos.end(), infos.begin(), infos.end()); + } + + bool notificationEnable = false; + ErrCode saveRef = ERR_OK; + for (const auto &bundleInfo : bundleInfos) { + sptr bundleOption = new (std::nothrow) NotificationBundleOption( + bundleInfo.applicationInfo.bundleName, bundleInfo.uid); + if (bundleOption == nullptr) { + ANS_LOGE("New bundle option obj error! bundlename:%{public}s", + bundleInfo.applicationInfo.bundleName.c_str()); + continue; + } + + saveRef = NotificationPreferences::GetInstance().GetNotificationsEnabledForBundle( + bundleOption, notificationEnable); + // record already exists + if (saveRef == ERR_OK) { + continue; + } + + saveRef = NotificationPreferences::GetInstance().SetNotificationsEnabledForBundle( + bundleOption, bundleInfo.applicationInfo.allowEnableNotification); + if (saveRef != ERR_OK) { + ANS_LOGE("Set enable error! code: %{public}d", saveRef); + } + } + }; + + notificationSvrQueue_ != nullptr ? notificationSvrQueue_->submit(task) : task(); +} + +ErrCode AdvancedNotificationService::CheckNotificationEnableStatus(bool ¬ificationEnable) +{ + auto bundleManager = BundleManagerHelper::GetInstance(); + if (bundleManager == nullptr) { + ANS_LOGE("BundleMgr is null!"); + return ERR_INVALID_VALUE; + } + + int32_t uid = IPCSkeleton::GetCallingUid(); + std::string bundleName = bundleManager->GetBundleNameByUid(uid); + sptr bundleOption = new (std::nothrow) NotificationBundleOption(bundleName, uid); + if (bundleOption == nullptr) { + ANS_LOGE("New obj error!"); + return ERR_INVALID_VALUE; + } + return NotificationPreferences::GetInstance().GetNotificationsEnabledForBundle(bundleOption, notificationEnable); +} + +ErrCode AdvancedNotificationService::PublishPreparedNotificationInner(const sptr &request) +{ + if (request == nullptr) { + ANS_LOGE("Request obj is null!"); + return ERR_INVALID_VALUE; + } + sptr bundleOption; + auto result = PrepareNotificationInfo(request, bundleOption); + if (result != ERR_OK) { + return result; + } + + if (IsNeedPushCheck(request->GetSlotType())) { + result = PushCheck(request); + if (result != ERR_OK) { + return result; + } + } + return PublishPreparedNotification(request, bundleOption); +} + void PushCallbackRecipient::OnRemoteDied(const wptr &remote) { ANS_LOGI("Push Callback died, remove the proxy object"); diff --git a/services/ans/src/bundle_manager_helper.cpp b/services/ans/src/bundle_manager_helper.cpp index c12f076effac76e625131fffd54531df17f11792..c6844103592e739898f4339388acedbe3db92d03 100644 --- a/services/ans/src/bundle_manager_helper.cpp +++ b/services/ans/src/bundle_manager_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -99,6 +99,9 @@ bool BundleManagerHelper::CheckApiCompatibility(const sptr lock(connectionMutex_); + Connect(); + if (bundleMgr_ == nullptr) { return false; } @@ -180,5 +183,21 @@ bool BundleManagerHelper::GetDistributedNotificationEnabled(const std::string &b return DEFAULT_DISTRIBUTED_ENABLE_IN_APPLICATION_INFO; } #endif + +bool BundleManagerHelper::GetBundleInfos( + const AppExecFwk::BundleFlag flag, std::vector &bundleInfos, int32_t userId) +{ + std::lock_guard lock(connectionMutex_); + Connect(); + + if (bundleMgr_ == nullptr) { + return false; + } + + std::string identity = IPCSkeleton::ResetCallingIdentity(); + bool ret = bundleMgr_->GetBundleInfos(flag, bundleInfos, userId); + IPCSkeleton::SetCallingIdentity(identity); + return ret; +} } // namespace Notification -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/services/ans/src/reminder_data_manager.cpp b/services/ans/src/reminder_data_manager.cpp index a2c646ab5bab0bccad6686f5a618fe2c4a833322..83c9ac9bbe38b57448a06edce7bb7972d8380f10 100644 --- a/services/ans/src/reminder_data_manager.cpp +++ b/services/ans/src/reminder_data_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -1058,6 +1058,11 @@ void ReminderDataManager::HandleSameNotificationIdShowing(const sptrInitNotificationEnableList(); + } + if (IsReminderAgentReady()) { return; } diff --git a/services/ans/src/system_event_observer.cpp b/services/ans/src/system_event_observer.cpp index 12a7c314731155fb3ed7cdb1ba2454e9d875c863..dc6ad1072ed526cad9407106ff34145136978800 100644 --- a/services/ans/src/system_event_observer.cpp +++ b/services/ans/src/system_event_observer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -35,6 +35,8 @@ SystemEventObserver::SystemEventObserver(const ISystemEvent &callbacks) : callba matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills); commonEventSubscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); @@ -102,7 +104,21 @@ void SystemEventObserver::OnReceiveEvent(const EventFwk::CommonEventData &data) callbacks_.onBundleDataCleared(bundleOption); } } + } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) { + if (callbacks_.onBundleAdd != nullptr) { + sptr bundleOption = GetBundleOption(want); + if (bundleOption != nullptr) { + callbacks_.onBundleAdd(bundleOption); + } + } + } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED) { + if (callbacks_.onBundleUpdate != nullptr) { + sptr bundleOption = GetBundleOption(want); + if (bundleOption != nullptr) { + callbacks_.onBundleUpdate(bundleOption); + } + } } } } // namespace Notification -} // namespace OHOS \ No newline at end of file +} // namespace OHOS