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