1 /*
2 * Copyright (c) 2024 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 "AudioParamParser"
17 #endif
18
19 #include "audio_service_log.h"
20 #include "config/audio_param_parser.h"
21 #include "audio_errors.h"
22 #ifdef USE_CONFIG_POLICY
23 #include "config_policy_utils.h"
24 #endif
25
26 namespace OHOS {
27 namespace AudioStandard {
AudioParamParser()28 AudioParamParser::AudioParamParser()
29 {
30 AUDIO_DEBUG_LOG("audio extra parameters constructor");
31 }
32
~AudioParamParser()33 AudioParamParser::~AudioParamParser()
34 {
35 AUDIO_DEBUG_LOG("audio extra parameters destructor");
36 }
37
LoadConfiguration(std::unordered_map<std::string,std::unordered_map<std::string,std::set<std::string>>> & audioParameterKeys)38 bool AudioParamParser::LoadConfiguration(
39 std::unordered_map<std::string, std::unordered_map<std::string, std::set<std::string>>> &audioParameterKeys)
40 {
41 AUDIO_INFO_LOG("start LoadConfiguration");
42 std::shared_ptr<AudioXmlNode> curNode = AudioXmlNode::Create();
43 int32_t ret = 0;
44
45 #ifdef USE_CONFIG_POLICY
46 CfgFiles *cfgFiles = GetCfgFiles(CONFIG_FILE);
47 if (cfgFiles == nullptr) {
48 AUDIO_ERR_LOG("Not found audio_param_config.xml");
49 return false;
50 }
51
52 for (int32_t i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) {
53 if (cfgFiles->paths[i] && *(cfgFiles->paths[i]) != '\0') {
54 AUDIO_INFO_LOG("extra parameter config file path: %{public}s", cfgFiles->paths[i]);
55 ret = curNode->Config(cfgFiles->paths[i], nullptr, 0);
56 break;
57 }
58 }
59 FreeCfgFiles(cfgFiles);
60 #endif
61
62 if (ret != SUCCESS) {
63 AUDIO_ERR_LOG("Load Config Failed");
64 curNode = nullptr;
65 return false;
66 }
67
68 if (!ParseInternal(curNode->GetCopyNode(), audioParameterKeys)) {
69 curNode = nullptr;
70 return false;
71 }
72
73 curNode = nullptr;
74 return true;
75 }
76
ParseInternal(std::shared_ptr<AudioXmlNode> curNode,std::unordered_map<std::string,std::unordered_map<std::string,std::set<std::string>>> & audioParameterKeys)77 bool AudioParamParser::ParseInternal(std::shared_ptr<AudioXmlNode> curNode,
78 std::unordered_map<std::string, std::unordered_map<std::string, std::set<std::string>>> &audioParameterKeys)
79 {
80 if (!curNode->IsNodeValid()) {
81 AUDIO_ERR_LOG("parse node is null");
82 return false;
83 }
84
85 for (; curNode->IsNodeValid(); curNode->MoveToNext()) {
86 if (curNode->CompareName("mainkeys")) {
87 ParseMainKeys(curNode->GetCopyNode(), audioParameterKeys);
88 } else {
89 ParseInternal(curNode->GetChildrenNode(), audioParameterKeys);
90 }
91 }
92
93 return true;
94 }
95
ParseMainKeys(std::shared_ptr<AudioXmlNode> curNode,std::unordered_map<std::string,std::unordered_map<std::string,std::set<std::string>>> & audioParameterKeys)96 void AudioParamParser::ParseMainKeys(std::shared_ptr<AudioXmlNode> curNode,
97 std::unordered_map<std::string, std::unordered_map<std::string, std::set<std::string>>> &audioParameterKeys)
98 {
99 curNode->MoveToChildren();
100 while (curNode->IsNodeValid()) {
101 if (curNode->IsElementNode()) {
102 ParseMainKey(curNode->GetCopyNode(), audioParameterKeys);
103 }
104 curNode->MoveToNext();
105 }
106 }
107
ParseMainKey(std::shared_ptr<AudioXmlNode> curNode,std::unordered_map<std::string,std::unordered_map<std::string,std::set<std::string>>> & audioParameterKeys)108 void AudioParamParser::ParseMainKey(std::shared_ptr<AudioXmlNode> curNode,
109 std::unordered_map<std::string, std::unordered_map<std::string, std::set<std::string>>> &audioParameterKeys)
110 {
111 std::string mainKeyName;
112 CHECK_AND_RETURN_LOG(curNode->GetProp("name", mainKeyName) == SUCCESS,
113 "get mainKeyName: %{public}s fail", mainKeyName.c_str());
114
115 curNode->MoveToChildren();
116 while (curNode->IsNodeValid()) {
117 if (curNode->IsElementNode()) {
118 ParseSubKeys(curNode->GetCopyNode(), mainKeyName, audioParameterKeys);
119 }
120 curNode->MoveToNext();
121 }
122 }
123
ParseSubKeys(std::shared_ptr<AudioXmlNode> curNode,std::string & mainKeyName,std::unordered_map<std::string,std::unordered_map<std::string,std::set<std::string>>> & audioParameterKeys)124 void AudioParamParser::ParseSubKeys(std::shared_ptr<AudioXmlNode> curNode, std::string &mainKeyName,
125 std::unordered_map<std::string, std::unordered_map<std::string, std::set<std::string>>> &audioParameterKeys)
126 {
127 std::unordered_map<std::string, std::set<std::string>> subKeyMap = {};
128 std::set<std::string> supportedUsage;
129 curNode->MoveToChildren();
130
131 while (curNode->IsNodeValid()) {
132 if (curNode->IsElementNode()) {
133 std::string subKeyName;
134 std::string usage;
135 std::regex regexDelimiter(",");
136 curNode->GetProp("name", subKeyName);
137 curNode->GetProp("usage", usage);
138
139 const std::sregex_token_iterator itEnd;
140 for (std::sregex_token_iterator it(usage.begin(), usage.end(), regexDelimiter, -1); it != itEnd; it++) {
141 supportedUsage.insert(it->str());
142 }
143 subKeyMap.emplace(subKeyName, supportedUsage);
144 supportedUsage.clear();
145 }
146 curNode->MoveToNext();
147 }
148 audioParameterKeys.emplace(mainKeyName, subKeyMap);
149 }
150 } // namespace AudioStandard
151 } // namespace OHOS
152