* 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 "pixel_map_bridge.h"
#include <dlfcn.h>
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace AAFwk {
namespace {
constexpr const char *IMAGE_NATIVE_WRAP_PATH = "libimage_native_wrap.z.so";
constexpr const char *SYMBOL_READ = "ImageNative_ReadPixelMapFromParcel";
constexpr const char *SYMBOL_WRITE = "ImageNative_WritePixelMapToParcel";
constexpr const char *SYMBOL_DESTROY = "ImageNative_DestroyPixelMap";
}
PixelMapBridge &PixelMapBridge::GetInstance()
{
static PixelMapBridge instance;
return instance;
}
PixelMapBridge::PixelMapBridge() = default;
PixelMapBridge::~PixelMapBridge()
{
UnloadLibrary();
}
void PixelMapBridge::UnloadLibrary()
{
std::lock_guard<std::mutex> lock(mutex_);
if (handle_ != nullptr) {
readFunc_ = nullptr;
writeFunc_ = nullptr;
destroyFunc_ = nullptr;
dlclose(handle_);
handle_ = nullptr;
}
}
bool PixelMapBridge::LoadLibrary()
{
std::lock_guard<std::mutex> lock(mutex_);
if (loadAttempted_) {
return handle_ != nullptr;
}
loadAttempted_ = true;
handle_ = dlopen(IMAGE_NATIVE_WRAP_PATH, RTLD_NOW | RTLD_GLOBAL);
if (handle_ == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "dlopen %{public}s failed", IMAGE_NATIVE_WRAP_PATH);
return false;
}
readFunc_ = reinterpret_cast<ReadPixelMapFunc>(dlsym(handle_, SYMBOL_READ));
writeFunc_ = reinterpret_cast<WritePixelMapFunc>(dlsym(handle_, SYMBOL_WRITE));
destroyFunc_ = reinterpret_cast<DestroyPixelMapFunc>(dlsym(handle_, SYMBOL_DESTROY));
if (readFunc_ == nullptr || writeFunc_ == nullptr || destroyFunc_ == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "dlsym pixelmap wrap symbols failed");
dlclose(handle_);
handle_ = nullptr;
return false;
}
return true;
}
Media::PixelMap *PixelMapBridge::ReadPixelMapFromParcel(Parcel *parcelPtr)
{
if (!LoadLibrary()) {
return nullptr;
}
std::lock_guard<std::mutex> lock(mutex_);
return readFunc_(parcelPtr);
}
bool PixelMapBridge::WritePixelMapToParcel(Media::PixelMap *pixelMapPtr, Parcel *parcelPtr)
{
if (!LoadLibrary()) {
return false;
}
std::lock_guard<std::mutex> lock(mutex_);
return writeFunc_(pixelMapPtr, parcelPtr);
}
void PixelMapBridge::DestroyPixelMap(Media::PixelMap *pixelMapPtr)
{
if (!LoadLibrary()) {
return;
}
std::lock_guard<std::mutex> lock(mutex_);
destroyFunc_(pixelMapPtr);
}
}
}