diff --git a/services/ans/include/notification_analytics_util.h b/services/ans/include/notification_analytics_util.h index 0263dda412dd03bad791df59e9aad5236bd285ed..848c5b1ae52eb12588442f5c7a51d7e364bc2ae2 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 0d14f3e01400bf74583baeeb9c7803852d1e8831..40d9e72a28d66091faffdc15bf049ec317679f91 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 1ef34c179779697409187ce13646d2a02615926f..98b353368fc7b608afb82170794b540e67611618 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