• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_manager.h"
17 
18 #include <cstring>
19 #include <dirent.h>
20 #include <dlfcn.h>
21 #include <iostream>
22 #include <mutex>
23 #include <string_ex.h>
24 #include <unistd.h>
25 
26 #include "edm_ipc_interface_code.h"
27 #include "edm_log.h"
28 #include "func_code_utils.h"
29 #include "permission_manager.h"
30 
31 namespace OHOS {
32 namespace EDM {
33 std::shared_ptr<PluginManager> PluginManager::instance_;
34 std::mutex PluginManager::mutexLock_;
35 
PluginManager()36 PluginManager::PluginManager()
37 {
38     EDMLOGD("PluginManager::PluginManager.");
39 }
40 
~PluginManager()41 PluginManager::~PluginManager()
42 {
43     EDMLOGD("PluginManager::~PluginManager.");
44     pluginsCode_.clear();
45     pluginsName_.clear();
46     for (auto handle : pluginHandles_) {
47         dlclose(handle);
48     }
49     pluginHandles_.clear();
50 }
51 
GetInstance()52 std::shared_ptr<PluginManager> PluginManager::GetInstance()
53 {
54     if (instance_ == nullptr) {
55         std::lock_guard<std::mutex> autoLock(mutexLock_);
56         if (instance_ == nullptr) {
57             instance_.reset(new (std::nothrow) PluginManager());
58         }
59     }
60 
61     IPluginManager::pluginManagerInstance_ = instance_.get();
62     return instance_;
63 }
64 
GetPluginByFuncCode(std::uint32_t funcCode)65 std::shared_ptr<IPlugin> PluginManager::GetPluginByFuncCode(std::uint32_t funcCode)
66 {
67     FuncCodeUtils::PrintFuncCode(funcCode);
68     FuncFlag flag = FuncCodeUtils::GetSystemFlag(funcCode);
69     if (flag == FuncFlag::POLICY_FLAG) {
70         std::uint32_t code = FuncCodeUtils::GetPolicyCode(funcCode);
71         EDMLOGD("PluginManager::code %{public}u", code);
72         auto it = pluginsCode_.find(code);
73         if (it != pluginsCode_.end()) {
74             return it->second;
75         }
76     }
77     EDMLOGD("GetPluginByFuncCode::return nullptr");
78     return nullptr;
79 }
80 
GetPluginByPolicyName(const std::string & policyName)81 std::shared_ptr<IPlugin> PluginManager::GetPluginByPolicyName(const std::string &policyName)
82 {
83     auto it = pluginsName_.find(policyName);
84     if (it != pluginsName_.end()) {
85         return it->second;
86     }
87     return nullptr;
88 }
89 
GetPluginByCode(std::uint32_t code)90 std::shared_ptr<IPlugin> PluginManager::GetPluginByCode(std::uint32_t code)
91 {
92     EDMLOGD("PluginManager::code %{public}u", code);
93     auto it = pluginsCode_.find(code);
94     if (it != pluginsCode_.end()) {
95         return it->second;
96     }
97     EDMLOGD("GetPluginByCode::return nullptr");
98     return nullptr;
99 }
100 
CreateExecuteStrategy(ExecuteStrategy strategy)101 std::shared_ptr<IPluginExecuteStrategy> PluginManager::CreateExecuteStrategy(ExecuteStrategy strategy)
102 {
103     if (strategy == ExecuteStrategy::ENHANCE) {
104         return enhanceStrategy_;
105     }
106     if (strategy == ExecuteStrategy::REPLACE) {
107         return replaceStrategy_;
108     }
109     return singleStrategy_;
110 }
111 
AddPlugin(std::shared_ptr<IPlugin> plugin)112 bool PluginManager::AddPlugin(std::shared_ptr<IPlugin> plugin)
113 {
114     if (plugin == nullptr) {
115         return false;
116     }
117     EDMLOGD("AddPlugin %{public}d", plugin->GetCode());
118     std::vector<IPlugin::PolicyPermissionConfig> configs = plugin->GetAllPermission();
119     if (configs.empty()) {
120         return false;
121     }
122     for (auto &config : configs) {
123         for (auto &typePermission : config.typePermissions) {
124             PermissionManager::GetInstance()->AddPermission(typePermission.second, typePermission.first);
125         }
126         for (auto &tagPermission : config.tagPermissions) {
127             for (auto &typePermission : tagPermission.second) {
128                 PermissionManager::GetInstance()->AddPermission(typePermission.second, typePermission.first);
129             }
130         }
131     }
132     pluginsCode_.insert(std::make_pair(plugin->GetCode(), plugin));
133     pluginsName_.insert(std::make_pair(plugin->GetPolicyName(), plugin));
134     if (extensionPluginMap_.find(plugin->GetCode()) != extensionPluginMap_.end()) {
135         EDMLOGD("PluginManager::AddPlugin %{public}d add extension plugin %{public}d", plugin->GetCode(),
136             extensionPluginMap_[plugin->GetCode()]);
137         plugin->SetExtensionPlugin(GetPluginByCode(extensionPluginMap_[plugin->GetCode()]));
138     }
139     if (executeStrategyMap_.find(plugin->GetCode()) != executeStrategyMap_.end()) {
140         plugin->SetExecuteStrategy(CreateExecuteStrategy(executeStrategyMap_[plugin->GetCode()]));
141     } else {
142         plugin->SetExecuteStrategy(CreateExecuteStrategy(ExecuteStrategy::SINGLE));
143     }
144     return true;
145 }
146 
AddExtensionPlugin(std::shared_ptr<IPlugin> extensionPlugin,uint32_t basicPluginCode,ExecuteStrategy strategy)147 bool PluginManager::AddExtensionPlugin(std::shared_ptr<IPlugin> extensionPlugin, uint32_t basicPluginCode,
148     ExecuteStrategy strategy)
149 {
150     if (AddPlugin(extensionPlugin)) {
151         auto basicPlugin = GetPluginByCode(basicPluginCode);
152         if (basicPlugin != nullptr) {
153             EDMLOGD("PluginManager::AddExtensionPlugin %{public}d add extension plugin %{public}d", basicPluginCode,
154                 extensionPlugin->GetCode());
155             basicPlugin->SetExtensionPlugin(extensionPlugin);
156             basicPlugin->SetExecuteStrategy(CreateExecuteStrategy(strategy));
157         }
158         extensionPlugin->SetPluginType(IPlugin::PluginType::EXTENSION);
159         extensionPluginMap_.insert(std::make_pair(basicPluginCode, extensionPlugin->GetCode()));
160         executeStrategyMap_.insert(std::make_pair(basicPluginCode, strategy));
161         return true;
162     }
163     return false;
164 }
165 
LoadPlugin()166 void PluginManager::LoadPlugin()
167 {
168     std::lock_guard<std::mutex> autoLock(mutexLock_);
169 #if defined(_ARM64_) || defined(_X86_64_)
170     std::string pluginDir = "/system/lib64/edm_plugin/";
171 #else
172     std::string pluginDir = "/system/lib/edm_plugin/";
173 #endif
174     DIR *dir = opendir(pluginDir.c_str());
175     if (dir == nullptr) {
176         EDMLOGE("PluginManager::LoadPlugin open edm_plugin dir fail.");
177         return;
178     }
179     struct dirent *entry;
180     while ((entry = readdir(dir)) != nullptr) {
181         if (entry->d_type == DT_REG && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
182             LoadPlugin(pluginDir + entry->d_name);
183         }
184     }
185     closedir(dir);
186 }
187 
LoadPlugin(const std::string & pluginPath)188 void PluginManager::LoadPlugin(const std::string &pluginPath)
189 {
190     void *handle = dlopen(pluginPath.c_str(), RTLD_LAZY);
191     if (!handle) {
192         EDMLOGE("PluginManager::open plugin so fail. %{public}s.", dlerror());
193         return;
194     }
195     pluginHandles_.push_back(handle);
196 }
197 
UnloadPlugin()198 void PluginManager::UnloadPlugin()
199 {
200     std::lock_guard<std::mutex> autoLock(mutexLock_);
201     for (auto codeIter = pluginsCode_.begin(); codeIter != pluginsCode_.end();) {
202         if (codeIter->second != nullptr) {
203             codeIter->second->ResetExtensionPlugin();
204         }
205         if (codeIter->second == nullptr || codeIter->first > static_cast<uint32_t>(EdmInterfaceCode::POLICY_CODE_END)) {
206             codeIter = pluginsCode_.erase(codeIter);
207         } else {
208             ++codeIter;
209         }
210     }
211     for (auto nameIter = pluginsName_.begin(); nameIter != pluginsName_.end();) {
212         if (nameIter->second == nullptr ||
213             nameIter->second->GetCode() > static_cast<uint32_t>(EdmInterfaceCode::POLICY_CODE_END)) {
214             nameIter = pluginsName_.erase(nameIter);
215         } else {
216             ++nameIter;
217         }
218     }
219     for (auto handleIter = pluginHandles_.begin(); handleIter != pluginHandles_.end();) {
220         auto handle = *handleIter;
221         if (handle == nullptr || dlclose(handle) == 0) {
222             handleIter = pluginHandles_.erase(handleIter);
223         } else {
224             EDMLOGE("PluginManager::UnloadPlugin close handle failed.");
225             ++handleIter;
226         }
227     }
228 }
229 
DumpPluginConfig(IPlugin::PolicyPermissionConfig config)230 void PluginManager::DumpPluginConfig(IPlugin::PolicyPermissionConfig config)
231 {
232     std::string permissionStr;
233     permissionStr.append("Type Permissions:");
234     for (const auto &typePermission : config.typePermissions) {
235         permissionStr.append("PermissionType: ");
236         if (typePermission.first == IPlugin::PermissionType::NORMAL_DEVICE_ADMIN) {
237             permissionStr.append("NORMAL_DEVICE_ADMIN:");
238         }
239         if (typePermission.first == IPlugin::PermissionType::SUPER_DEVICE_ADMIN) {
240             permissionStr.append("SUPER_DEVICE_ADMIN:");
241         }
242         if (typePermission.first == IPlugin::PermissionType::BYOD_DEVICE_ADMIN) {
243             permissionStr.append("BYOD_DEVICE_ADMIN:");
244         }
245         permissionStr.append(typePermission.second);
246     }
247     permissionStr.append("Tag Permissions:");
248     for (const auto &tagPermission : config.tagPermissions) {
249         permissionStr.append("ApiTag: ");
250         permissionStr.append(tagPermission.first);
251         for (const auto &tag : tagPermission.second) {
252             if (tag.first == IPlugin::PermissionType::NORMAL_DEVICE_ADMIN) {
253                 permissionStr.append("NORMAL_DEVICE_ADMIN:");
254             }
255             if (tag.first == IPlugin::PermissionType::SUPER_DEVICE_ADMIN) {
256                 permissionStr.append("SUPER_DEVICE_ADMIN:");
257             }
258             if (tag.first == IPlugin::PermissionType::BYOD_DEVICE_ADMIN) {
259                 permissionStr.append("BYOD_DEVICE_ADMIN:");
260             }
261             permissionStr.append(tag.second);
262         }
263     }
264     EDMLOGD("Config permission:%{public}s", permissionStr.c_str());
265 }
266 
DumpPlugin()267 void PluginManager::DumpPlugin()
268 {
269     for (auto it = pluginsCode_.begin(); it != pluginsCode_.end(); it++) {
270         std::vector<IPlugin::PolicyPermissionConfig> configs = it->second->GetAllPermission();
271         EDMLOGD("PluginManager::Dump plugins_code.code:%{public}u,name:%{public}s",
272             it->first, it->second->GetPolicyName().c_str());
273         for (auto &config : configs) {
274             DumpPluginConfig(config);
275         }
276     }
277     for (auto it = pluginsName_.begin(); it != pluginsName_.end(); it++) {
278         std::vector<IPlugin::PolicyPermissionConfig> configs = it->second->GetAllPermission();
279         EDMLOGD("PluginManager::Dump plugins_name.name:%{public}s,code:%{public}u",
280             it->first.c_str(), it->second->GetCode());
281         for (auto &config : configs) {
282             DumpPluginConfig(config);
283         }
284     }
285 }
286 } // namespace EDM
287 } // namespace OHOS
288