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 #include "audio_errors.h"
22 #include "config_policy_utils.h"
23
24 namespace OHOS {
25 namespace AudioStandard {
26 namespace {
27 static std::map<std::string, DeviceType> deviceTypeMap_ = {
28 {"DEVICE_TYPE_WIRED_HEADSET", DEVICE_TYPE_WIRED_HEADSET},
29 {"DEVICE_TYPE_WIRED_HEADPHONES", DEVICE_TYPE_WIRED_HEADPHONES},
30 {"DEVICE_TYPE_BLUETOOTH_SCO", DEVICE_TYPE_BLUETOOTH_SCO},
31 {"DEVICE_TYPE_BLUETOOTH_A2DP", DEVICE_TYPE_BLUETOOTH_A2DP},
32 {"DEVICE_TYPE_BLUETOOTH_A2DP_IN", DEVICE_TYPE_BLUETOOTH_A2DP_IN},
33 {"DEVICE_TYPE_USB_HEADSET", DEVICE_TYPE_USB_HEADSET},
34 {"DEVICE_TYPE_DP", DEVICE_TYPE_DP},
35 {"DEVICE_TYPE_HDMI", DEVICE_TYPE_HDMI},
36 {"DEVICE_TYPE_LINE_DIGITAL", DEVICE_TYPE_LINE_DIGITAL},
37 {"DEVICE_TYPE_USB_ARM_HEADSET", DEVICE_TYPE_USB_ARM_HEADSET},
38 {"DEVICE_TYPE_HDMI", DEVICE_TYPE_HDMI},
39 };
40 }
LoadConfiguration()41 bool AudioDeviceParser::LoadConfiguration()
42 {
43 char buf[MAX_PATH_LEN];
44 char *path = GetOneCfgFile(DEVICE_CONFIG_FILE, buf, MAX_PATH_LEN);
45 CHECK_AND_RETURN_RET_LOG(path != nullptr && *path != '\0', ERROR, "invalid path!");
46 curNode_ = AudioXmlNode::Create();
47 int32_t ret = curNode_->Config(path, nullptr, 0);
48 if (ret != SUCCESS) {
49 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
50 Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_CONFIG_ERROR,
51 Media::MediaMonitor::FAULT_EVENT);
52 bean->Add("CATEGORY", Media::MediaMonitor::AUDIO_DEVICE_PRIVACY);
53 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
54 }
55 CHECK_AND_RETURN_RET_LOG(curNode_->IsNodeValid(), false, "xmlReadFile Failed");
56 if (!ParseInternal(curNode_->GetCopyNode())) {
57 return false;
58 }
59 audioDeviceManager_->OnXmlParsingCompleted(devicePrivacyMaps_);
60 return true;
61 }
62
Destroy()63 void AudioDeviceParser::Destroy()
64 {
65 curNode_->FreeDoc();
66 }
67
ParseInternal(std::shared_ptr<AudioXmlNode> curNode)68 bool AudioDeviceParser::ParseInternal(std::shared_ptr<AudioXmlNode> curNode)
69 {
70 for (; curNode->IsNodeValid(); curNode->MoveToNext()) {
71 if (curNode->IsElementNode()) {
72 switch (GetDeviceNodeNameAsInt(curNode)) {
73 case ADAPTER:
74 ParseAudioDevicePrivacyType(curNode->GetCopyNode(), devicePrivacyType_);
75 break;
76 default:
77 ParseInternal(curNode->GetChildrenNode());
78 break;
79 }
80 }
81 }
82 return true;
83 }
84
ParseDevicePrivacyInfo(std::shared_ptr<AudioXmlNode> curNode,std::list<DevicePrivacyInfo> & deviceLists)85 void AudioDeviceParser::ParseDevicePrivacyInfo(std::shared_ptr<AudioXmlNode> curNode,
86 std::list<DevicePrivacyInfo> &deviceLists)
87 {
88 while (curNode->IsNodeValid()) {
89 if (curNode->IsElementNode()) {
90 DevicePrivacyInfo deviceInfo = {};
91 curNode->GetProp("name", deviceInfo.deviceName);
92
93 std::string pValue;
94 curNode->GetProp("type", pValue);
95 deviceInfo.deviceType = deviceTypeMap_[pValue];
96
97 curNode->GetProp("role", pValue);
98 uint32_t intValue = 0;
99 ParseDeviceRole(pValue, intValue);
100 deviceInfo.deviceRole = static_cast<DeviceRole>(intValue);
101
102 curNode->GetProp("Category", pValue);
103 intValue = 0;
104 ParseDeviceCategory(pValue, intValue);
105 deviceInfo.deviceCategory = static_cast<DeviceCategory>(intValue);
106
107 curNode->GetProp("usage", pValue);
108 intValue = 0;
109 ParseDeviceUsage(pValue, intValue);
110 deviceInfo.deviceUsage = static_cast<DeviceUsage>(intValue);
111
112 deviceLists.push_back(deviceInfo);
113 AUDIO_DEBUG_LOG("AudioDeviceParser: name:%{public}s, type:%{public}d, role:%{public}d, Category:%{public}d,"
114 "Usage:%{public}d", deviceInfo.deviceName.c_str(), deviceInfo.deviceType, deviceInfo.deviceRole,
115 deviceInfo.deviceCategory, deviceInfo.deviceUsage);
116 }
117 curNode->MoveToNext();
118 }
119 }
120
ParserDevicePrivacyInfoList(std::shared_ptr<AudioXmlNode> curNode,std::list<DevicePrivacyInfo> & deviceLists)121 void AudioDeviceParser::ParserDevicePrivacyInfoList(std::shared_ptr<AudioXmlNode> curNode,
122 std::list<DevicePrivacyInfo> &deviceLists)
123 {
124 while (curNode->IsNodeValid()) {
125 if (curNode->CompareName("devices")) {
126 ParseDevicePrivacyInfo(curNode->GetChildrenNode(), deviceLists);
127 }
128 curNode->MoveToNext();
129 }
130 }
131
ParseAudioDevicePrivacyType(std::shared_ptr<AudioXmlNode> curNode,AudioDevicePrivacyType & deviceType)132 void AudioDeviceParser::ParseAudioDevicePrivacyType(std::shared_ptr<AudioXmlNode> curNode,
133 AudioDevicePrivacyType &deviceType)
134 {
135 while (curNode->IsNodeValid()) {
136 //read deviceType
137 if (curNode->CompareName("adapter")) {
138 std::string adapterName;
139 CHECK_AND_RETURN_LOG(curNode->GetProp("name", adapterName) == SUCCESS, "get prop adapterName fail!");
140 AUDIO_DEBUG_LOG("AudioDeviceParser: adapter name: %{public}s", adapterName.c_str());
141 devicePrivacyType_ = GetDevicePrivacyType(adapterName);
142 std::list<DevicePrivacyInfo> deviceLists = {};
143
144 ParserDevicePrivacyInfoList(curNode->GetChildrenNode(), deviceLists);
145 devicePrivacyMaps_[devicePrivacyType_] = deviceLists;
146 } else {
147 return;
148 }
149 curNode->MoveToNext();
150 }
151 }
152
GetDevicePrivacyType(const std::string & devicePrivacyType)153 AudioDevicePrivacyType AudioDeviceParser::GetDevicePrivacyType(const std::string &devicePrivacyType)
154 {
155 if (devicePrivacyType == PRIVACY_TYPE) {
156 return AudioDevicePrivacyType::TYPE_PRIVACY;
157 } else if (devicePrivacyType == PUBLIC_TYPE) {
158 return AudioDevicePrivacyType::TYPE_PUBLIC;
159 } else {
160 return AudioDevicePrivacyType::TYPE_NEGATIVE;
161 }
162 }
163
GetDeviceNodeNameAsInt(std::shared_ptr<AudioXmlNode> curNode)164 DeviceNodeName AudioDeviceParser::GetDeviceNodeNameAsInt(std::shared_ptr<AudioXmlNode> curNode)
165 {
166 if (curNode->CompareName("adapter")) {
167 return DeviceNodeName::ADAPTER;
168 } else {
169 return DeviceNodeName::UNKNOWN_NODE;
170 }
171 }
172
split(const std::string & line,const std::string & sep)173 std::vector<std::string> split(const std::string &line, const std::string &sep)
174 {
175 std::vector<std::string> buf;
176 size_t temp = 0;
177 std::string::size_type pos = 0;
178 while (true) {
179 pos = line.find(sep, temp);
180 if (pos == std::string::npos) {
181 break;
182 }
183 buf.push_back(line.substr(temp, pos-temp));
184 temp = pos + sep.length();
185 }
186 buf.push_back(line.substr(temp, line.length()));
187 return buf;
188 }
189
ParseDeviceRole(const std::string & deviceRole,uint32_t & deviceRoleFlag)190 void AudioDeviceParser::ParseDeviceRole(const std::string &deviceRole, uint32_t &deviceRoleFlag)
191 {
192 std::vector<std::string> buf = split(deviceRole, ",");
193 for (const auto &role : buf) {
194 if (role == "output") {
195 deviceRoleFlag |= DeviceRole::OUTPUT_DEVICE;
196 } else if (role == "input") {
197 deviceRoleFlag |= DeviceRole::INPUT_DEVICE;
198 }
199 }
200 }
201
ParseDeviceCategory(const std::string & deviceCategory,uint32_t & deviceCategoryFlag)202 void AudioDeviceParser::ParseDeviceCategory(const std::string &deviceCategory, uint32_t &deviceCategoryFlag)
203 {
204 std::vector<std::string> buf = split(deviceCategory, ",");
205 for (const auto &category : buf) {
206 if (category == "HEADPHONE") {
207 deviceCategoryFlag |= DeviceCategory::BT_HEADPHONE;
208 } else if (category == "GLASSES") {
209 deviceCategoryFlag |= DeviceCategory::BT_GLASSES;
210 } else if (category == "SOUNDBOX") {
211 deviceCategoryFlag |= DeviceCategory::BT_SOUNDBOX;
212 } else if (category == "CAR") {
213 deviceCategoryFlag |= DeviceCategory::BT_CAR;
214 } else if (category == "HEADPHONE_UNWEAR") {
215 deviceCategoryFlag |= DeviceCategory::BT_UNWEAR_HEADPHONE;
216 } else if (category == "WATCH") {
217 deviceCategoryFlag |= DeviceCategory::BT_WATCH;
218 }
219 }
220 }
221
ParseDeviceUsage(const std::string & deviceUsage,uint32_t & deviceUsageFlag)222 void AudioDeviceParser::ParseDeviceUsage(const std::string &deviceUsage, uint32_t &deviceUsageFlag)
223 {
224 std::vector<std::string> buf = split(deviceUsage, ",");
225 for (const auto &usage : buf) {
226 if (usage == "media") {
227 deviceUsageFlag |= DeviceUsage::MEDIA;
228 } else if (usage == "voice") {
229 deviceUsageFlag |= DeviceUsage::VOICE;
230 } else if (usage == "recongnition") {
231 deviceUsageFlag |= DeviceUsage::RECOGNITION;
232 }
233 }
234 }
235 } // namespace AudioStandard
236 } // namespace OHOS