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