1 /*
2 * Copyright (c) 2025 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 #include <random>
17 #include "hiappevent_agent.h"
18 #include "media_log.h"
19 #include "media_errors.h"
20 #ifdef SUPPORT_HIAPPEVENT
21 #include "app_event.h"
22 #include "app_event_processor_mgr.h"
23 #include "osal/utils/steady_clock.h"
24 #endif
25
26 #ifdef SUPPORT_HIAPPEVENT
27 namespace {
28 constexpr auto KNAME = "ha_app_event";
29 constexpr auto KAPPID = "com_hua" "wei_hmos_sdk_ocg";
30 constexpr auto SDKNAME = "OS_AVPlayerKit";
31 constexpr int32_t KTIMEOUT = 90; // trigger interval in seconds
32 constexpr int32_t KCONDROW = 30; // trigger batch size
33 constexpr int64_t REPORT_INTERVAL = 1000; // 1s
34 static int64_t g_processorId = -1;
35 static std::mutex g_processorMutex;
36 }
37 #endif
38
39 namespace OHOS {
40 namespace Media {
41
42 using namespace OHOS::HiviewDFX;
43 #ifdef SUPPORT_HIAPPEVENT
44 using namespace OHOS::HiviewDFX::HiAppEvent;
45 #endif
46
HiAppEventAgent()47 HiAppEventAgent::HiAppEventAgent()
48 {
49 #ifdef SUPPORT_HIAPPEVENT
50 hiAppEventTask_ = std::make_unique<Task>(
51 "OS_Ply_HiAppEvent", "HiAppEventGroup", TaskType::SINGLETON, TaskPriority::NORMAL, false);
52 #endif
53 }
54
~HiAppEventAgent()55 HiAppEventAgent::~HiAppEventAgent()
56 {
57 #ifdef SUPPORT_HIAPPEVENT
58 hiAppEventTask_.reset();
59 #endif
60 }
61
62 #ifdef SUPPORT_HIAPPEVENT
WriteEndEvent(const std::string & transId,const int errCode,const std::string & apiName,int64_t startTime,HiviewDFX::HiTraceId traceId)63 void HiAppEventAgent::WriteEndEvent(const std::string &transId,
64 const int errCode, const std::string& apiName, int64_t startTime, HiviewDFX::HiTraceId traceId)
65 {
66 int result = errCode == MSERR_OK ? API_RESULT_SUCCESS : API_RESULT_FAILED;
67 Event event("api_diagnostic", "api_exec_end", OHOS::HiviewDFX::HiAppEvent::BEHAVIOR);
68 event.AddParam("trans_id", transId);
69 event.AddParam("api_name", apiName);
70 event.AddParam("sdk_name", std::string(SDKNAME));
71 event.AddParam("begin_time", startTime);
72 event.AddParam("end_time", SteadyClock::GetCurrentTimeMs());
73 event.AddParam("result", result);
74 event.AddParam("error_code", errCode);
75 event.AddParam("contents", apiName);
76 if (traceId.IsValid()) {
77 event.AddParam("hiTraceID", static_cast<int64_t>(traceId.GetChainId()));
78 }
79 Write(event);
80 }
81 #endif
82
83 #ifdef SUPPORT_HIAPPEVENT
AddProcessor()84 int64_t HiAppEventAgent::AddProcessor()
85 {
86 ReportConfig config;
87 config.name = KNAME;
88 config.appId = KAPPID;
89 config.routeInfo = "AUTO";
90 config.triggerCond.timeout = KTIMEOUT;
91 config.triggerCond.row = KCONDROW;
92 config.eventConfigs.clear();
93 {
94 EventConfig event1;
95 event1.domain = "api_diagnostic";
96 event1.name = "api_exec_end";
97 event1.isRealTime = false;
98 config.eventConfigs.push_back(event1);
99 }
100 {
101 EventConfig event2;
102 event2.domain = "api_diagnostic";
103 event2.name = "api_called_stat";
104 event2.isRealTime = true;
105 config.eventConfigs.push_back(event2);
106 }
107 {
108 EventConfig event3;
109 event3.domain = "api_diagnostic";
110 event3.name = "api_called_stat_cnt";
111 event3.isRealTime = true;
112 config.eventConfigs.push_back(event3);
113 }
114 return AppEventProcessorMgr::AddProcessor(config);
115 }
116 #endif
117
TraceApiEvent(int errCode,const std::string & apiName,int64_t startTime,HiviewDFX::HiTraceId traceId)118 void HiAppEventAgent::TraceApiEvent(
119 int errCode, const std::string& apiName, int64_t startTime, HiviewDFX::HiTraceId traceId)
120 {
121 #ifdef SUPPORT_HIAPPEVENT
122 {
123 std::lock_guard<std::mutex> lock(g_processorMutex);
124 if (g_processorId == -1) {
125 g_processorId = AddProcessor();
126 }
127 if (g_processorId < 0) {
128 return;
129 }
130 auto it = lastReportTime_.find(apiName);
131 if (it != lastReportTime_.end() && startTime <= it->second + REPORT_INTERVAL) {
132 return;
133 }
134 lastReportTime_[apiName] = startTime;
135 }
136
137 if (hiAppEventTask_ == nullptr) {
138 return;
139 }
140 std::weak_ptr<HiAppEventAgent> agent = shared_from_this();
141 hiAppEventTask_->SubmitJobOnce([agent, errCode, apiName, startTime, traceId]() {
142 auto ptr = agent.lock();
143 CHECK_AND_RETURN_NOLOG(ptr != nullptr);
144 ptr->TraceApiEventAsync(errCode, apiName, startTime, traceId);
145 });
146 #else
147 (void)errCode;
148 (void)apiName;
149 (void)startTime;
150 (void)traceId;
151 #endif
152 }
153
154 #ifdef SUPPORT_HIAPPEVENT
TraceApiEventAsync(int errCode,const std::string & apiName,int64_t startTime,HiviewDFX::HiTraceId traceId)155 void HiAppEventAgent::TraceApiEventAsync(
156 int errCode, const std::string& apiName, int64_t startTime, HiviewDFX::HiTraceId traceId)
157 {
158 std::string transId = GenerateTransId();
159 WriteEndEvent(transId, errCode, apiName, startTime, traceId);
160 }
161 #endif
162
GenerateTransId()163 std::string HiAppEventAgent::GenerateTransId()
164 {
165 std::random_device rd;
166 std::mt19937 gen(rd());
167 std::uniform_int_distribution<int64_t> dist(0, 1e12);
168
169 return "transId_" + std::to_string(dist(gen));
170 }
171
172 } // namespace Media
173 } // namespace OHOS
174