/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef PLUGIN_MANAGER_H #define PLUGIN_MANAGER_H #include #include #include #include "nocopyable.h" #include "i_context.h" #include "i_plugin_manager.h" namespace OHOS { namespace Msdp { namespace DeviceStatus { // Loading、unloading and bookkeeping of modules. class PluginManager final : public IPluginManager { template class Plugin final { public: Plugin(IContext *context, void *handle); ~Plugin(); DISALLOW_COPY_AND_MOVE(Plugin); IPlugin* GetInstance(); private: IContext *context_ { nullptr }; void *handle_ { nullptr }; IPlugin *instance_ { nullptr }; }; template using CreatePlugin = IPlugin* (*)(IContext *context); template using DestroyPlugin = void (*)(IPlugin *); public: PluginManager(IContext *context) : context_(context) {} ~PluginManager() = default; DISALLOW_COPY_AND_MOVE(PluginManager); ICooperate* LoadCooperate() override; void UnloadCooperate() override; IMotionDrag* LoadMotionDrag() override; void UnloadMotionDrag() override; private: template std::unique_ptr> LoadLibrary(IContext *context, const char *libPath); private: std::mutex lock_; IContext *context_ { nullptr }; std::unique_ptr> cooperate_ { nullptr }; std::unique_ptr> motionDrag_ { nullptr }; }; template PluginManager::Plugin::Plugin(IContext *context, void *handle) : context_(context), handle_(handle) {} template PluginManager::Plugin::~Plugin() { if (instance_ != nullptr) { DestroyPlugin destroy = reinterpret_cast>(::dlsym(handle_, "DestroyInstance")); if (destroy != nullptr) { destroy(instance_); } } ::dlclose(handle_); } template IPlugin* PluginManager::Plugin::GetInstance() { if (instance_ != nullptr) { return instance_; } CreatePlugin create = reinterpret_cast>(::dlsym(handle_, "CreateInstance")); if (create != nullptr) { instance_ = create(context_); } return instance_; } template std::unique_ptr> PluginManager::LoadLibrary(IContext *context, const char *libPath) { char realPath[PATH_MAX] = { 0 }; if (realpath(libPath, realPath) == nullptr) { FI_HILOGE("Path is error, path is %{private}s", libPath); return nullptr; } void *handle = ::dlopen(libPath, RTLD_NOW); return (handle != nullptr ? std::make_unique>(context, handle) : nullptr); } } // namespace DeviceStatus } // namespace Msdp } // namespace OHOS #endif // PLUGIN_MANAGER_H