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