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