1f7a47986Sopenharmony_ci/* 2f7a47986Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3f7a47986Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4f7a47986Sopenharmony_ci * you may not use this file except in compliance with the License. 5f7a47986Sopenharmony_ci * You may obtain a copy of the License at 6f7a47986Sopenharmony_ci * 7f7a47986Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8f7a47986Sopenharmony_ci * 9f7a47986Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10f7a47986Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11f7a47986Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f7a47986Sopenharmony_ci * See the License for the specific language governing permissions and 13f7a47986Sopenharmony_ci * limitations under the License. 14f7a47986Sopenharmony_ci */ 15f7a47986Sopenharmony_ci 16f7a47986Sopenharmony_ci#include "plugin_manager.h" 17f7a47986Sopenharmony_ci 18f7a47986Sopenharmony_ci#include <cstring> 19f7a47986Sopenharmony_ci#include <dirent.h> 20f7a47986Sopenharmony_ci#include <dlfcn.h> 21f7a47986Sopenharmony_ci#include <iostream> 22f7a47986Sopenharmony_ci#include <mutex> 23f7a47986Sopenharmony_ci#include <string_ex.h> 24f7a47986Sopenharmony_ci#include <unistd.h> 25f7a47986Sopenharmony_ci 26f7a47986Sopenharmony_ci#include "edm_ipc_interface_code.h" 27f7a47986Sopenharmony_ci#include "edm_log.h" 28f7a47986Sopenharmony_ci#include "func_code_utils.h" 29f7a47986Sopenharmony_ci#include "permission_manager.h" 30f7a47986Sopenharmony_ci 31f7a47986Sopenharmony_cinamespace OHOS { 32f7a47986Sopenharmony_cinamespace EDM { 33f7a47986Sopenharmony_cistd::shared_ptr<PluginManager> PluginManager::instance_; 34f7a47986Sopenharmony_cistd::mutex PluginManager::mutexLock_; 35f7a47986Sopenharmony_ci 36f7a47986Sopenharmony_ciPluginManager::PluginManager() 37f7a47986Sopenharmony_ci{ 38f7a47986Sopenharmony_ci EDMLOGD("PluginManager::PluginManager."); 39f7a47986Sopenharmony_ci} 40f7a47986Sopenharmony_ci 41f7a47986Sopenharmony_ciPluginManager::~PluginManager() 42f7a47986Sopenharmony_ci{ 43f7a47986Sopenharmony_ci EDMLOGD("PluginManager::~PluginManager."); 44f7a47986Sopenharmony_ci pluginsCode_.clear(); 45f7a47986Sopenharmony_ci pluginsName_.clear(); 46f7a47986Sopenharmony_ci for (auto handle : pluginHandles_) { 47f7a47986Sopenharmony_ci dlclose(handle); 48f7a47986Sopenharmony_ci } 49f7a47986Sopenharmony_ci pluginHandles_.clear(); 50f7a47986Sopenharmony_ci} 51f7a47986Sopenharmony_ci 52f7a47986Sopenharmony_cistd::shared_ptr<PluginManager> PluginManager::GetInstance() 53f7a47986Sopenharmony_ci{ 54f7a47986Sopenharmony_ci if (instance_ == nullptr) { 55f7a47986Sopenharmony_ci std::lock_guard<std::mutex> autoLock(mutexLock_); 56f7a47986Sopenharmony_ci if (instance_ == nullptr) { 57f7a47986Sopenharmony_ci instance_.reset(new (std::nothrow) PluginManager()); 58f7a47986Sopenharmony_ci } 59f7a47986Sopenharmony_ci } 60f7a47986Sopenharmony_ci 61f7a47986Sopenharmony_ci IPluginManager::pluginManagerInstance_ = instance_.get(); 62f7a47986Sopenharmony_ci return instance_; 63f7a47986Sopenharmony_ci} 64f7a47986Sopenharmony_ci 65f7a47986Sopenharmony_cistd::shared_ptr<IPlugin> PluginManager::GetPluginByFuncCode(std::uint32_t funcCode) 66f7a47986Sopenharmony_ci{ 67f7a47986Sopenharmony_ci FuncCodeUtils::PrintFuncCode(funcCode); 68f7a47986Sopenharmony_ci FuncFlag flag = FuncCodeUtils::GetSystemFlag(funcCode); 69f7a47986Sopenharmony_ci if (flag == FuncFlag::POLICY_FLAG) { 70f7a47986Sopenharmony_ci std::uint32_t code = FuncCodeUtils::GetPolicyCode(funcCode); 71f7a47986Sopenharmony_ci EDMLOGD("PluginManager::code %{public}u", code); 72f7a47986Sopenharmony_ci auto it = pluginsCode_.find(code); 73f7a47986Sopenharmony_ci if (it != pluginsCode_.end()) { 74f7a47986Sopenharmony_ci return it->second; 75f7a47986Sopenharmony_ci } 76f7a47986Sopenharmony_ci } 77f7a47986Sopenharmony_ci EDMLOGD("GetPluginByFuncCode::return nullptr"); 78f7a47986Sopenharmony_ci return nullptr; 79f7a47986Sopenharmony_ci} 80f7a47986Sopenharmony_ci 81f7a47986Sopenharmony_cistd::shared_ptr<IPlugin> PluginManager::GetPluginByPolicyName(const std::string &policyName) 82f7a47986Sopenharmony_ci{ 83f7a47986Sopenharmony_ci auto it = pluginsName_.find(policyName); 84f7a47986Sopenharmony_ci if (it != pluginsName_.end()) { 85f7a47986Sopenharmony_ci return it->second; 86f7a47986Sopenharmony_ci } 87f7a47986Sopenharmony_ci return nullptr; 88f7a47986Sopenharmony_ci} 89f7a47986Sopenharmony_ci 90f7a47986Sopenharmony_cistd::shared_ptr<IPlugin> PluginManager::GetPluginByCode(std::uint32_t code) 91f7a47986Sopenharmony_ci{ 92f7a47986Sopenharmony_ci EDMLOGD("PluginManager::code %{public}u", code); 93f7a47986Sopenharmony_ci auto it = pluginsCode_.find(code); 94f7a47986Sopenharmony_ci if (it != pluginsCode_.end()) { 95f7a47986Sopenharmony_ci return it->second; 96f7a47986Sopenharmony_ci } 97f7a47986Sopenharmony_ci EDMLOGD("GetPluginByCode::return nullptr"); 98f7a47986Sopenharmony_ci return nullptr; 99f7a47986Sopenharmony_ci} 100f7a47986Sopenharmony_ci 101f7a47986Sopenharmony_cistd::shared_ptr<IPluginExecuteStrategy> PluginManager::CreateExecuteStrategy(ExecuteStrategy strategy) 102f7a47986Sopenharmony_ci{ 103f7a47986Sopenharmony_ci if (strategy == ExecuteStrategy::ENHANCE) { 104f7a47986Sopenharmony_ci return enhanceStrategy_; 105f7a47986Sopenharmony_ci } 106f7a47986Sopenharmony_ci if (strategy == ExecuteStrategy::REPLACE) { 107f7a47986Sopenharmony_ci return replaceStrategy_; 108f7a47986Sopenharmony_ci } 109f7a47986Sopenharmony_ci return singleStrategy_; 110f7a47986Sopenharmony_ci} 111f7a47986Sopenharmony_ci 112f7a47986Sopenharmony_cibool PluginManager::AddPlugin(std::shared_ptr<IPlugin> plugin) 113f7a47986Sopenharmony_ci{ 114f7a47986Sopenharmony_ci if (plugin == nullptr) { 115f7a47986Sopenharmony_ci return false; 116f7a47986Sopenharmony_ci } 117f7a47986Sopenharmony_ci EDMLOGD("AddPlugin %{public}d", plugin->GetCode()); 118f7a47986Sopenharmony_ci IPlugin::PolicyPermissionConfig setConfig = plugin->GetAllPermission(FuncOperateType::SET); 119f7a47986Sopenharmony_ci IPlugin::PolicyPermissionConfig getConfig = plugin->GetAllPermission(FuncOperateType::GET); 120f7a47986Sopenharmony_ci IPlugin::PermissionType setType = plugin->GetPermissionType(FuncOperateType::SET); 121f7a47986Sopenharmony_ci IPlugin::PermissionType getType = plugin->GetPermissionType(FuncOperateType::GET); 122f7a47986Sopenharmony_ci ErrCode result = PermissionManager::GetInstance()->AddPermission(setConfig.permission, setType); 123f7a47986Sopenharmony_ci if (result == ERR_OK && getConfig.permission != setConfig.permission) { 124f7a47986Sopenharmony_ci result = PermissionManager::GetInstance()->AddPermission(getConfig.permission, getType); 125f7a47986Sopenharmony_ci } 126f7a47986Sopenharmony_ci if (result == ERR_OK) { 127f7a47986Sopenharmony_ci for (auto &item : setConfig.tagPermissions) { 128f7a47986Sopenharmony_ci if (PermissionManager::GetInstance()->AddPermission(item.second, setType) != ERR_OK) { 129f7a47986Sopenharmony_ci return false; 130f7a47986Sopenharmony_ci } 131f7a47986Sopenharmony_ci } 132f7a47986Sopenharmony_ci for (auto &item : getConfig.tagPermissions) { 133f7a47986Sopenharmony_ci if (PermissionManager::GetInstance()->AddPermission(item.second, getType) != ERR_OK) { 134f7a47986Sopenharmony_ci return false; 135f7a47986Sopenharmony_ci } 136f7a47986Sopenharmony_ci } 137f7a47986Sopenharmony_ci pluginsCode_.insert(std::make_pair(plugin->GetCode(), plugin)); 138f7a47986Sopenharmony_ci pluginsName_.insert(std::make_pair(plugin->GetPolicyName(), plugin)); 139f7a47986Sopenharmony_ci if (extensionPluginMap_.count(plugin->GetCode()) > 0) { 140f7a47986Sopenharmony_ci EDMLOGD("PluginManager::AddPlugin %{public}d add extension plugin %{public}d", plugin->GetCode(), 141f7a47986Sopenharmony_ci extensionPluginMap_[plugin->GetCode()]); 142f7a47986Sopenharmony_ci plugin->SetExtensionPlugin(GetPluginByCode(extensionPluginMap_[plugin->GetCode()])); 143f7a47986Sopenharmony_ci } 144f7a47986Sopenharmony_ci if (executeStrategyMap_.count(plugin->GetCode()) > 0) { 145f7a47986Sopenharmony_ci plugin->SetExecuteStrategy(CreateExecuteStrategy(executeStrategyMap_[plugin->GetCode()])); 146f7a47986Sopenharmony_ci } else { 147f7a47986Sopenharmony_ci plugin->SetExecuteStrategy(CreateExecuteStrategy(ExecuteStrategy::SINGLE)); 148f7a47986Sopenharmony_ci } 149f7a47986Sopenharmony_ci return true; 150f7a47986Sopenharmony_ci } 151f7a47986Sopenharmony_ci return false; 152f7a47986Sopenharmony_ci} 153f7a47986Sopenharmony_ci 154f7a47986Sopenharmony_cibool PluginManager::AddExtensionPlugin(std::shared_ptr<IPlugin> extensionPlugin, uint32_t basicPluginCode, 155f7a47986Sopenharmony_ci ExecuteStrategy strategy) 156f7a47986Sopenharmony_ci{ 157f7a47986Sopenharmony_ci if (AddPlugin(extensionPlugin)) { 158f7a47986Sopenharmony_ci auto basicPlugin = GetPluginByCode(basicPluginCode); 159f7a47986Sopenharmony_ci if (basicPlugin != nullptr) { 160f7a47986Sopenharmony_ci EDMLOGD("PluginManager::AddExtensionPlugin %{public}d add extension plugin %{public}d", basicPluginCode, 161f7a47986Sopenharmony_ci extensionPlugin->GetCode()); 162f7a47986Sopenharmony_ci basicPlugin->SetExtensionPlugin(extensionPlugin); 163f7a47986Sopenharmony_ci basicPlugin->SetExecuteStrategy(CreateExecuteStrategy(strategy)); 164f7a47986Sopenharmony_ci } 165f7a47986Sopenharmony_ci extensionPlugin->SetPluginType(IPlugin::PluginType::EXTENSION); 166f7a47986Sopenharmony_ci extensionPluginMap_.insert(std::make_pair(basicPluginCode, extensionPlugin->GetCode())); 167f7a47986Sopenharmony_ci executeStrategyMap_.insert(std::make_pair(basicPluginCode, strategy)); 168f7a47986Sopenharmony_ci return true; 169f7a47986Sopenharmony_ci } 170f7a47986Sopenharmony_ci return false; 171f7a47986Sopenharmony_ci} 172f7a47986Sopenharmony_ci 173f7a47986Sopenharmony_civoid PluginManager::LoadPlugin() 174f7a47986Sopenharmony_ci{ 175f7a47986Sopenharmony_ci std::lock_guard<std::mutex> autoLock(mutexLock_); 176f7a47986Sopenharmony_ci#if defined(_ARM64_) || defined(_X86_64_) 177f7a47986Sopenharmony_ci std::string pluginDir = "/system/lib64/edm_plugin/"; 178f7a47986Sopenharmony_ci#else 179f7a47986Sopenharmony_ci std::string pluginDir = "/system/lib/edm_plugin/"; 180f7a47986Sopenharmony_ci#endif 181f7a47986Sopenharmony_ci DIR *dir = opendir(pluginDir.c_str()); 182f7a47986Sopenharmony_ci if (dir == nullptr) { 183f7a47986Sopenharmony_ci EDMLOGE("PluginManager::LoadPlugin open edm_plugin dir fail."); 184f7a47986Sopenharmony_ci return; 185f7a47986Sopenharmony_ci } 186f7a47986Sopenharmony_ci struct dirent *entry; 187f7a47986Sopenharmony_ci while ((entry = readdir(dir)) != nullptr) { 188f7a47986Sopenharmony_ci if (entry->d_type == DT_REG && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 189f7a47986Sopenharmony_ci LoadPlugin(pluginDir + entry->d_name); 190f7a47986Sopenharmony_ci } 191f7a47986Sopenharmony_ci } 192f7a47986Sopenharmony_ci closedir(dir); 193f7a47986Sopenharmony_ci} 194f7a47986Sopenharmony_ci 195f7a47986Sopenharmony_civoid PluginManager::LoadPlugin(const std::string &pluginPath) 196f7a47986Sopenharmony_ci{ 197f7a47986Sopenharmony_ci void *handle = dlopen(pluginPath.c_str(), RTLD_LAZY); 198f7a47986Sopenharmony_ci if (!handle) { 199f7a47986Sopenharmony_ci EDMLOGE("PluginManager::open plugin so fail. %{public}s.", dlerror()); 200f7a47986Sopenharmony_ci return; 201f7a47986Sopenharmony_ci } 202f7a47986Sopenharmony_ci pluginHandles_.push_back(handle); 203f7a47986Sopenharmony_ci} 204f7a47986Sopenharmony_ci 205f7a47986Sopenharmony_civoid PluginManager::UnloadPlugin() 206f7a47986Sopenharmony_ci{ 207f7a47986Sopenharmony_ci std::lock_guard<std::mutex> autoLock(mutexLock_); 208f7a47986Sopenharmony_ci for (auto codeIter = pluginsCode_.begin(); codeIter != pluginsCode_.end();) { 209f7a47986Sopenharmony_ci if (codeIter->second != nullptr) { 210f7a47986Sopenharmony_ci codeIter->second->ResetExtensionPlugin(); 211f7a47986Sopenharmony_ci } 212f7a47986Sopenharmony_ci if (codeIter->second == nullptr || codeIter->first > static_cast<uint32_t>(EdmInterfaceCode::POLICY_CODE_END)) { 213f7a47986Sopenharmony_ci codeIter = pluginsCode_.erase(codeIter); 214f7a47986Sopenharmony_ci } else { 215f7a47986Sopenharmony_ci ++codeIter; 216f7a47986Sopenharmony_ci } 217f7a47986Sopenharmony_ci } 218f7a47986Sopenharmony_ci for (auto nameIter = pluginsName_.begin(); nameIter != pluginsName_.end();) { 219f7a47986Sopenharmony_ci if (nameIter->second == nullptr || 220f7a47986Sopenharmony_ci nameIter->second->GetCode() > static_cast<uint32_t>(EdmInterfaceCode::POLICY_CODE_END)) { 221f7a47986Sopenharmony_ci nameIter = pluginsName_.erase(nameIter); 222f7a47986Sopenharmony_ci } else { 223f7a47986Sopenharmony_ci ++nameIter; 224f7a47986Sopenharmony_ci } 225f7a47986Sopenharmony_ci } 226f7a47986Sopenharmony_ci for (auto handleIter = pluginHandles_.begin(); handleIter != pluginHandles_.end();) { 227f7a47986Sopenharmony_ci auto handle = *handleIter; 228f7a47986Sopenharmony_ci if (handle == nullptr || dlclose(handle) == 0) { 229f7a47986Sopenharmony_ci handleIter = pluginHandles_.erase(handleIter); 230f7a47986Sopenharmony_ci } else { 231f7a47986Sopenharmony_ci EDMLOGE("PluginManager::UnloadPlugin close handle failed."); 232f7a47986Sopenharmony_ci ++handleIter; 233f7a47986Sopenharmony_ci } 234f7a47986Sopenharmony_ci } 235f7a47986Sopenharmony_ci EDMLOGI("PluginManager::UnloadPlugin finish."); 236f7a47986Sopenharmony_ci} 237f7a47986Sopenharmony_ci 238f7a47986Sopenharmony_civoid PluginManager::DumpPlugin() 239f7a47986Sopenharmony_ci{ 240f7a47986Sopenharmony_ci for (auto it = pluginsCode_.begin(); it != pluginsCode_.end(); it++) { 241f7a47986Sopenharmony_ci std::string setTagPermissions; 242f7a47986Sopenharmony_ci std::string getTagPermissions; 243f7a47986Sopenharmony_ci IPlugin::PolicyPermissionConfig setConfig = it->second->GetAllPermission(FuncOperateType::SET); 244f7a47986Sopenharmony_ci IPlugin::PolicyPermissionConfig getConfig = it->second->GetAllPermission(FuncOperateType::GET); 245f7a47986Sopenharmony_ci for (auto &item : setConfig.tagPermissions) { 246f7a47986Sopenharmony_ci setTagPermissions.append(item.second); 247f7a47986Sopenharmony_ci } 248f7a47986Sopenharmony_ci for (auto &item : getConfig.tagPermissions) { 249f7a47986Sopenharmony_ci getTagPermissions.append(item.second); 250f7a47986Sopenharmony_ci } 251f7a47986Sopenharmony_ci EDMLOGD("PluginManager::Dump plugins_code.code:%{public}u,name:%{public}s,get permission:%{public}s, " 252f7a47986Sopenharmony_ci "set permission:%{public}s,get tagPermissions:%{public}s,set tagPermissions:%{public}s", 253f7a47986Sopenharmony_ci it->first, it->second->GetPolicyName().c_str(), 254f7a47986Sopenharmony_ci it->second->GetPermission(FuncOperateType::GET).c_str(), 255f7a47986Sopenharmony_ci it->second->GetPermission(FuncOperateType::SET).c_str(), 256f7a47986Sopenharmony_ci getTagPermissions.c_str(), setTagPermissions.c_str()); 257f7a47986Sopenharmony_ci } 258f7a47986Sopenharmony_ci for (auto it = pluginsName_.begin(); it != pluginsName_.end(); it++) { 259f7a47986Sopenharmony_ci std::string setTagPermissions; 260f7a47986Sopenharmony_ci std::string getTagPermissions; 261f7a47986Sopenharmony_ci IPlugin::PolicyPermissionConfig setConfig = it->second->GetAllPermission(FuncOperateType::SET); 262f7a47986Sopenharmony_ci IPlugin::PolicyPermissionConfig getConfig = it->second->GetAllPermission(FuncOperateType::GET); 263f7a47986Sopenharmony_ci for (auto &item : setConfig.tagPermissions) { 264f7a47986Sopenharmony_ci setTagPermissions.append(item.second); 265f7a47986Sopenharmony_ci } 266f7a47986Sopenharmony_ci for (auto &item : getConfig.tagPermissions) { 267f7a47986Sopenharmony_ci getTagPermissions.append(item.second); 268f7a47986Sopenharmony_ci } 269f7a47986Sopenharmony_ci EDMLOGD("PluginManager::Dump plugins_name.name:%{public}s,code:%{public}u,get permission type:%{public}s, " 270f7a47986Sopenharmony_ci "set permission type:%{public}s,get tagPermissions:%{public}s,set tagPermissions:%{public}s", 271f7a47986Sopenharmony_ci it->first.c_str(), it->second->GetCode(), 272f7a47986Sopenharmony_ci it->second->GetPermission(FuncOperateType::GET).c_str(), 273f7a47986Sopenharmony_ci it->second->GetPermission(FuncOperateType::SET).c_str(), 274f7a47986Sopenharmony_ci getTagPermissions.c_str(), setTagPermissions.c_str()); 275f7a47986Sopenharmony_ci } 276f7a47986Sopenharmony_ci} 277f7a47986Sopenharmony_ci} // namespace EDM 278f7a47986Sopenharmony_ci} // namespace OHOS 279