From 72c2e7e8faa481e894a5e5f5b6b77bd9024dfa19 Mon Sep 17 00:00:00 2001 From: wufarong Date: Tue, 20 May 2025 11:41:19 +0800 Subject: [PATCH 1/2] =?UTF-8?q?title=E6=A0=A1=E9=AA=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E8=AF=A6=E7=BB=86=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wufarong --- services/ans/src/permission_filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ans/src/permission_filter.cpp b/services/ans/src/permission_filter.cpp index 00207a553..9726c3193 100644 --- a/services/ans/src/permission_filter.cpp +++ b/services/ans/src/permission_filter.cpp @@ -69,7 +69,7 @@ ErrCode PermissionFilter::OnPublish(const std::shared_ptr &r if (result == ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST) { message.ErrorCode(ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST).Message("Slot type not exist."); NotificationAnalyticsUtil::ReportPublishFailedEvent(record->request, message); - ANS_LOGE("Slot type not exist."); + ANS_LOGE("Slot type %{public}d not exist.", slotType); } } -- Gitee From 22581794ad4b1053b4e8ca7cf32aeb5045c26893 Mon Sep 17 00:00:00 2001 From: wufarong Date: Thu, 29 May 2025 20:06:49 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AE=9E=E5=86=B5=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=89=93=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wufarong --- .../ans/include/notification_analytics_util.h | 22 ++ .../common/notification_analytics_util.cpp | 224 ++++++++++++++++++ .../notification_analytics_util_test.cpp | 25 ++ 3 files changed, 271 insertions(+) diff --git a/services/ans/include/notification_analytics_util.h b/services/ans/include/notification_analytics_util.h index 0263dda41..848c5b1ae 100644 --- a/services/ans/include/notification_analytics_util.h +++ b/services/ans/include/notification_analytics_util.h @@ -166,6 +166,12 @@ struct ReportSlotMessage { bool status; }; +struct ReportLiveViewMessage { + int32_t successNum; + int32_t FailedNum; + int64_t startTime; +}; + class NotificationAnalyticsUtil { public: static void ReportPublishFailedEvent(const sptr& request, const HaMetaMessage& message); @@ -198,6 +204,8 @@ public: static void ReportBadgeChange(const sptr &badgeData); static bool ReportAllBundlesSlotEnabled(); + + static void ReportLiveViewNumber(const sptr& request, const int32_t reportType); private: static void ReportNotificationEvent(const sptr& request, EventFwk::Want want, int32_t eventCode, const std::string& reason); @@ -266,6 +274,20 @@ private: static bool BuildSlotReportCache(ReportCache& reportCache, std::list& slotEnabledReportList); + + static void AddLiveViewSuccessNum(std::string bundle, int32_t status); + + static void AddLiveViewFailedNum(std::string bundle, int32_t status); + + static void CreateLiveViewTimerExecute(); + + static ReportCache AggregateLiveView(); + + static void ExecuteLiveViewReport(); + + static void AddLocalLiveViewSuccessNum(std::string bundle); + + static void AddLocalLiveViewFailedNum(std::string bundle); }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/common/notification_analytics_util.cpp b/services/ans/src/common/notification_analytics_util.cpp index 0d14f3e01..40d9e72a2 100644 --- a/services/ans/src/common/notification_analytics_util.cpp +++ b/services/ans/src/common/notification_analytics_util.cpp @@ -75,6 +75,7 @@ static std::map> flowC {ANS_CUSTOMIZE_CODE, {}}, }; static std::map badgeInfos; +static std::map liveViewMessages; int32_t HaMetaMessage::syncWatch_ = 0; int32_t HaMetaMessage::syncHeadSet_ = 0; @@ -116,6 +117,15 @@ static std::mutex slotEnabledListMutex_; static bool g_reportSlotFlag = false; static std::mutex reportSlotEnabledMutex_; +static int32_t LIVEVIEW_SUB_CODE = 202; +static int32_t LIVEVIEW_AGGREGATE_NUM = 10; +static std::mutex ReportLiveViewMessageMutex_; +static uint64_t reportLiveViewMessageTimerId_ = 0; +static std::shared_ptr liveViewTimeInfo = std::make_shared(); +static int32_t LIVEVIEW_REPORT_INTERVAL = 2 * NotificationConstant::HOUR_TO_MS; +static const int32_t LIVE_VIEW_CREATE = 0; +static bool g_reportLiveViewFlag = false; + HaMetaMessage::HaMetaMessage(uint32_t sceneId, uint32_t branchId) : sceneId_(sceneId), branchId_(branchId) { @@ -285,6 +295,7 @@ void NotificationAnalyticsUtil::ReportPublishFailedEvent(const sptr& request, @@ -311,6 +322,7 @@ void NotificationAnalyticsUtil::ReportPublishSuccessEvent(const sptr& request, const int32_t reportType) +{ + NotificationNapi::ContentType contentType; + NotificationNapi::AnsEnumUtil::ContentTypeCToJS( + static_cast(request->GetNotificationType()), contentType); + if (contentType == NotificationNapi::ContentType::NOTIFICATION_CONTENT_LIVE_VIEW) { + auto content = request->GetContent()->GetNotificationContent(); + auto liveViewContent = std::static_pointer_cast(content); + if (liveViewContent->GetExtraInfo() != nullptr) { + std::string bundle = request->GetOwnerBundleName() + MESSAGE_DELIMITER + + liveViewContent->GetExtraInfo()->GetStringParam("event"); + std::lock_guard lock(ReportLiveViewMessageMutex_); + if (reportType == ANS_CUSTOMIZE_CODE) { + AddLiveViewSuccessNum(bundle, static_cast(liveViewContent->GetLiveViewStatus())); + } else if (reportType == PUBLISH_ERROR_EVENT_CODE) { + AddLiveViewFailedNum(bundle, static_cast(liveViewContent->GetLiveViewStatus())); + } + CreateLiveViewTimerExecute(); + } + } + if (contentType == NotificationNapi::ContentType::NOTIFICATION_CONTENT_LOCAL_LIVE_VIEW) { + std::lock_guard lock(ReportLiveViewMessageMutex_); + std::string bundle = request->GetOwnerBundleName() + "#-99"; + if (reportType == ANS_CUSTOMIZE_CODE) { + AddLocalLiveViewSuccessNum(bundle); + } else if (reportType == PUBLISH_ERROR_EVENT_CODE) { + AddLocalLiveViewFailedNum(bundle); + } + CreateLiveViewTimerExecute(); + } +} + +void NotificationAnalyticsUtil::AddLiveViewSuccessNum(std::string bundle, int32_t status) +{ + auto iter = liveViewMessages.find(bundle); + switch (status) { + case LIVE_VIEW_CREATE: + if (iter != liveViewMessages.end()) { + iter->second.successNum ++; + } else { + ReportLiveViewMessage liveViewMessage; + liveViewMessage.FailedNum = 0; + liveViewMessage.successNum = 1; + liveViewMessage.startTime = GetCurrentTime(); + liveViewMessages[bundle] = liveViewMessage; + } + break; + default: + break; + } +} + +void NotificationAnalyticsUtil::AddLiveViewFailedNum(std::string bundle, int32_t status) +{ + auto iter = liveViewMessages.find(bundle); + switch (status) { + case LIVE_VIEW_CREATE: + if (iter != liveViewMessages.end()) { + iter->second.FailedNum ++; + } else { + ReportLiveViewMessage liveViewMessage; + liveViewMessage.FailedNum = 1; + liveViewMessage.successNum = 0; + liveViewMessage.startTime = GetCurrentTime(); + liveViewMessages[bundle] = liveViewMessage; + } + break; + default: + break; + } +} + +void NotificationAnalyticsUtil::AddLocalLiveViewFailedNum(std::string bundle) +{ + auto iter = liveViewMessages.find(bundle); + if (iter != liveViewMessages.end()) { + iter->second.FailedNum ++; + } else { + ReportLiveViewMessage liveViewMessage; + liveViewMessage.FailedNum = 1; + liveViewMessage.successNum = 0; + liveViewMessage.startTime = GetCurrentTime(); + liveViewMessages[bundle] = liveViewMessage; + } +} + +void NotificationAnalyticsUtil::AddLocalLiveViewSuccessNum(std::string bundle) +{ + auto iter = liveViewMessages.find(bundle); + if (iter != liveViewMessages.end()) { + iter->second.successNum ++; + } else { + ReportLiveViewMessage liveViewMessage; + liveViewMessage.FailedNum = 0; + liveViewMessage.successNum = 1; + liveViewMessage.startTime = GetCurrentTime(); + liveViewMessages[bundle] = liveViewMessage; + } +} + +void NotificationAnalyticsUtil::CreateLiveViewTimerExecute() +{ + if (g_reportLiveViewFlag) { + ANS_LOGW("now has liveview message is reporting"); + return; + } + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + if (timer == nullptr) { + ANS_LOGE("Failed to start timer due to get TimeServiceClient is null."); + g_reportLiveViewFlag = false; + return; + } + if (reportLiveViewMessageTimerId_ == 0) { + reportLiveViewMessageTimerId_ = timer->CreateTimer(liveViewTimeInfo); + } + + auto triggerFunc = [] { + ExecuteLiveViewReport(); + }; + + liveViewTimeInfo->SetCallbackInfo(triggerFunc); + timer->StartTimer(reportLiveViewMessageTimerId_, NotificationAnalyticsUtil::GetCurrentTime() + + LIVEVIEW_REPORT_INTERVAL * NotificationConstant::SECOND_TO_MS); + g_reportLiveViewFlag = true; +} + +void NotificationAnalyticsUtil::ExecuteLiveViewReport() +{ + std::lock_guard lock(ReportLiveViewMessageMutex_); + if (liveViewMessages.empty()) { + ANS_LOGI("report end"); + g_reportLiveViewFlag = false; + return; + } + if (reportAggregateTimeId == 0) { + sptr aggregateTimer = MiscServices::TimeServiceClient::GetInstance(); + if (aggregateTimer == nullptr) { + ANS_LOGE("Failed to start timer due to get TimeServiceClient is null."); + g_reportLiveViewFlag = false; + return; + } + reportAggregateTimeId = aggregateTimer->CreateTimer(reportAggregateTimeInfo); + } + ReportCache reportCache = AggregateLiveView(); + reportAggList.emplace_back(reportCache); + if (!g_successReportFlag) { + ExecuteSuccessCacheList(); + } + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + if (timer == nullptr) { + ANS_LOGE("Failed to start timer due to get TimeServiceClient is null."); + return; + } + auto triggerFunc = [] { + ExecuteLiveViewReport(); + }; + liveViewTimeInfo->SetCallbackInfo(triggerFunc); + timer->StartTimer(reportLiveViewMessageTimerId_, NotificationAnalyticsUtil::GetCurrentTime() + + LIVEVIEW_REPORT_INTERVAL * NotificationConstant::SECOND_TO_MS); + g_reportLiveViewFlag = true; +} + +ReportCache NotificationAnalyticsUtil::AggregateLiveView() +{ + nlohmann::json ansData; + ansData["subCode"] = std::to_string(LIVEVIEW_SUB_CODE); + int32_t aggreCount = LIVEVIEW_AGGREGATE_NUM; + std::string data; + std::vector reportBundles; + int64_t startTime = GetCurrentTime(); + + std::vector> messageVector(liveViewMessages.begin(), + liveViewMessages.end()); + std::sort(messageVector.begin(), messageVector.end(), [](const std::pair &a, + std::pair &b) { + return a.second.startTime < b.second.startTime; + }); + for (const auto &message : messageVector) { + ReportLiveViewMessage liveViewData = message.second; + std::string create = std::to_string(liveViewData.successNum) + "," + std::to_string(liveViewData.FailedNum); + std::string update; + std::string end; + std::string cancel; + std::string singleData = message.first + ":" + create + MESSAGE_DELIMITER + + update + MESSAGE_DELIMITER + end + MESSAGE_DELIMITER + cancel + MESSAGE_DELIMITER; + data += singleData; + startTime = startTime < liveViewData.startTime ? startTime : liveViewData.startTime; + reportBundles.emplace_back(message.first); + aggreCount --; + if (aggreCount <= 0) { + break; + } + data += ","; + } + for (auto bundle : reportBundles) { + liveViewMessages.erase(bundle); + } + ansData["data"] = data; + ansData["startTime"] = startTime; + ansData["endTime"] = GetCurrentTime(); + std::string message = ansData.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace); + EventFwk::Want want; + want.SetAction(NOTIFICATION_EVENT_PUSH_AGENT); + want.SetParam("ansData", message); + + ReportCache reportCache; + reportCache.want = want; + reportCache.eventCode = ANS_CUSTOMIZE_CODE; + return reportCache; +} + bool NotificationAnalyticsUtil::IsAllowedBundle(const sptr& request) { ANS_LOGD("IsAllowedBundle enter"); @@ -660,6 +883,7 @@ std::string NotificationAnalyticsUtil::BuildExtraInfoWithReq(const HaMetaMessage reason["status"] = static_cast(liveViewContent->GetLiveViewStatus()); if (liveViewContent->GetExtraInfo() != nullptr) { reason["et"] = liveViewContent->GetExtraInfo()->GetStringParam("event"); + reason["lt"] = liveViewContent->GetExtraInfo()->GetIntParam("LayoutData.layoutType", -1); } } 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 1ef34c179..98b353368 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 @@ -495,5 +495,30 @@ HWTEST_F(NotificationAnalyticsUtilTest, BuildAnsData_300, Function | SmallTest | ASSERT_FALSE(ret.find("keyNode") != std::string::npos); } + +/** + * @tc.name: AggregateLiveView_001 + * @tc.desc: Test AggregateLiveView + * @tc.type: FUNC + */ +HWTEST_F(NotificationAnalyticsUtilTest, AggregateLiveView_001, Function | SmallTest | Level1) +{ + std::string bundle = "com.example.app#TAXI"; + int32_t status = 0; + + NotificationAnalyticsUtil::AddLiveViewFailedNum(bundle, status); + NotificationAnalyticsUtil::AddLiveViewSuccessNum(bundle, status); + bundle = "com.example.app2#-99"; + NotificationAnalyticsUtil::AddLocalLiveViewFailedNum(bundle); + NotificationAnalyticsUtil::AddLocalLiveViewSuccessNum(bundle); + ReportCache reportCache = NotificationAnalyticsUtil::AggregateLiveView(); + + EXPECT_EQ(reportCache.eventCode, 7); + std::string ansData = reportCache.want.GetStringParam("ansData"); + nlohmann::json jsonData = nlohmann::json::parse(ansData); + EXPECT_TRUE(jsonData["data"].is_string()); + EXPECT_TRUE(jsonData["startTime"].is_number_integer()); + EXPECT_TRUE(jsonData["endTime"].is_number_integer()); +} } } \ No newline at end of file -- Gitee