* Copyright (c) 2026 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.
*/
#include <cinttypes>
#include "bgtask_plugin_mgr.h"
#include "bgtaskmgr_log_wrapper.h"
#include "plugin_mgr.h"
namespace OHOS {
namespace BackgroundTaskMgr {
using namespace OHOS::ResourceSchedule;
namespace {
const std::string_view LIB_NAME = "libbgtaskmgr_service.z.so";
}
IMPLEMENT_SINGLE_INSTANCE(BgtaskPluginMgr);
void BgtaskPluginMgr::RegisterAsyncPluginByValue(const uint32_t resType,
const std::shared_ptr<BgtaskPlugin> plugin)
{
auto valueList = plugin->GetPluginValue(resType);
for (const auto& value : valueList) {
if (value != RES_VALUE_FOR_ALL) {
PluginMgr::GetInstance().SubscribeResourceAccurately(std::string(LIB_NAME), resType, value);
} else {
PluginMgr::GetInstance().SubscribeResource(std::string(LIB_NAME), resType);
}
}
}
void BgtaskPluginMgr::Init()
{
std::lock_guard<std::mutex> lock(cbMapMutex_);
for (auto it = asyncCbMap_.begin(); it != asyncCbMap_.end(); it++) {
if (it->second != nullptr) {
it->second->Init();
RegisterAsyncPluginByValue(it->first, it->second);
BGTASK_LOGI("Subscribe async resType: %{public}u", it->first);
}
}
pluginEnable.store(true);
BGTASK_LOGI("BgtaskPluginMgr init success, %{public}zu plugins registered", asyncCbMap_.size());
}
void BgtaskPluginMgr::Disable()
{
pluginEnable.store(false);
std::lock_guard<std::mutex> lock(cbMapMutex_);
for (auto it = asyncCbMap_.begin(); it != asyncCbMap_.end(); it++) {
auto valueList = it->second->GetPluginValue(it->first);
for (const auto& value : valueList) {
if (value == RES_VALUE_FOR_ALL) {
PluginMgr::GetInstance().UnSubscribeResource(std::string(LIB_NAME), it->first);
} else {
PluginMgr::GetInstance().UnSubscribeResourceAccurately(std::string(LIB_NAME), it->first, value);
}
}
it->second->Uninit();
}
}
void BgtaskPluginMgr::DispatchResource(const std::shared_ptr<ResourceSchedule::ResData>& resData)
{
if (!pluginEnable.load() || resData == nullptr) {
BGTASK_LOGE("SuspendManagerPluginMgr not enable or data is nullptr");
return;
}
BGTASK_LOGD("BgtaskPluginMgr dispatch resource, type: %{public}u, value: %{public}" PRId64,
resData->resType, resData->value);
std::lock_guard<std::mutex> lock(cbMapMutex_);
auto iter = asyncCbMap_.find(resData->resType);
if (iter != asyncCbMap_.end() && iter->second != nullptr) {
iter->second->DispatchResource(resData->resType, resData->value, resData->payload);
}
}
void BgtaskPluginMgr::RegisterAsyncPlugin(const uint32_t resType, const std::shared_ptr<BgtaskPlugin> plugin)
{
if (plugin == nullptr) {
BGTASK_LOGE("plugin is null");
return;
}
BGTASK_LOGD("Register async plugin, type: %{public}u", resType);
std::lock_guard<std::mutex> lock(cbMapMutex_);
auto it = asyncCbMap_.find(resType);
if (it != asyncCbMap_.end() && it->second != nullptr) {
BGTASK_LOGW("resType:%{public}u registed by %{public}s", resType, it->second->GetPluginName().c_str());
} else {
if (pluginEnable.load()) {
RegisterAsyncPluginByValue(resType, plugin);
BGTASK_LOGI("Register async plugin, type: %{public}u", resType);
}
}
asyncCbMap_.emplace(resType, plugin);
}
extern "C" bool OnPluginInit(std::string& libName)
{
if (libName != std::string(LIB_NAME)) {
BGTASK_LOGE("lib name is not match");
return false;
}
BgtaskPluginMgr::GetInstance().Init();
BGTASK_LOGD("BgtaskPluginMgr OnPluginInit success");
return true;
}
extern "C" void OnPluginDisable()
{
BgtaskPluginMgr::GetInstance().Disable();
BGTASK_LOGD("BgtaskPluginMgr OnPluginDisable success");
}
extern "C" void OnDispatchResource(const std::shared_ptr<ResourceSchedule::ResData>& resData)
{
BgtaskPluginMgr::GetInstance().DispatchResource(resData);
}
}
}