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