1/* 2 * Copyright (c) 2023-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#include "module_loader.h" 16 17#include <dlfcn.h> 18 19#include "app_event_processor_proxy.h" 20#include "file_util.h" 21#include "hiappevent_base.h" 22#include "hilog/log.h" 23 24#undef LOG_DOMAIN 25#define LOG_DOMAIN 0xD002D07 26 27#undef LOG_TAG 28#define LOG_TAG "ModuleLoader" 29 30namespace OHOS { 31namespace HiviewDFX { 32namespace HiAppEvent { 33namespace { 34std::string GetModulePath(const std::string& moduleName) 35{ 36 const std::string searchDirs[] = { 37 "/system/lib/platformsdk/", "/system/lib64/platformsdk/", "/system/lib/", "/system/lib64/" 38 }; 39 std::string modulePath; 40 std::string libName = "lib" + moduleName + ".z.so"; 41 for (auto& searchDir : searchDirs) { 42 std::string tempModulePath = searchDir + libName; 43 if (FileUtil::IsFileExists(tempModulePath)) { 44 modulePath = tempModulePath; 45 break; 46 } 47 } 48 return modulePath; 49} 50} 51std::mutex ModuleLoader::moduleMutex_; 52std::mutex ModuleLoader::processorMutex_; 53 54ModuleLoader::~ModuleLoader() 55{ 56 processors_.clear(); 57 58 for (auto it = modules_.begin(); it != modules_.end(); ++it) { 59 dlclose(it->second); 60 HILOG_INFO(LOG_CORE, "succ to unload module=%{public}s", it->first.c_str()); 61 } 62 modules_.clear(); 63} 64 65int ModuleLoader::Load(const std::string& moduleName) 66{ 67 std::lock_guard<std::mutex> lock(moduleMutex_); 68 if (modules_.find(moduleName) != modules_.end()) { 69 HILOG_DEBUG(LOG_CORE, "the module=%{public}s already exists", moduleName.c_str()); 70 return 0; 71 } 72 73 std::string modulePath = GetModulePath(moduleName); 74 if (modulePath.empty()) { 75 HILOG_WARN(LOG_CORE, "the module=%{public}s does not exist.", moduleName.c_str()); 76 return -1; 77 } 78 void* handler = nullptr; 79 if (handler = dlopen(modulePath.c_str(), RTLD_GLOBAL); handler == nullptr) { 80 HILOG_ERROR(LOG_CORE, "failed to load module=%{public}s, error=%{public}s.", modulePath.c_str(), dlerror()); 81 return -1; 82 } 83 HILOG_INFO(LOG_CORE, "succ to load module=%{public}s.", modulePath.c_str()); 84 modules_[moduleName] = handler; 85 return 0; 86} 87 88int ModuleLoader::Unload(const std::string& moduleName) 89{ 90 std::lock_guard<std::mutex> lock(moduleMutex_); 91 if (modules_.find(moduleName) == modules_.end()) { 92 HILOG_WARN(LOG_CORE, "the module=%{public}s does not exists", moduleName.c_str()); 93 return -1; 94 } 95 dlclose(modules_[moduleName]); 96 modules_.erase(moduleName); 97 HILOG_INFO(LOG_CORE, "succ to unload module=%{public}s", moduleName.c_str()); 98 return 0; 99} 100 101int ModuleLoader::RegisterProcessor(const std::string& name, std::shared_ptr<AppEventProcessor> processor) 102{ 103 if (name.empty() || processor == nullptr) { 104 HILOG_WARN(LOG_CORE, "the name or processor is invalid"); 105 return -1; 106 } 107 std::lock_guard<std::mutex> lock(processorMutex_); 108 if (processors_.find(name) != processors_.end()) { 109 HILOG_WARN(LOG_CORE, "the processor already exists"); 110 return -1; 111 } 112 processors_[name] = processor; 113 return 0; 114} 115 116int ModuleLoader::UnregisterProcessor(const std::string& name) 117{ 118 std::lock_guard<std::mutex> lock(processorMutex_); 119 if (processors_.find(name) == processors_.end()) { 120 HILOG_WARN(LOG_CORE, "the name is invalid"); 121 return -1; 122 } 123 processors_.erase(name); 124 return 0; 125} 126 127std::shared_ptr<AppEventObserver> ModuleLoader::CreateProcessorProxy(const std::string& name) 128{ 129 std::lock_guard<std::mutex> lock(processorMutex_); 130 if (processors_.find(name) == processors_.end()) { 131 HILOG_WARN(LOG_CORE, "the name is invalid"); 132 return nullptr; 133 } 134 return std::make_shared<AppEventProcessorProxy>(name, processors_[name]); 135} 136} // namespace HiAppEvent 137} // namespace HiviewDFX 138} // namespace OHOS 139