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