• 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 #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