1 /*
2 * Copyright (c) 2022 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 #include <cstring>
18 #include <dirent.h>
19 #include <dlfcn.h>
20 #include <iostream>
21 #include <memory>
22 #include <mutex>
23 #include <string_ex.h>
24 #include <unistd.h>
25 #include "edm_log.h"
26 #include "permission_manager.h"
27
28 namespace OHOS {
29 namespace EDM {
30 std::shared_ptr<PluginManager> PluginManager::instance_;
31 std::mutex PluginManager::mutexLock_;
32
PluginManager()33 PluginManager::PluginManager()
34 {
35 EDMLOGD("PluginManager::PluginManager.");
36 }
37
~PluginManager()38 PluginManager::~PluginManager()
39 {
40 EDMLOGD("PluginManager::~PluginManager.");
41 for (auto entry : pluginsCode_) {
42 entry.second.reset();
43 entry.second = nullptr;
44 }
45 pluginsCode_.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 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 }
75 EDMLOGD("GetPluginByFuncCode::return nullptr");
76 return nullptr;
77 }
78
GetPluginByPolicyName(const std::string & policyName)79 std::shared_ptr<IPlugin> PluginManager::GetPluginByPolicyName(const std::string &policyName)
80 {
81 auto it = pluginsName_.find(policyName);
82 if (it != pluginsName_.end()) {
83 return it->second;
84 }
85 return nullptr;
86 }
87
AddPlugin(std::shared_ptr<IPlugin> plugin)88 bool PluginManager::AddPlugin(std::shared_ptr<IPlugin> plugin)
89 {
90 EDMLOGD("AddPlugin");
91 if (plugin == nullptr) {
92 return false;
93 }
94 ErrCode result = PermissionManager::GetInstance()->AddPermission(plugin->GetPermission());
95 if (result == ERR_OK) {
96 pluginsCode_.insert(std::make_pair(plugin->GetCode(), plugin));
97 pluginsName_.insert(std::make_pair(plugin->GetPolicyName(), plugin));
98 }
99 return result;
100 }
101
Init()102 void PluginManager::Init()
103 {
104 LoadPlugin();
105 }
106
LoadPlugin()107 void PluginManager::LoadPlugin()
108 {
109 #ifdef _ARM64_
110 std::string pluginDir = "/system/lib64/edm_plugin/";
111 #else
112 std::string pluginDir = "/system/lib/edm_plugin/";
113 #endif
114 DIR *dir = opendir(pluginDir.c_str());
115 if (dir == nullptr) {
116 EDMLOGE("PluginManager::LoadPlugin open edm_plugin dir fail.");
117 return;
118 }
119 struct dirent *entry;
120 while ((entry = readdir(dir)) != nullptr) {
121 if (entry->d_type == DT_REG && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
122 LoadPlugin(pluginDir + entry->d_name);
123 }
124 }
125 closedir(dir);
126 }
127
LoadPlugin(const std::string & pluginPath)128 void PluginManager::LoadPlugin(const std::string &pluginPath)
129 {
130 void *handle = dlopen(pluginPath.c_str(), RTLD_LAZY);
131 if (!handle) {
132 EDMLOGE("PluginManager::open plugin so fail. %{public}s.", dlerror());
133 return;
134 }
135 char *szError = dlerror();
136 if (szError != nullptr) {
137 EDMLOGW("PluginManager::loading plugin fail. %{public}s.", szError);
138 }
139 pluginHandles_.push_back(handle);
140 }
141
DumpPlugin()142 void PluginManager::DumpPlugin()
143 {
144 for (auto it = pluginsCode_.begin(); it != pluginsCode_.end(); it++) {
145 EDMLOGD("PluginManager::Dump plugins_code.code:%{public}u,name:%{public}s,permission:%{public}s",
146 it->first, it->second->GetPolicyName().c_str(), it->second->GetPermission().c_str());
147 }
148 for (auto it = pluginsName_.begin(); it != pluginsName_.end(); it++) {
149 EDMLOGD("PluginManager::Dump plugins_name.name:%{public}s,code:%{public}u,permission:%{public}s",
150 it->first.c_str(), it->second->GetCode(), it->second->GetPermission().c_str());
151 }
152 }
153 } // namespace EDM
154 } // namespace OHOS
155