1 /*
2  * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define HST_LOG_TAG "DfxAgent"
17 
18 #include "dfx_agent.h"
19 #include "common/log.h"
20 #include "common/media_source.h"
21 #include "hisysevent.h"
22 
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "DfxAgent" };
25 constexpr int64_t LAG_EVENT_THRESHOLD_MS = 500; // Lag threshold is 500 ms
26 }
27 
28 namespace OHOS {
29 namespace Media {
30 
DfxAgent(const std::string& groupId, const std::string& appName)31 DfxAgent::DfxAgent(const std::string& groupId, const std::string& appName) : groupId_(groupId), appName_(appName)
32 {
33     dfxTask_ = std::make_unique<Task>("OS_Ply_Dfx", groupId_, TaskType::GLOBAL, TaskPriority::NORMAL, false);
34     MEDIA_LOG_I("DfxAgent create for app " PUBLIC_LOG_S, appName_.c_str());
35 }
36 
~DfxAgent()37 DfxAgent::~DfxAgent()
38 {
39     dfxTask_.reset();
40 }
41 
SetDemuxer(std::weak_ptr<Pipeline::DemuxerFilter> demuxer)42 void DfxAgent::SetDemuxer(std::weak_ptr<Pipeline::DemuxerFilter> demuxer)
43 {
44     demuxer_ = demuxer;
45 }
46 
SetSourceType(PlayerDfxSourceType type)47 void DfxAgent::SetSourceType(PlayerDfxSourceType type)
48 {
49     sourceType_ = type;
50 }
51 
SetInstanceId(const std::string& instanceId)52 void DfxAgent::SetInstanceId(const std::string& instanceId)
53 {
54     instanceId_ = instanceId;
55 }
56 
OnAudioLagEvent(int64_t lagDuration)57 void DfxAgent::OnAudioLagEvent(int64_t lagDuration)
58 {
59     FALSE_RETURN(lagDuration >= LAG_EVENT_THRESHOLD_MS);
60     std::string msg = "lagEvent=Audio";
61     ReportLagEvent(lagDuration, msg);
62 }
63 
OnVideoLagEvent(int64_t lagDuration)64 void DfxAgent::OnVideoLagEvent(int64_t lagDuration)
65 {
66     FALSE_RETURN(lagDuration >= LAG_EVENT_THRESHOLD_MS);
67     std::string msg = "lagEvent=Video";
68     ReportLagEvent(lagDuration, msg);
69 }
70 
OnStreamLagEvent(int64_t lagDuration)71 void DfxAgent::OnStreamLagEvent(int64_t lagDuration)
72 {
73     FALSE_RETURN(lagDuration >= LAG_EVENT_THRESHOLD_MS);
74     std::string msg = "lagEvent=Stream";
75     ReportLagEvent(lagDuration, msg);
76 }
77 
GetNetworkInfo(std::string& networkInfo)78 bool DfxAgent::GetNetworkInfo(std::string& networkInfo)
79 {
80     auto demuxer = demuxer_.lock();
81     FALSE_RETURN_V(demuxer != nullptr, false);
82     DownloadInfo downLoadInfo;
83     auto ret = demuxer->GetDownloadInfo(downLoadInfo);
84     if (ret != Status::OK) {
85         networkInfo = "";
86         return false;
87     }
88     networkInfo = (";timeout=" + std::to_string(downLoadInfo.isTimeOut));
89     networkInfo += (";avgDownloadSpeed=" + std::to_string(downLoadInfo.avgDownloadSpeed));
90     return true;
91 }
92 
ReportLagEvent(int64_t lagDuration, const std::string& eventMsg)93 void DfxAgent::ReportLagEvent(int64_t lagDuration, const std::string& eventMsg)
94 {
95     FALSE_RETURN(dfxTask_ != nullptr);
96     dfxTask_->SubmitJobOnce([this, lagDuration, eventMsg] {
97         FALSE_RETURN(!hasReported_);
98         std::string msg = eventMsg;
99         std::string netInfo = "";
100         if (GetNetworkInfo(netInfo)) {
101             msg += netInfo;
102         }
103         MEDIA_LOG_W("PLAYER_LAG event reported, lagDuration=" PUBLIC_LOG_D64 ", msg=" PUBLIC_LOG_S,
104             lagDuration, eventMsg.c_str());
105         HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::MULTI_MEDIA,
106             "PLAYER_LAG",
107             OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
108             "APP_NAME", appName_,
109             "INSTANCE_ID", instanceId_,
110             "SOURCE_TYPE", static_cast<uint8_t>(sourceType_),
111             "LAG_DURATION", static_cast<int32_t>(lagDuration),
112             "MSG", msg);
113         hasReported_ = true;
114     });
115 }
ResetAgent()116 void DfxAgent::ResetAgent()
117 {
118     FALSE_RETURN(dfxTask_ != nullptr);
119     dfxTask_->SubmitJobOnce([this] {
120         hasReported_ = false;
121     });
122 }
123 }  // namespace Media
124 }  // namespace OHOS