1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "external_loader.h"
17 #include "effect_trace.h"
18
19 #include <dlfcn.h>
20
21 namespace OHOS {
22 namespace Media {
23 namespace Effect {
Instance()24 ExternLoader *ExternLoader::Instance()
25 {
26 static ExternLoader instance;
27 return &instance;
28 }
29
LoadExtSo()30 void ExternLoader::LoadExtSo()
31 {
32 EFFECT_TRACE_NAME("ExternLoader::LoadExtSo");
33 std::unique_lock<std::mutex> lock(loadExtSo_);
34 EFFECT_LOGI("EFilterFactory:LoadExtSo enter!");
35 if (isExtLoad_) {
36 return;
37 }
38
39 void *effectExtHandle = dlopen("libimage_effect_ext.so", RTLD_NOW);
40 if (effectExtHandle == nullptr) {
41 EFFECT_LOGE("EFilterFactory: dlopen libimage_effect_ext.so failed! dlerror=%{public}s", dlerror());
42 isExtLoad_ = false;
43 return;
44 }
45 EFFECT_LOGI("EFilterFactory: dlopen libimage_effect_ext.so success!");
46
47 bool allSymbolsLoaded = true; // 用于跟踪所有符号是否加载成功
48
49 void* initFunc = dlsym(effectExtHandle, "Init");
50 if (!initFunc) {
51 EFFECT_LOGE("EFilterFactory: dlsym Init failed! dlerror=%{public}s", dlerror());
52 allSymbolsLoaded = false;
53 }
54
55 void* deinitFunc = dlsym(effectExtHandle, "Deinit");
56 if (!deinitFunc) {
57 EFFECT_LOGE("EFilterFactory: dlsym Deinit failed! dlerror=%{public}s", dlerror());
58 allSymbolsLoaded = false;
59 }
60
61 void* initModuleFunc = dlsym(effectExtHandle, "InitMoudle");
62 if (!initModuleFunc) {
63 EFFECT_LOGE("EFilterFactory: dlsym InitMoudle failed! dlerror=%{public}s", dlerror());
64 allSymbolsLoaded = false;
65 }
66
67 void* deinitModuleFunc = dlsym(effectExtHandle, "DeinitModule");
68 if (!deinitModuleFunc) {
69 EFFECT_LOGE("EFilterFactory: dlsym DeinitModule failed! dlerror=%{public}s", dlerror());
70 allSymbolsLoaded = false;
71 }
72
73 // 如果dlsym调用成功, 将临时指针赋值给类成员
74 if (allSymbolsLoaded) {
75 initFunc_ = reinterpret_cast<InitModuleFunc>(initFunc);
76 deinitFunc_ = reinterpret_cast<InitModuleFunc>(deinitFunc);
77 initModuleFunc_ = reinterpret_cast<InitModuleFunc>(initModuleFunc);
78 deinitModuleFunc_ = reinterpret_cast<InitModuleFunc>(deinitModuleFunc);
79 isExtLoad_ = true;
80 } else {
81 // 如果有任何dlsym调用失败, 关闭动态链接库
82 dlclose(effectExtHandle);
83 effectExtHandle = nullptr;
84 isExtLoad_ = false;
85 EFFECT_LOGE("EFilterFactory: LoadExtSo failed due to dlsym errors.");
86 }
87 }
88
IsExtLoad() const89 bool ExternLoader::IsExtLoad() const
90 {
91 return isExtLoad_;
92 }
93
GetInitFunc() const94 InitFunc ExternLoader::GetInitFunc() const
95 {
96 return initFunc_;
97 }
98
GetDeinitFunc() const99 InitFunc ExternLoader::GetDeinitFunc() const
100 {
101 return deinitFunc_;
102 }
103
GetInitModuleFunc() const104 InitModuleFunc ExternLoader::GetInitModuleFunc() const
105 {
106 return initModuleFunc_;
107 }
108
GetDeinitModuleFunc() const109 InitModuleFunc ExternLoader::GetDeinitModuleFunc() const
110 {
111 return deinitModuleFunc_;
112 }
113
InitExt()114 void ExternLoader::InitExt()
115 {
116 std::unique_lock<std::mutex> lock(initExtSo_);
117 if (!IsExtLoad()) {
118 LoadExtSo();
119 }
120
121 if (hasInitExt_) {
122 return;
123 }
124
125 auto initFunc = ExternLoader::Instance()->GetInitFunc();
126 if (initFunc) {
127 initFunc();
128 } else {
129 EFFECT_LOGE("EFilterFactory: shared lib so not find function!");
130 }
131 hasInitExt_ = true;
132 }
133 } // namespace Effect
134 } // namespace Media
135 } // namespace OHOS