• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioServerHpaeDump"
17 #endif
18 
19 #include "audio_server_hpae_dump.h"
20 #include <sstream>
21 #include "audio_utils.h"
22 #include "audio_errors.h"
23 #include "audio_service.h"
24 #include "audio_dump_pcm.h"
25 #include "audio_performance_monitor.h"
26 #include "manager/hdi_adapter_manager.h"
27 #include "i_hpae_manager.h"
28 
29 using namespace std;
30 using namespace OHOS::AudioStandard::HPAE;
31 namespace OHOS {
32 namespace AudioStandard {
33 static const int32_t OPERATION_TIMEOUT_IN_MS = 1000;  // 1000ms
34 
AudioServerHpaeDump()35 AudioServerHpaeDump::AudioServerHpaeDump()
36 {
37     AUDIO_DEBUG_LOG("AudioServerHpaeDump construct");
38     InitDumpFuncMap();
39 }
40 
~AudioServerHpaeDump()41 AudioServerHpaeDump::~AudioServerHpaeDump()
42 {}
43 
InitDumpFuncMap()44 void AudioServerHpaeDump::InitDumpFuncMap()
45 {
46     dumpFuncMap[u"-h"] = &AudioServerHpaeDump::HelpInfoDump;
47     dumpFuncMap[u"-p"] = &AudioServerHpaeDump::PlaybackSinkDump;
48     dumpFuncMap[u"-r"] = &AudioServerHpaeDump::RecordSourceDump;
49     dumpFuncMap[u"-m"] = &AudioServerHpaeDump::HDFModulesDump;
50     dumpFuncMap[u"-ep"] = &AudioServerHpaeDump::PolicyHandlerDump;
51     dumpFuncMap[u"-ct"] = &AudioServerHpaeDump::AudioCacheTimeDump;
52     dumpFuncMap[u"-cm"] = &AudioServerHpaeDump::AudioCacheMemoryDump;
53     dumpFuncMap[u"-pm"] = &AudioServerHpaeDump::AudioPerformMonitorDump;
54     dumpFuncMap[u"-ha"] = &AudioServerHpaeDump::HdiAdapterDump;
55 }
56 
AudioDataDump(std::string & dumpString,std::queue<std::u16string> & argQue)57 void AudioServerHpaeDump::AudioDataDump(std::string &dumpString, std::queue<std::u16string> &argQue)
58 {
59     ArgDataDump(dumpString, argQue);
60 }
61 
ServerDataDump(string & dumpString)62 void AudioServerHpaeDump::ServerDataDump(string &dumpString)
63 {
64     PlaybackSinkDump(dumpString);
65     RecordSourceDump(dumpString);
66     HDFModulesDump(dumpString);
67     PolicyHandlerDump(dumpString);
68 }
69 
GetDeviceSinkInfo(std::string & dumpString,std::string deviceName)70 void AudioServerHpaeDump::GetDeviceSinkInfo(std::string &dumpString, std::string deviceName)
71 {
72     lock_guard<mutex> lock(lock_);
73     AUDIO_INFO_LOG("GetDeviceSinkInfo %{public}s start.", deviceName.c_str());
74     isFinishGetSinkInfo_ = false;
75     IHpaeManager::GetHpaeManager().DumpSinkInfo(deviceName);
76     std::unique_lock<std::mutex> waitLock(callbackMutex_);
77     dumpHpaeSinkInfo_.clear();
78     bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
79         return isFinishGetSinkInfo_;  // will be true when got notified.
80     });
81     if (!stopWaiting) {
82         AUDIO_ERR_LOG("GetDeviceSinkInfo timeout!");
83         return;
84     }
85     AUDIO_INFO_LOG("GetDeviceSinkInfo %{public}s end.", deviceName.c_str());
86     dumpString += dumpHpaeSinkInfo_;
87 }
88 
PlaybackSinkDump(std::string & dumpString)89 void AudioServerHpaeDump::PlaybackSinkDump(std::string &dumpString)
90 {
91     dumpString += "Hpae AudioServer Playback sink Dump:\n\n";
92     for (auto it = devicesInfo_.sinkInfos.begin(); it != devicesInfo_.sinkInfos.end(); it++) {
93         dumpString += it->deviceName + ":\n";
94         GetDeviceSinkInfo(dumpString, it->deviceName);
95         dumpString += "\n";
96     }
97     dumpString += "\n";
98     PlaybackSinkInputDump(dumpString);
99 }
100 
OnDumpSinkInfoCb(std::string & dumpStr,int32_t result)101 void AudioServerHpaeDump::OnDumpSinkInfoCb(std::string &dumpStr, int32_t result)
102 {
103     std::unique_lock<std::mutex> waitLock(callbackMutex_);
104     dumpHpaeSinkInfo_ = dumpStr;
105     isFinishGetSinkInfo_ = true;
106     AUDIO_INFO_LOG(
107         "AudioServerHpaeDump OnDumpSinkInfoCb %{public}s, result %{public}d", dumpHpaeSinkInfo_.c_str(), result);
108     callbackCV_.notify_all();
109 }
110 
GetDeviceSourceInfo(std::string & dumpString,std::string deviceName)111 void AudioServerHpaeDump::GetDeviceSourceInfo(std::string &dumpString, std::string deviceName)
112 {
113     lock_guard<mutex> lock(lock_);
114     AUDIO_INFO_LOG("GetDeviceSourceInfo %{public}s start.", deviceName.c_str());
115     isFinishGetSourceInfo_ = false;
116     IHpaeManager::GetHpaeManager().DumpSourceInfo(deviceName);
117     std::unique_lock<std::mutex> waitLock(callbackMutex_);
118     dumpHpaeSourceInfo_.clear();
119     bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
120         return isFinishGetSourceInfo_;  // will be true when got notified.
121     });
122     if (!stopWaiting) {
123         AUDIO_ERR_LOG("GetDeviceSourceInfo timeout!");
124         return;
125     }
126     AUDIO_INFO_LOG("GetDeviceSourceInfo %{public}s end.", deviceName.c_str());
127     dumpString += dumpHpaeSourceInfo_;
128 }
129 
RecordSourceDump(std::string & dumpString)130 void AudioServerHpaeDump::RecordSourceDump(std::string &dumpString)
131 {
132     dumpString += "Hpae AudioServer Record source Dump:\n\n";
133     for (auto it = devicesInfo_.sourceInfos.begin(); it != devicesInfo_.sourceInfos.end(); it++) {
134         dumpString += it->deviceName + ":\n";
135         GetDeviceSourceInfo(dumpString, it->deviceName);
136         dumpString += "\n";
137     }
138     dumpString += "\n";
139     RecordSourceOutputDump(dumpString);
140 }
141 
OnDumpSourceInfoCb(std::string & dumpStr,int32_t result)142 void AudioServerHpaeDump::OnDumpSourceInfoCb(std::string &dumpStr, int32_t result)
143 {
144     std::unique_lock<std::mutex> waitLock(callbackMutex_);
145     dumpHpaeSourceInfo_ = dumpStr;
146     isFinishGetSourceInfo_ = true;
147     AUDIO_INFO_LOG(
148         "AudioServerHpaeDump OnDumpSourceInfoCb %{public}s, result %{public}d", dumpHpaeSourceInfo_.c_str(), result);
149     callbackCV_.notify_all();
150 }
151 
ArgDataDump(std::string & dumpString,std::queue<std::u16string> & argQue)152 void AudioServerHpaeDump::ArgDataDump(std::string &dumpString, std::queue<std::u16string> &argQue)
153 {
154     CHECK_AND_RETURN(GetDevicesInfo());
155     dumpString += "Hpae AudioServer Data Dump:\n\n";
156     if (argQue.empty()) {
157         ServerDataDump(dumpString);
158         return;
159     }
160     while (!argQue.empty()) {
161         std::u16string para = argQue.front();
162         if (para == u"-h") {
163             dumpString.clear();
164             (this->*dumpFuncMap[para])(dumpString);
165             return;
166         } else if (para == u"-p") {
167             dumpString.clear();
168             (this->*dumpFuncMap[para])(dumpString);
169             return;
170         } else if (dumpFuncMap.count(para) == 0) {
171             dumpString.clear();
172             AppendFormat(dumpString, "Please input correct param:\n");
173             HelpInfoDump(dumpString);
174             return;
175         } else {
176             (this->*dumpFuncMap[para])(dumpString);
177         }
178         argQue.pop();
179     }
180 }
181 
HelpInfoDump(string & dumpString)182 void AudioServerHpaeDump::HelpInfoDump(string &dumpString)
183 {
184     AppendFormat(dumpString, "usage:\n");
185     AppendFormat(dumpString, "  -h\t\t\t|help text for hidumper audio\n");
186     AppendFormat(dumpString, "  -p\t\t\t|dump hpae playback streams\n");
187     AppendFormat(dumpString, "  -r\t\t\t|dump hpae record streams\n");
188 }
189 
Initialize()190 int32_t AudioServerHpaeDump::Initialize()
191 {
192     AUDIO_INFO_LOG("AudioServerHpaeDump Initialize");
193     IHpaeManager::GetHpaeManager().RegisterHpaeDumpCallback(weak_from_this());
194     return SUCCESS;
195 }
196 
HDFModulesDump(std::string & dumpString)197 void AudioServerHpaeDump::HDFModulesDump(std::string &dumpString)
198 {
199     lock_guard<mutex> lock(lock_);
200     dumpHdfModulesInfo_ += "\nHDF Input Modules\n";
201     AppendFormat(dumpHdfModulesInfo_, "- %zu HDF Input Modules (s) available:\n", devicesInfo_.sourceInfos.size());
202 
203     for (auto it = devicesInfo_.sourceInfos.begin(); it != devicesInfo_.sourceInfos.end(); it++) {
204         HpaeSinkSourceInfo &sourceInfo = *it;
205         AppendFormat(dumpHdfModulesInfo_, "  Module %d\n", it - devicesInfo_.sourceInfos.begin() + 1);
206         AppendFormat(dumpHdfModulesInfo_, "  - Module Name: %s\n", (sourceInfo.deviceName).c_str());
207         AppendFormat(dumpHdfModulesInfo_, "  - Module Configuration: %s\n\n", sourceInfo.config.c_str());
208     }
209 
210     dumpHdfModulesInfo_ += "HDF Output Modules\n";
211     AppendFormat(dumpHdfModulesInfo_, "- %zu HDF Output Modules (s) available:\n", devicesInfo_.sinkInfos.size());
212 
213     for (auto it = devicesInfo_.sinkInfos.begin(); it != devicesInfo_.sinkInfos.end(); it++) {
214         HpaeSinkSourceInfo &sinkInfo = *it;
215         AppendFormat(dumpHdfModulesInfo_, "  Module %d\n", it - devicesInfo_.sinkInfos.begin() + 1);
216         AppendFormat(dumpHdfModulesInfo_, "  - Module Name: %s\n", (sinkInfo.deviceName).c_str());
217         AppendFormat(dumpHdfModulesInfo_, "  - Module Configuration: %s\n\n", sinkInfo.config.c_str());
218     }
219 
220     AUDIO_INFO_LOG("HDFModulesDump : \n%{public}s end", dumpHdfModulesInfo_.c_str());
221     dumpString += dumpHdfModulesInfo_;
222 }
223 
GetDevicesInfo()224 bool AudioServerHpaeDump::GetDevicesInfo()
225 {
226     lock_guard<mutex> lock(lock_);
227     IHpaeManager::GetHpaeManager().DumpAllAvailableDevice(devicesInfo_);
228     std::unique_lock<std::mutex> waitLock(callbackMutex_);
229     isFinishGetHdfModulesInfo_ = false;
230     dumpHdfModulesInfo_.clear();
231     bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
232         return isFinishGetHdfModulesInfo_;  // will be true when got notified.
233     });
234     CHECK_AND_RETURN_RET_LOG(stopWaiting, false, "DumpAllAvailableDevice timeout!");
235     return true;
236 }
237 
OnDumpAllAvailableDeviceCb(int32_t result)238 void AudioServerHpaeDump::OnDumpAllAvailableDeviceCb(int32_t result)
239 {
240     std::unique_lock<std::mutex> waitLock(callbackMutex_);
241     isFinishGetHdfModulesInfo_ = true;
242     AUDIO_INFO_LOG(
243         "sink count %{public}zu, source count %{public}zu, result %{public}d",
244         devicesInfo_.sinkInfos.size(), devicesInfo_.sourceInfos.size(), result);
245     callbackCV_.notify_all();
246 }
247 
PolicyHandlerDump(std::string & dumpString)248 void AudioServerHpaeDump::PolicyHandlerDump(std::string &dumpString)
249 {
250     AUDIO_INFO_LOG("PolicyHandlerDump");
251     AudioService::GetInstance()->Dump(dumpString);
252 }
253 
AudioCacheTimeDump(std::string & dumpString)254 void AudioServerHpaeDump::AudioCacheTimeDump(std::string &dumpString)
255 {
256     AUDIO_INFO_LOG("AudioCacheTimeDump");
257     dumpString += "\nAudioCached Time\n";
258 
259     int64_t startTime = 0;
260     int64_t endTime = 0;
261     AudioCacheMgr::GetInstance().GetCachedDuration(startTime, endTime);
262     dumpString += "Call dump get time: [ " + ClockTime::NanoTimeToString(startTime) + " ~ " +
263         ClockTime::NanoTimeToString(endTime) + " ], cur: [ " +
264         ClockTime::NanoTimeToString(ClockTime::GetRealNano()) + " ] \n";
265 }
266 
AudioCacheMemoryDump(std::string & dumpString)267 void AudioServerHpaeDump::AudioCacheMemoryDump(std::string &dumpString)
268 {
269     AUDIO_INFO_LOG("AudioCacheMemoryDump");
270     dumpString += "\nAudioCached Memory\n";
271 
272     size_t dataLength = 0;
273     size_t bufferLength = 0;
274     size_t structLength = 0;
275     AudioCacheMgr::GetInstance().GetCurMemoryCondition(dataLength, bufferLength, structLength);
276     dumpString += "dataLength: " + std::to_string(dataLength / BYTE_TO_KB_SIZE) + " KB, " +
277                     "bufferLength: " + std::to_string(bufferLength / BYTE_TO_KB_SIZE) + " KB, " +
278                     "structLength: " + std::to_string(structLength / BYTE_TO_KB_SIZE) + " KB \n";
279 }
280 
AudioPerformMonitorDump(std::string & dumpString)281 void AudioServerHpaeDump::AudioPerformMonitorDump(std::string &dumpString)
282 {
283     AUDIO_INFO_LOG("AudioPerformMonitorDump");
284     dumpString += "\n Dump Audio Performance Monitor Record Infos\n";
285     AudioPerformanceMonitor::GetInstance().DumpMonitorInfo(dumpString);
286 }
287 
HdiAdapterDump(std::string & dumpString)288 void AudioServerHpaeDump::HdiAdapterDump(std::string &dumpString)
289 {
290     AUDIO_INFO_LOG("HdiAdapterDump");
291     dumpString += "\nHdiAdapter Info\n";
292     HdiAdapterManager::GetInstance().DumpInfo(dumpString);
293 }
294 
PlaybackSinkInputDump(std::string & dumpString)295 void AudioServerHpaeDump::PlaybackSinkInputDump(std::string &dumpString)
296 {
297     lock_guard<mutex> lock(lock_);
298     AUDIO_INFO_LOG("get sinkinputs dump info");
299     isFinishGetStreamInfo_ = false;
300     dumpSinkInputsInfo_.clear();
301     IHpaeManager::GetHpaeManager().DumpSinkInputsInfo();
302     std::unique_lock<std::mutex> waitLock(callbackMutex_);
303 
304     bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
305         return isFinishGetStreamInfo_;  // will be true when got notified.
306     });
307     if (!stopWaiting) {
308         AUDIO_ERR_LOG("PlaybackSinkInputDump timeout!");
309         return;
310     }
311     AUDIO_INFO_LOG("PlaybackSinkInputDump SUCCESS, info : \n%{public}s", dumpSinkInputsInfo_.c_str());
312     dumpString += dumpSinkInputsInfo_;
313 }
314 
RecordSourceOutputDump(std::string & dumpString)315 void AudioServerHpaeDump::RecordSourceOutputDump(std::string &dumpString)
316 {
317     lock_guard<mutex> lock(lock_);
318     AUDIO_INFO_LOG("get sourceoutputs dump info");
319     isFinishGetStreamInfo_ = false;
320     dumpSourceOutputsInfo_.clear();
321     IHpaeManager::GetHpaeManager().DumpSourceOutputsInfo();
322     std::unique_lock<std::mutex> waitLock(callbackMutex_);
323 
324     bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
325         return isFinishGetStreamInfo_;  // will be true when got notified.
326     });
327     if (!stopWaiting) {
328         AUDIO_ERR_LOG("RecordSourceOutputDump timeout!");
329         return;
330     }
331     AUDIO_INFO_LOG("RecordSourceOutputDump SUCCESS, info : \n%{public}s", dumpSourceOutputsInfo_.c_str());
332     dumpString += dumpSourceOutputsInfo_;
333 }
334 
TransTimeToString(uint64_t timetamp)335 static std::string TransTimeToString(uint64_t timetamp)
336 {
337     auto tp = std::chrono::system_clock::time_point(std::chrono::milliseconds(timetamp));
338     time_t time = std::chrono::system_clock::to_time_t(tp);
339     struct tm *timeinfo = localtime(&time);
340     if (!timeinfo) {
341         return "Invalid time";
342     }
343     char buffer[80];
344     CHECK_AND_RETURN_RET_LOG(strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", timeinfo) != 0, "error time",
345         "strftime failed");
346     return buffer;
347 }
348 
TransHpaeInputOutputInfoToStr(const HpaeInputOutputInfo & info,const size_t & idx,std::string & tempDumpStr)349 static void TransHpaeInputOutputInfoToStr(const HpaeInputOutputInfo &info, const size_t &idx, std::string &tempDumpStr)
350 {
351     std::ostringstream oss;
352     oss << "  Stream " << idx << "\n"
353         << "  - Stream Id: " << info.sessionId << "\n"
354         << "  - Device Name: " << info.deviceName << "\n"
355         << "  - Application Name: " << GetBundleNameByToken(info.tokenId) << "\n"
356         << "  - Process Id: " << info.pid << "\n"
357         << "  - User Id: " << info.uid << "\n"
358         << "  - Offload Enable: " << (info.offloadEnable ? "true" : "false") << "\n"
359         << "  - stream can be captured: " << (info.privacyType == 0 ? "true" : "false") << "\n"
360         << "  - Stream Configuration: " << info.config << "\n"
361         << "  - Status: " << (info.state == HPAE_SESSION_RUNNING ? "RUNNING" : "STOPPED/PAUSED") << "\n"
362         << "  - Stream Start Time: " << TransTimeToString(info.startTime) << "\n\n";
363     tempDumpStr += oss.str();
364 }
365 
OnDumpSinkInputsInfoCb(std::vector<HpaeInputOutputInfo> & sinkInputs,int32_t result)366 void AudioServerHpaeDump::OnDumpSinkInputsInfoCb(std::vector<HpaeInputOutputInfo> &sinkInputs, int32_t result)
367 {
368     std::unique_lock<std::mutex> waitLock(callbackMutex_);
369     if (result == SUCCESS) {
370         dumpSinkInputsInfo_ += "Playback Streams\n";
371         AppendFormat(dumpSinkInputsInfo_, "- %zu Playback stream (s) available:\n", sinkInputs.size());
372         for (auto it = sinkInputs.begin(); it != sinkInputs.end(); it++) {
373             HpaeInputOutputInfo info = *it;
374             TransHpaeInputOutputInfoToStr(info, it - sinkInputs.begin() + 1, dumpSinkInputsInfo_);
375         }
376         dumpSinkInputsInfo_ += "\n";
377     }
378     isFinishGetStreamInfo_ = true;
379     AUDIO_INFO_LOG("AudioServerHpaeDump OnDumpSinkInputsInfoCb result %{public}d", result);
380     callbackCV_.notify_all();
381 }
382 
OnDumpSourceOutputsInfoCb(std::vector<HpaeInputOutputInfo> & sourceOutputs,int32_t result)383 void AudioServerHpaeDump::OnDumpSourceOutputsInfoCb(std::vector<HpaeInputOutputInfo> &sourceOutputs, int32_t result)
384 {
385     std::unique_lock<std::mutex> waitLock(callbackMutex_);
386     if (result == SUCCESS) {
387         dumpSourceOutputsInfo_ += "Record Streams\n";
388         AppendFormat(dumpSourceOutputsInfo_, "- %zu Record stream (s) available:\n", sourceOutputs.size());
389         for (auto it = sourceOutputs.begin(); it != sourceOutputs.end(); it++) {
390             HpaeInputOutputInfo info = *it;
391             TransHpaeInputOutputInfoToStr(info, it - sourceOutputs.begin() + 1, dumpSourceOutputsInfo_);
392         }
393         dumpSourceOutputsInfo_ += "\n";
394     }
395     isFinishGetStreamInfo_ = true;
396     AUDIO_INFO_LOG("AudioServerHpaeDump OnDumpSourceOutputsInfoCb result %{public}d", result);
397     callbackCV_.notify_all();
398 }
399 }  // namespace AudioStandard
400 }  // namespace OHOS
401