• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #ifndef LOG_TAG
17 #define LOG_TAG "AudioPolicyParser"
18 #endif
19 
20 #include "audio_policy_parser.h"
21 #include "audio_utils.h"
22 #include "audio_errors.h"
23 
24 #include <sstream>
25 
26 namespace OHOS {
27 namespace AudioStandard {
28 constexpr int32_t AUDIO_MS_PER_S = 1000;
29 constexpr uint32_t LAYOUT_MONO_CHANNEL_ENUM = 1;
30 constexpr uint32_t LAYOUT_STEREO_CHANNEL_ENUM = 2;
31 constexpr uint32_t LAYOUT_QUAD_CHANNEL_ENUM = 4;
32 constexpr uint32_t LAYOUT_5POINT1_CHANNEL_ENUM = 6;
33 constexpr uint32_t LAYOUT_7POINT1_CHANNEL_ENUM = 8;
34 constexpr uint32_t S16LE_TO_BYTE = 2;
35 constexpr uint32_t S24LE_TO_BYTE = 3;
36 constexpr uint32_t S32LE_TO_BYTE = 4;
37 
38 static std::map<std::string, uint32_t> layoutStrToChannels = {
39     {"CH_LAYOUT_MONO", LAYOUT_MONO_CHANNEL_ENUM},
40     {"CH_LAYOUT_STEREO", LAYOUT_STEREO_CHANNEL_ENUM},
41     {"CH_LAYOUT_5POINT1", LAYOUT_5POINT1_CHANNEL_ENUM},
42     {"CH_LAYOUT_QUAD", LAYOUT_QUAD_CHANNEL_ENUM},
43     {"CH_LAYOUT_7POINT1", LAYOUT_7POINT1_CHANNEL_ENUM},
44 };
45 
46 static std::map<std::string, uint32_t> formatStrToEnum = {
47     {"s16le", S16LE_TO_BYTE},
48     {"s24le", S24LE_TO_BYTE},
49     {"s32le", S32LE_TO_BYTE},
50 };
51 
52 static std::map<std::string, uint32_t> audioFlagStrToEnum = {
53     {"AUDIO_FLAG_NORMAL", AUDIO_FLAG_NORMAL},
54     {"AUDIO_FLAG_MMAP", AUDIO_FLAG_MMAP},
55 };
56 
57 static std::map<std::string, uint32_t> audioUsageStrToEnum = {
58     {"AUDIO_USAGE_NORMAL", AUDIO_USAGE_NORMAL},
59     {"AUDIO_USAGE_VOIP", AUDIO_USAGE_VOIP},
60 };
61 
62 // LCOV_EXCL_START
LoadConfiguration()63 bool AudioPolicyParser::LoadConfiguration()
64 {
65     AUDIO_INFO_LOG("Enter");
66     if (curNode_->Config(CHIP_PROD_CONFIG_FILE, nullptr, 0) != SUCCESS) {
67         if (curNode_->Config(CONFIG_FILE, nullptr, 0) != SUCCESS) {
68             AUDIO_ERR_LOG("LoadConfiguration readFile Failed");
69             return false;
70         }
71     }
72 
73     if (!ParseInternal(curNode_->GetCopyNode())) {
74         AUDIO_ERR_LOG("Audio policy config xml parse failed.");
75         return false;
76     }
77     std::unordered_map<std::string, std::string> volumeGroupMap {};
78     std::unordered_map<std::string, std::string> interruptGroupMap {};
79 
80     ConvertAdapterInfoToGroupInfo(volumeGroupMap, interruptGroupMap);
81     ConvertAdapterInfoToAudioModuleInfo();
82 
83     volumeGroupMap_ = volumeGroupMap;
84     interruptGroupMap_ = interruptGroupMap;
85 
86     portObserver_.OnAudioPolicyXmlParsingCompleted(adapterInfoMap_);
87     portObserver_.OnXmlParsingCompleted(xmlParsedDataMap_);
88     portObserver_.OnVolumeGroupParsed(volumeGroupMap_);
89     portObserver_.OnInterruptGroupParsed(interruptGroupMap_);
90     portObserver_.OnGlobalConfigsParsed(globalConfigs_);
91 
92     AUDIO_INFO_LOG("Done");
93     return true;
94 }
95 
Destroy()96 void AudioPolicyParser::Destroy()
97 {
98     curNode_->FreeDoc();
99 }
100 
ParseInternal(std::shared_ptr<AudioXmlNode> curNode)101 bool AudioPolicyParser::ParseInternal(std::shared_ptr<AudioXmlNode> curNode)
102 {
103     for (; curNode->IsNodeValid(); curNode->MoveToNext()) {
104         if (curNode->IsElementNode()) {
105             switch (GetXmlNodeTypeAsInt(curNode)) {
106                 case XmlNodeType::ADAPTERS:
107                     ParseAdapters(curNode->GetCopyNode());
108                     break;
109                 case XmlNodeType::VOLUME_GROUPS:
110                     ParseGroups(curNode->GetCopyNode(), XmlNodeType::VOLUME_GROUPS);
111                     break;
112                 case XmlNodeType::INTERRUPT_GROUPS:
113                     ParseGroups(curNode->GetCopyNode(), XmlNodeType::INTERRUPT_GROUPS);
114                     break;
115                 case XmlNodeType::GLOBAL_CONFIGS:
116                     ParseGlobalConfigs(curNode->GetCopyNode());
117                     break;
118                 default:
119                     ParseInternal(curNode->GetChildrenNode());
120                     break;
121             }
122         }
123     }
124     return true;
125 }
126 
ParseAdapters(std::shared_ptr<AudioXmlNode> curNode)127 void AudioPolicyParser::ParseAdapters(std::shared_ptr<AudioXmlNode> curNode)
128 {
129     curNode->MoveToChildren();
130 
131     while (curNode->IsNodeValid()) {
132         if (curNode->IsElementNode()) {
133             ParseAdapter(curNode->GetCopyNode());
134         }
135         curNode->MoveToNext();
136     }
137 }
138 
ConvertAdapterInfoToGroupInfo(std::unordered_map<std::string,std::string> & volumeGroupMap,std::unordered_map<std::string,std::string> & interruptGroupMap)139 void AudioPolicyParser::ConvertAdapterInfoToGroupInfo(std::unordered_map<std::string, std::string> &volumeGroupMap,
140     std::unordered_map<std::string, std::string> &interruptGroupMap)
141 {
142     for (auto &[sinkName, groupName] : volumeGroupMap_) {
143         volumeGroupMap["Speaker"] = groupName;
144     }
145 
146     for (auto &[sinkName, groupName] : interruptGroupMap_) {
147         interruptGroupMap["Speaker"] = groupName;
148     }
149 }
150 
GetCommontAudioModuleInfo(PipeInfo & pipeInfo,AudioModuleInfo & audioModuleInfo)151 void AudioPolicyParser::GetCommontAudioModuleInfo(PipeInfo &pipeInfo, AudioModuleInfo &audioModuleInfo)
152 {
153     audioModuleInfo.role = pipeInfo.paPropRole_;
154 
155     for (auto sampleRate : pipeInfo.sampleRates_) {
156         audioModuleInfo.supportedRate_.insert(sampleRate);
157     }
158     for (auto channelLayout : pipeInfo.channelLayouts_) {
159         audioModuleInfo.supportedChannels_.insert(channelLayout);
160     }
161 
162     audioModuleInfo.lib = pipeInfo.lib_;
163 
164     if (pipeInfo.streamPropInfos_.size() != 0) {
165         audioModuleInfo.rate = std::to_string((*pipeInfo.streamPropInfos_.begin()).sampleRate_);
166         audioModuleInfo.format = (*pipeInfo.streamPropInfos_.begin()).format_;
167         audioModuleInfo.channels = std::to_string((*pipeInfo.streamPropInfos_.begin()).channelLayout_);
168         audioModuleInfo.bufferSize = std::to_string((*pipeInfo.streamPropInfos_.begin()).bufferSize_);
169     }
170 
171     for (auto &config : pipeInfo.configInfos_) {
172         if (config.name_ == "filePath") {
173             audioModuleInfo.fileName = config.value_;
174         }
175     }
176 
177     audioModuleInfo.fixedLatency = pipeInfo.fixedLatency_;
178     audioModuleInfo.renderInIdleState = pipeInfo.renderInIdleState_;
179 }
180 
GetClassTypeByAdapterType(AdaptersType adapterType)181 ClassType AudioPolicyParser::GetClassTypeByAdapterType(AdaptersType adapterType)
182 {
183     if (adapterType == AdaptersType::TYPE_PRIMARY) {
184         return ClassType::TYPE_PRIMARY;
185     } else if (adapterType == AdaptersType::TYPE_A2DP) {
186         return ClassType::TYPE_A2DP;
187     } else if (adapterType == AdaptersType::TYPE_REMOTE_AUDIO) {
188         return ClassType::TYPE_REMOTE_AUDIO;
189     } else if (adapterType == AdaptersType::TYPE_FILE_IO) {
190         return ClassType::TYPE_FILE_IO;
191     } else if (adapterType == AdaptersType::TYPE_USB) {
192         return ClassType::TYPE_USB;
193     }  else if (adapterType == AdaptersType::TYPE_DP) {
194         return ClassType::TYPE_DP;
195     } else {
196         return ClassType::TYPE_INVALID;
197     }
198 }
199 
200 // LCOV_EXCL_STOP
GetOffloadAndOpenMicState(AudioAdapterInfo & adapterInfo,bool & shouldEnableOffload)201 void AudioPolicyParser::GetOffloadAndOpenMicState(AudioAdapterInfo &adapterInfo,
202     bool &shouldEnableOffload)
203 {
204     for (auto &pipeInfo : adapterInfo.pipeInfos_) {
205         if (pipeInfo.paPropRole_ == MODULE_TYPE_SINK &&
206             pipeInfo.name_.find(MODULE_SINK_OFFLOAD) != std::string::npos) {
207             shouldEnableOffload = true;
208         }
209     }
210 }
211 
GetAudioModuleInfoName(std::string & pipeInfoName,std::list<AudioPipeDeviceInfo> & deviceInfos)212 std::string AudioPolicyParser::GetAudioModuleInfoName(std::string &pipeInfoName,
213     std::list<AudioPipeDeviceInfo> &deviceInfos)
214 {
215     for (auto &deviceInfo : deviceInfos) {
216         if (std::find(deviceInfo.supportPipes_.begin(), deviceInfo.supportPipes_.end(), pipeInfoName) !=
217             deviceInfo.supportPipes_.end()) {
218             return deviceInfo.name_;
219         }
220     }
221     return "";
222 }
223 
224 // LCOV_EXCL_START
ConvertAdapterInfoToAudioModuleInfo()225 void AudioPolicyParser::ConvertAdapterInfoToAudioModuleInfo()
226 {
227     for (auto &[adapterType, adapterInfo] : adapterInfoMap_) {
228         std::list<AudioModuleInfo> audioModuleList = {};
229         bool shouldEnableOffload = false;
230         if (adapterType == AdaptersType::TYPE_PRIMARY) {
231             GetOffloadAndOpenMicState(adapterInfo, shouldEnableOffload);
232         }
233 
234         std::string currentRole = "";
235         for (auto &pipeInfo : adapterInfo.pipeInfos_) {
236             if (currentRole == pipeInfo.pipeRole_) {
237                 continue;
238             }
239             currentRole = pipeInfo.pipeRole_;
240             CHECK_AND_CONTINUE_LOG(pipeInfo.name_.find(MODULE_SINK_OFFLOAD) == std::string::npos,
241                 "skip offload out sink.");
242             AudioModuleInfo audioModuleInfo = {};
243             GetCommontAudioModuleInfo(pipeInfo, audioModuleInfo);
244 
245             audioModuleInfo.className = adapterInfo.adapterName_;
246             // The logic here strongly depends on the moduleName in the XML
247             if (pipeInfo.moduleName_ != "") {
248                 audioModuleInfo.name = pipeInfo.moduleName_;
249             } else {
250                 audioModuleInfo.name = GetAudioModuleInfoName(pipeInfo.name_, adapterInfo.deviceInfos_);
251             }
252 
253             audioModuleInfo.adapterName = adapterInfo.adapterName_;
254             if (adapterType == AdaptersType::TYPE_FILE_IO) {
255                 audioModuleInfo.adapterName = STR_INIT;
256                 audioModuleInfo.format = STR_INIT;
257                 audioModuleInfo.className = FILE_CLASS;
258             }
259             audioModuleInfo.sinkLatency = globalConfigs_.globalPaConfigs_.sinkLatency_;
260 
261             shouldOpenMicSpeaker_ ? audioModuleInfo.OpenMicSpeaker = "1" : audioModuleInfo.OpenMicSpeaker = "0";
262             audioModuleInfo.defaultAdapterEnable = shouldSetDefaultAdapter_ ? "1" : "0";
263             if (adapterType == AdaptersType::TYPE_PRIMARY &&
264                 shouldEnableOffload && pipeInfo.paPropRole_ == MODULE_TYPE_SINK) {
265                 audioModuleInfo.offloadEnable = "1";
266             }
267             audioModuleList.push_back(audioModuleInfo);
268         }
269         std::list<AudioModuleInfo> audioModuleListTmp = audioModuleList;
270         std::list<AudioModuleInfo> audioModuleListData = {};
271         for (auto audioModuleInfo : audioModuleList) {
272             audioModuleInfo.ports = audioModuleListTmp;
273             audioModuleListData.push_back(audioModuleInfo);
274             AUDIO_WARNING_LOG("name:%{public}s, adapter name:%{public}s, adapter type:%{public}d",
275                 audioModuleInfo.name.c_str(), audioModuleInfo.adapterName.c_str(), adapterType);
276         }
277         ClassType classType = GetClassTypeByAdapterType(adapterType);
278         xmlParsedDataMap_[classType] = audioModuleListData;
279     }
280 }
281 
ParseAdapter(std::shared_ptr<AudioXmlNode> curNode)282 void AudioPolicyParser::ParseAdapter(std::shared_ptr<AudioXmlNode> curNode)
283 {
284     std::string adapterName;
285     CHECK_AND_RETURN_LOG(curNode->GetProp("name", adapterName) == SUCCESS, "get prop name fail!");
286     AdaptersType adaptersType = GetAdaptersType(adapterName);
287     adapterInfoMap_[adaptersType] = {};
288 
289     std::string supportScene;
290     curNode->GetProp("supportSelectScene", supportScene);
291 
292     AudioAdapterInfo adapterInfo = {};
293     adapterInfo.adapterName_ = adapterName;
294     adapterInfo.adaptersupportScene_ = supportScene;
295 
296     curNode->MoveToChildren();
297     while (curNode->IsNodeValid()) {
298         if (curNode->IsElementNode()) {
299             switch (GetAdapterTypeAsInt(curNode)) {
300                 case AdapterType::PIPES:
301                     ParsePipes(curNode->GetCopyNode(), adapterInfo);
302                     break;
303                 case AdapterType::DEVICES:
304                     ParseDevices(curNode->GetCopyNode(), adapterInfo);
305                     break;
306                 default:
307                     ParseAdapter(curNode->GetChildrenNode());
308                     break;
309             }
310         }
311         curNode->MoveToNext();
312     }
313     adapterInfoMap_[adaptersType] = adapterInfo;
314 }
315 
ParsePipes(std::shared_ptr<AudioXmlNode> curNode,AudioAdapterInfo & adapterInfo)316 void AudioPolicyParser::ParsePipes(std::shared_ptr<AudioXmlNode> curNode, AudioAdapterInfo &adapterInfo)
317 {
318     curNode->MoveToChildren();
319     std::list<PipeInfo> pipeInfos;
320 
321     while (curNode->IsNodeValid()) {
322         if (curNode->IsElementNode()) {
323             PipeInfo pipeInfo {};
324 
325             int32_t ret = 0;
326             curNode->GetProp("name", pipeInfo.name_);
327             curNode->GetProp("role", pipeInfo.pipeRole_);
328             curNode->GetProp("flags", pipeInfo.pipeFlags_);
329             ParsePipeInfos(curNode->GetCopyNode(), pipeInfo);
330             pipeInfos.push_back(pipeInfo);
331         }
332         curNode->MoveToNext();
333     }
334     adapterInfo.pipeInfos_ = pipeInfos;
335 }
336 
SplitChannelStringToSet(std::string & str,std::set<uint32_t> & result)337 void AudioPolicyParser::SplitChannelStringToSet(std::string &str, std::set<uint32_t> &result)
338 {
339     std::stringstream ss(str);
340     std::string token;
341 
342     while (std::getline(ss, token, ',')) {
343         result.insert(layoutStrToChannels[token]);
344     }
345 }
346 
ParsePipeInfos(std::shared_ptr<AudioXmlNode> curNode,PipeInfo & pipeInfo)347 void AudioPolicyParser::ParsePipeInfos(std::shared_ptr<AudioXmlNode> curNode, PipeInfo &pipeInfo)
348 {
349     curNode->MoveToChildren();
350     while (curNode->IsNodeValid()) {
351         if (curNode->IsElementNode()) {
352             switch (GetPipeInfoTypeAsInt(curNode)) {
353                 case PipeType::PA_PROP:
354                     curNode->GetProp("lib", pipeInfo.lib_);
355                     curNode->GetProp("role", pipeInfo.paPropRole_);
356                     curNode->GetProp("fixed_latency", pipeInfo.fixedLatency_);
357                     curNode->GetProp("render_in_idle_state", pipeInfo.renderInIdleState_);
358                     curNode->GetProp("moduleName", pipeInfo.moduleName_);
359                     break;
360                 case PipeType::STREAM_PROP:
361                     ParseStreamProps(curNode->GetCopyNode(), pipeInfo);
362                     break;
363                 case PipeType::CONFIGS:
364                     ParseConfigs(curNode->GetCopyNode(), pipeInfo);
365                     break;
366                 default:
367                     ParsePipeInfos(curNode->GetChildrenNode(), pipeInfo);
368                     break;
369             }
370         }
371         curNode->MoveToNext();
372     }
373 }
374 
GetAdapterTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)375 AdapterType AudioPolicyParser::GetAdapterTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)
376 {
377     if (curNode->CompareName("pipes")) {
378         return AdapterType::PIPES;
379     } else if (curNode->CompareName("devices")) {
380         return AdapterType::DEVICES;
381     } else {
382         return AdapterType::UNKNOWN;
383     }
384 }
385 
GetPipeInfoTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)386 PipeType AudioPolicyParser::GetPipeInfoTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)
387 {
388     if (curNode->CompareName("paProp")) {
389         return PipeType::PA_PROP;
390     } else if (curNode->CompareName("streamProps")) {
391         return PipeType::STREAM_PROP;
392     } else if (curNode->CompareName("attributes")) {
393         return PipeType::CONFIGS;
394     } else {
395         return PipeType::UNKNOWN;
396     }
397 }
398 
ParseStreamProps(std::shared_ptr<AudioXmlNode> curNode,PipeInfo & pipeInfo)399 void AudioPolicyParser::ParseStreamProps(std::shared_ptr<AudioXmlNode> curNode, PipeInfo &pipeInfo)
400 {
401     curNode->MoveToChildren();
402     std::list<StreamPropInfo> streamPropInfos;
403 
404     while (curNode->IsNodeValid()) {
405         if (curNode->IsElementNode()) {
406             StreamPropInfo streamPropInfo = {};
407             curNode->GetProp("format", streamPropInfo.format_);
408 
409             std::string sampleRateStr;
410             curNode->GetProp("sampleRates", sampleRateStr);
411             StringConverter(sampleRateStr, streamPropInfo.sampleRate_);
412             pipeInfo.sampleRates_.push_back(streamPropInfo.sampleRate_);
413 
414             std::string periodInMsStr;
415             curNode->GetProp("periodInMs", periodInMsStr);
416             StringConverter(periodInMsStr, streamPropInfo.periodInMs_);
417 
418             std::string channelLayoutStr;
419             curNode->GetProp("channelLayout", channelLayoutStr);
420             streamPropInfo.channelLayout_ = layoutStrToChannels[channelLayoutStr];
421             pipeInfo.channelLayouts_.push_back(streamPropInfo.channelLayout_);
422 
423             std::string bufferSizeStr;
424             int32_t ret = curNode->GetProp("bufferSize", bufferSizeStr);
425             if (ret == SUCCESS) {
426                 StringConverter(bufferSizeStr, streamPropInfo.bufferSize_);
427             } else {
428                 streamPropInfo.bufferSize_ = formatStrToEnum[streamPropInfo.format_] * streamPropInfo.sampleRate_ *
429                     streamPropInfo.periodInMs_ * streamPropInfo.channelLayout_ / AUDIO_MS_PER_S;
430             }
431             streamPropInfos.push_back(streamPropInfo);
432         }
433         curNode->MoveToNext();
434     }
435     pipeInfo.streamPropInfos_ = streamPropInfos;
436 }
437 
ParseConfigs(std::shared_ptr<AudioXmlNode> curNode,PipeInfo & pipeInfo)438 void AudioPolicyParser::ParseConfigs(std::shared_ptr<AudioXmlNode> curNode, PipeInfo &pipeInfo)
439 {
440     curNode->MoveToChildren();
441     std::list<ConfigInfo> configInfos;
442 
443     while (curNode->IsNodeValid()) {
444         if (curNode->IsElementNode()) {
445             ConfigInfo configInfo = {};
446             curNode->GetProp("name", configInfo.name_);
447             curNode->GetProp("value", configInfo.value_);
448             configInfos.push_back(configInfo);
449             HandleConfigFlagAndUsage(configInfo, pipeInfo);
450         }
451         curNode->MoveToNext();
452     }
453     if (pipeInfo.audioUsage_ == AUDIO_USAGE_VOIP && pipeInfo.audioFlag_ == AUDIO_FLAG_MMAP) {
454         portObserver_.OnVoipConfigParsed(true);
455     }
456     pipeInfo.configInfos_ = configInfos;
457 }
458 
HandleConfigFlagAndUsage(ConfigInfo & configInfo,PipeInfo & pipeInfo)459 void AudioPolicyParser::HandleConfigFlagAndUsage(ConfigInfo &configInfo, PipeInfo &pipeInfo)
460 {
461     if (configInfo.name_ == "flag") {
462         auto it = audioFlagStrToEnum.find(configInfo.value_);
463         if (it != audioFlagStrToEnum.end()) {
464             pipeInfo.audioFlag_ = static_cast<int32_t>(it->second);
465         }
466     } else if (configInfo.name_ == "usage") {
467         auto it = audioUsageStrToEnum.find(configInfo.value_);
468         if (it != audioUsageStrToEnum.end()) {
469             pipeInfo.audioUsage_ = static_cast<int32_t>(it->second);
470         }
471     }
472 }
473 
ParseDevices(std::shared_ptr<AudioXmlNode> curNode,AudioAdapterInfo & adapterInfo)474 void AudioPolicyParser::ParseDevices(std::shared_ptr<AudioXmlNode> curNode, AudioAdapterInfo &adapterInfo)
475 {
476     curNode->MoveToChildren();
477     std::list<AudioPipeDeviceInfo> deviceInfos = {};
478 
479     while (curNode->IsNodeValid()) {
480         if (curNode->IsElementNode()) {
481             AudioPipeDeviceInfo deviceInfo = {};
482             curNode->GetProp("name", deviceInfo.name_);
483             curNode->GetProp("type", deviceInfo.type_);
484             curNode->GetProp("pin", deviceInfo.pin_);
485             curNode->GetProp("role", deviceInfo.role_);
486 
487             std::string supportPipeInStr;
488             curNode->GetProp("supportPipes", supportPipeInStr);
489             SplitStringToList(supportPipeInStr, deviceInfo.supportPipes_);
490             deviceInfos.push_back(deviceInfo);
491         }
492         curNode->MoveToNext();
493     }
494     adapterInfo.deviceInfos_ = deviceInfos;
495 }
496 
SplitStringToList(std::string & str,std::list<std::string> & result)497 void AudioPolicyParser::SplitStringToList(std::string &str, std::list<std::string> &result)
498 {
499     char *token = std::strtok(&str[0], ",");
500     while (token != nullptr) {
501         result.push_back(token);
502         token = std::strtok(nullptr, ",");
503     }
504 }
505 
ParseGroups(std::shared_ptr<AudioXmlNode> curNode,XmlNodeType type)506 void AudioPolicyParser::ParseGroups(std::shared_ptr<AudioXmlNode> curNode, XmlNodeType type)
507 {
508     curNode->MoveToChildren();
509 
510     while (curNode->IsNodeValid()) {
511         if (curNode->IsElementNode()) {
512             ParseGroup(curNode->GetCopyNode(), type);
513         }
514         curNode->MoveToNext();
515     }
516 }
517 
ParseGroup(std::shared_ptr<AudioXmlNode> curNode,XmlNodeType type)518 void AudioPolicyParser::ParseGroup(std::shared_ptr<AudioXmlNode> curNode, XmlNodeType type)
519 {
520     curNode->MoveToChildren();
521 
522     while (curNode->IsNodeValid()) {
523         if (curNode->IsElementNode()) {
524             std::string groupName;
525             curNode->GetProp("name", groupName);
526             ParseGroupSink(curNode->GetCopyNode(), type, groupName);
527         }
528         curNode->MoveToNext();
529     }
530 }
531 
ParseGroupSink(std::shared_ptr<AudioXmlNode> curNode,XmlNodeType type,std::string & groupName)532 void AudioPolicyParser::ParseGroupSink(std::shared_ptr<AudioXmlNode> curNode, XmlNodeType type, std::string &groupName)
533 {
534     curNode->MoveToChildren();
535 
536     while (curNode->IsNodeValid()) {
537         if (curNode->IsElementNode()) {
538             std::string sinkName;
539             curNode->GetProp("name", sinkName);
540             if (type == XmlNodeType::VOLUME_GROUPS) {
541                 volumeGroupMap_[sinkName] = groupName;
542             } else if (type == XmlNodeType::INTERRUPT_GROUPS) {
543                 interruptGroupMap_[sinkName] = groupName;
544             }
545         }
546         curNode->MoveToNext();
547     }
548 }
549 
ParseGlobalConfigs(std::shared_ptr<AudioXmlNode> curNode)550 void AudioPolicyParser::ParseGlobalConfigs(std::shared_ptr<AudioXmlNode> curNode)
551 {
552     curNode->MoveToChildren();
553     while (curNode->IsNodeValid()) {
554         if (curNode->IsElementNode()) {
555             switch (GetGlobalConfigTypeAsInt(curNode)) {
556                 case GlobalConfigType::DEFAULT_OUTPUT:
557                     curNode->GetProp("adapter", globalConfigs_.adapter_);
558                     curNode->GetProp("pipe", globalConfigs_.pipe_);
559                     curNode->GetProp("device", globalConfigs_.device_);
560                     break;
561                 case GlobalConfigType::COMMON_CONFIGS:
562                     ParseCommonConfigs(curNode->GetCopyNode());
563                     break;
564                 case GlobalConfigType::PA_CONFIGS:
565                     ParsePAConfigs(curNode->GetCopyNode());
566                     break;
567                 case GlobalConfigType::DEFAULT_MAX_CON_CURRENT_INSTANCE:
568                     ParseDefaultMaxInstances(curNode->GetCopyNode());
569                     break;
570                 default:
571                     ParseGlobalConfigs(curNode->GetChildrenNode());
572                     break;
573             }
574         }
575         curNode->MoveToNext();
576     }
577 }
578 
GetGlobalConfigTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)579 GlobalConfigType AudioPolicyParser::GetGlobalConfigTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)
580 {
581     if (curNode->CompareName("defaultOutput")) {
582         return GlobalConfigType::DEFAULT_OUTPUT;
583     } else if (curNode->CompareName("commonConfigs")) {
584         return GlobalConfigType::COMMON_CONFIGS;
585     } else if (curNode->CompareName("paConfigs")) {
586         return GlobalConfigType::PA_CONFIGS;
587     } else if (curNode->CompareName("maxConcurrentInstances")) {
588         return GlobalConfigType::DEFAULT_MAX_CON_CURRENT_INSTANCE;
589     } else {
590         return GlobalConfigType::UNKNOWN;
591     }
592 }
593 
ParsePAConfigs(std::shared_ptr<AudioXmlNode> curNode)594 void AudioPolicyParser::ParsePAConfigs(std::shared_ptr<AudioXmlNode> curNode)
595 {
596     curNode->MoveToChildren();
597 
598     while (curNode->IsNodeValid()) {
599         if (curNode->IsElementNode()) {
600             std::string name;
601             std::string value;
602             curNode->GetProp("name", name);
603             curNode->GetProp("value", value);
604             uint64_t convertValue = 0;
605 
606             switch (GetPaConfigType(name)) {
607                 case PAConfigType::AUDIO_LATENCY:
608                     CHECK_AND_RETURN_LOG(StringConverter(value, convertValue),
609                         "convert invalid value: %{public}s", value.c_str());
610                     portObserver_.OnAudioLatencyParsed(convertValue);
611                     globalConfigs_.globalPaConfigs_.audioLatency_ = value;
612                     break;
613                 case PAConfigType::SINK_LATENCY:
614                     CHECK_AND_RETURN_LOG(StringConverter(value, convertValue),
615                         "convert invalid value: %{public}s", value.c_str());
616                     portObserver_.OnSinkLatencyParsed(convertValue);
617                     globalConfigs_.globalPaConfigs_.sinkLatency_ = value;
618                     break;
619                 default:
620                     ParsePAConfigs(curNode->GetChildrenNode());
621                     break;
622             }
623         }
624         curNode->MoveToNext();
625     }
626 }
627 
ParseDefaultMaxInstances(std::shared_ptr<AudioXmlNode> curNode)628 void AudioPolicyParser::ParseDefaultMaxInstances(std::shared_ptr<AudioXmlNode> curNode)
629 {
630     curNode->MoveToChildren();
631     while (curNode->IsNodeValid()) {
632         if (curNode->IsElementNode()) {
633             std::string sExtendInfo;
634             curNode->GetContent(sExtendInfo);
635             switch (GetDefaultMaxInstanceTypeAsInt(curNode)) {
636                 case DefaultMaxInstanceType::OUTPUT:
637                     ParseOutputMaxInstances(curNode->GetCopyNode());
638                     break;
639                 case DefaultMaxInstanceType::INPUT:
640                     ParseInputMaxInstances(curNode->GetCopyNode());
641                     break;
642                 default:
643                     ParseDefaultMaxInstances(curNode->GetChildrenNode());
644                     break;
645             }
646         }
647         curNode->MoveToNext();
648     }
649 }
650 
ParseOutputMaxInstances(std::shared_ptr<AudioXmlNode> curNode)651 void AudioPolicyParser::ParseOutputMaxInstances(std::shared_ptr<AudioXmlNode> curNode)
652 {
653     curNode->MoveToChildren();
654     std::list<ConfigInfo> configInfos;
655 
656     while (curNode->IsNodeValid()) {
657         if (curNode->IsElementNode()) {
658             ConfigInfo configInfo = {};
659             curNode->GetProp("name", configInfo.name_);
660             curNode->GetProp("flag", configInfo.type_);
661             curNode->GetProp("value", configInfo.value_);
662             configInfos.push_back(configInfo);
663         }
664         curNode->MoveToNext();
665     }
666     globalConfigs_.outputConfigInfos_ = configInfos;
667 }
668 
ParseInputMaxInstances(std::shared_ptr<AudioXmlNode> curNode)669 void AudioPolicyParser::ParseInputMaxInstances(std::shared_ptr<AudioXmlNode> curNode)
670 {
671     curNode->MoveToChildren();
672     std::list<ConfigInfo> configInfos;
673 
674     while (curNode->IsNodeValid()) {
675         if (curNode->IsElementNode()) {
676             ConfigInfo configInfo = {};
677             curNode->GetProp("name", configInfo.name_);
678             curNode->GetProp("flag", configInfo.type_);
679             curNode->GetProp("value", configInfo.value_);
680             configInfos.push_back(configInfo);
681         }
682         curNode->MoveToNext();
683     }
684     globalConfigs_.inputConfigInfos_ = configInfos;
685 }
686 
ParseCommonConfigs(std::shared_ptr<AudioXmlNode> curNode)687 void AudioPolicyParser::ParseCommonConfigs(std::shared_ptr<AudioXmlNode> curNode)
688 {
689     curNode->MoveToChildren();
690     std::list<ConfigInfo> configInfos;
691 
692     while (curNode->IsNodeValid()) {
693         if (curNode->IsElementNode()) {
694             ConfigInfo configInfo = {};
695             curNode->GetProp("name", configInfo.name_);
696             curNode->GetProp("value", configInfo.value_);
697             configInfos.push_back(configInfo);
698             if (configInfo.name_ == "updateRouteSupport") {
699                 AUDIO_INFO_LOG("update route support: %{public}s", configInfo.value_.c_str());
700                 HandleUpdateRouteSupportParsed(configInfo.value_);
701             } else if (configInfo.name_ == "anahsShowType") {
702                 AUDIO_INFO_LOG("anahs pc support: %{public}s", configInfo.value_.c_str());
703                 HandleUpdateAnahsSupportParsed(configInfo.value_);
704             } else if (configInfo.name_ == "setDefaultAdapter") {
705                 AUDIO_INFO_LOG("default adapter support: %{public}s", configInfo.value_.c_str());
706                 HandleDefaultAdapterSupportParsed(configInfo.value_);
707             }
708         }
709         curNode->MoveToNext();
710     }
711     globalConfigs_.commonConfigs_ = configInfos;
712 }
713 
HandleUpdateRouteSupportParsed(std::string & value)714 void AudioPolicyParser::HandleUpdateRouteSupportParsed(std::string &value)
715 {
716     if (value == "true") {
717         portObserver_.OnUpdateRouteSupport(true);
718         shouldOpenMicSpeaker_ = true;
719     } else {
720         portObserver_.OnUpdateRouteSupport(false);
721         shouldOpenMicSpeaker_ = false;
722     }
723 }
724 
HandleUpdateAnahsSupportParsed(std::string & value)725 void AudioPolicyParser::HandleUpdateAnahsSupportParsed(std::string &value)
726 {
727     std::string anahsShowType = "Dialog";
728     anahsShowType = value;
729     AUDIO_INFO_LOG("HandleUpdateAnahsSupportParsed show type: %{public}s", anahsShowType.c_str());
730     portObserver_.OnUpdateAnahsSupport(anahsShowType);
731 }
732 
HandleDefaultAdapterSupportParsed(std::string & value)733 void AudioPolicyParser::HandleDefaultAdapterSupportParsed(std::string &value)
734 {
735     if (value == "true") {
736         portObserver_.OnUpdateDefaultAdapter(true);
737         shouldSetDefaultAdapter_ = true;
738     } else {
739         portObserver_.OnUpdateDefaultAdapter(false);
740         shouldSetDefaultAdapter_ = false;
741     }
742 }
743 
GetXmlNodeTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)744 XmlNodeType AudioPolicyParser::GetXmlNodeTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)
745 {
746     if (curNode->CompareName("adapters")) {
747         return XmlNodeType::ADAPTERS;
748     } else if (curNode->CompareName("volumeGroups")) {
749         return XmlNodeType::VOLUME_GROUPS;
750     } else if (curNode->CompareName("interruptGroups")) {
751         return XmlNodeType::INTERRUPT_GROUPS;
752     } else if (curNode->CompareName("globalConfigs")) {
753         return XmlNodeType::GLOBAL_CONFIGS;
754     } else {
755         return XmlNodeType::XML_UNKNOWN;
756     }
757 }
758 
GetAdaptersType(const std::string & adapterName)759 AdaptersType AudioPolicyParser::GetAdaptersType(const std::string &adapterName)
760 {
761     if (adapterName == ADAPTER_PRIMARY_TYPE)
762         return AdaptersType::TYPE_PRIMARY;
763     else if (adapterName == ADAPTER_A2DP_TYPE)
764         return AdaptersType::TYPE_A2DP;
765     else if (adapterName == ADAPTER_REMOTE_TYPE)
766         return AdaptersType::TYPE_REMOTE_AUDIO;
767     else if (adapterName == ADAPTER_FILE_TYPE)
768         return AdaptersType::TYPE_FILE_IO;
769     else if (adapterName == ADAPTER_USB_TYPE)
770         return AdaptersType::TYPE_USB;
771     else if (adapterName == ADAPTER_DP_TYPE)
772         return AdaptersType::TYPE_DP;
773     else
774         return AdaptersType::TYPE_INVALID;
775 }
776 
GetPaConfigType(std::string & name)777 PAConfigType AudioPolicyParser::GetPaConfigType(std::string &name)
778 {
779     if (name =="audioLatency") {
780         return PAConfigType::AUDIO_LATENCY;
781     } else if (name =="sinkLatency") {
782         return PAConfigType::SINK_LATENCY;
783     } else {
784         return PAConfigType::UNKNOWN;
785     }
786 }
787 
GetDefaultMaxInstanceTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)788 DefaultMaxInstanceType AudioPolicyParser::GetDefaultMaxInstanceTypeAsInt(std::shared_ptr<AudioXmlNode> curNode)
789 {
790     if (curNode->CompareName("output")) {
791         return DefaultMaxInstanceType::OUTPUT;
792     } else if (curNode->CompareName("input")) {
793         return DefaultMaxInstanceType::INPUT;
794     } else {
795         return DefaultMaxInstanceType::UNKNOWN;
796     }
797 }
798 // LCOV_EXCL_STOP
799 } // namespace AudioStandard
800 } // namespace OHOS
801