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 "AudioVolumeParser"
17 #endif
18
19 #include "audio_volume_parser.h"
20 #ifdef USE_CONFIG_POLICY
21 #include "config_policy_utils.h"
22 #endif
23 #include "audio_utils.h"
24 #include "media_monitor_manager.h"
25
26 namespace OHOS {
27 namespace AudioStandard {
AudioVolumeParser()28 AudioVolumeParser::AudioVolumeParser()
29 {
30 AUDIO_INFO_LOG("AudioVolumeParser ctor");
31 audioStreamMap_ = {
32 {"VOICE_CALL", STREAM_VOICE_CALL},
33 {"MUSIC", STREAM_MUSIC},
34 {"RING", STREAM_RING},
35 {"VOICE_ASSISTANT", STREAM_VOICE_ASSISTANT},
36 {"ALARM", STREAM_ALARM},
37 {"ACCESSIBILITY", STREAM_ACCESSIBILITY},
38 {"ULTRASONIC", STREAM_ULTRASONIC},
39 {"SYSTEM", STREAM_SYSTEM},
40 {"APP", STREAM_APP}
41 };
42
43 audioDeviceMap_ = {
44 {"earpiece", EARPIECE_VOLUME_TYPE},
45 {"speaker", SPEAKER_VOLUME_TYPE},
46 {"headset", HEADSET_VOLUME_TYPE},
47 };
48 }
49
~AudioVolumeParser()50 AudioVolumeParser::~AudioVolumeParser()
51 {
52 AUDIO_INFO_LOG("AudioVolumeParser dtor");
53 }
54
ParseVolumeConfig(const char * path,StreamVolumeInfoMap & streamVolumeInfoMap)55 int32_t AudioVolumeParser::ParseVolumeConfig(const char *path, StreamVolumeInfoMap &streamVolumeInfoMap)
56 {
57 std::shared_ptr<AudioXmlNode> curNode = AudioXmlNode::Create();
58 int32_t ret = curNode->Config(path, nullptr, 0);
59 if (ret != SUCCESS) {
60 WriteVolumeConfigErrorEvent();
61 return ERROR;
62 }
63
64 if (!curNode->CompareName("audio_volume_config")) {
65 AUDIO_ERR_LOG("Missing tag - audio_volume_config in : %s", path);
66 WriteVolumeConfigErrorEvent();
67 curNode = nullptr;
68 return ERROR;
69 }
70 curNode->MoveToChildren();
71 if (!curNode->IsNodeValid()) {
72 AUDIO_ERR_LOG("empty volume config in : %s", path);
73 WriteVolumeConfigErrorEvent();
74 curNode = nullptr;
75 return ERROR;
76 }
77
78 while (curNode->IsNodeValid()) {
79 if (curNode->CompareName("volume_type")) {
80 ParseStreamInfos(curNode->GetCopyNode(), streamVolumeInfoMap);
81 break;
82 } else {
83 curNode->MoveToNext();
84 }
85 }
86 curNode = nullptr;
87 return SUCCESS;
88 }
89
WriteVolumeConfigErrorEvent()90 void AudioVolumeParser::WriteVolumeConfigErrorEvent()
91 {
92 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
93 Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_CONFIG_ERROR,
94 Media::MediaMonitor::FAULT_EVENT);
95 bean->Add("CATEGORY", Media::MediaMonitor::AUDIO_VOLUME_CONFIG);
96 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
97 }
98
LoadConfig(StreamVolumeInfoMap & streamVolumeInfoMap)99 int32_t AudioVolumeParser::LoadConfig(StreamVolumeInfoMap &streamVolumeInfoMap)
100 {
101 AUDIO_INFO_LOG("Load Volume Config xml");
102 int ret = ERROR;
103 #ifdef USE_CONFIG_POLICY
104 CfgFiles *cfgFiles = GetCfgFiles(AUDIO_VOLUME_CONFIG_FILE);
105 if (cfgFiles == nullptr) {
106 AUDIO_ERR_LOG("Not found audio_volume_config.xml!");
107 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
108 Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_CONFIG_ERROR,
109 Media::MediaMonitor::FAULT_EVENT);
110 bean->Add("CATEGORY", Media::MediaMonitor::AUDIO_VOLUME_CONFIG);
111 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
112 return ERROR;
113 }
114
115 for (int32_t i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) {
116 if (cfgFiles->paths[i] && *(cfgFiles->paths[i]) != '\0') {
117 AUDIO_INFO_LOG("volume config file path:%{public}s", cfgFiles->paths[i]);
118 ret = ParseVolumeConfig(cfgFiles->paths[i], streamVolumeInfoMap);
119 break;
120 }
121 }
122 FreeCfgFiles(cfgFiles);
123 #else
124 ret = ParseVolumeConfig(AUDIO_VOLUME_CONFIG_FILE, streamVolumeInfoMap);
125 AUDIO_INFO_LOG("use default volume config file path:%{public}s", AUDIO_VOLUME_CONFIG_FILE);
126 #endif
127 return ret;
128 }
129
ParseStreamInfos(std::shared_ptr<AudioXmlNode> curNode,StreamVolumeInfoMap & streamVolumeInfoMap)130 void AudioVolumeParser::ParseStreamInfos(std::shared_ptr<AudioXmlNode> curNode,
131 StreamVolumeInfoMap &streamVolumeInfoMap)
132 {
133 AUDIO_DEBUG_LOG("AudioVolumeParser::ParseStreamInfos");
134 while (curNode->IsNodeValid()) {
135 if (curNode->CompareName("volume_type")) {
136 std::shared_ptr<StreamVolumeInfo> streamVolInfo = std::make_shared<StreamVolumeInfo>();
137 if (ParseStreamVolumeInfoAttr(curNode->GetCopyNode(), streamVolInfo) == AUDIO_OK) {
138 ParseDeviceVolumeInfos(curNode->GetChildrenNode(), streamVolInfo);
139 AUDIO_DEBUG_LOG("Parse streamType:%{public}d ", streamVolInfo->streamType);
140 streamVolumeInfoMap[streamVolInfo->streamType] = streamVolInfo;
141 }
142 }
143 curNode->MoveToNext();
144 }
145 }
146
ParseStreamVolumeInfoAttr(std::shared_ptr<AudioXmlNode> curNode,std::shared_ptr<StreamVolumeInfo> & streamVolInfo)147 int32_t AudioVolumeParser::ParseStreamVolumeInfoAttr(std::shared_ptr<AudioXmlNode> curNode,
148 std::shared_ptr<StreamVolumeInfo> &streamVolInfo)
149 {
150 AUDIO_DEBUG_LOG("AudioVolumeParser::ParseStreamVolumeInfoAttr");
151 std::string pValueStr;
152 CHECK_AND_RETURN_RET_LOG(curNode->GetProp("type", pValueStr) == SUCCESS,
153 ERR_INVALID_PARAM, "invalid type parameter");
154
155 if (pValueStr == "VOICE_PC") {
156 VolumeUtils::SetPCVolumeEnable(true);
157 AUDIO_INFO_LOG("PC Volume is Enable");
158 // only read PC volume flag
159 return ERR_NOT_SUPPORTED;
160 }
161 streamVolInfo->streamType = audioStreamMap_[pValueStr];
162
163 CHECK_AND_RETURN_RET_LOG(curNode->GetProp("minidx", pValueStr) == SUCCESS,
164 ERR_INVALID_PARAM, "invalid minidx parameter");
165 CHECK_AND_RETURN_RET_LOG(StringConverter<int32_t>(pValueStr, streamVolInfo->minLevel), ERROR,
166 "convert streamVolInfo->minLevel fail!");
167 AUDIO_DEBUG_LOG("minidx: %{public}d", streamVolInfo->minLevel);
168
169 CHECK_AND_RETURN_RET_LOG(curNode->GetProp("maxidx", pValueStr) == SUCCESS,
170 ERR_INVALID_PARAM, "invalid maxidx parameter");
171 CHECK_AND_RETURN_RET_LOG(StringConverter<int32_t>(pValueStr, streamVolInfo->maxLevel), ERROR,
172 "convert streamVolInfo->maxLevel fail!");
173 AUDIO_DEBUG_LOG("maxidx: %{public}d", streamVolInfo->maxLevel);
174
175 CHECK_AND_RETURN_RET_LOG(curNode->GetProp("defaultidx", pValueStr) == SUCCESS,
176 ERR_INVALID_PARAM, "invalid defaultidx parameter");
177 CHECK_AND_RETURN_RET_LOG(StringConverter<int32_t>(pValueStr, streamVolInfo->defaultLevel), ERROR,
178 "convert streamVolInfo->defaultLevel fail!");
179 AUDIO_DEBUG_LOG("defaultidx: %{public}d", streamVolInfo->defaultLevel);
180
181 return AUDIO_OK;
182 }
183
ParseDeviceVolumeInfos(std::shared_ptr<AudioXmlNode> curNode,std::shared_ptr<StreamVolumeInfo> & streamVolInfo)184 void AudioVolumeParser::ParseDeviceVolumeInfos(std::shared_ptr<AudioXmlNode> curNode,
185 std::shared_ptr<StreamVolumeInfo> &streamVolInfo)
186 {
187 AUDIO_DEBUG_LOG("AudioVolumeParser::ParseDeviceVolumeInfos");
188 while (curNode->IsNodeValid()) {
189 if (curNode->CompareName("volumecurve")) {
190 std::string pValueStr;
191 curNode->GetProp("deviceClass", pValueStr);
192 std::shared_ptr<DeviceVolumeInfo> deviceVolInfo = std::make_shared<DeviceVolumeInfo>();
193 deviceVolInfo->deviceType = audioDeviceMap_[pValueStr];
194 AUDIO_DEBUG_LOG("deviceVolInfo->deviceType %{public}d;", deviceVolInfo->deviceType);
195 int32_t result = curNode->GetProp("defaultidx", pValueStr);
196 if (result == SUCCESS) {
197 StringConverter<int32_t>(pValueStr, deviceVolInfo->defaultLevel);
198 } else {
199 AUDIO_DEBUG_LOG("The defaultidx attribute is not configured or defaultidx parameter is invalid");
200 }
201 ParseVolumePoints(curNode->GetChildrenNode(), deviceVolInfo);
202 streamVolInfo->deviceVolumeInfos[deviceVolInfo->deviceType] = deviceVolInfo;
203 }
204 curNode->MoveToNext();
205 }
206 }
207
ParseVolumePoints(std::shared_ptr<AudioXmlNode> curNode,std::shared_ptr<DeviceVolumeInfo> & deviceVolInfo)208 void AudioVolumeParser::ParseVolumePoints(std::shared_ptr<AudioXmlNode> curNode,
209 std::shared_ptr<DeviceVolumeInfo> &deviceVolInfo)
210 {
211 AUDIO_DEBUG_LOG("AudioVolumeParser::ParseVolumePoints");
212 while (curNode->IsNodeValid()) {
213 if (curNode->CompareName("point")) {
214 struct VolumePoint volumePoint;
215 std::string pValueStr;
216 curNode->GetProp("idx", pValueStr);
217 CHECK_AND_RETURN_LOG(StringConverter(pValueStr, volumePoint.index),
218 "convert volumePoint.index fail!");
219 AUDIO_DEBUG_LOG("idx: %{public}d", volumePoint.index);
220
221 curNode->GetProp("decibel", pValueStr);
222 CHECK_AND_RETURN_LOG(StringConverter(pValueStr, volumePoint.dbValue),
223 "convert volumePoint.dbValue fail!");
224 AUDIO_DEBUG_LOG("decibel: %{public}d", volumePoint.dbValue);
225
226 deviceVolInfo->volumePoints.push_back(volumePoint);
227 }
228 curNode->MoveToNext();
229 }
230 }
231 } // namespace AudioStandard
232 } // namespace OHOS
233