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 "AudioDeviceParser"
17 #endif
18
19 #include "audio_device_parser.h"
20 #include "media_monitor_manager.h"
21
22 namespace OHOS {
23 namespace AudioStandard {
LoadConfiguration()24 bool AudioDeviceParser::LoadConfiguration()
25 {
26 mDoc_ = xmlReadFile(DEVICE_CONFIG_FILE, nullptr, 0);
27 if (mDoc_ == 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_DEVICE_PRIVACY);
32 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
33 }
34 CHECK_AND_RETURN_RET_LOG(mDoc_ != nullptr, false,
35 "xmlReadFile Failed");
36
37 return true;
38 }
39
Parse()40 bool AudioDeviceParser::Parse()
41 {
42 xmlNode *root = xmlDocGetRootElement(mDoc_);
43 CHECK_AND_RETURN_RET_LOG(root != nullptr, false,
44 "xmlDocGetRootElement Failed");
45
46 if (!ParseInternal(root)) {
47 return false;
48 }
49 audioDeviceManager_->OnXmlParsingCompleted(devicePrivacyMaps_);
50 return true;
51 }
52
Destroy()53 void AudioDeviceParser::Destroy()
54 {
55 if (mDoc_ != nullptr) {
56 xmlFreeDoc(mDoc_);
57 }
58 }
59
ParseInternal(xmlNode * node)60 bool AudioDeviceParser::ParseInternal(xmlNode *node)
61 {
62 xmlNode *currNode = node;
63 for (; currNode; currNode = currNode->next) {
64 if (XML_ELEMENT_NODE == currNode->type) {
65 switch (GetDeviceNodeNameAsInt(currNode)) {
66 case ADAPTER:
67 ParseAudioDevicePrivacyType(currNode, devicePrivacyType_);
68 break;
69 default:
70 ParseInternal((currNode->xmlChildrenNode));
71 break;
72 }
73 }
74 }
75 return true;
76 }
77
ParseDevicePrivacyInfo(xmlNode * node,std::list<DevicePrivacyInfo> & deviceLists)78 void AudioDeviceParser::ParseDevicePrivacyInfo(xmlNode *node, std::list<DevicePrivacyInfo> &deviceLists)
79 {
80 xmlNode *deviceNode = node;
81
82 while (deviceNode != nullptr) {
83 if (deviceNode->type == XML_ELEMENT_NODE) {
84 DevicePrivacyInfo deviceInfo = {};
85 char *pValue = reinterpret_cast<char*>(xmlGetProp(deviceNode,
86 reinterpret_cast<xmlChar*>(const_cast<char*>("name"))));
87 deviceInfo.deviceName = pValue;
88 xmlFree(pValue);
89
90 pValue = reinterpret_cast<char*>(xmlGetProp(deviceNode,
91 reinterpret_cast<xmlChar*>(const_cast<char*>("type"))));
92 deviceInfo.deviceType = deviceTypeMap_[pValue];
93 xmlFree(pValue);
94
95 pValue = reinterpret_cast<char*>(xmlGetProp(deviceNode,
96 reinterpret_cast<xmlChar*>(const_cast<char*>("role"))));
97 uint32_t intValue = 0;
98 ParseDeviceRole(pValue, intValue);
99 deviceInfo.deviceRole = static_cast<DeviceRole>(intValue);
100 xmlFree(pValue);
101
102 pValue = reinterpret_cast<char*>(xmlGetProp(deviceNode,
103 reinterpret_cast<xmlChar*>(const_cast<char*>("Category"))));
104 intValue = 0;
105 ParseDeviceCategory(pValue, intValue);
106 deviceInfo.deviceCategory = static_cast<DeviceCategory>(intValue);
107 xmlFree(pValue);
108
109 pValue = reinterpret_cast<char*>(xmlGetProp(deviceNode,
110 reinterpret_cast<xmlChar*>(const_cast<char*>("usage"))));
111 intValue = 0;
112 ParseDeviceUsage(pValue, intValue);
113 deviceInfo.deviceUsage = static_cast<DeviceUsage>(intValue);
114 xmlFree(pValue);
115 deviceLists.push_back(deviceInfo);
116 AUDIO_DEBUG_LOG("AudioDeviceParser: name:%{public}s, type:%{public}d, role:%{public}d, Category:%{public}d,"
117 "Usage:%{public}d", deviceInfo.deviceName.c_str(), deviceInfo.deviceType, deviceInfo.deviceRole,
118 deviceInfo.deviceCategory, deviceInfo.deviceUsage);
119 }
120 deviceNode = deviceNode->next;
121 }
122 }
123
ParserDevicePrivacyInfoList(xmlNode * node,std::list<DevicePrivacyInfo> & deviceLists)124 void AudioDeviceParser::ParserDevicePrivacyInfoList(xmlNode *node, std::list<DevicePrivacyInfo> &deviceLists)
125 {
126 xmlNode *currentNode = node;
127 while (currentNode != nullptr) {
128 if (currentNode->type == XML_ELEMENT_NODE
129 && (!xmlStrcmp(currentNode->name, reinterpret_cast<const xmlChar*>("devices")))) {
130 ParseDevicePrivacyInfo(currentNode->xmlChildrenNode, deviceLists);
131 }
132 currentNode = currentNode->next;
133 }
134 }
135
ParseAudioDevicePrivacyType(xmlNode * node,AudioDevicePrivacyType & deviceType)136 void AudioDeviceParser::ParseAudioDevicePrivacyType(xmlNode *node, AudioDevicePrivacyType &deviceType)
137 {
138 xmlNode *currNode = node;
139 while (currNode != nullptr) {
140 //read deviceType
141 if (currNode->type == XML_ELEMENT_NODE &&
142 (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("adapter")))) {
143 std::string adapterName = ExtractPropertyValue("name", currNode);
144 if (adapterName.empty()) {
145 AUDIO_ERR_LOG("AudioDeviceParser: No name provided for the adapter %{public}s", node->name);
146 return;
147 } else {
148 AUDIO_DEBUG_LOG("AudioDeviceParser: adapter name: %{public}s", adapterName.c_str());
149 devicePrivacyType_ = GetDevicePrivacyType(adapterName);
150 std::list<DevicePrivacyInfo> deviceLists = {};
151 ParserDevicePrivacyInfoList(currNode->xmlChildrenNode, deviceLists);
152 devicePrivacyMaps_[devicePrivacyType_] = deviceLists;
153 }
154 } else {
155 return;
156 }
157 currNode = currNode->next;
158 }
159 }
160
GetDevicePrivacyType(const std::string & devicePrivacyType)161 AudioDevicePrivacyType AudioDeviceParser::GetDevicePrivacyType(const std::string &devicePrivacyType)
162 {
163 if (devicePrivacyType == PRIVACY_TYPE) {
164 return AudioDevicePrivacyType::TYPE_PRIVACY;
165 } else if (devicePrivacyType == PUBLIC_TYPE) {
166 return AudioDevicePrivacyType::TYPE_PUBLIC;
167 } else {
168 return AudioDevicePrivacyType::TYPE_NEGATIVE;
169 }
170 }
171
ExtractPropertyValue(const std::string & propName,xmlNode * node)172 std::string AudioDeviceParser::ExtractPropertyValue(const std::string &propName, xmlNode *node)
173 {
174 std::string propValue = "";
175 xmlChar *tempValue = nullptr;
176
177 if (xmlHasProp(node, reinterpret_cast<const xmlChar*>(propName.c_str()))) {
178 tempValue = xmlGetProp(node, reinterpret_cast<const xmlChar*>(propName.c_str()));
179 }
180
181 if (tempValue != nullptr) {
182 propValue = reinterpret_cast<const char*>(tempValue);
183 xmlFree(tempValue);
184 }
185
186 return propValue;
187 }
188
GetDeviceNodeNameAsInt(xmlNode * node)189 DeviceNodeName AudioDeviceParser::GetDeviceNodeNameAsInt(xmlNode *node)
190 {
191 if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("adapter"))) {
192 return DeviceNodeName::ADAPTER;
193 } else {
194 return DeviceNodeName::UNKNOWN_NODE;
195 }
196 }
197
split(const std::string & line,const std::string & sep)198 std::vector<std::string> split(const std::string &line, const std::string &sep)
199 {
200 std::vector<std::string> buf;
201 size_t temp = 0;
202 std::string::size_type pos = 0;
203 while (true) {
204 pos = line.find(sep, temp);
205 if (pos == std::string::npos) {
206 break;
207 }
208 buf.push_back(line.substr(temp, pos-temp));
209 temp = pos + sep.length();
210 }
211 buf.push_back(line.substr(temp, line.length()));
212 return buf;
213 }
214
ParseDeviceRole(const std::string & deviceRole,uint32_t & deviceRoleFlag)215 void AudioDeviceParser::ParseDeviceRole(const std::string &deviceRole, uint32_t &deviceRoleFlag)
216 {
217 std::vector<std::string> buf = split(deviceRole, ",");
218 for (const auto &role : buf) {
219 if (role == "output") {
220 deviceRoleFlag |= DeviceRole::OUTPUT_DEVICE;
221 } else if (role == "input") {
222 deviceRoleFlag |= DeviceRole::INPUT_DEVICE;
223 }
224 }
225 }
226
ParseDeviceCategory(const std::string & deviceCategory,uint32_t & deviceCategoryFlag)227 void AudioDeviceParser::ParseDeviceCategory(const std::string &deviceCategory, uint32_t &deviceCategoryFlag)
228 {
229 std::vector<std::string> buf = split(deviceCategory, ",");
230 for (const auto &category : buf) {
231 if (category == "HEADPHONE") {
232 deviceCategoryFlag |= DeviceCategory::BT_HEADPHONE;
233 } else if (category == "GLASSES") {
234 deviceCategoryFlag |= DeviceCategory::BT_GLASSES;
235 } else if (category == "SOUNDBOX") {
236 deviceCategoryFlag |= DeviceCategory::BT_SOUNDBOX;
237 } else if (category == "CAR") {
238 deviceCategoryFlag |= DeviceCategory::BT_CAR;
239 } else if (category == "HEADPHONE_UNWEAR") {
240 deviceCategoryFlag |= DeviceCategory::BT_UNWEAR_HEADPHONE;
241 } else if (category == "WATCH") {
242 deviceCategoryFlag |= DeviceCategory::BT_WATCH;
243 }
244 }
245 }
246
ParseDeviceUsage(const std::string & deviceUsage,uint32_t & deviceUsageFlag)247 void AudioDeviceParser::ParseDeviceUsage(const std::string &deviceUsage, uint32_t &deviceUsageFlag)
248 {
249 std::vector<std::string> buf = split(deviceUsage, ",");
250 for (const auto &usage : buf) {
251 if (usage == "media") {
252 deviceUsageFlag |= DeviceUsage::MEDIA;
253 } else if (usage == "voice") {
254 deviceUsageFlag |= DeviceUsage::VOICE;
255 } else if (usage == "recongnition") {
256 deviceUsageFlag |= DeviceUsage::RECOGNITION;
257 }
258 }
259 }
260 } // namespace AudioStandard
261 } // namespace OHOS