1 /*
2 * Copyright (c) 2023 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 "AudioUsageStrategyParser"
17 #endif
18
19 #include "audio_usage_strategy_parser.h"
20 #include "media_monitor_manager.h"
21
22 namespace OHOS {
23 namespace AudioStandard {
LoadConfiguration()24 bool AudioUsageStrategyParser::LoadConfiguration()
25 {
26 doc_ = xmlReadFile(DEVICE_CONFIG_FILE, nullptr, 0);
27 if (doc_ == nullptr) {
28 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
29 Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_CONFIG_ERROR,
30 Media::MediaMonitor::FAULT_EVENT);
31 bean->Add("CATEGORY", Media::MediaMonitor::AUDIO_USAGE_STRATEGY);
32 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
33 }
34 CHECK_AND_RETURN_RET_LOG(doc_ != nullptr, false, "xmlReadFile failed");
35
36 return true;
37 }
38
Parse()39 bool AudioUsageStrategyParser::Parse()
40 {
41 xmlNode *root = xmlDocGetRootElement(doc_);
42 CHECK_AND_RETURN_RET_LOG(root != nullptr, false, "xmlDocGetRootElement Failed");
43
44 if (!ParseInternal(root)) {
45 return false;
46 }
47 return true;
48 }
49
Destroy()50 void AudioUsageStrategyParser::Destroy()
51 {
52 if (doc_ != nullptr) {
53 xmlFreeDoc(doc_);
54 }
55 }
56
ParseInternal(xmlNode * node)57 bool AudioUsageStrategyParser::ParseInternal(xmlNode *node)
58 {
59 xmlNode *currNode = node;
60 for (; currNode; currNode = currNode->next) {
61 if (XML_ELEMENT_NODE == currNode->type &&
62 (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("adapter")))) {
63 char *pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
64 reinterpret_cast<xmlChar*>(const_cast<char*>("name"))));
65 if (strcmp(pValue, "streamUsage") == 0) {
66 ParserStreamUsageList(currNode->xmlChildrenNode);
67 } else if (strcmp(pValue, "sourceType") == 0) {
68 ParserSourceTypeList(currNode->xmlChildrenNode);
69 }
70 } else {
71 ParseInternal((currNode->xmlChildrenNode));
72 }
73 }
74 return true;
75 }
76
ParserStreamUsageList(xmlNode * node)77 void AudioUsageStrategyParser::ParserStreamUsageList(xmlNode *node)
78 {
79 xmlNode *strategyNode = node;
80 while (strategyNode != nullptr) {
81 if (strategyNode->type == XML_ELEMENT_NODE &&
82 (!xmlStrcmp(strategyNode->name, reinterpret_cast<const xmlChar*>("strategy")))) {
83 char *strategyName = reinterpret_cast<char*>(xmlGetProp(strategyNode,
84 reinterpret_cast<xmlChar*>(const_cast<char*>("name"))));
85
86 char *streamUsages = reinterpret_cast<char*>(xmlGetProp(strategyNode,
87 reinterpret_cast<xmlChar*>(const_cast<char*>("streamUsage"))));
88 ParserStreamUsageInfo(strategyName, streamUsages);
89 xmlFree(strategyName);
90 xmlFree(streamUsages);
91 }
92 strategyNode = strategyNode->next;
93 }
94 }
95
ParserSourceTypeList(xmlNode * node)96 void AudioUsageStrategyParser::ParserSourceTypeList(xmlNode *node)
97 {
98 xmlNode *strategyNode = node;
99 while (strategyNode != nullptr) {
100 if (strategyNode->type == XML_ELEMENT_NODE &&
101 (!xmlStrcmp(strategyNode->name, reinterpret_cast<const xmlChar*>("strategy")))) {
102 char *strategyName = reinterpret_cast<char*>(xmlGetProp(strategyNode,
103 reinterpret_cast<xmlChar*>(const_cast<char*>("name"))));
104 char *sourceTypes = reinterpret_cast<char*>(xmlGetProp(strategyNode,
105 reinterpret_cast<xmlChar*>(const_cast<char*>("sourceType"))));
106 ParserSourceTypeInfo(strategyName, sourceTypes);
107 xmlFree(strategyName);
108 xmlFree(sourceTypes);
109 }
110 strategyNode = strategyNode->next;
111 }
112 }
113
split(const std::string & line,const std::string & sep)114 std::vector<std::string> AudioUsageStrategyParser::split(const std::string &line, const std::string &sep)
115 {
116 std::vector<std::string> buf;
117 size_t temp = 0;
118 std::string::size_type pos = 0;
119 while (true) {
120 pos = line.find(sep, temp);
121 if (pos == std::string::npos) {
122 break;
123 }
124 buf.push_back(line.substr(temp, pos-temp));
125 temp = pos + sep.length();
126 }
127 buf.push_back(line.substr(temp, line.length()));
128 return buf;
129 }
130
ParserStreamUsage(const std::vector<std::string> & buf,const std::string & routerName)131 void AudioUsageStrategyParser::ParserStreamUsage(const std::vector<std::string> &buf,
132 const std::string &routerName)
133 {
134 StreamUsage usage;
135 for (auto &name : buf) {
136 auto pos = streamUsageMap.find(name);
137 if (pos != streamUsageMap.end()) {
138 usage = pos->second;
139 }
140 renderConfigMap_[usage] = routerName;
141 }
142 }
143
ParserStreamUsageInfo(const std::string & strategyName,const std::string & streamUsage)144 void AudioUsageStrategyParser::ParserStreamUsageInfo(const std::string &strategyName,
145 const std::string &streamUsage)
146 {
147 std::vector<std::string> buf = split(streamUsage, ",");
148 if (strategyName == "MEDIA_RENDER") {
149 ParserStreamUsage(buf, "MediaRenderRouters");
150 } else if (strategyName == "CALL_RENDER") {
151 ParserStreamUsage(buf, "CallRenderRouters");
152 } else if (strategyName == "RING_RENDER") {
153 ParserStreamUsage(buf, "RingRenderRouters");
154 } else if (strategyName == "TONE_RENDER") {
155 ParserStreamUsage(buf, "ToneRenderRouters");
156 }
157 }
158
ParserSourceTypes(const std::vector<std::string> & buf,const std::string & sourceTypes)159 void AudioUsageStrategyParser::ParserSourceTypes(const std::vector<std::string> &buf,
160 const std::string &sourceTypes)
161 {
162 SourceType sourceType;
163 for (auto &name : buf) {
164 auto pos = sourceTypeMap.find(name);
165 if (pos != sourceTypeMap.end()) {
166 sourceType = pos->second;
167 }
168 capturerConfigMap_[sourceType] = sourceTypes;
169 }
170 }
171
ParserSourceTypeInfo(const std::string & strategyName,const std::string & sourceTypes)172 void AudioUsageStrategyParser::ParserSourceTypeInfo(const std::string &strategyName, const std::string &sourceTypes)
173 {
174 std::vector<std::string> buf = split(sourceTypes, ",");
175 if (strategyName == "RECORD_CAPTURE") {
176 ParserSourceTypes(buf, "RecordCaptureRouters");
177 } else if (strategyName == "CALL_CAPTURE") {
178 ParserSourceTypes(buf, "CallCaptureRouters");
179 } else if (strategyName == "VOICE_MESSAGE") {
180 ParserSourceTypes(buf, "VoiceMessages");
181 }
182 }
183 } // namespace AudioStandard
184 } // namespace OHOS
185