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 
16 #include "plugin_switch.h"
17 
18 #include "res_sched_log.h"
19 
20 using namespace std;
21 
22 namespace OHOS {
23 namespace ResourceSchedule {
24 namespace {
25 constexpr auto XML_TAG_PLUGIN_LIST = "pluginlist";
26 constexpr auto XML_TAG_PLUGIN = "plugin";
27 constexpr auto XML_ATTR_LIB_PATH = "libpath";
28 constexpr auto XML_ATTR_LIB_PATH_EXE = "libpathexe";
29 constexpr auto XML_ATTR_SWITCH = "switch";
30 constexpr auto SWITCH_ON = "1";
31 }
32 
IsInvalidNode(const xmlNode & currNode)33 bool PluginSwitch::IsInvalidNode(const xmlNode& currNode)
34 {
35     if (!currNode.name || currNode.type == XML_COMMENT_NODE) {
36         return true;
37     }
38     return false;
39 }
40 
FillinPluginInfo(const xmlNode * currNode,PluginInfo & info,bool isRssExe)41 bool PluginSwitch::FillinPluginInfo(const xmlNode* currNode, PluginInfo& info, bool isRssExe)
42 {
43     xmlChar *attrValue = nullptr;
44     if (!isRssExe) {
45         attrValue = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>(XML_ATTR_LIB_PATH));
46     } else {
47         attrValue = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>(XML_ATTR_LIB_PATH_EXE));
48     }
49     if (!attrValue) {
50         RESSCHED_LOGW("%{public}s, libPath null!", __func__);
51         return false;
52     }
53     std::string libPath = reinterpret_cast<const char*>(attrValue);
54     if (libPath.empty()) {
55         RESSCHED_LOGW("%{public}s, libPath empty!", __func__);
56         return false;
57     }
58     info.libPath = libPath;
59     xmlFree(attrValue);
60 
61     attrValue = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>(XML_ATTR_SWITCH));
62     if (attrValue) {
63         std::string value = reinterpret_cast<const char*>(attrValue);
64         if (value == SWITCH_ON) {
65             info.switchOn = true;
66         }
67         xmlFree(attrValue);
68     }
69     return true;
70 }
71 
LoadFromConfigContent(const string & content,bool isRssExe)72 bool PluginSwitch::LoadFromConfigContent(const string& content, bool isRssExe)
73 {
74     // skip the empty string, else you will get empty node
75     xmlDocPtr xmlDocPtr = xmlReadMemory(content.c_str(), content.length(), nullptr, nullptr,
76         XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
77     if (!xmlDocPtr) {
78         RESSCHED_LOGE("%{public}s, xmlReadFile error!", __func__);
79         return false;
80     }
81     xmlNodePtr rootNodePtr = xmlDocGetRootElement(xmlDocPtr);
82     if (!rootNodePtr || !rootNodePtr->name ||
83         xmlStrcmp(rootNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_PLUGIN_LIST)) != 0) {
84         RESSCHED_LOGE("%{public}s, root element tag wrong!", __func__);
85         xmlFreeDoc(xmlDocPtr);
86         return false;
87     }
88 
89     xmlNodePtr currNodePtr = rootNodePtr->xmlChildrenNode;
90     for (; currNodePtr; currNodePtr = currNodePtr->next) {
91         if (IsInvalidNode(*currNodePtr)) {
92             continue;
93         }
94 
95         if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_PLUGIN)) != 0) {
96             RESSCHED_LOGW("%{public}s, plugin (%{public}s) config wrong!", __func__, currNodePtr->name);
97             xmlFreeDoc(xmlDocPtr);
98             return false;
99         }
100 
101         PluginInfo info;
102         if (!FillinPluginInfo(currNodePtr, info, isRssExe)) {
103             RESSCHED_LOGW("%{public}s, fill in pluginInfo error!", __func__);
104             continue;
105         }
106         pluginSwitchMap_[info.libPath] = info;
107     }
108     xmlFreeDoc(xmlDocPtr);
109     return true;
110 }
111 
GetPluginSwitch()112 std::list<PluginInfo> PluginSwitch::GetPluginSwitch()
113 {
114     std::list<PluginInfo> pluginInfoList;
115     for (auto iter: pluginSwitchMap_) {
116         pluginInfoList.emplace_back(iter.second);
117     }
118     return pluginInfoList;
119 }
120 } // namespace ResourceSchedule
121 } // namespace OHOS
122