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 "AudioStrategyRouterParser"
17 #endif
18 
19 #include "audio_strategy_router_parser.h"
20 #include "user_select_router.h"
21 #include "privacy_priority_router.h"
22 #include "public_priority_router.h"
23 #include "stream_filter_router.h"
24 #include "cockpit_phone_router.h"
25 #include "pair_device_router.h"
26 #include "default_router.h"
27 
28 #include "media_monitor_manager.h"
29 
30 namespace OHOS {
31 namespace AudioStandard {
LoadConfiguration()32 bool AudioStrategyRouterParser::LoadConfiguration()
33 {
34     doc_ = xmlReadFile(DEVICE_CONFIG_FILE, nullptr, 0);
35     if (doc_ == nullptr) {
36         AUDIO_ERR_LOG("Not found audio_strategy_router.xml!");
37         std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
38         Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_CONFIG_ERROR, Media::MediaMonitor::FAULT_EVENT);
39         bean->Add("CATEGORY", Media::MediaMonitor::AUDIO_STRATEGY_ROUTER);
40         Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
41         return false;
42     }
43     return true;
44 }
45 
Parse()46 bool AudioStrategyRouterParser::Parse()
47 {
48     xmlNode *root = xmlDocGetRootElement(doc_);
49     CHECK_AND_RETURN_RET_LOG(root != nullptr, false, "xmlDocGetRootElement failed");
50 
51     bool ret = ParseInternal(root);
52     CHECK_AND_RETURN_RET_LOG(ret, false, "Audio strategy router xml parse failed.");
53     return true;
54 }
55 
Destroy()56 void AudioStrategyRouterParser::Destroy()
57 {
58     if (doc_ != nullptr) {
59         xmlFreeDoc(doc_);
60     }
61 }
62 
ParseInternal(xmlNode * node)63 bool AudioStrategyRouterParser::ParseInternal(xmlNode *node)
64 {
65     xmlNode *currNode = node;
66 
67     for (; currNode; currNode = currNode->next) {
68         if (XML_ELEMENT_NODE == currNode->type) {
69             if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("strategy"))) {
70                 ParserStrategyInfo(currNode);
71             } else {
72                 ParseInternal((currNode->xmlChildrenNode));
73             }
74         }
75     }
76     return true;
77 }
78 
ParserStrategyInfo(xmlNode * node)79 void AudioStrategyRouterParser::ParserStrategyInfo(xmlNode *node)
80 {
81     xmlNode *strategyNode = node;
82     string name = ExtractPropertyValue("name", strategyNode);
83     string routers = ExtractPropertyValue("routers", strategyNode);
84 
85     if (name == "MEDIA_RENDER") {
86         AddRouters(mediaRenderRouters_, routers);
87     } else if (name == "CALL_RENDER") {
88         AddRouters(callRenderRouters_, routers);
89     } else if (name == "RING_RENDER") {
90         AddRouters(ringRenderRouters_, routers);
91     } else if (name == "TONE_RENDER") {
92         AddRouters(toneRenderRouters_, routers);
93     } else if (name == "RECORD_CAPTURE") {
94         AddRouters(recordCaptureRouters_, routers);
95     } else if (name == "CALL_CAPTURE") {
96         AddRouters(callCaptureRouters_, routers);
97     } else if (name == "VOICE_MESSAGE") {
98         AddRouters(voiceMessageRouters_, routers);
99     }
100 }
101 
ExtractPropertyValue(const std::string & propName,xmlNode * node)102 std::string AudioStrategyRouterParser::ExtractPropertyValue(const std::string &propName, xmlNode *node)
103 {
104     std::string propValue = "";
105     xmlChar *tempValue = nullptr;
106 
107     if (xmlHasProp(node, reinterpret_cast<const xmlChar*>(propName.c_str()))) {
108         tempValue = xmlGetProp(node, reinterpret_cast<const xmlChar*>(propName.c_str()));
109     }
110 
111     if (tempValue != nullptr) {
112         propValue = reinterpret_cast<const char*>(tempValue);
113         xmlFree(tempValue);
114     }
115 
116     return propValue;
117 }
118 
split(const std::string & line,const std::string & sep)119 std::vector<std::string> AudioStrategyRouterParser::split(const std::string &line, const std::string &sep)
120 {
121     std::vector<std::string> buf;
122     size_t temp = 0;
123     std::string::size_type pos = 0;
124     while (true) {
125         pos = line.find(sep, temp);
126         if (pos == std::string::npos) {
127             break;
128         }
129         buf.push_back(line.substr(temp, pos-temp));
130         temp = pos + sep.length();
131     }
132     buf.push_back(line.substr(temp, line.length()));
133     return buf;
134 }
135 
AddRouters(std::vector<std::unique_ptr<RouterBase>> & routers,string & routeName)136 void AudioStrategyRouterParser::AddRouters(std::vector<std::unique_ptr<RouterBase>> &routers, string &routeName)
137 {
138     vector<string> buf = split(routeName, ",");
139     for (const auto &name : buf) {
140         if (name == "UserSelectRouter") {
141             routers.push_back(make_unique<UserSelectRouter>());
142         } else if (name == "PrivacyPriorityRouter") {
143             routers.push_back(make_unique<PrivacyPriorityRouter>());
144         } else if (name == "PublicPriorityRouter") {
145             routers.push_back(make_unique<PublicPriorityRouter>());
146         } else if (name == "StreamFilterRouter") {
147             routers.push_back(make_unique<StreamFilterRouter>());
148         } else if (name == "DefaultRouter") {
149             routers.push_back(make_unique<DefaultRouter>());
150         } else if (name == "CockpitPhoneRouter") {
151             routers.push_back(make_unique<CockpitPhoneRouter>());
152         } else if (name == "PairDeviceRouter") {
153             routers.push_back(make_unique<PairDeviceRouter>());
154         }
155     }
156 }
157 } // namespace AudioStandard
158 } // namespace OHOS
159