17405867cSopenharmony_ci/*
27405867cSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
37405867cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
47405867cSopenharmony_ci * you may not use this file except in compliance with the License.
57405867cSopenharmony_ci * You may obtain a copy of the License at
67405867cSopenharmony_ci *
77405867cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
87405867cSopenharmony_ci *
97405867cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
107405867cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
117405867cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127405867cSopenharmony_ci * See the License for the specific language governing permissions and
137405867cSopenharmony_ci * limitations under the License.
147405867cSopenharmony_ci */
157405867cSopenharmony_ci#include "module_loader.h"
167405867cSopenharmony_ci
177405867cSopenharmony_ci#include <dlfcn.h>
187405867cSopenharmony_ci
197405867cSopenharmony_ci#include "app_event_processor_proxy.h"
207405867cSopenharmony_ci#include "file_util.h"
217405867cSopenharmony_ci#include "hiappevent_base.h"
227405867cSopenharmony_ci#include "hilog/log.h"
237405867cSopenharmony_ci
247405867cSopenharmony_ci#undef LOG_DOMAIN
257405867cSopenharmony_ci#define LOG_DOMAIN 0xD002D07
267405867cSopenharmony_ci
277405867cSopenharmony_ci#undef LOG_TAG
287405867cSopenharmony_ci#define LOG_TAG "ModuleLoader"
297405867cSopenharmony_ci
307405867cSopenharmony_cinamespace OHOS {
317405867cSopenharmony_cinamespace HiviewDFX {
327405867cSopenharmony_cinamespace HiAppEvent {
337405867cSopenharmony_cinamespace {
347405867cSopenharmony_cistd::string GetModulePath(const std::string& moduleName)
357405867cSopenharmony_ci{
367405867cSopenharmony_ci    const std::string searchDirs[] = {
377405867cSopenharmony_ci        "/system/lib/platformsdk/", "/system/lib64/platformsdk/", "/system/lib/", "/system/lib64/"
387405867cSopenharmony_ci    };
397405867cSopenharmony_ci    std::string modulePath;
407405867cSopenharmony_ci    std::string libName = "lib" + moduleName + ".z.so";
417405867cSopenharmony_ci    for (auto& searchDir : searchDirs) {
427405867cSopenharmony_ci        std::string tempModulePath = searchDir + libName;
437405867cSopenharmony_ci        if (FileUtil::IsFileExists(tempModulePath)) {
447405867cSopenharmony_ci            modulePath = tempModulePath;
457405867cSopenharmony_ci            break;
467405867cSopenharmony_ci        }
477405867cSopenharmony_ci    }
487405867cSopenharmony_ci    return modulePath;
497405867cSopenharmony_ci}
507405867cSopenharmony_ci}
517405867cSopenharmony_cistd::mutex ModuleLoader::moduleMutex_;
527405867cSopenharmony_cistd::mutex ModuleLoader::processorMutex_;
537405867cSopenharmony_ci
547405867cSopenharmony_ciModuleLoader::~ModuleLoader()
557405867cSopenharmony_ci{
567405867cSopenharmony_ci    processors_.clear();
577405867cSopenharmony_ci
587405867cSopenharmony_ci    for (auto it = modules_.begin(); it != modules_.end(); ++it) {
597405867cSopenharmony_ci        dlclose(it->second);
607405867cSopenharmony_ci        HILOG_INFO(LOG_CORE, "succ to unload module=%{public}s", it->first.c_str());
617405867cSopenharmony_ci    }
627405867cSopenharmony_ci    modules_.clear();
637405867cSopenharmony_ci}
647405867cSopenharmony_ci
657405867cSopenharmony_ciint ModuleLoader::Load(const std::string& moduleName)
667405867cSopenharmony_ci{
677405867cSopenharmony_ci    std::lock_guard<std::mutex> lock(moduleMutex_);
687405867cSopenharmony_ci    if (modules_.find(moduleName) != modules_.end()) {
697405867cSopenharmony_ci        HILOG_DEBUG(LOG_CORE, "the module=%{public}s already exists", moduleName.c_str());
707405867cSopenharmony_ci        return 0;
717405867cSopenharmony_ci    }
727405867cSopenharmony_ci
737405867cSopenharmony_ci    std::string modulePath = GetModulePath(moduleName);
747405867cSopenharmony_ci    if (modulePath.empty()) {
757405867cSopenharmony_ci        HILOG_WARN(LOG_CORE, "the module=%{public}s does not exist.", moduleName.c_str());
767405867cSopenharmony_ci        return -1;
777405867cSopenharmony_ci    }
787405867cSopenharmony_ci    void* handler = nullptr;
797405867cSopenharmony_ci    if (handler = dlopen(modulePath.c_str(), RTLD_GLOBAL); handler == nullptr) {
807405867cSopenharmony_ci        HILOG_ERROR(LOG_CORE, "failed to load module=%{public}s, error=%{public}s.", modulePath.c_str(), dlerror());
817405867cSopenharmony_ci        return -1;
827405867cSopenharmony_ci    }
837405867cSopenharmony_ci    HILOG_INFO(LOG_CORE, "succ to load module=%{public}s.", modulePath.c_str());
847405867cSopenharmony_ci    modules_[moduleName] = handler;
857405867cSopenharmony_ci    return 0;
867405867cSopenharmony_ci}
877405867cSopenharmony_ci
887405867cSopenharmony_ciint ModuleLoader::Unload(const std::string& moduleName)
897405867cSopenharmony_ci{
907405867cSopenharmony_ci    std::lock_guard<std::mutex> lock(moduleMutex_);
917405867cSopenharmony_ci    if (modules_.find(moduleName) == modules_.end()) {
927405867cSopenharmony_ci        HILOG_WARN(LOG_CORE, "the module=%{public}s does not exists", moduleName.c_str());
937405867cSopenharmony_ci        return -1;
947405867cSopenharmony_ci    }
957405867cSopenharmony_ci    dlclose(modules_[moduleName]);
967405867cSopenharmony_ci    modules_.erase(moduleName);
977405867cSopenharmony_ci    HILOG_INFO(LOG_CORE, "succ to unload module=%{public}s", moduleName.c_str());
987405867cSopenharmony_ci    return 0;
997405867cSopenharmony_ci}
1007405867cSopenharmony_ci
1017405867cSopenharmony_ciint ModuleLoader::RegisterProcessor(const std::string& name, std::shared_ptr<AppEventProcessor> processor)
1027405867cSopenharmony_ci{
1037405867cSopenharmony_ci    if (name.empty() || processor == nullptr) {
1047405867cSopenharmony_ci        HILOG_WARN(LOG_CORE, "the name or processor is invalid");
1057405867cSopenharmony_ci        return -1;
1067405867cSopenharmony_ci    }
1077405867cSopenharmony_ci    std::lock_guard<std::mutex> lock(processorMutex_);
1087405867cSopenharmony_ci    if (processors_.find(name) != processors_.end()) {
1097405867cSopenharmony_ci        HILOG_WARN(LOG_CORE, "the processor already exists");
1107405867cSopenharmony_ci        return -1;
1117405867cSopenharmony_ci    }
1127405867cSopenharmony_ci    processors_[name] = processor;
1137405867cSopenharmony_ci    return 0;
1147405867cSopenharmony_ci}
1157405867cSopenharmony_ci
1167405867cSopenharmony_ciint ModuleLoader::UnregisterProcessor(const std::string& name)
1177405867cSopenharmony_ci{
1187405867cSopenharmony_ci    std::lock_guard<std::mutex> lock(processorMutex_);
1197405867cSopenharmony_ci    if (processors_.find(name) == processors_.end()) {
1207405867cSopenharmony_ci        HILOG_WARN(LOG_CORE, "the name is invalid");
1217405867cSopenharmony_ci        return -1;
1227405867cSopenharmony_ci    }
1237405867cSopenharmony_ci    processors_.erase(name);
1247405867cSopenharmony_ci    return 0;
1257405867cSopenharmony_ci}
1267405867cSopenharmony_ci
1277405867cSopenharmony_cistd::shared_ptr<AppEventObserver> ModuleLoader::CreateProcessorProxy(const std::string& name)
1287405867cSopenharmony_ci{
1297405867cSopenharmony_ci    std::lock_guard<std::mutex> lock(processorMutex_);
1307405867cSopenharmony_ci    if (processors_.find(name) == processors_.end()) {
1317405867cSopenharmony_ci        HILOG_WARN(LOG_CORE, "the name is invalid");
1327405867cSopenharmony_ci        return nullptr;
1337405867cSopenharmony_ci    }
1347405867cSopenharmony_ci    return std::make_shared<AppEventProcessorProxy>(name, processors_[name]);
1357405867cSopenharmony_ci}
1367405867cSopenharmony_ci} // namespace HiAppEvent
1377405867cSopenharmony_ci} // namespace HiviewDFX
1387405867cSopenharmony_ci} // namespace OHOS
139