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 OHOS {
24 namespace Media {
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "DfxAgent" };
27 constexpr int64_t LAG_EVENT_THRESHOLD_MS = 500; // Lag threshold is 500 ms
28 ConcurrentUidSet g_appUidSet{};
29 }
30
31 const std::map<DfxEventType, DfxEventHandleFunc> DfxAgent::DFX_EVENT_HANDLERS_ = {
32 { DfxEventType::DFX_INFO_PLAYER_VIDEO_LAG, DfxAgent::ProcessVideoLagEvent },
33 { DfxEventType::DFX_INFO_PLAYER_AUDIO_LAG, DfxAgent::ProcessAudioLagEvent },
34 { DfxEventType::DFX_INFO_PLAYER_STREAM_LAG, DfxAgent::ProcessStreamLagEvent },
35 { DfxEventType::DFX_INFO_PLAYER_EOS_SEEK, DfxAgent::ProcessEosSeekEvent },
36 };
37
38
DfxAgent(const std::string & groupId,const std::string & appName)39 DfxAgent::DfxAgent(const std::string& groupId, const std::string& appName) : groupId_(groupId), appName_(appName)
40 {
41 dfxTask_ = std::make_unique<Task>("OS_Ply_Dfx", groupId_, TaskType::GLOBAL, TaskPriority::NORMAL, false);
42 MEDIA_LOG_I("DfxAgent create for app " PUBLIC_LOG_S, appName_.c_str());
43 }
44
~DfxAgent()45 DfxAgent::~DfxAgent()
46 {
47 dfxTask_.reset();
48 }
49
SetSourceType(PlayerDfxSourceType type)50 void DfxAgent::SetSourceType(PlayerDfxSourceType type)
51 {
52 FALSE_RETURN(dfxTask_ != nullptr);
53 std::weak_ptr<DfxAgent> agent = shared_from_this();
54 dfxTask_->SubmitJobOnce([agent, type] {
55 auto ptr = agent.lock();
56 FALSE_RETURN_MSG(ptr != nullptr, "DfxAgent is released");
57 ptr->sourceType_ = type;
58 });
59 }
60
SetInstanceId(const std::string & instanceId)61 void DfxAgent::SetInstanceId(const std::string& instanceId)
62 {
63 FALSE_RETURN(dfxTask_ != nullptr);
64 std::weak_ptr<DfxAgent> agent = shared_from_this();
65 dfxTask_->SubmitJobOnce([agent, instanceId] {
66 auto ptr = agent.lock();
67 FALSE_RETURN_MSG(ptr != nullptr, "DfxAgent is released");
68 ptr->instanceId_ = instanceId;
69 });
70 }
71
OnDfxEvent(const DfxEvent & event)72 void DfxAgent::OnDfxEvent(const DfxEvent &event)
73 {
74 auto ret = DfxAgent::DFX_EVENT_HANDLERS_.find(event.type);
75 FALSE_RETURN(ret != DfxAgent::DFX_EVENT_HANDLERS_.end());
76 FALSE_RETURN(dfxTask_ != nullptr);
77 std::weak_ptr<DfxAgent> agent = shared_from_this();
78 dfxTask_->SubmitJobOnce([agent, event, handler = ret->second] {
79 auto ptr = agent.lock();
80 FALSE_RETURN_MSG(ptr != nullptr, "DfxAgent is released");
81 handler(ptr, event);
82 });
83 }
84
ReportLagEvent(int64_t lagDuration,const std::string & eventMsg)85 void DfxAgent::ReportLagEvent(int64_t lagDuration, const std::string& eventMsg)
86 {
87 FALSE_RETURN(dfxTask_ != nullptr);
88 std::weak_ptr<DfxAgent> agent = shared_from_this();
89 dfxTask_->SubmitJobOnce([agent, lagDuration, eventMsg] {
90 auto ptr = agent.lock();
91 FALSE_RETURN_MSG(ptr != nullptr, "DfxAgent is released");
92 FALSE_RETURN(!(ptr->hasReported_));
93 std::string msg = eventMsg;
94 MEDIA_LOG_W("PLAYER_LAG event reported, lagDuration=" PUBLIC_LOG_D64 ", msg=" PUBLIC_LOG_S,
95 lagDuration, eventMsg.c_str());
96 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::MULTI_MEDIA,
97 "PLAYER_LAG",
98 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
99 "APP_NAME", ptr->appName_,
100 "INSTANCE_ID", ptr->instanceId_,
101 "SOURCE_TYPE", static_cast<uint8_t>(ptr->sourceType_),
102 "LAG_DURATION", static_cast<int32_t>(lagDuration),
103 "MSG", msg);
104 ptr->hasReported_ = true;
105 });
106 }
107
ReportEosSeek0Event(int32_t appUid)108 void DfxAgent::ReportEosSeek0Event(int32_t appUid)
109 {
110 FALSE_RETURN(dfxTask_ != nullptr);
111 dfxTask_->SubmitJobOnce([appUid, appName = appName_] {
112 FALSE_RETURN(g_appUidSet.IsAppFirstEvent(appUid));
113 MEDIA_LOG_I("EOS_SEEK_0 event reported, appName = %{public}s appUid = %{public}d", appName.c_str(), appUid);
114 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::MULTI_MEDIA,
115 "EOS_SEEK_0",
116 OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
117 "APP_NAME", appName,
118 "APP_UID", appUid);
119 });
120 }
121
ResetAgent()122 void DfxAgent::ResetAgent()
123 {
124 FALSE_RETURN(dfxTask_ != nullptr);
125 std::weak_ptr<DfxAgent> agent = shared_from_this();
126 dfxTask_->SubmitJobOnce([agent] {
127 auto ptr = agent.lock();
128 FALSE_RETURN_MSG(ptr != nullptr, "DfxAgent is released");
129 ptr->hasReported_ = false;
130 });
131 }
132
ProcessVideoLagEvent(std::weak_ptr<DfxAgent> ptr,const DfxEvent & event)133 void DfxAgent::ProcessVideoLagEvent(std::weak_ptr<DfxAgent> ptr, const DfxEvent &event)
134 {
135 auto agent = ptr.lock();
136 FALSE_RETURN(agent != nullptr);
137 int64_t lagDuration = AnyCast<int64_t>(event.param);
138 FALSE_RETURN(lagDuration >= LAG_EVENT_THRESHOLD_MS);
139 std::string msg = "lagEvent=Video";
140 agent->ReportLagEvent(lagDuration, msg);
141 }
142
ProcessAudioLagEvent(std::weak_ptr<DfxAgent> ptr,const DfxEvent & event)143 void DfxAgent::ProcessAudioLagEvent(std::weak_ptr<DfxAgent> ptr, const DfxEvent &event)
144 {
145 auto agent = ptr.lock();
146 FALSE_RETURN(agent != nullptr);
147 int64_t lagDuration = AnyCast<int64_t>(event.param);
148 FALSE_RETURN(lagDuration >= LAG_EVENT_THRESHOLD_MS);
149 std::string msg = "lagEvent=Audio";
150 agent->ReportLagEvent(lagDuration, msg);
151 }
152
ProcessStreamLagEvent(std::weak_ptr<DfxAgent> ptr,const DfxEvent & event)153 void DfxAgent::ProcessStreamLagEvent(std::weak_ptr<DfxAgent> ptr, const DfxEvent &event)
154 {
155 auto agent = ptr.lock();
156 FALSE_RETURN(agent != nullptr);
157 int64_t lagDuration = AnyCast<int64_t>(event.param);
158 FALSE_RETURN(lagDuration >= LAG_EVENT_THRESHOLD_MS);
159 std::string msg = "lagEvent=Stream";
160 agent->ReportLagEvent(lagDuration, msg);
161 }
162
ProcessEosSeekEvent(std::weak_ptr<DfxAgent> ptr,const DfxEvent & event)163 void DfxAgent::ProcessEosSeekEvent(std::weak_ptr<DfxAgent> ptr, const DfxEvent &event)
164 {
165 auto agent = ptr.lock();
166 FALSE_RETURN(agent != nullptr);
167 int64_t appUid = AnyCast<int32_t>(event.param);
168 agent->ReportEosSeek0Event(appUid);
169 }
170 } // namespace Media
171 } // namespace OHOS