1 /*
2 * Copyright (c) 2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioEffectServer"
17 #endif
18
19 #include <iostream>
20 #include <vector>
21 #include "functional"
22 #include "memory"
23 #include <dlfcn.h>
24 #include "unistd.h"
25 #include "audio_service_log.h"
26 #include "audio_effect_server.h"
27 #include "media_monitor_manager.h"
28
29 namespace OHOS {
30 namespace AudioStandard {
31
32 #if (defined(__aarch64__) || defined(__x86_64__))
33 constexpr const char *LD_EFFECT_LIBRARY_PATH[] = {"/sys_prod/lib64/", "/system/lib64/"};
34 #else
35 constexpr const char *LD_EFFECT_LIBRARY_PATH[] = {"/sys_prod/lib/", "/system/lib/"};
36 #endif
37
ResolveLibrary(const std::string & path,std::string & resovledPath)38 bool ResolveLibrary(const std::string &path, std::string &resovledPath)
39 {
40 for (auto *libDir: LD_EFFECT_LIBRARY_PATH) {
41 std::string candidatePath = std::string(libDir) + "/" + path;
42 if (access(candidatePath.c_str(), R_OK) == 0) {
43 resovledPath = std::move(candidatePath);
44 return true;
45 }
46 }
47
48 return false;
49 }
50
LoadLibrary(const std::string & relativePath,std::shared_ptr<AudioEffectLibEntry> & libEntry)51 static bool LoadLibrary(const std::string &relativePath, std::shared_ptr<AudioEffectLibEntry> &libEntry) noexcept
52 {
53 std::string absolutePath;
54 // find library in adsolutePath
55 if (!ResolveLibrary(relativePath, absolutePath)) {
56 AUDIO_ERR_LOG("<log error> find library falied in effect directories: %{public}s",
57 relativePath.c_str());
58 return false;
59 }
60
61 void* handle = dlopen(absolutePath.c_str(), 1);
62 if (!handle) {
63 AUDIO_ERR_LOG("<log error> dlopen lib %{public}s Fail", relativePath.c_str());
64 return false;
65 } else {
66 AUDIO_INFO_LOG("<log info> dlopen lib %{public}s successful", relativePath.c_str());
67 }
68 dlerror(); // clean existing errors;
69
70 AudioEffectLibrary *audioEffectLibHandle = static_cast<AudioEffectLibrary *>(dlsym(handle,
71 AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR));
72 if (!audioEffectLibHandle) {
73 AUDIO_ERR_LOG("<log error> dlsym failed: error: %{public}s", dlerror());
74 #ifndef TEST_COVERAGE
75 dlclose(handle);
76 #endif
77 return false;
78 }
79 AUDIO_INFO_LOG("<log info> dlsym lib %{public}s successful", relativePath.c_str());
80
81 libEntry->audioEffectLibHandle = audioEffectLibHandle;
82
83 return true;
84 }
85
LoadLibraries(const std::vector<Library> & libs,std::vector<std::shared_ptr<AudioEffectLibEntry>> & libList)86 static void LoadLibraries(const std::vector<Library> &libs, std::vector<std::shared_ptr<AudioEffectLibEntry>> &libList)
87 {
88 for (Library library: libs) {
89 AUDIO_INFO_LOG("<log info> loading %{public}s : %{public}s", library.name.c_str(), library.path.c_str());
90
91 std::shared_ptr<AudioEffectLibEntry> libEntry = std::make_shared<AudioEffectLibEntry>();
92 libEntry->libraryName = library.name;
93
94 bool loadLibrarySuccess = LoadLibrary(library.path, libEntry);
95 if (!loadLibrarySuccess) {
96 AUDIO_ERR_LOG("<log error> loadLibrary fail, please check logs!");
97
98 // hisysevent for load engine error
99 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
100 Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_EFFECT_ENGINE_ERROR,
101 Media::MediaMonitor::FAULT_EVENT);
102 bean->Add("ENGINE_TYPE", Media::MediaMonitor::AUDIO_EFFECT_PROCESS_ENGINE);
103 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
104
105 continue;
106 }
107
108 // Register library load success
109 libList.emplace_back(std::move(libEntry));
110 }
111 }
112
FindLibrary(const std::string & name,const std::vector<std::shared_ptr<AudioEffectLibEntry>> & libList)113 std::shared_ptr<AudioEffectLibEntry> FindLibrary(const std::string &name,
114 const std::vector<std::shared_ptr<AudioEffectLibEntry>> &libList)
115 {
116 for (const std::shared_ptr<AudioEffectLibEntry> &lib : libList) {
117 if (lib->libraryName == name) {
118 return lib;
119 }
120 }
121
122 return nullptr;
123 }
124
LoadEffect(const Effect & effect,const std::vector<std::shared_ptr<AudioEffectLibEntry>> & libList)125 static bool LoadEffect(const Effect &effect, const std::vector<std::shared_ptr<AudioEffectLibEntry>> &libList)
126 {
127 std::shared_ptr<AudioEffectLibEntry> currentLibEntry = FindLibrary(effect.libraryName, libList);
128 if (currentLibEntry == nullptr) {
129 AUDIO_ERR_LOG("<log error> could not find library %{public}s to load effect %{public}s",
130 effect.libraryName.c_str(), effect.name.c_str());
131 return false;
132 }
133 // check effect
134 AudioEffectDescriptor descriptor;
135 descriptor.libraryName = effect.libraryName;
136 descriptor.effectName = effect.name;
137
138 bool ret = currentLibEntry->audioEffectLibHandle->checkEffect(descriptor);
139 if (ret) {
140 currentLibEntry->effectName.push_back(effect.name);
141 } else {
142 AUDIO_ERR_LOG("<log error> the effect %{public}s in lib %{public}s, open check file!",
143 effect.name.c_str(), effect.libraryName.c_str());
144 return false;
145 }
146
147 return true;
148 }
149
CheckEffects(const std::vector<Effect> & effects,const std::vector<std::shared_ptr<AudioEffectLibEntry>> & libList,std::vector<Effect> & successEffectList)150 void CheckEffects(const std::vector<Effect> &effects, const std::vector<std::shared_ptr<AudioEffectLibEntry>> &libList,
151 std::vector<Effect> &successEffectList)
152 {
153 for (Effect effect: effects) {
154 bool ret = LoadEffect(effect, libList);
155 if (!ret) {
156 AUDIO_ERR_LOG("<log error> LoadEffects have failures, please check log!");
157 continue;
158 }
159
160 successEffectList.push_back(effect);
161 }
162 }
163
AudioEffectServer()164 AudioEffectServer::AudioEffectServer()
165 {
166 AUDIO_INFO_LOG("AudioEffectServer ctor");
167 }
168
~AudioEffectServer()169 AudioEffectServer::~AudioEffectServer()
170 {
171 }
172
LoadAudioEffects(const std::vector<Library> & libraries,const std::vector<Effect> & effects,std::vector<Effect> & successEffectList)173 bool AudioEffectServer::LoadAudioEffects(const std::vector<Library> &libraries, const std::vector<Effect> &effects,
174 std::vector<Effect> &successEffectList)
175 {
176 // load library
177 LoadLibraries(libraries, effectLibEntries_);
178
179 // check effects
180 CheckEffects(effects, effectLibEntries_, successEffectList);
181 if (successEffectList.size() > 0) {
182 return true;
183 } else {
184 return false;
185 }
186 }
187
GetEffectEntries()188 std::vector<std::shared_ptr<AudioEffectLibEntry>> &AudioEffectServer::GetEffectEntries()
189 {
190 return effectLibEntries_;
191 }
192
193 } // namespce AudioStandard
194 } // namespace OHOS
195