1 /*
2  * Copyright (c) 2021-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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioServerDump"
17 #endif
18 
19 #include "audio_server_dump.h"
20 #include "audio_utils.h"
21 #include "audio_service.h"
22 #include "pa_adapter_tools.h"
23 #include "audio_dump_pcm.h"
24 
25 using namespace std;
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 
AudioServerDump()30 AudioServerDump::AudioServerDump() : mainLoop(nullptr),
31     api(nullptr),
32     context(nullptr),
33     isMainLoopStarted_(false),
34     isContextConnected_(false)
35 {
36     AUDIO_DEBUG_LOG("AudioServerDump construct");
37     InitDumpFuncMap();
38 }
39 
~AudioServerDump()40 AudioServerDump::~AudioServerDump()
41 {
42     ResetPAAudioDump();
43 }
44 
InitDumpFuncMap()45 void AudioServerDump::InitDumpFuncMap()
46 {
47     dumpFuncMap[u"-h"] = &AudioServerDump::HelpInfoDump;
48     dumpFuncMap[u"-p"] = &AudioServerDump::PlaybackSinkDump;
49     dumpFuncMap[u"-r"] = &AudioServerDump::RecordSourceDump;
50     dumpFuncMap[u"-m"] = &AudioServerDump::HDFModulesDump;
51     dumpFuncMap[u"-ep"] = &AudioServerDump::PolicyHandlerDump;
52     dumpFuncMap[u"-ct"] = &AudioServerDump::AudioCacheTimeDump;
53     dumpFuncMap[u"-cm"] = &AudioServerDump::AudioCacheMemoryDump;
54 }
55 
ResetPAAudioDump()56 void AudioServerDump::ResetPAAudioDump()
57 {
58     lock_guard<mutex> lock(ctrlMutex_);
59     if (mainLoop && (isMainLoopStarted_ == true)) {
60         pa_threaded_mainloop_stop(mainLoop);
61     }
62 
63     if (context) {
64         pa_context_set_state_callback(context, nullptr, nullptr);
65         if (isContextConnected_ == true) {
66             AUDIO_INFO_LOG("[AudioServerDump] disconnect context!");
67             pa_context_disconnect(context);
68         }
69         pa_context_unref(context);
70     }
71 
72     if (mainLoop) {
73         pa_threaded_mainloop_free(mainLoop);
74     }
75 
76     isMainLoopStarted_  = false;
77     isContextConnected_ = false;
78     mainLoop = nullptr;
79     context  = nullptr;
80     api      = nullptr;
81 }
82 
Initialize()83 int32_t AudioServerDump::Initialize()
84 {
85     mainLoop = pa_threaded_mainloop_new();
86     if (mainLoop == nullptr) {
87         return AUDIO_DUMP_INIT_ERR;
88     }
89 
90     api = pa_threaded_mainloop_get_api(mainLoop);
91     if (api == nullptr) {
92         ResetPAAudioDump();
93         return AUDIO_DUMP_INIT_ERR;
94     }
95 
96     context = pa_context_new(api, "AudioServerDump");
97     if (context == nullptr) {
98         ResetPAAudioDump();
99         return AUDIO_DUMP_INIT_ERR;
100     }
101 
102     pa_context_set_state_callback(context, PAContextStateCb, mainLoop);
103 
104     if (pa_context_connect(context, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) {
105         int error = pa_context_errno(context);
106         AUDIO_ERR_LOG("context connect error: %{public}s", pa_strerror(error));
107         ResetPAAudioDump();
108         return AUDIO_DUMP_INIT_ERR;
109     }
110 
111     isContextConnected_ = true;
112     PaLockGuard lock(mainLoop);
113 
114     if (pa_threaded_mainloop_start(mainLoop) < 0) {
115         AUDIO_ERR_LOG("Audio Service not started");
116         ResetPAAudioDump();
117         return AUDIO_DUMP_INIT_ERR;
118     }
119 
120     isMainLoopStarted_ = true;
121     while (isMainLoopStarted_) {
122         pa_context_state_t state = pa_context_get_state(context);
123         if (state == PA_CONTEXT_READY) {
124             break;
125         }
126 
127         if (!PA_CONTEXT_IS_GOOD(state)) {
128             int error = pa_context_errno(context);
129             AUDIO_ERR_LOG("context bad state error: %{public}s", pa_strerror(error));
130             ResetPAAudioDump();
131             return AUDIO_DUMP_INIT_ERR;
132         }
133 
134         pa_threaded_mainloop_wait(mainLoop);
135     }
136 
137     return AUDIO_DUMP_SUCCESS;
138 }
139 
OnTimeOut()140 void AudioServerDump::OnTimeOut()
141 {
142     PaLockGuard lock(mainLoop);
143     pa_threaded_mainloop_signal(mainLoop, 0);
144 }
145 
IsEndWith(const std::string & mainStr,const std::string & toMatch)146 bool AudioServerDump::IsEndWith(const std::string &mainStr, const std::string &toMatch)
147 {
148     if (mainStr.size() >= toMatch.size() &&
149         mainStr.compare(mainStr.size() - toMatch.size(), toMatch.size(), toMatch) == 0) {
150         return true;
151     }
152     return false;
153 }
154 
IsValidModule(const std::string moduleName)155 bool AudioServerDump::IsValidModule(const std::string moduleName)
156 {
157     if (moduleName.rfind("fifo", 0) == SUCCESS) {
158         return false; // Module starts with fifo, Not valid module
159     }
160 
161     if (IsEndWith(moduleName, "monitor")) {
162         return false; // Module ends with monitor, Not valid module
163     }
164     return true;
165 }
166 
ServerDataDump(string & dumpString)167 void AudioServerDump::ServerDataDump(string &dumpString)
168 {
169     PlaybackSinkDump(dumpString);
170     RecordSourceDump(dumpString);
171     HDFModulesDump(dumpString);
172     PolicyHandlerDump(dumpString);
173 }
174 
ArgDataDump(std::string & dumpString,std::queue<std::u16string> & argQue)175 void AudioServerDump::ArgDataDump(std::string &dumpString, std::queue<std::u16string>& argQue)
176 {
177     dumpString += "AudioServer Data Dump:\n\n";
178     if (argQue.empty()) {
179         ServerDataDump(dumpString);
180         return;
181     }
182     while (!argQue.empty()) {
183         std::u16string para = argQue.front();
184         if (para == u"-h") {
185             dumpString.clear();
186             (this->*dumpFuncMap[para])(dumpString);
187             return;
188         } else if (dumpFuncMap.count(para) == 0) {
189             dumpString.clear();
190             AppendFormat(dumpString, "Please input correct param:\n");
191             HelpInfoDump(dumpString);
192             return;
193         } else {
194             (this->*dumpFuncMap[para])(dumpString);
195         }
196         argQue.pop();
197     }
198 }
199 
HelpInfoDump(string & dumpString)200 void AudioServerDump::HelpInfoDump(string &dumpString)
201 {
202     AppendFormat(dumpString, "usage:\n");
203     AppendFormat(dumpString, "  -h\t\t\t|help text for hidumper audio\n");
204     AppendFormat(dumpString, "  -p\t\t\t|dump pa playback streams\n");
205     AppendFormat(dumpString, "  -r\t\t\t|dump pa record streams\n");
206     AppendFormat(dumpString, "  -m\t\t\t|dump hdf input modules\n");
207     AppendFormat(dumpString, "  -ep\t\t\t|dump policyhandler info\n");
208     AppendFormat(dumpString, "  -ct\t\t\t|dump AudioCached time info\n");
209     AppendFormat(dumpString, "  -cm\t\t\t|dump AudioCached memory info\n");
210 }
211 
AudioDataDump(string & dumpString,std::queue<std::u16string> & argQue)212 void AudioServerDump::AudioDataDump(string &dumpString, std::queue<std::u16string>& argQue)
213 {
214     if (mainLoop == nullptr || context == nullptr) {
215         AUDIO_ERR_LOG("Audio Service Not running");
216         return;
217     }
218 
219     PaLockGuard lock(mainLoop);
220     pa_operation *operation = nullptr;
221     operation = pa_context_get_sink_info_list(context,
222         AudioServerDump::PASinkInfoCallback, reinterpret_cast<void *>(this));
223 
224     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
225         pa_threaded_mainloop_wait(mainLoop);
226     }
227 
228     pa_operation_unref(operation);
229     operation = pa_context_get_sink_input_info_list(context,
230         AudioServerDump::PASinkInputInfoCallback, reinterpret_cast<void *>(this));
231 
232     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
233         pa_threaded_mainloop_wait(mainLoop);
234     }
235 
236     pa_operation_unref(operation);
237     operation = pa_context_get_source_info_list(context,
238         AudioServerDump::PASourceInfoCallback, reinterpret_cast<void *>(this));
239 
240     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
241         pa_threaded_mainloop_wait(mainLoop);
242     }
243 
244     pa_operation_unref(operation);
245     operation = pa_context_get_source_output_info_list(context,
246         AudioServerDump::PASourceOutputInfoCallback, reinterpret_cast<void *>(this));
247 
248     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
249         pa_threaded_mainloop_wait(mainLoop);
250     }
251 
252     pa_operation_unref(operation);
253 
254     ArgDataDump(dumpString, argQue);
255 
256     return;
257 }
258 
PAContextStateCb(pa_context * context,void * userdata)259 void AudioServerDump::PAContextStateCb(pa_context *context, void *userdata)
260 {
261     pa_threaded_mainloop *mainLoop = reinterpret_cast<pa_threaded_mainloop *>(userdata);
262 
263     switch (pa_context_get_state(context)) {
264         case PA_CONTEXT_READY:
265         case PA_CONTEXT_TERMINATED:
266         case PA_CONTEXT_FAILED:
267             pa_threaded_mainloop_signal(mainLoop, 0);
268             break;
269 
270         case PA_CONTEXT_UNCONNECTED:
271         case PA_CONTEXT_CONNECTING:
272         case PA_CONTEXT_AUTHORIZING:
273         case PA_CONTEXT_SETTING_NAME:
274         default:
275             break;
276     }
277     return;
278 }
279 
PASinkInfoCallback(pa_context * c,const pa_sink_info * i,int eol,void * userdata)280 void AudioServerDump::PASinkInfoCallback(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
281 {
282     AudioServerDump *asDump = reinterpret_cast<AudioServerDump *>(userdata);
283     CHECK_AND_RETURN_LOG(asDump != nullptr, "Failed to get sink information");
284 
285     pa_threaded_mainloop *mainLoop = reinterpret_cast<pa_threaded_mainloop *>(asDump->mainLoop);
286 
287     CHECK_AND_RETURN_LOG(eol >= 0, "Failed to get sink information: %{public}s", pa_strerror(pa_context_errno(c)));
288 
289     if (eol) {
290         pa_threaded_mainloop_signal(mainLoop, 0);
291         return;
292     }
293 
294     SinkSourceInfo sinkInfo;
295 
296     if (i->name != nullptr) {
297         string sinkName(i->name);
298         if (IsValidModule(sinkName)) {
299             (sinkInfo.name).assign(sinkName);
300             sinkInfo.sampleSpec = i->sample_spec;
301             asDump->streamData_.sinkDevices.push_back(sinkInfo);
302         }
303     }
304 }
305 
PASinkInputInfoCallback(pa_context * c,const pa_sink_input_info * i,int eol,void * userdata)306 void AudioServerDump::PASinkInputInfoCallback(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata)
307 {
308     AudioServerDump *asDump = reinterpret_cast<AudioServerDump *>(userdata);
309     CHECK_AND_RETURN_LOG(asDump != nullptr, "Failed to get sink input information");
310     pa_threaded_mainloop *mainLoop = reinterpret_cast<pa_threaded_mainloop *>(asDump->mainLoop);
311     CHECK_AND_RETURN_LOG(eol >= 0, "Failed to get sink input information: %{public}s",
312         pa_strerror(pa_context_errno(c)));
313     if (eol) {
314         pa_threaded_mainloop_signal(mainLoop, 0);
315         return;
316     }
317     InputOutputInfo sinkInputInfo;
318     sinkInputInfo.sampleSpec = i->sample_spec;
319     sinkInputInfo.corked = i->corked;
320     if (i->proplist != nullptr) {
321         const char *applicationname = pa_proplist_gets(i->proplist, "application.name");
322         const char *processid = pa_proplist_gets(i->proplist, "application.process.id");
323         const char *user = pa_proplist_gets(i->proplist, "application.process.user");
324         const char *sessionid = pa_proplist_gets(i->proplist, "stream.sessionID");
325         const char *sessionstarttime = pa_proplist_gets(i->proplist, "stream.startTime");
326         const char *privacytype = pa_proplist_gets(i->proplist, "stream.privacyType");
327         if (applicationname != nullptr) {
328             string applicationName(applicationname);
329             (sinkInputInfo.applicationName).assign(applicationName);
330         }
331         if (processid != nullptr) {
332             string processId(processid);
333             (sinkInputInfo.processId).assign(processId);
334         }
335         if (user != nullptr) {
336             struct passwd *p;
337             if ((p = getpwnam(user)) != nullptr) {
338                 sinkInputInfo.userId = uint32_t(p->pw_uid);
339             }
340         }
341         if (sessionid != nullptr) {
342             string sessionId(sessionid);
343             (sinkInputInfo.sessionId).assign(sessionId);
344         }
345         if (sessionstarttime != nullptr) {
346             string sessionStartTime(sessionstarttime);
347             (sinkInputInfo.sessionStartTime).assign(sessionStartTime);
348         }
349         if (privacytype != nullptr) {
350             string privacyType(privacytype);
351             (sinkInputInfo.privacyType).assign(privacyType);
352         }
353     }
354     asDump->streamData_.sinkInputs.push_back(sinkInputInfo);
355 }
356 
PASourceInfoCallback(pa_context * c,const pa_source_info * i,int eol,void * userdata)357 void AudioServerDump::PASourceInfoCallback(pa_context *c, const pa_source_info *i, int eol, void *userdata)
358 {
359     AudioServerDump *asDump = reinterpret_cast<AudioServerDump *>(userdata);
360     CHECK_AND_RETURN_LOG(asDump != nullptr, "Failed to get source information");
361 
362     pa_threaded_mainloop *mainLoop = reinterpret_cast<pa_threaded_mainloop *>(asDump->mainLoop);
363     CHECK_AND_RETURN_LOG(eol >= 0, "Failed to get source information: %{public}s",
364         pa_strerror(pa_context_errno(c)));
365 
366     if (eol) {
367         pa_threaded_mainloop_signal(mainLoop, 0);
368         return;
369     }
370 
371     SinkSourceInfo sourceInfo;
372 
373     if (i->name != nullptr) {
374         string sourceName(i->name);
375         if (IsValidModule(sourceName)) {
376             (sourceInfo.name).assign(sourceName);
377             sourceInfo.sampleSpec = i->sample_spec;
378             asDump->streamData_.sourceDevices.push_back(sourceInfo);
379         }
380     }
381 }
382 
PASourceOutputInfoCallback(pa_context * c,const pa_source_output_info * i,int eol,void * userdata)383 void AudioServerDump::PASourceOutputInfoCallback(pa_context *c, const pa_source_output_info *i, int eol,
384     void *userdata)
385 {
386     AudioServerDump *asDump = reinterpret_cast<AudioServerDump *>(userdata);
387     CHECK_AND_RETURN_LOG(asDump != nullptr, "Failed to get source output information");
388     pa_threaded_mainloop *mainLoop = reinterpret_cast<pa_threaded_mainloop *>(asDump->mainLoop);
389     CHECK_AND_RETURN_LOG(eol >= 0, "Failed to get source output information: %{public}s",
390         pa_strerror(pa_context_errno(c)));
391     if (eol) {
392         pa_threaded_mainloop_signal(mainLoop, 0);
393         return;
394     }
395     InputOutputInfo sourceOutputInfo;
396     sourceOutputInfo.sampleSpec = i->sample_spec;
397     sourceOutputInfo.corked = i->corked;
398     if (i->proplist != nullptr) {
399         const char *applicationname = pa_proplist_gets(i->proplist, "application.name");
400         const char *processid = pa_proplist_gets(i->proplist, "application.process.id");
401         const char *user = pa_proplist_gets(i->proplist, "application.process.user");
402         const char *sessionid = pa_proplist_gets(i->proplist, "stream.sessionID");
403         const char *sessionstarttime = pa_proplist_gets(i->proplist, "stream.startTime");
404         const char *privacytype = pa_proplist_gets(i->proplist, "stream.privacyType");
405         if (applicationname != nullptr) {
406             string applicationName(applicationname);
407             (sourceOutputInfo.applicationName).assign(applicationName);
408         }
409         if (processid != nullptr) {
410             string processId(processid);
411             (sourceOutputInfo.processId).assign(processId);
412         }
413         if (user != nullptr) {
414             struct passwd *p;
415             if ((p = getpwnam(user)) != nullptr) {
416                 sourceOutputInfo.userId = uint32_t(p->pw_uid);
417             }
418         }
419         if (sessionid != nullptr) {
420             string sessionId(sessionid);
421             (sourceOutputInfo.sessionId).assign(sessionId);
422         }
423         if (sessionstarttime != nullptr) {
424             string sessionStartTime(sessionstarttime);
425             (sourceOutputInfo.sessionStartTime).assign(sessionStartTime);
426         }
427         if (privacytype != nullptr) {
428             string privacyType(privacytype);
429             (sourceOutputInfo.privacyType).assign(privacyType);
430         }
431     }
432     asDump->streamData_.sourceOutputs.push_back(sourceOutputInfo);
433 }
434 
PlaybackSinkDump(std::string & dumpString)435 void AudioServerDump::PlaybackSinkDump(std::string &dumpString)
436 {
437     AUDIO_INFO_LOG("PlaybackSinkDump enter");
438     char s[PA_SAMPLE_SPEC_SNPRINT_MAX];
439 
440     dumpString += "Playback Streams\n";
441 
442     AppendFormat(dumpString, "- %zu Playback stream (s) available:\n", streamData_.sinkInputs.size());
443 
444     for (auto it = streamData_.sinkInputs.begin(); it != streamData_.sinkInputs.end(); it++) {
445         InputOutputInfo sinkInputInfo = *it;
446 
447         AppendFormat(dumpString, "  Stream %d\n", it - streamData_.sinkInputs.begin() + 1);
448         AppendFormat(dumpString, "  - Stream Id: %s\n", (sinkInputInfo.sessionId).c_str());
449         AppendFormat(dumpString, "  - Application Name: %s\n", ((sinkInputInfo.applicationName).c_str()));
450         AppendFormat(dumpString, "  - Process Id: %s\n", (sinkInputInfo.processId).c_str());
451         AppendFormat(dumpString, "  - User Id: %u\n", sinkInputInfo.userId);
452         AppendFormat(dumpString, "  - stream can be captured: %s\n",
453             sinkInputInfo.privacyType == "0" ? "true" : "false");
454 
455         char *inputSampleSpec = pa_sample_spec_snprint(s, sizeof(s), &(sinkInputInfo.sampleSpec));
456         AppendFormat(dumpString, "  - Stream Configuration: %s\n", inputSampleSpec);
457         dumpString += "  - Status:";
458         dumpString += (sinkInputInfo.corked) ? "STOPPED/PAUSED" : "RUNNING";
459         AppendFormat(dumpString, "\n  - Stream Start Time: %s\n", (sinkInputInfo.sessionStartTime).c_str());
460         dumpString += "\n";
461     }
462 }
463 
RecordSourceDump(std::string & dumpString)464 void AudioServerDump::RecordSourceDump(std::string &dumpString)
465 {
466     char s[PA_SAMPLE_SPEC_SNPRINT_MAX];
467     dumpString += "Record Streams \n";
468     AppendFormat(dumpString, "- %zu Record stream (s) available:\n", streamData_.sourceOutputs.size());
469 
470     for (auto it = streamData_.sourceOutputs.begin(); it != streamData_.sourceOutputs.end(); it++) {
471         InputOutputInfo sourceOutputInfo = *it;
472         AppendFormat(dumpString, "  Stream %d\n", it - streamData_.sourceOutputs.begin() + 1);
473         AppendFormat(dumpString, "  - Stream Id: %s\n", (sourceOutputInfo.sessionId).c_str());
474         AppendFormat(dumpString, "  - Application Name: %s\n", (sourceOutputInfo.applicationName).c_str());
475         AppendFormat(dumpString, "  - Process Id: %s\n", sourceOutputInfo.processId.c_str());
476         AppendFormat(dumpString, "  - User Id: %u\n", sourceOutputInfo.userId);
477 
478         char *outputSampleSpec = pa_sample_spec_snprint(s, sizeof(s), &(sourceOutputInfo.sampleSpec));
479         AppendFormat(dumpString, "  - Stream Configuration: %s\n", outputSampleSpec);
480         dumpString += "  - Status:";
481         dumpString += (sourceOutputInfo.corked) ? "STOPPED/PAUSED" : "RUNNING";
482         AppendFormat(dumpString, "\n  - Stream Start Time: %s\n", (sourceOutputInfo.sessionStartTime).c_str());
483         dumpString += "\n";
484     }
485 }
486 
HDFModulesDump(std::string & dumpString)487 void AudioServerDump::HDFModulesDump(std::string &dumpString)
488 {
489     char s[PA_SAMPLE_SPEC_SNPRINT_MAX];
490 
491     dumpString += "\nHDF Input Modules\n";
492     AppendFormat(dumpString, "- %zu HDF Input Modules (s) available:\n", streamData_.sourceDevices.size());
493 
494     for (auto it = streamData_.sourceDevices.begin(); it != streamData_.sourceDevices.end(); it++) {
495         SinkSourceInfo sourceInfo = *it;
496 
497         AppendFormat(dumpString, "  Module %d\n", it - streamData_.sourceDevices.begin() + 1);
498         AppendFormat(dumpString, "  - Module Name: %s\n", (sourceInfo.name).c_str());
499         char *hdfOutSampleSpec = pa_sample_spec_snprint(s, sizeof(s), &(sourceInfo.sampleSpec));
500         AppendFormat(dumpString, "  - Module Configuration: %s\n\n", hdfOutSampleSpec);
501     }
502 
503     dumpString += "HDF Output Modules\n";
504     AppendFormat(dumpString, "- %zu HDF Output Modules (s) available:\n", streamData_.sinkDevices.size());
505 
506     for (auto it = streamData_.sinkDevices.begin(); it != streamData_.sinkDevices.end(); it++) {
507         SinkSourceInfo sinkInfo = *it;
508         AppendFormat(dumpString, "  Module %d\n", it - streamData_.sinkDevices.begin() + 1);
509         AppendFormat(dumpString, "  - Module Name: %s\n", (sinkInfo.name).c_str());
510         char *hdfInSampleSpec = pa_sample_spec_snprint(s, sizeof(s), &(sinkInfo.sampleSpec));
511         AppendFormat(dumpString, "  - Module Configuration: %s\n\n", hdfInSampleSpec);
512     }
513 }
514 
PolicyHandlerDump(std::string & dumpString)515 void AudioServerDump::PolicyHandlerDump(std::string &dumpString)
516 {
517     AUDIO_INFO_LOG("PolicyHandlerDump");
518     AudioService::GetInstance()->Dump(dumpString);
519 }
520 
AudioCacheTimeDump(std::string & dumpString)521 void AudioServerDump::AudioCacheTimeDump(std::string &dumpString)
522 {
523     AUDIO_INFO_LOG("AudioCacheTimeDump");
524     dumpString += "\nAudioCached Time\n";
525 
526     int64_t startTime = 0;
527     int64_t endTime = 0;
528     AudioCacheMgr::GetInstance().GetCachedDuration(startTime, endTime);
529     dumpString += "Call dump get time: [ " + ClockTime::NanoTimeToString(startTime) + " ~ " +
530         ClockTime::NanoTimeToString(endTime) + " ], cur: [ " +
531         ClockTime::NanoTimeToString(ClockTime::GetRealNano()) + " ] \n";
532 }
533 
AudioCacheMemoryDump(std::string & dumpString)534 void AudioServerDump::AudioCacheMemoryDump(std::string &dumpString)
535 {
536     AUDIO_INFO_LOG("AudioCacheMemoryDump");
537     dumpString += "\nAudioCached Memory\n";
538 
539     size_t dataLength = 0;
540     size_t bufferLength = 0;
541     size_t structLength = 0;
542     AudioCacheMgr::GetInstance().GetCurMemoryCondition(dataLength, bufferLength, structLength);
543     dumpString += "dataLength: " + std::to_string(dataLength / BYTE_TO_KB_SIZE) + " KB, " +
544                     "bufferLength: " + std::to_string(bufferLength / BYTE_TO_KB_SIZE) + " KB, " +
545                     "structLength: " + std::to_string(structLength / BYTE_TO_KB_SIZE) + " KB \n";
546 }
547 } // namespace AudioStandard
548 } // namespace OHOS
549