1 /*
2 * Copyright (c) 2021-2022 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 #include "audio_concurrency_parser.h"
16
17 namespace OHOS {
18 namespace AudioStandard {
19
LoadConfig(std::map<std::pair<AudioPipeType,AudioPipeType>,ConcurrencyAction> & concurrencyMap)20 int32_t AudioConcurrencyParser::LoadConfig(std::map<std::pair<AudioPipeType, AudioPipeType>,
21 ConcurrencyAction> &concurrencyMap)
22 {
23 doc_ = xmlReadFile(AUDIO_CONCURRENCY_CONFIG_FILE, nullptr, 0);
24 CHECK_AND_RETURN_RET_LOG(doc_ != nullptr, ERR_OPERATION_FAILED, "xmlRead AudioConcurrencyConfigFile failed!");
25 xmlNode *root = xmlDocGetRootElement(doc_);
26 CHECK_AND_RETURN_RET_LOG(root != nullptr, ERR_OPERATION_FAILED, "xmlDocGetRootElement failed!");
27 if (xmlStrcmp(root->name, reinterpret_cast<const xmlChar*>("audioConcurrencyPolicy"))) {
28 AUDIO_ERR_LOG("Missing tag - audioConcurrencyPolicy");
29 xmlFreeDoc(doc_);
30 return ERR_OPERATION_FAILED;
31 }
32 ParseInternal(root, concurrencyMap);
33 return SUCCESS;
34 }
35
ParseInternal(xmlNode * node,std::map<std::pair<AudioPipeType,AudioPipeType>,ConcurrencyAction> & concurrencyMap)36 void AudioConcurrencyParser::ParseInternal(xmlNode *node, std::map<std::pair<AudioPipeType, AudioPipeType>,
37 ConcurrencyAction> &concurrencyMap)
38 {
39 xmlNode *curNode = node;
40 for (; curNode; curNode = curNode->next) {
41 if (curNode->type == XML_ELEMENT_NODE &&
42 !xmlStrcmp(curNode->name, reinterpret_cast<const xmlChar*>("existingStream"))) {
43 char *nodeName = reinterpret_cast<char*>(xmlGetProp(curNode,
44 reinterpret_cast<xmlChar*>(const_cast<char*>("name"))));
45 std::string existingStream = nodeName;
46 AUDIO_DEBUG_LOG("existingStream: %{public}s", existingStream.c_str());
47 ParseIncoming(existingStream, curNode->children, concurrencyMap);
48 } else {
49 ParseInternal((curNode->children), concurrencyMap);
50 }
51 }
52 return;
53 }
54
ParseIncoming(const std::string & existing,xmlNode * node,std::map<std::pair<AudioPipeType,AudioPipeType>,ConcurrencyAction> & concurrencyMap)55 void AudioConcurrencyParser::ParseIncoming(const std::string &existing, xmlNode *node,
56 std::map<std::pair<AudioPipeType, AudioPipeType>, ConcurrencyAction> &concurrencyMap)
57 {
58 xmlNode *incomingNode = node;
59 while (incomingNode != nullptr) {
60 if (incomingNode->type == XML_ELEMENT_NODE &&
61 !xmlStrcmp(incomingNode->name, reinterpret_cast<const xmlChar*>("incomingStream"))) {
62 char *incomingName = reinterpret_cast<char*>(xmlGetProp(incomingNode,
63 reinterpret_cast<xmlChar*>(const_cast<char*>("name"))));
64 char *actionName = reinterpret_cast<char*>(xmlGetProp(incomingNode,
65 reinterpret_cast<xmlChar*>(const_cast<char*>("action"))));
66 std::string incoming = incomingName;
67 std::string action = actionName;
68 AUDIO_DEBUG_LOG("existing: %{public}s %{public}d, incoming: %{public}s %{public}d, action: %{public}s",
69 existing.c_str(), audioPipeTypeMap_[existing], incoming.c_str(),
70 audioPipeTypeMap_[incoming], action.c_str());
71 std::pair<AudioPipeType, AudioPipeType> concurrencyPair =
72 std::make_pair(audioPipeTypeMap_[existing], audioPipeTypeMap_[incoming]);
73 ConcurrencyAction concurrencyAction = (action == "play both" || action == "mix") ? PLAY_BOTH :
74 (action == "concede existing" ? CONCEDE_EXISTING : CONCEDE_INCOMING);
75 concurrencyMap.emplace(concurrencyPair, concurrencyAction);
76 xmlFree(incomingName);
77 xmlFree(actionName);
78 }
79 incomingNode = incomingNode->next;
80 }
81 }
82 } // namespace AudioStandard
83 } // namespace OHOS