diff --git a/frameworks/ans/src/notification.cpp b/frameworks/ans/src/notification.cpp index ca7903ae7c2001e782d8a939de15039501821e34..9faed72747eb7c6aa0442b57bd561bed2f60cbba 100644 --- a/frameworks/ans/src/notification.cpp +++ b/frameworks/ans/src/notification.cpp @@ -30,7 +30,7 @@ Notification::Notification(const sptr &request) } request_ = request; if (request != nullptr) { - key_ = request->GetBaseKey(""); + key_ = request->GetBaseKey(deviceId_); } } @@ -39,7 +39,7 @@ Notification::Notification(const std::string &deviceId, const sptrGetBaseKey(deviceId); + key_ = request->GetBaseKey(deviceId_); } } diff --git a/frameworks/ans/src/notification_request.cpp b/frameworks/ans/src/notification_request.cpp index 0df61d034dabad924226f4f4b60775ae947a6090..27440b1c09fe18076de4719f78e8ebe80e71b744 100644 --- a/frameworks/ans/src/notification_request.cpp +++ b/frameworks/ans/src/notification_request.cpp @@ -2348,6 +2348,11 @@ bool NotificationRequest::IsSystemLiveView() const (notificationContentType_ == NotificationContent::Type::LOCAL_LIVE_VIEW); } +bool NotificationRequest::IsLiveView() const +{ + return IsCommonLiveView() || IsSystemLiveView(); +} + ErrCode NotificationRequest::CheckVersion(const sptr &oldRequest) const { auto content = notificationContent_->GetNotificationContent(); @@ -2483,14 +2488,18 @@ std::string NotificationRequest::GetBaseKey(const std::string &deviceId) const char *keySpliter = "_"; std::stringstream stream; + int32_t flag = 0; + if (isLiveViewForceControl_ && IsLiveView()) { + flag = 1; + } if (IsAgentNotification()) { stream << deviceId << keySpliter << ownerUserId_ << keySpliter << ownerUid_ << keySpliter << ownerBundleName_ << keySpliter << - label_ << keySpliter << notificationId_; + label_ << keySpliter << notificationId_ << keySpliter << flag; } else { stream << deviceId << keySpliter << creatorUserId_ << keySpliter << creatorUid_ << keySpliter << creatorBundleName_ << keySpliter << - label_ << keySpliter << notificationId_; + label_ << keySpliter << notificationId_ << keySpliter << flag; } return stream.str(); } @@ -2503,6 +2512,12 @@ std::string NotificationRequest::GetKey() return stream.str(); } + +void NotificationRequest::SetLiveViewForceControl(bool forceControl) +{ + isLiveViewForceControl_ = forceControl; +} + bool NotificationRequest::CheckImageOverSizeForPixelMap( const std::shared_ptr &pixelMap, uint32_t maxSize) { diff --git a/frameworks/ans/src/notification_slot.cpp b/frameworks/ans/src/notification_slot.cpp index 1ecac11bec3ed75c951773c9e9e7d081c862264e..2412b39254991bd5ab26c052df1afb58b9b368dd 100644 --- a/frameworks/ans/src/notification_slot.cpp +++ b/frameworks/ans/src/notification_slot.cpp @@ -16,6 +16,7 @@ #include "notification_slot.h" #include "ans_const_define.h" #include "ans_log_wrapper.h" +#include "notification_constant.h" namespace OHOS { namespace Notification { @@ -156,7 +157,6 @@ void NotificationSlot::SetType(NotificationConstant::SlotType type) SetSound(DEFAULT_NOTIFICATION_SOUND); SetVibrationStyle(DEFAULT_NOTIFICATION_VIBRATION); SetLevel(LEVEL_DEFAULT); - SetForceControl(true); break; case NotificationConstant::SlotType::CUSTOMER_SERVICE: id_ = "CUSTOMER_SERVICE"; diff --git a/frameworks/ans/test/unittest/BUILD.gn b/frameworks/ans/test/unittest/BUILD.gn index ae68e1aefe029b4bd40d2a49a62cc73a0c29df3d..ddf7aefc50e48db7f0a4a928a871785e07bf3066 100644 --- a/frameworks/ans/test/unittest/BUILD.gn +++ b/frameworks/ans/test/unittest/BUILD.gn @@ -55,6 +55,7 @@ ohos_unittest("ans_reminder_unit_test") { "${frameworks_module_ans_path}/test/unittest/notification_picture_content_test.cpp", "${frameworks_module_ans_path}/test/unittest/notification_progress_test.cpp", "${frameworks_module_ans_path}/test/unittest/notification_request_test.cpp", + "${frameworks_module_ans_path}/test/unittest/notification_slot_test.cpp", "${frameworks_module_ans_path}/test/unittest/notification_sorting_map_test.cpp", "${frameworks_module_ans_path}/test/unittest/notification_sorting_test.cpp", "${frameworks_module_ans_path}/test/unittest/notification_subscribe_info_test.cpp", diff --git a/frameworks/ans/test/unittest/notification_request_test.cpp b/frameworks/ans/test/unittest/notification_request_test.cpp index 5257eca81d37b1d073ce775452c1794a22ffab64..dbf15e15025f627846913bbeccf2767aecb38f89 100644 --- a/frameworks/ans/test/unittest/notification_request_test.cpp +++ b/frameworks/ans/test/unittest/notification_request_test.cpp @@ -13,7 +13,9 @@ * limitations under the License. */ +#include "notification_content.h" #include +#include #include #define private public @@ -953,7 +955,7 @@ HWTEST_F(NotificationRequestTest, GetNotificationRequestKey_0001, Level1) notificationRequest.SetLabel(string("test")); notificationRequest.SetCreatorBundleName(string("push.com")); auto key = notificationRequest.GetKey(); - string expectKey {"ans_live_view__1_0_push.com_test_10"}; + string expectKey {"ans_live_view__1_0_push.com_test_10_0"}; EXPECT_EQ(key, expectKey); } @@ -973,7 +975,30 @@ HWTEST_F(NotificationRequestTest, GetNotificationRequestKey_0002, Level1) notificationRequest.SetOwnerBundleName(string("test.com")); notificationRequest.SetIsAgentNotification(true); auto key = notificationRequest.GetKey(); - string expectKey {"ans_live_view__1_2_test.com_test_10"}; + string expectKey {"ans_live_view__1_2_test.com_test_10_0"}; + EXPECT_EQ(key, expectKey); +} + +/** + * @tc.name: GetNotificationRequestKey_0003 + * @tc.desc: Check get key right + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(NotificationRequestTest, GetNotificationRequestKey_0003, Level1) +{ + int32_t myNotificationId = 10; + NotificationRequest notificationRequest(myNotificationId); + auto pContent = std::make_shared(); + notificationRequest.SetOwnerUid(2); + notificationRequest.SetOwnerUserId(1); + notificationRequest.SetLabel(string("test")); + notificationRequest.SetOwnerBundleName(string("test.com")); + notificationRequest.SetIsAgentNotification(true); + notificationRequest.SetSlotType(NotificationConstant::SlotType::LIVE_VIEW); + notificationRequest.SetContent(std::make_shared(pContent)); + auto key = notificationRequest.GetKey(); + string expectKey {"ans_live_view__1_2_test.com_test_10_0"}; EXPECT_EQ(key, expectKey); } @@ -1205,5 +1230,35 @@ HWTEST_F(NotificationRequestTest, SetArchiveDeadLine_0001, Level1) notificationRequest.SetArchiveDeadLine(archiveDeadLine); EXPECT_EQ(notificationRequest.GetArchiveDeadLine(), 1); } + +/** + * @tc.name: SetLiveViewForceControl_00001 + * @tc.desc: Test SetLiveViewForceControl parameters. + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(NotificationRequestTest, SetLiveViewForceControl_00001, Level1) +{ + std::string deviceId = "DeviceId"; + int32_t userId = 10; + int32_t uid = 20; + std::string label = "Lable"; + int32_t id = 30; + auto pContent = std::make_shared(); + sptr request = sptr::MakeSptr(); + request->SetIsAgentNotification(true); + request->SetOwnerUid(uid); + request->SetOwnerUserId(userId); + request->SetLabel(label); + request->SetNotificationId(id); + request->SetCreatorBundleName("come.push"); + request->SetOwnerBundleName("come.test"); + request->SetSlotType(NotificationConstant::SlotType::LIVE_VIEW); + request->SetContent(std::make_shared(pContent)); + request->SetLiveViewForceControl(true); + + std::string result = "ans_live_view__10_20_come.test_Lable_30_1"; + EXPECT_EQ(request->GetKey(), result); +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/ans/test/unittest/notification_slot_test.cpp b/frameworks/ans/test/unittest/notification_slot_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa5f26fd2365fb62c990f19eab258661bfa99caa --- /dev/null +++ b/frameworks/ans/test/unittest/notification_slot_test.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021-2022 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 +#include "notification_slot.h" + +using namespace testing::ext; + +namespace OHOS { +namespace Notification { +class NotificationSlotTest : public testing::Test { +public: + static void SetUpTestCase() {}; + static void TearDownTestCase() {}; + void SetUp() {}; + void TearDown() {}; +}; + +/** + * @tc.name: SetType_0100 + * @tc.desc: Set LiveView Type + * @tc.type: FUNC + * @tc.require: issueI5RW70 + */ +HWTEST_F(NotificationSlotTest, SetType_0100, Level1) +{ + NotificationSlot notificationSlot(NotificationConstant::SlotType::LIVE_VIEW); + + EXPECT_EQ(notificationSlot.GetForceControl(), false); + EXPECT_EQ(notificationSlot.GetLockScreenVisibleness(), NotificationConstant::VisiblenessType::PUBLIC); + EXPECT_EQ(notificationSlot.GetName(), "LIVE_VIEW"); + EXPECT_EQ(notificationSlot.GetLevel(), NotificationSlot::LEVEL_DEFAULT); +} + +/** + * @tc.name: SetType_0200 + * @tc.desc: Set CUSTOMER_SERVICE Type + * @tc.type: FUNC + * @tc.require: issueI5RW70 + */ +HWTEST_F(NotificationSlotTest, SetType_0200, Level1) +{ + NotificationSlot notificationSlot(NotificationConstant::SlotType::CUSTOMER_SERVICE); + + EXPECT_EQ(notificationSlot.GetForceControl(), false); + EXPECT_EQ(notificationSlot.GetLockScreenVisibleness(), NotificationConstant::VisiblenessType::SECRET); + EXPECT_EQ(notificationSlot.GetName(), "CUSTOMER_SERVICE"); + EXPECT_EQ(notificationSlot.GetLevel(), NotificationSlot::LEVEL_LOW); +} + +/** + * @tc.name: SetType_0300 + * @tc.desc: Set EMERGENCY_INFORMATION Type + * @tc.type: FUNC + * @tc.require: issueI5RW70 + */ +HWTEST_F(NotificationSlotTest, SetType_0300, Level1) +{ + NotificationSlot notificationSlot(NotificationConstant::SlotType::EMERGENCY_INFORMATION); + + EXPECT_EQ(notificationSlot.GetForceControl(), false); + EXPECT_EQ(notificationSlot.GetLockScreenVisibleness(), NotificationConstant::VisiblenessType::PUBLIC); + EXPECT_EQ(notificationSlot.GetName(), "EMERGENCY_INFORMATION"); + EXPECT_EQ(notificationSlot.GetLevel(), NotificationSlot::LEVEL_HIGH); +} +} +} \ No newline at end of file diff --git a/frameworks/ans/test/unittest/notification_test.cpp b/frameworks/ans/test/unittest/notification_test.cpp index 60ef02bd8c059f8bfd6fa319cbc1834bcec4e731..38ce6df12fb230d3870cfd8d903691fc75d2e15d 100644 --- a/frameworks/ans/test/unittest/notification_test.cpp +++ b/frameworks/ans/test/unittest/notification_test.cpp @@ -216,7 +216,7 @@ HWTEST_F(NotificationTest, GenerateNotificationKey_00001, Function | SmallTest | request->SetNotificationId(id); request->SetCreatorBundleName("come.test"); auto rrc = std::make_shared(request); - std::string result = "_10_20_come.test_Lable_30"; + std::string result = "_10_20_come.test_Lable_30_0"; EXPECT_EQ(rrc->GetKey(), result); } @@ -242,7 +242,7 @@ HWTEST_F(NotificationTest, GenerateNotificationKey_00002, Function | SmallTest | request->SetCreatorBundleName("come.push"); request->SetOwnerBundleName("come.test"); auto rrc = std::make_shared(deviceId, request); - std::string result = "DeviceId_10_20_come.test_Lable_30"; + std::string result = "DeviceId_10_20_come.test_Lable_30_0"; EXPECT_EQ(rrc->GetKey(), result); } @@ -301,7 +301,7 @@ HWTEST_F(NotificationTest, Dump_00001, Function | SmallTest | Level1) std::string deviceId = "DeviceId"; sptr request = new NotificationRequest(); auto rrc = std::make_shared(deviceId, request); - std::string ret = "Notification{ key = DeviceId_-1_0___0, ledLightColor = 0, " + std::string ret = "Notification{ key = DeviceId_-1_0___0_0, ledLightColor = 0, " "lockscreenVisbleness = 0, remindType = -1, isRemoveAllowed = true, sourceType = 0, " "deviceId = DeviceId, request = NotificationRequest{ notificationId = 0, slotType = 3, " "createTime = 0, deliveryTime = 0, autoDeletedTime = -1, settingsText = , " diff --git a/interfaces/inner_api/notification_request.h b/interfaces/inner_api/notification_request.h index 541f8529434e844b219a1884f67dc058e02a9b52..82a098bff124a91e5f9b998c7e29b8b5860d868e 100644 --- a/interfaces/inner_api/notification_request.h +++ b/interfaces/inner_api/notification_request.h @@ -1208,6 +1208,8 @@ public: bool IsSystemLiveView() const; + bool IsLiveView() const; + /** * @brief Checks whether the image size exceeds the limit in content. * @@ -1372,6 +1374,13 @@ public: */ bool IsUpdateByOwnerAllowed() const; + /** + * @brief Read a NotificationRequest object from a Parcel. + * + * @param forceControl Indicates the parcel object. + */ + void SetLiveViewForceControl(bool forceControl); + private: /** * Indicates the color mask, used for calculation with the ARGB value set by setColor(int32_t). @@ -1491,6 +1500,7 @@ private: bool isRemoveAllowed_ {true}; bool isCoverActionButtons_ {false}; bool isUpdateByOwnerAllowed_ {false}; + bool isLiveViewForceControl_ {false}; std::shared_ptr wantAgent_ {}; std::shared_ptr removalWantAgent_ {}; diff --git a/services/ans/include/access_token_helper.h b/services/ans/include/access_token_helper.h index 6eaf2783ff6d532f2f1cb995eb14bd62b43dc74e..77fe1adfee03a60313a6cf542559bd58b0102f0b 100644 --- a/services/ans/include/access_token_helper.h +++ b/services/ans/include/access_token_helper.h @@ -35,6 +35,7 @@ public: const Security::AccessToken::AccessTokenID &tokenCaller, const std::string &permission); static bool VerifyNativeToken(const Security::AccessToken::AccessTokenID &callerToken); static bool IsSystemApp(); + static bool IsThirdPartApp(); static bool IsDlpHap(const Security::AccessToken::AccessTokenID &callerToken); static bool VerifyShellToken(const Security::AccessToken::AccessTokenID &callerToken); static bool CheckPermission(const std::string &permission); diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 710daf36fe77489111b5ee7f92ec1778a8ad8a0e..ec1a62dc0012ec432cc41f97d5d822b4d36680b0 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -25,6 +25,8 @@ #include "event_handler.h" #include "event_runner.h" #include "ffrt.h" +#include "notification_request.h" +#include "notification_slot.h" #include "refbase.h" #include "ans_const_define.h" @@ -77,6 +79,8 @@ public: static sptr GetInstance(); static std::map& GetDefaultSlotConfig(); + + static bool GetSlotForceControl(const sptr &slot); void SelfClean(); @@ -907,8 +911,8 @@ public: */ void OnDistributedKvStoreDeathRecipient(); - ErrCode CancelPreparedNotification( - int32_t notificationId, const std::string &label, const sptr &bundleOption); + ErrCode CancelPreparedNotification(int32_t notificationId, const std::string &label, + const sptr &bundleOption, const bool checkLiveViewForceControl = false); ErrCode PrepareNotificationInfo( const sptr &request, sptr &bundleOption); ErrCode PublishPreparedNotification(const sptr &request, @@ -1158,7 +1162,8 @@ private: void UpdateInDelayNotificationList(const std::shared_ptr &record); ErrCode AssignToNotificationList(const std::shared_ptr &record); ErrCode RemoveFromNotificationList(const sptr &bundleOption, const std::string &label, - int32_t notificationId, sptr ¬ification, bool isCancel = false); + int32_t notificationId, sptr ¬ification, bool checkLiveViewForceControl, + bool isCancel = false); ErrCode RemoveFromNotificationList(const std::string &key, sptr ¬ification, bool isCancel, int32_t removeReason); ErrCode RemoveFromNotificationListForDeleteAll(const std::string &key, @@ -1168,7 +1173,8 @@ private: std::shared_ptr GetFromNotificationList(const int32_t ownerUid, const int32_t notificationId); std::shared_ptr GetFromDelayedNotificationList( const int32_t ownerUid, const int32_t notificationId); - std::vector GetNotificationKeys(const sptr &bundleOption); + std::vector GetNotificationKeys(const sptr &bundleOption, + bool checkLiveViewForceControl = false); bool IsNotificationExists(const std::string &key); void SortNotificationList(); static bool NotificationCompare( @@ -1201,7 +1207,10 @@ private: void TriggerRemoveWantAgent(const sptr &request); bool CheckApiCompatibility(const sptr &bundleOption); ErrCode IsAllowedNotifySelf(const sptr &bundleOption, bool &allowed); - + ErrCode SetLiveViewForceControlToRequest(const sptr &request, + const sptr &bundleOption); + bool CheckLiveViewForceControlAsBundle(const bool checkLiveViewForceControl, + const sptr &request, const sptr &bundleOption); ErrCode SetNotificationRemindType(sptr notification, bool isLocal); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED std::vector GetLocalNotificationKeys(const sptr &bundleOption); diff --git a/services/ans/src/access_token_helper.cpp b/services/ans/src/access_token_helper.cpp index 880749654800d48c68d86bf0429acfb50ef8ee0b..4f1945e255ba60dc1155d9e6158e65c50684c408 100644 --- a/services/ans/src/access_token_helper.cpp +++ b/services/ans/src/access_token_helper.cpp @@ -57,6 +57,19 @@ bool AccessTokenHelper::IsSystemApp() return false; } +bool AccessTokenHelper::IsThirdPartApp() +{ + AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); + ATokenTypeEnum type = AccessTokenKit::GetTokenTypeFlag(tokenId); + if (type == ATokenTypeEnum::TOKEN_HAP) { + uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID(); + if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) { + return true; + } + } + return false; +} + bool AccessTokenHelper::IsDlpHap(const AccessTokenID &callerToken) { ATokenTypeEnum type = AccessTokenKit::GetTokenTypeFlag(callerToken); diff --git a/services/ans/src/advanced_notification_live_view_service.cpp b/services/ans/src/advanced_notification_live_view_service.cpp index f3019203756337c2252600b1042f85a00cffc5d5..192b1d7583ec26e799e3e7e58effe261c2bd2844 100644 --- a/services/ans/src/advanced_notification_live_view_service.cpp +++ b/services/ans/src/advanced_notification_live_view_service.cpp @@ -353,7 +353,7 @@ ErrCode AdvancedNotificationService::IsAllowedRemoveSlot(const sptrGetForceControl()) { + if (!GetSlotForceControl(slot)) { ANS_LOGI("Liveview slot is not force control."); return ERR_OK; } diff --git a/services/ans/src/advanced_notification_publish_service.cpp b/services/ans/src/advanced_notification_publish_service.cpp index 2f10f5b17e573fd127cba69a2228b005f21b65e4..04aeab3612e63027dfee9435fea8a251fb9a7469 100644 --- a/services/ans/src/advanced_notification_publish_service.cpp +++ b/services/ans/src/advanced_notification_publish_service.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "access_token_helper.h" #include "advanced_notification_service.h" #include @@ -190,7 +191,8 @@ ErrCode AdvancedNotificationService::Cancel(int32_t notificationId, const std::s return ERR_ANS_INVALID_BUNDLE; } bundleOption->SetInstanceKey(instanceKey); - return CancelPreparedNotification(notificationId, label, bundleOption); + bool checkLiveViewForceControl = AccessTokenHelper::IsThirdPartApp(); + return CancelPreparedNotification(notificationId, label, bundleOption, checkLiveViewForceControl); } ErrCode AdvancedNotificationService::CancelAll(int32_t instanceKey) @@ -211,8 +213,8 @@ ErrCode AdvancedNotificationService::CancelAll(int32_t instanceKey) ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { ANS_LOGD("ffrt enter!"); sptr notification = nullptr; - - std::vector keys = GetNotificationKeys(bundleOption); + bool checkForceControl = AccessTokenHelper::IsThirdPartApp(); + std::vector keys = GetNotificationKeys(bundleOption, checkForceControl); std::vector> notifications; for (auto key : keys) { #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED @@ -285,7 +287,7 @@ ErrCode AdvancedNotificationService::CancelAsBundle( } sptr bundle = new (std::nothrow) NotificationBundleOption( bundleOption->GetBundleName(), uid); - return CancelPreparedNotification(notificationId, "", bundle); + return CancelPreparedNotification(notificationId, "", bundle, true); } ErrCode AdvancedNotificationService::CancelAsBundle( @@ -342,7 +344,7 @@ ErrCode AdvancedNotificationService::CancelAsBundleWithAgent( } sptr bundle = new (std::nothrow) NotificationBundleOption( bundleOption->GetBundleName(), uid); - return CancelPreparedNotification(id, "", bundle); + return CancelPreparedNotification(id, "", bundle, false); } return ERR_ANS_NO_AGENT_SETTING; @@ -1343,7 +1345,7 @@ ErrCode AdvancedNotificationService::RemoveAllNotificationsInner(const sptrslot != nullptr) { - if (record->slot->GetForceControl() && record->slot->GetEnable()) { + if (GetSlotForceControl(record->slot) && record->slot->GetEnable()) { continue; } } @@ -1750,7 +1752,7 @@ ErrCode AdvancedNotificationService::SetEnabledForBundleSlot(const sptrGetEnable() == enabled && slot->GetForceControl() == isForceControl) { + if (slot->GetEnable() == enabled && GetSlotForceControl(slot) == isForceControl) { // 设置authorizedStatus为已授权 slot->SetAuthorizedStatus(NotificationSlot::AuthorizedStatus::AUTHORIZED); std::vector> slots; @@ -1786,7 +1788,7 @@ ErrCode AdvancedNotificationService::SetEnabledForBundleSlot(const sptrGetEnable()) { RemoveNotificationBySlot(bundle, slot); } else { - if (!slot->GetForceControl() && !allowed) { + if (!GetSlotForceControl(slot) && !allowed) { RemoveNotificationBySlot(bundle, slot); } } @@ -1923,12 +1925,12 @@ ErrCode AdvancedNotificationService::PublishNotificationBySa(const sptrnotification = new (std::nothrow) Notification(request); if (record->notification == nullptr) { ANS_LOGE("Failed to create notification"); return ERR_ANS_NO_MEMORY; } - if (notificationSvrQueue_ == nullptr) { ANS_LOGE("Serial queue is invalid."); return ERR_ANS_INVALID_PARAM; @@ -2151,7 +2153,7 @@ ErrCode AdvancedNotificationService::DuplicateMsgControl(const sptrGenerateUniqueKey(); if (IsDuplicateMsg(uniqueKey)) { ANS_LOGI("Duplicate msg, no need to notify, key is %{public}s, appmessageId is %{public}s", - request->GetKey().c_str(), request->GetAppMessageId().c_str()); + uniqueKey.c_str(), request->GetAppMessageId().c_str()); return ERR_ANS_DUPLICATE_MSG; } diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 0a3dd82550250757798e7db33885cd96db4ea0d0..d46e7654efebff9c719ad5fac2d3754cdc2a4567 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -32,8 +32,10 @@ #include "ans_permission_def.h" #include "bundle_manager_helper.h" #include "errors.h" +#include "notification_bundle_option.h" #include "notification_extension_wrapper.h" #include "notification_record.h" +#include "refbase.h" #include "os_account_manager_helper.h" #ifdef DEVICE_USAGE_STATISTICS_ENABLE #include "bundle_active_client.h" @@ -355,8 +357,8 @@ ErrCode AdvancedNotificationService::AssignToNotificationList(const std::shared_ return result; } -ErrCode AdvancedNotificationService::CancelPreparedNotification( - int32_t notificationId, const std::string &label, const sptr &bundleOption) +ErrCode AdvancedNotificationService::CancelPreparedNotification(int32_t notificationId, + const std::string &label, const sptr &bundleOption, const bool checkLiveViewForceControl) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); if (bundleOption == nullptr) { @@ -371,7 +373,8 @@ ErrCode AdvancedNotificationService::CancelPreparedNotification( ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { ANS_LOGD("ffrt enter!"); sptr notification = nullptr; - result = RemoveFromNotificationList(bundleOption, label, notificationId, notification, true); + result = RemoveFromNotificationList(bundleOption, label, notificationId, notification, + checkLiveViewForceControl, true); if (result != ERR_OK) { return; } @@ -556,6 +559,7 @@ std::shared_ptr AdvancedNotificationService::MakeNotificatio const sptr &request, const sptr &bundleOption) { auto record = std::make_shared(); + SetLiveViewForceControlToRequest(request, bundleOption); record->request = request; record->notification = new (std::nothrow) Notification(request); if (record->notification == nullptr) { @@ -979,6 +983,10 @@ ErrCode AdvancedNotificationService::GetActiveNotifications( for (auto record : notificationList_) { if ((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) && (record->bundleOption->GetUid() == bundleOption->GetUid())) { + bool checkLiveViewForceControl = AccessTokenHelper::IsThirdPartApp(); + if (CheckLiveViewForceControlAsBundle(checkLiveViewForceControl, record->request, bundleOption)) { + continue; + } notifications.push_back(record->request); } } @@ -1007,6 +1015,10 @@ ErrCode AdvancedNotificationService::GetActiveNotificationNums(uint64_t &num) for (auto record : notificationList_) { if ((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) && (record->bundleOption->GetUid() == bundleOption->GetUid())) { + bool checkLiveViewForceControl = AccessTokenHelper::IsThirdPartApp(); + if (CheckLiveViewForceControlAsBundle(checkLiveViewForceControl, record->request, bundleOption)) { + continue; + } count += 1; } } @@ -1078,14 +1090,18 @@ ErrCode AdvancedNotificationService::GetUnifiedGroupInfoFromDb(std::string &enab } std::vector AdvancedNotificationService::GetNotificationKeys( - const sptr &bundleOption) + const sptr &bundleOption, bool checkLiveViewForceControl) { std::vector keys; for (auto record : notificationList_) { - if ((bundleOption != nullptr) && - (record->bundleOption->GetUid() != bundleOption->GetUid())) { - continue; + if (bundleOption != nullptr) { + if (record->bundleOption->GetUid() != bundleOption->GetUid()) { + continue; + } + if (CheckLiveViewForceControlAsBundle(checkLiveViewForceControl, record->request, bundleOption)) { + continue; + } } keys.push_back(record->notification->GetKey()); } @@ -1102,7 +1118,8 @@ std::vector AdvancedNotificationService::GetNotificationKeys( } ErrCode AdvancedNotificationService::RemoveFromNotificationList(const sptr &bundleOption, - const std::string &label, int32_t notificationId, sptr ¬ification, bool isCancel) + const std::string &label, int32_t notificationId, sptr ¬ification, bool checkLiveViewForceControl, + bool isCancel) { for (auto record : notificationList_) { if ((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) && @@ -1113,6 +1130,9 @@ ErrCode AdvancedNotificationService::RemoveFromNotificationList(const sptrdeviceId.empty() #endif ) { + if (CheckLiveViewForceControlAsBundle(checkLiveViewForceControl, record->request, bundleOption)) { + continue; + } if (!isCancel && !record->notification->IsRemoveAllowed()) { return ERR_ANS_NOTIFICATION_IS_UNALLOWED_REMOVEALLOWED; } diff --git a/services/ans/src/advanced_notification_slot_service.cpp b/services/ans/src/advanced_notification_slot_service.cpp index 5a21ccaf56d2b973f463c588d7ba00dc6399401e..2afb4aa95a770c07365d80b8c58fc096a8d56780 100644 --- a/services/ans/src/advanced_notification_slot_service.cpp +++ b/services/ans/src/advanced_notification_slot_service.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "access_token_helper.h" @@ -27,8 +28,12 @@ #include "common_event_manager.h" #include "common_event_support.h" #include "hitrace_meter_adapter.h" +#include "notification_preferences.h" +#include "notification_slot.h" #include "os_account_manager_helper.h" #include "ipc_skeleton.h" +#include "notification_bundle_option.h" +#include "refbase.h" #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED #include "smart_reminder_center.h" #endif @@ -787,5 +792,38 @@ bool AdvancedNotificationService::IsAgentRelationship(const std::string &agentBu return result; } + +ErrCode AdvancedNotificationService::SetLiveViewForceControlToRequest(const sptr &request, + const sptr &bundleOption) +{ + if (request->IsLiveView()) { + sptr slot; + NotificationConstant::SlotType slotType = request->GetSlotType(); + ErrCode result = NotificationPreferences::GetInstance().GetNotificationSlot(bundleOption, slotType, slot); + if ((result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) || + (result == ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST)) { + slot = new (std::nothrow) NotificationSlot(slotType); + } + if (slot != nullptr) { + request->SetLiveViewForceControl(GetSlotForceControl(slot)); + } + } + return ERR_OK; +} + + +bool AdvancedNotificationService::CheckLiveViewForceControlAsBundle(const bool checkLiveViewForceControl, + const sptr &request, const sptr &bundleOption) +{ + if (checkLiveViewForceControl && request->IsLiveView()) { + sptr slot; + NotificationConstant::SlotType slotType = request->GetSlotType(); + ErrCode result = NotificationPreferences::GetInstance().GetNotificationSlot(bundleOption, slotType, slot); + if (result == ERR_OK && slot != nullptr) { + return GetSlotForceControl(slot); + } + } + return false; +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/advanced_notification_utils.cpp b/services/ans/src/advanced_notification_utils.cpp index ff229bb293f468dd234b033627b41b630fb6d745..9d303d7520353174c548f0c9c2b0217145a0c485 100644 --- a/services/ans/src/advanced_notification_utils.cpp +++ b/services/ans/src/advanced_notification_utils.cpp @@ -123,6 +123,15 @@ sptr AdvancedNotificationService::GenerateBundleOption return bundleOption; } +bool AdvancedNotificationService::GetSlotForceControl(const sptr &slot) +{ + if (slot->GetType() == NotificationConstant::SlotType::LIVE_VIEW && + pushCallBacks_.find(slot->GetType()) != pushCallBacks_.end()) { + return true; + } + return slot->GetForceControl(); +} + sptr AdvancedNotificationService::GenerateValidBundleOption( const sptr &bundleOption) { diff --git a/services/ans/src/permission_filter.cpp b/services/ans/src/permission_filter.cpp index dd1207b4ae4e8434d852123349ca5494cdadd5a2..c100f8b9f20652a70ec2248e0e782ed0e473a5ad 100644 --- a/services/ans/src/permission_filter.cpp +++ b/services/ans/src/permission_filter.cpp @@ -18,7 +18,9 @@ #include "ans_inner_errors.h" #include "ans_log_wrapper.h" #include "bundle_manager_helper.h" +#include "notification_constant.h" #include "notification_preferences.h" +#include "advanced_notification_service.h" namespace OHOS { namespace Notification { @@ -47,7 +49,7 @@ ErrCode PermissionFilter::OnPublish(const std::shared_ptr &r result = NotificationPreferences::GetInstance().GetNotificationSlot(record->bundleOption, slotType, slot); if (result == ERR_OK) { if (slot != nullptr) { - isForceControl = slot->GetForceControl(); + isForceControl = AdvancedNotificationService::GetSlotForceControl(slot); } else { result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_ENABLED; ANS_LOGE("Type[%{public}d] slot does not exist", slotType); diff --git a/services/ans/test/unittest/advanced_notification_slot_service_test.cpp b/services/ans/test/unittest/advanced_notification_slot_service_test.cpp index b2960ec1ccf3843722427cee19c3be9a2253b6b9..59c10b120e3c801a770ab7aac4ffdedf4a0540ac 100644 --- a/services/ans/test/unittest/advanced_notification_slot_service_test.cpp +++ b/services/ans/test/unittest/advanced_notification_slot_service_test.cpp @@ -13,6 +13,12 @@ * limitations under the License. */ +#include "errors.h" +#include "notification.h" +#include "notification_basic_content.h" +#include "notification_normal_content.h" +#include "notification_request.h" +#include "refbase.h" #include #include #include @@ -536,5 +542,84 @@ HWTEST_F(AnsSlotServiceTest, GetConfigSlotReminderModeByType_00001, Function | S DelayedSingleton::GetInstance()->GetConfigSlotReminderModeByType(slotType); ASSERT_EQ(reminderMode, (int)0b111111); } + +/** + * @tc.name: SetLiveViewForceControlToRequest_00001 + * @tc.desc: Test SetLiveViewForceControlToRequest + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AnsSlotServiceTest, SetLiveViewForceControlToRequest_00001, Function | SmallTest | Level1) +{ + sptr bundle = new NotificationBundleOption("test", 1); + sptr request = new NotificationRequest(); + auto pContent = std::make_shared(); + request->SetSlotType(NotificationConstant::SlotType::LIVE_VIEW); + request->SetContent(std::make_shared(pContent)); + + auto ret = advancedNotificationService_->SetLiveViewForceControlToRequest(request, bundle); + + EXPECT_EQ(ret, (int)ERR_OK); +} + +/** + * @tc.name: CheckLiveViewForceControlAsBundle_00001 + * @tc.desc: Test CheckLiveViewForceControlAsBundle + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AnsSlotServiceTest, CheckLiveViewForceControlAsBundle_00001, Function | SmallTest | Level1) +{ + sptr bundle = new NotificationBundleOption("test", 1); + sptr request = new NotificationRequest(); + auto pContent = std::make_shared(); + request->SetSlotType(NotificationConstant::SlotType::LIVE_VIEW); + request->SetContent(std::make_shared(pContent)); + + sptr notification = new Notification(request); + auto ret = advancedNotificationService_->CheckLiveViewForceControlAsBundle(false, request, bundle); + + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: CheckLiveViewForceControlAsBundle_00001 + * @tc.desc: Test CheckLiveViewForceControlAsBundle + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AnsSlotServiceTest, CheckLiveViewForceControlAsBundle_00002, Function | SmallTest | Level1) +{ + sptr bundle = new NotificationBundleOption("test", 1); + sptr request = new NotificationRequest(); + auto pContent = std::make_shared(); + request->SetSlotType(NotificationConstant::SlotType::LIVE_VIEW); + request->SetContent(std::make_shared(pContent)); + + sptr notification = new Notification(request); + auto ret = advancedNotificationService_->CheckLiveViewForceControlAsBundle(true, request, bundle); + + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: CheckLiveViewForceControlAsBundle_00001 + * @tc.desc: Test CheckLiveViewForceControlAsBundle + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AnsSlotServiceTest, CheckLiveViewForceControlAsBundle_00003, Function | SmallTest | Level1) +{ + sptr bundle = new NotificationBundleOption("test", 1); + sptr request = new NotificationRequest(); + auto pContent = std::make_shared(); + request->SetSlotType(NotificationConstant::SlotType::CONTENT_INFORMATION); + request->SetContent(std::make_shared(pContent)); + + sptr notification = new Notification(request); + auto ret = advancedNotificationService_->CheckLiveViewForceControlAsBundle(true, request, bundle); + + EXPECT_EQ(ret, false); +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/test/unittest/advanced_notification_utils_test.cpp b/services/ans/test/unittest/advanced_notification_utils_test.cpp index 4941fa0faeb8320ee7072ff4fb0fd804e6faf791..c2363cffa42b1cdb5e4f4d7aece13d5d1deb74bc 100644 --- a/services/ans/test/unittest/advanced_notification_utils_test.cpp +++ b/services/ans/test/unittest/advanced_notification_utils_test.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "gtest/gtest.h" @@ -448,5 +449,31 @@ HWTEST_F(AnsUtilsTest, OnBundleDataUpdate_00001, Function | SmallTest | Level1) NotificationPreferences::GetInstance().SetHasPoppedDialog(bundle, true); advancedNotificationService_->OnBundleDataUpdate(bundle); } + +/** + * @tc.name: GetSlotForceControl_00001 + * @tc.desc: Test GetSlotForceControl + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AnsUtilsTest, GetSlotForceControl_00001, Function | SmallTest | Level1) +{ + sptr slot = new (std::nothrow) NotificationSlot(NotificationConstant::SlotType::LIVE_VIEW); + + ASSERT_EQ(AdvancedNotificationService::GetSlotForceControl(slot), false); +} + +/** + * @tc.name: GetSlotForceControl_00002 + * @tc.desc: Test GetSlotForceControl + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AnsUtilsTest, GetSlotForceControl_00002, Function | SmallTest | Level1) +{ + sptr slot = new (std::nothrow) NotificationSlot(NotificationConstant::SlotType::SOCIAL_COMMUNICATION); + + ASSERT_EQ(AdvancedNotificationService::GetSlotForceControl(slot), false); +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/test/unittest/notification_preferences_database_test.cpp b/services/ans/test/unittest/notification_preferences_database_test.cpp index 692ae12008f20d979d506e3dfcc8166df33b13aa..1fbd9b1b24d9e0b8f08fd764178142c274b60209 100644 --- a/services/ans/test/unittest/notification_preferences_database_test.cpp +++ b/services/ans/test/unittest/notification_preferences_database_test.cpp @@ -808,6 +808,23 @@ HWTEST_F(NotificationPreferencesDatabaseTest, ParseSlotFromDisturbeDB_01300, Fun preferncesDB_->ParseSlotFromDisturbeDB(bundleInfo, bundleKey, entry, -1); } +/** + * @tc.number : ParseSlotFromDisturbeDB_01400 + * @tc.name : ParseSlotFromDisturbeDB + */ +HWTEST_F(NotificationPreferencesDatabaseTest, ParseSlotFromDisturbeDB_01400, Function | SmallTest | Level1) +{ + NotificationPreferencesInfo::BundleInfo bundleInfo; + bundleInfo.SetBundleName(bundleName_); + bundleInfo.SetBundleUid(bundleUid_); + std::string bundleKey = "bundleKey"; + std::pair entry; + entry.first = "ans_bundle_bundleKey_slot_type_1_isForceControl"; + entry.second = "1"; + ASSERT_NE(nullptr, preferncesDB_); + preferncesDB_->ParseSlotFromDisturbeDB(bundleInfo, bundleKey, entry, -1); +} + /** * @tc.name : PutHasPoppedDialog_00100 * @tc.number :