180922886Sopenharmony_ci/* 280922886Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 380922886Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 480922886Sopenharmony_ci * you may not use this file except in compliance with the License. 580922886Sopenharmony_ci * You may obtain a copy of the License at 680922886Sopenharmony_ci * 780922886Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 880922886Sopenharmony_ci * 980922886Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1080922886Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1180922886Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1280922886Sopenharmony_ci * See the License for the specific language governing permissions and 1380922886Sopenharmony_ci * limitations under the License. 1480922886Sopenharmony_ci */ 1580922886Sopenharmony_ci 1680922886Sopenharmony_ci#undef LOG_TAG 1780922886Sopenharmony_ci#define LOG_TAG "AVSessionDynamicLoader" 1880922886Sopenharmony_ci 1980922886Sopenharmony_ci#include <dlfcn.h> 2080922886Sopenharmony_ci#include <openssl/crypto.h> 2180922886Sopenharmony_ci#include "avsession_log.h" 2280922886Sopenharmony_ci#include "avsession_errors.h" 2380922886Sopenharmony_ci#include "avsession_dynamic_loader.h" 2480922886Sopenharmony_ci#include "directory_ex.h" 2580922886Sopenharmony_ci 2680922886Sopenharmony_cinamespace OHOS { 2780922886Sopenharmony_cinamespace AVSession { 2880922886Sopenharmony_ciusing namespace std; 2980922886Sopenharmony_ci 3080922886Sopenharmony_ciAVSessionDynamicLoader::AVSessionDynamicLoader() 3180922886Sopenharmony_ci{ 3280922886Sopenharmony_ci SLOGI("AVSessionDynamicLoader ctor"); 3380922886Sopenharmony_ci} 3480922886Sopenharmony_ci 3580922886Sopenharmony_ciAVSessionDynamicLoader::~AVSessionDynamicLoader() 3680922886Sopenharmony_ci{ 3780922886Sopenharmony_ci SLOGI("AVSessionDynamicLoader dtor"); 3880922886Sopenharmony_ci for (auto iterator = dynamicLibHandle_.begin(); iterator != dynamicLibHandle_.end(); ++iterator) { 3980922886Sopenharmony_ci#ifndef TEST_COVERAGE 4080922886Sopenharmony_ci if (iterator->second != nullptr) { 4180922886Sopenharmony_ci OPENSSL_thread_stop(); 4280922886Sopenharmony_ci } 4380922886Sopenharmony_ci dlclose(iterator->second); 4480922886Sopenharmony_ci#endif 4580922886Sopenharmony_ci SLOGI("close library avsession_dynamic success: %{public}s", iterator->first.c_str()); 4680922886Sopenharmony_ci } 4780922886Sopenharmony_ci} 4880922886Sopenharmony_ci 4980922886Sopenharmony_civoid* AVSessionDynamicLoader::OpenDynamicHandle(std::string dynamicLibrary) 5080922886Sopenharmony_ci{ 5180922886Sopenharmony_ci std::lock_guard loaderLock(libLock_); 5280922886Sopenharmony_ci // if not opened, then open directly 5380922886Sopenharmony_ci // do we need lock? 5480922886Sopenharmony_ci // further optimization: 5580922886Sopenharmony_ci // 1. split all dependencies to separate libraries 5680922886Sopenharmony_ci // 2. just close each library not all 5780922886Sopenharmony_ci char realCachePath[PATH_MAX] = { 0X00 }; 5880922886Sopenharmony_ci char *realPathRes = realpath(dynamicLibrary.c_str(), realCachePath); 5980922886Sopenharmony_ci if (realPathRes == nullptr || dynamicLibrary.find(".so") == std::string::npos) { 6080922886Sopenharmony_ci SLOGD("OpenDynamicHandle get dynamicLibrary %{public}s", dynamicLibrary.c_str()); 6180922886Sopenharmony_ci } 6280922886Sopenharmony_ci if (dynamicLibHandle_[dynamicLibrary] == nullptr) { 6380922886Sopenharmony_ci char sourceLibraryRealPath[PATH_MAX] = { 0x00 }; 6480922886Sopenharmony_ci if (realpath(dynamicLibrary.c_str(), sourceLibraryRealPath) == nullptr) { 6580922886Sopenharmony_ci SLOGE("check avsession_dynamic path failed %{public}s", dynamicLibrary.c_str()); 6680922886Sopenharmony_ci return nullptr; 6780922886Sopenharmony_ci } 6880922886Sopenharmony_ci 6980922886Sopenharmony_ci#ifndef TEST_COVERAGE 7080922886Sopenharmony_ci void* dynamicLibHandle = dlopen(sourceLibraryRealPath, RTLD_NOW); 7180922886Sopenharmony_ci if (dynamicLibHandle == nullptr) { 7280922886Sopenharmony_ci SLOGE("Failed to open library avsession_dynamic, reason: %{public}sn", dlerror()); 7380922886Sopenharmony_ci return nullptr; 7480922886Sopenharmony_ci } 7580922886Sopenharmony_ci SLOGI("open library %{public}s success", dynamicLibrary.c_str()); 7680922886Sopenharmony_ci dynamicLibHandle_[dynamicLibrary] = dynamicLibHandle; 7780922886Sopenharmony_ci#else 7880922886Sopenharmony_ci SLOGI("in test coverage state, dlclose/dlopen may conflict with llvm"); 7980922886Sopenharmony_ci#endif 8080922886Sopenharmony_ci } 8180922886Sopenharmony_ci return dynamicLibHandle_[dynamicLibrary]; 8280922886Sopenharmony_ci} 8380922886Sopenharmony_ci 8480922886Sopenharmony_civoid* AVSessionDynamicLoader::GetFuntion(std::string dynamicLibrary, std::string function) 8580922886Sopenharmony_ci{ 8680922886Sopenharmony_ci std::lock_guard loaderLock(libLock_); 8780922886Sopenharmony_ci // if not opened, then open directly 8880922886Sopenharmony_ci if (dynamicLibHandle_[dynamicLibrary] == nullptr) { 8980922886Sopenharmony_ci OpenDynamicHandle(dynamicLibrary); 9080922886Sopenharmony_ci } 9180922886Sopenharmony_ci 9280922886Sopenharmony_ci void* handle = nullptr; 9380922886Sopenharmony_ci if (dynamicLibHandle_[dynamicLibrary] != nullptr) { 9480922886Sopenharmony_ci handle = dlsym(dynamicLibHandle_[dynamicLibrary], function.c_str()); 9580922886Sopenharmony_ci if (handle == nullptr) { 9680922886Sopenharmony_ci SLOGE("Failed to load %{public}s, reason: %{public}sn", function.c_str(), dlerror()); 9780922886Sopenharmony_ci return nullptr; 9880922886Sopenharmony_ci } 9980922886Sopenharmony_ci SLOGI("GetFuntion %{public}s success", function.c_str()); 10080922886Sopenharmony_ci } 10180922886Sopenharmony_ci return handle; 10280922886Sopenharmony_ci} 10380922886Sopenharmony_ci 10480922886Sopenharmony_civoid AVSessionDynamicLoader::CloseDynamicHandle(std::string dynamicLibrary) 10580922886Sopenharmony_ci{ 10680922886Sopenharmony_ci std::lock_guard loaderLock(libLock_); 10780922886Sopenharmony_ci // if already opened, then close all 10880922886Sopenharmony_ci if (dynamicLibHandle_[dynamicLibrary] != nullptr) { 10980922886Sopenharmony_ci#ifndef TEST_COVERAGE 11080922886Sopenharmony_ci OPENSSL_thread_stop(); 11180922886Sopenharmony_ci dlclose(dynamicLibHandle_[dynamicLibrary]); 11280922886Sopenharmony_ci#endif 11380922886Sopenharmony_ci dynamicLibHandle_[dynamicLibrary] = nullptr; 11480922886Sopenharmony_ci SLOGI("close library avsession_dynamic success: %{public}s", dynamicLibrary.c_str()); 11580922886Sopenharmony_ci } 11680922886Sopenharmony_ci} 11780922886Sopenharmony_ci 11880922886Sopenharmony_ci} // namespace AVSession 11980922886Sopenharmony_ci} // namespace OHOS