diff --git a/services/ans/include/notification_analytics_util.h b/services/ans/include/notification_analytics_util.h index 89f83b947f6a2a2d244a423fe689490e9a19729b..abbeb5a4a4bc8365faf94831a2dd589469bce281 100644 --- a/services/ans/include/notification_analytics_util.h +++ b/services/ans/include/notification_analytics_util.h @@ -88,10 +88,12 @@ class OperationalMeta { public: void ToJson(nlohmann::json& jsonObject); public: + int32_t createTime; int32_t syncTime; int32_t delTime; int32_t clickTime; int32_t replyTime; + std::set hashCodes; }; class OperationalData { @@ -114,7 +116,9 @@ public: std::string ToJson(); bool DetermineWhetherToSend(); HaOperationMessage& KeyNode(bool keyNodeFlag); - HaOperationMessage& SyncPublish(std::vector& deviceTypes); + HaOperationMessage& SyncPublish(const std::string& hashCode, + std::vector& deviceTypes); + HaOperationMessage& SyncDelete(const std::string& hashCode); HaOperationMessage& SyncDelete(std::string deviceType, const std::string& reason); HaOperationMessage& SyncClick(std::string deviceType); HaOperationMessage& SyncReply(std::string deviceType); diff --git a/services/ans/src/common/notification_analytics_util.cpp b/services/ans/src/common/notification_analytics_util.cpp index b8a0e8db4095f762466037f480bee03ebf41342c..7c96b535828ec0417c421073b005122bb9f903a3 100644 --- a/services/ans/src/common/notification_analytics_util.cpp +++ b/services/ans/src/common/notification_analytics_util.cpp @@ -99,6 +99,7 @@ static int32_t SLOT_REPORT_INTERVAL = 7 * 24 * NotificationConstant::HOUR_TO_MS; static int64_t lastReportTime_ = 0; static ffrt::mutex lastReportTimeMutex_; static int32_t SLOT_SUB_CODE = 101; +static int32_t DISTRIBUTED_SUB_CODE = 102; static int32_t SLOT_ONCE_REPORT = 10; static uint32_t SLOT_MAX_REPORT = 200; static uint64_t reportSlotEnabledTimerId_ = 0; @@ -226,10 +227,11 @@ std::string HaMetaMessage::Build() const void OperationalMeta::ToJson(nlohmann::json& jsonObject) { - jsonObject["s"] = syncTime; - jsonObject["d"] = delTime; - jsonObject["c"] = clickTime; - jsonObject["r"] = replyTime; + jsonObject["cr"] = createTime; + jsonObject["sy"] = syncTime; + jsonObject["de"] = delTime; + jsonObject["cl"] = clickTime; + jsonObject["re"] = replyTime; } OperationalData::OperationalData() @@ -274,11 +276,17 @@ std::string HaOperationMessage::ToJson() return jsonObject.dump(); } -void SetPublishTime(const std::vector& deviceTypes, OperationalData& data) +void SetPublishTime(const std::string& hashCode, const std::vector& deviceTypes, + OperationalData& data) { int32_t isWatchHeadSet = 0; for (auto& device : deviceTypes) { if (data.dataMap.find(device) != data.dataMap.end()) { + if (!data.dataMap[device].hashCodes.count(hashCode)) { + data.dataMap[device].createTime++; + data.dataMap[device].hashCodes.insert(hashCode); + data.countTime++; + } data.dataMap[device].syncTime++; if (device == NotificationConstant::HEADSET_DEVICE_TYPE || device == NotificationConstant::WEARABLE_DEVICE_TYPE || @@ -293,12 +301,30 @@ void SetPublishTime(const std::vector& deviceTypes, OperationalData } } -HaOperationMessage& HaOperationMessage::SyncPublish(std::vector& deviceTypes) +void SetDeleteTime(const std::string& hashCode, OperationalData& data) +{ + for (auto& device : data.dataMap) { + device.second.hashCodes.erase(hashCode); + } +} + +HaOperationMessage& HaOperationMessage::SyncPublish(const std::string& hashCode, + std::vector& deviceTypes) +{ + if (isLiveView_) { + SetPublishTime(hashCode, deviceTypes, liveViewData); + } else { + SetPublishTime(hashCode, deviceTypes, notificationData); + } + return *this; +} + +HaOperationMessage& HaOperationMessage::SyncDelete(const std::string& hashCode) { if (isLiveView_) { - SetPublishTime(deviceTypes, liveViewData); + SetDeleteTime(hashCode, liveViewData); } else { - SetPublishTime(deviceTypes, notificationData); + SetDeleteTime(hashCode, notificationData); } return *this; } @@ -1428,8 +1454,10 @@ void NotificationAnalyticsUtil::ReportOperationsDotEvent(HaOperationMessage& ope HaMetaMessage message; std::string extraInfo = NotificationAnalyticsUtil::BuildExtraInfo(message); NotificationAnalyticsUtil::SetCommonWant(want, message, extraInfo); - std::string ansData = operationMessage.ToJson(); - want.SetParam("ansData", ansData); + nlohmann::json ansData; + ansData["data"] = operationMessage.ToJson(); + ansData["subCode"] = std::to_string(DISTRIBUTED_SUB_CODE); + want.SetParam("ansData", ansData.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace)); ANS_LOGI("Publish operation event :%{public}s", operationMessage.ToJson().c_str()); operationMessage.ResetData(); IN_PROCESS_CALL_WITHOUT_RET(AddListCache(want, ANS_CUSTOMIZE_CODE)); diff --git a/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp b/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp index 4f70e9c753236e695b352b304ea52a230a3b8113..8794429005e3d999f00dfcce5ef4bac9eabf5f7d 100644 --- a/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp +++ b/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp @@ -863,6 +863,11 @@ ErrCode AdvancedNotificationService::GetDistributedAuthStatus( return ERR_ANS_NON_SYSTEM_APP; } + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + ANS_LOGE("no permission"); + return ERR_ANS_PERMISSION_DENIED; + } + return NotificationPreferences::GetInstance()->GetDistributedAuthStatus(deviceType, deviceId, userId, isAuth); } @@ -895,6 +900,11 @@ ErrCode AdvancedNotificationService::SetDistributedAuthStatus( return ERR_ANS_NON_SYSTEM_APP; } + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + ANS_LOGE("no permission"); + return ERR_ANS_PERMISSION_DENIED; + } + auto result = NotificationPreferences::GetInstance()->SetDistributedAuthStatus(deviceType, deviceId, userId, isAuth); if (result == ERR_OK) { diff --git a/services/ans/src/notification_subscriber_manager.cpp b/services/ans/src/notification_subscriber_manager.cpp index 5700fb351a5d043131f3122c88b25ca15cb7b148..b5a09e5337da8a00e56d58f1950e42ce1bbbc596 100644 --- a/services/ans/src/notification_subscriber_manager.cpp +++ b/services/ans/src/notification_subscriber_manager.cpp @@ -638,6 +638,11 @@ void NotificationSubscriberManager::NotifyCanceledInner( ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId()); std::shared_ptr liveViewContent = nullptr; + if (notification->GetNotificationRequestPoint() != nullptr) { + bool liveView = notification->GetNotificationRequest().IsCommonLiveView(); + HaOperationMessage(liveView).SyncDelete(notification->GetKey()); + } + ANS_LOGI("CancelNotification key = %{public}s", notification->GetKey().c_str()); for (auto record : subscriberRecordList_) { ANS_LOGD("%{public}s record->userId = <%{public}d>", __FUNCTION__, record->userId); @@ -726,6 +731,10 @@ void NotificationSubscriberManager::BatchNotifyCanceledInner(const std::vectorGetKey()).append("-"); + if (notification->GetNotificationRequestPoint() != nullptr) { + bool liveView = notification->GetNotificationRequestPoint()->IsCommonLiveView(); + HaOperationMessage(liveView).SyncDelete(notification->GetKey()); + } } ANS_LOGI("CancelNotification key = %{public}s", notificationKeys.c_str()); @@ -923,12 +932,13 @@ void NotificationSubscriberManager::TrackCodeLog(const sptr ¬if } } + std::string hashCode = notification->GetKey(); std::vector deviceTypes; for (auto& flag : *flagsMap) { deviceTypes.push_back(flag.first); } HaOperationMessage operation = HaOperationMessage(commonLiveView).KeyNode(keyNode) - .SyncPublish(deviceTypes); + .SyncPublish(hashCode, deviceTypes); NotificationAnalyticsUtil::ReportOperationsDotEvent(operation); } diff --git a/services/ans/test/unittest/advanced_notification_service_test/advanced_notification_distributed_manager_service_test.cpp b/services/ans/test/unittest/advanced_notification_service_test/advanced_notification_distributed_manager_service_test.cpp index 0f155723b3ff8644c38662422e1782f169b5227f..b300581aeda7a5e36ef648d513ea0aa86053c30d 100644 --- a/services/ans/test/unittest/advanced_notification_service_test/advanced_notification_distributed_manager_service_test.cpp +++ b/services/ans/test/unittest/advanced_notification_service_test/advanced_notification_distributed_manager_service_test.cpp @@ -825,6 +825,7 @@ HWTEST_F(AdvancedNotificationDistMgrServiceTest, GetDistributedAuthStatus_100, F HWTEST_F(AdvancedNotificationDistMgrServiceTest, GetDistributedAuthStatus_200, Function | SmallTest | Level1) { MockGetTokenTypeFlag(ATokenTypeEnum::TOKEN_HAP); + MockIsVerfyPermisson(true); MockIsSystemApp(true); const std::string deviceType = ""; const std::string deviceId = ""; @@ -836,6 +837,27 @@ HWTEST_F(AdvancedNotificationDistMgrServiceTest, GetDistributedAuthStatus_200, F ASSERT_EQ(ret, (int)ERR_OK); } +/** + * @tc.name: GetDistributedAuthStatus_300 + * @tc.desc: Test GetDistributedAuthStatus when succeed to call. + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AdvancedNotificationDistMgrServiceTest, GetDistributedAuthStatus_300, Function | SmallTest | Level1) +{ + MockGetTokenTypeFlag(ATokenTypeEnum::TOKEN_HAP); + MockIsSystemApp(true); + MockIsVerfyPermisson(false); + const std::string deviceType = ""; + const std::string deviceId = ""; + int32_t userId = 100; + bool isAuth = false; + + auto ret = advancedNotificationService_->GetDistributedAuthStatus(deviceType, deviceId, userId, isAuth); + + ASSERT_EQ(ret, (int)ERR_ANS_PERMISSION_DENIED); +} + /** * @tc.name: SetDistributedAuthStatus_100 * @tc.desc: Test SetDistributedAuthStatus when caller is not subsystem or system app. @@ -865,6 +887,7 @@ HWTEST_F(AdvancedNotificationDistMgrServiceTest, SetDistributedAuthStatus_100, F HWTEST_F(AdvancedNotificationDistMgrServiceTest, SetDistributedAuthStatus_200, Function | SmallTest | Level1) { MockGetTokenTypeFlag(ATokenTypeEnum::TOKEN_HAP); + MockIsVerfyPermisson(true); MockIsSystemApp(true); const std::string deviceType = ""; const std::string deviceId = ""; @@ -876,6 +899,27 @@ HWTEST_F(AdvancedNotificationDistMgrServiceTest, SetDistributedAuthStatus_200, F ASSERT_EQ(ret, (int)ERR_OK); } +/** + * @tc.name: SetDistributedAuthStatus_300 + * @tc.desc: Test SetDistributedAuthStatus when succeed to call. + * @tc.type: FUNC + * @tc.require: issue + */ +HWTEST_F(AdvancedNotificationDistMgrServiceTest, SetDistributedAuthStatus_300, Function | SmallTest | Level1) +{ + MockGetTokenTypeFlag(ATokenTypeEnum::TOKEN_HAP); + MockIsSystemApp(true); + MockIsVerfyPermisson(false); + const std::string deviceType = ""; + const std::string deviceId = ""; + int32_t userId = 100; + bool isAuth = false; + + auto ret = advancedNotificationService_->SetDistributedAuthStatus(deviceType, deviceId, userId, isAuth); + + ASSERT_EQ(ret, (int)ERR_ANS_PERMISSION_DENIED); +} + /** * @tc.name: GetDistributedDevicelist_0100 * @tc.desc: Test GetDistributedDevicelist. diff --git a/services/ans/test/unittest/common_utils/notification_analytics_util_test.cpp b/services/ans/test/unittest/common_utils/notification_analytics_util_test.cpp index c3195ca1e8124b49d783fd4acd461158d949841f..5d3afbd72fac79804e123f8172b20385311ac0b0 100644 --- a/services/ans/test/unittest/common_utils/notification_analytics_util_test.cpp +++ b/services/ans/test/unittest/common_utils/notification_analytics_util_test.cpp @@ -179,20 +179,22 @@ HWTEST_F(NotificationAnalyticsUtilTest, Operation_100, Function | SmallTest | Le deviceTypes.push_back("abc"); deviceTypes.push_back("2in1"); deviceTypes.push_back("tablet"); - operationMessage.KeyNode(true).SyncPublish(deviceTypes); + operationMessage.KeyNode(true).SyncPublish("notification_1", deviceTypes); operationMessage.ToJson(); - ASSERT_EQ(operationMessage.notificationData.countTime, 2); + ASSERT_EQ(operationMessage.notificationData.countTime, 4); operationMessage.ResetData(); + operationMessage.KeyNode(true).SyncDelete("notification_1"); operationMessage = HaOperationMessage(true); deviceTypes.clear(); deviceTypes.push_back("abc"); deviceTypes.push_back("wearable"); deviceTypes.push_back("headset"); - operationMessage.KeyNode(false).SyncPublish(deviceTypes); + operationMessage.KeyNode(false).SyncPublish("notification_1", deviceTypes); operationMessage.ToJson(); - ASSERT_EQ(operationMessage.liveViewData.countTime, 2); + ASSERT_EQ(operationMessage.liveViewData.countTime, 4); ASSERT_EQ(operationMessage.liveViewData.syncWatchHead, 1); + operationMessage.KeyNode(false).SyncDelete("notification_1"); } /** @@ -203,6 +205,7 @@ HWTEST_F(NotificationAnalyticsUtilTest, Operation_100, Function | SmallTest | Le HWTEST_F(NotificationAnalyticsUtilTest, Operation_200, Function | SmallTest | Level1) { HaOperationMessage operationMessage = HaOperationMessage(false); + operationMessage.notificationData.countTime = 0; operationMessage.SyncDelete("2in1", std::string()).SyncClick("2in1").SyncReply("2in1"); operationMessage.SyncDelete("pcb", std::string()).SyncClick("pcb").SyncReply("pcb"); operationMessage.ToJson(); @@ -210,6 +213,7 @@ HWTEST_F(NotificationAnalyticsUtilTest, Operation_200, Function | SmallTest | Le ASSERT_EQ(operationMessage.notificationData.countTime, 3); operationMessage.ResetData(); + operationMessage.liveViewData.countTime = 0; operationMessage = HaOperationMessage(true); operationMessage.ResetData(); operationMessage.SyncDelete("2in1", std::string()).SyncClick("2in1").SyncReply("2in1"); diff --git a/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp b/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp index 0f73628510b1473bdfdd0667db2f381bbb010c5f..9eecdebe30fca1c473377a2715dae11e106b9b9d 100644 --- a/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp +++ b/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp @@ -275,7 +275,8 @@ bool DistributedPublishService::ForWardRemove(const std::shared_ptr& bo for (auto peerDevice : peerDevices) { auto peerDeviceInfo = peerDevice.second; - if (peerDeviceInfo.deviceId_ == deviceId) { + if (peerDeviceInfo.deviceId_ == deviceId || + (peerDeviceInfo.IsPadOrPc() && peerDeviceInfo.peerState_ != DeviceState::STATE_ONLINE)) { ANS_LOGD("no need ForWardRemove"); continue; }