• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "audio_volume_parser.h"
16 #ifdef USB_CONFIG_POLICY
17 #include "config_policy_utils.h"
18 #endif
19 
20 namespace OHOS {
21 namespace AudioStandard {
AudioVolumeParser()22 AudioVolumeParser::AudioVolumeParser()
23 {
24     AUDIO_INFO_LOG("AudioVolumeParser ctor");
25     audioStreamMap_ = {
26         {"VOICE_CALL", STREAM_VOICE_CALL},
27         {"MUSIC", STREAM_MUSIC},
28         {"RING", STREAM_RING},
29         {"VOICE_ASSISTANT", STREAM_VOICE_ASSISTANT},
30         {"ALARM", STREAM_ALARM},
31         {"ACCESSIBILITY", STREAM_ACCESSIBILITY},
32         {"ULTRASONIC", STREAM_ULTRASONIC},
33     };
34 
35     audioDeviceMap_ = {
36         {"earpiece", EARPIECE_VOLUME_TYPE},
37         {"speaker", SPEAKER_VOLUME_TYPE},
38         {"headset", HEADSET_VOLUME_TYPE},
39     };
40 }
41 
~AudioVolumeParser()42 AudioVolumeParser::~AudioVolumeParser()
43 {
44     AUDIO_INFO_LOG("AudioVolumeParser dtor");
45 }
46 
ParseVolumeConfig(const char * path,StreamVolumeInfoMap & streamVolumeInfoMap)47 int32_t AudioVolumeParser::ParseVolumeConfig(const char *path, StreamVolumeInfoMap &streamVolumeInfoMap)
48 {
49     xmlDoc *doc = nullptr;
50     xmlNode *rootElement = nullptr;
51     if ((doc = xmlReadFile(path, nullptr, 0)) == nullptr) {
52         AUDIO_ERR_LOG("could not parse file %{public}s", path);
53         return ERROR;
54     }
55     rootElement = xmlDocGetRootElement(doc);
56     xmlNode *currNode = rootElement;
57     CHECK_AND_RETURN_RET_LOG(currNode != nullptr, ERROR, "root element is null");
58     if (xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("audio_volume_config"))) {
59         AUDIO_ERR_LOG("Missing tag - audio_volume_config in : %s", path);
60         xmlFreeDoc(doc);
61         xmlCleanupParser();
62         return ERROR;
63     }
64     if (currNode->children) {
65         currNode = currNode->children;
66     } else {
67         AUDIO_ERR_LOG("empty volume config in : %s", path);
68         xmlFreeDoc(doc);
69         xmlCleanupParser();
70         return ERROR;
71     }
72 
73     while (currNode != nullptr) {
74         if ((currNode->type == XML_ELEMENT_NODE) &&
75             (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("volume_type")))) {
76             ParseStreamInfos(currNode, streamVolumeInfoMap);
77             break;
78         } else {
79             currNode = currNode->next;
80         }
81     }
82 
83     xmlFreeDoc(doc);
84     xmlCleanupParser();
85     return SUCCESS;
86 }
87 
LoadConfig(StreamVolumeInfoMap & streamVolumeInfoMap)88 int32_t AudioVolumeParser::LoadConfig(StreamVolumeInfoMap &streamVolumeInfoMap)
89 {
90     AUDIO_INFO_LOG("Load Volume Config xml");
91     int ret = ERROR;
92 #ifdef USB_CONFIG_POLICY
93     CfgFiles *cfgFiles = GetCfgFiles(AUDIO_VOLUME_CONFIG_FILE);
94     if (cfgFiles == nullptr) {
95         AUDIO_ERR_LOG("Not found audio_volume_config.xml!");
96         return ERROR;
97     }
98 
99     for (int32_t i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) {
100         if (cfgFiles->paths[i] && *(cfgFiles->paths[i]) != '\0') {
101             AUDIO_INFO_LOG("volume config file path:%{public}s", cfgFiles->paths[i]);
102             ret = ParseVolumeConfig(cfgFiles->paths[i], streamVolumeInfoMap);
103             break;
104         }
105     }
106     FreeCfgFiles(cfgFiles);
107 #else
108     ret = ParseVolumeConfig(AUDIO_VOLUME_CONFIG_FILE, streamVolumeInfoMap);
109     AUDIO_INFO_LOG("use default volume config file path:%{public}s", AUDIO_VOLUME_CONFIG_FILE);
110 #endif
111     return ret;
112 }
113 
ParseStreamInfos(xmlNode * node,StreamVolumeInfoMap & streamVolumeInfoMap)114 void AudioVolumeParser::ParseStreamInfos(xmlNode *node, StreamVolumeInfoMap &streamVolumeInfoMap)
115 {
116     xmlNode *currNode = node;
117     AUDIO_DEBUG_LOG("AudioVolumeParser::ParseStreamInfos");
118     while (currNode) {
119         if (currNode->type == XML_ELEMENT_NODE
120             && (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("volume_type")))) {
121             std::shared_ptr<StreamVolumeInfo> streamVolInfo = std::make_shared<StreamVolumeInfo>();
122             ParseStreamVolumeInfoAttr(currNode, streamVolInfo);
123             ParseDeviceVolumeInfos(currNode->children, streamVolInfo);
124             AUDIO_DEBUG_LOG("Parse streamType:%{public}d ", streamVolInfo->streamType);
125             streamVolumeInfoMap[streamVolInfo->streamType] = streamVolInfo;
126         }
127         currNode = currNode->next;
128     }
129 }
130 
ParseStreamVolumeInfoAttr(xmlNode * node,std::shared_ptr<StreamVolumeInfo> & streamVolInfo)131 void AudioVolumeParser::ParseStreamVolumeInfoAttr(xmlNode *node, std::shared_ptr<StreamVolumeInfo> &streamVolInfo)
132 {
133     xmlNode *currNode = node;
134     AUDIO_DEBUG_LOG("AudioVolumeParser::ParseStreamVolumeInfoAttr");
135     char *pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
136         reinterpret_cast<xmlChar*>(const_cast<char*>("type"))));
137     streamVolInfo->streamType = audioStreamMap_[pValue];
138     AUDIO_DEBUG_LOG("stream type: %{public}s; currNode->name %{public}s;", pValue, currNode->name);
139     xmlFree(pValue);
140 
141     pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
142         reinterpret_cast<xmlChar*>(const_cast<char*>("minidx"))));
143     streamVolInfo->minLevel = atoi(pValue);
144     AUDIO_DEBUG_LOG("minidx: %{public}d", atoi(pValue));
145     xmlFree(pValue);
146 
147     pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
148         reinterpret_cast<xmlChar*>(const_cast<char*>("maxidx"))));
149     streamVolInfo->maxLevel = atoi(pValue);
150     AUDIO_DEBUG_LOG("minidx: %{public}d", atoi(pValue));
151     xmlFree(pValue);
152 
153     pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
154         reinterpret_cast<xmlChar*>(const_cast<char*>("defaultidx"))));
155     streamVolInfo->defaultLevel = atoi(pValue);
156     AUDIO_DEBUG_LOG("defaultidx: %{public}d", atoi(pValue));
157     xmlFree(pValue);
158 }
159 
ParseDeviceVolumeInfos(xmlNode * node,std::shared_ptr<StreamVolumeInfo> & streamVolInfo)160 void AudioVolumeParser::ParseDeviceVolumeInfos(xmlNode *node, std::shared_ptr<StreamVolumeInfo> &streamVolInfo)
161 {
162     xmlNode *currNode = node;
163     AUDIO_DEBUG_LOG("AudioVolumeParser::ParseDeviceVolumeInfos");
164     while (currNode) {
165         if (currNode->type == XML_ELEMENT_NODE
166             && (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("volumecurve")))) {
167             char *pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
168                 reinterpret_cast<xmlChar*>(const_cast<char*>("deviceClass"))));
169             std::shared_ptr<DeviceVolumeInfo> deviceVolInfo = std::make_shared<DeviceVolumeInfo>();
170             AUDIO_DEBUG_LOG("deviceClass: %{public}s; currNode->name %{public}s;", pValue, currNode->name);
171             deviceVolInfo->deviceType = audioDeviceMap_[pValue];
172             AUDIO_DEBUG_LOG("deviceVolInfo->deviceType %{public}d;", deviceVolInfo->deviceType);
173             xmlFree(pValue);
174             ParseVolumePoints(currNode->children, deviceVolInfo);
175             streamVolInfo->deviceVolumeInfos[deviceVolInfo->deviceType] = deviceVolInfo;
176         }
177         currNode = currNode->next;
178     }
179 }
180 
ParseVolumePoints(xmlNode * node,std::shared_ptr<DeviceVolumeInfo> & deviceVolInfo)181 void AudioVolumeParser::ParseVolumePoints(xmlNode *node, std::shared_ptr<DeviceVolumeInfo> &deviceVolInfo)
182 {
183     xmlNode *currNode = node;
184     AUDIO_DEBUG_LOG("AudioVolumeParser::ParseVolumePoints");
185     while (currNode) {
186         if (currNode->type == XML_ELEMENT_NODE
187             && (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("point")))) {
188             struct VolumePoint volumePoint;
189             char *pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
190                 reinterpret_cast<xmlChar*>(const_cast<char*>("idx"))));
191             volumePoint.index = atoi(pValue);
192             AUDIO_DEBUG_LOG("idx: %{public}d", atoi(pValue));
193             xmlFree(pValue);
194             pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
195                 reinterpret_cast<xmlChar*>(const_cast<char*>("decibel"))));
196             volumePoint.dbValue = atoi(pValue);
197             AUDIO_DEBUG_LOG("decibel: %{public}d", atoi(pValue));
198             xmlFree(pValue);
199             deviceVolInfo->volumePoints.push_back(volumePoint);
200         }
201         currNode = currNode->next;
202     }
203 }
204 } // namespace AudioStandard
205 } // namespace OHOS
206