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 <securec.h>
16 #include <string.h>
17 #include "effect_core.h"
18 #include "effect_host_common.h"
19 #include "v1_0/effect_types_vdi.h"
20 #include "v1_0/effect_factory.h"
21 #include "osal_mem.h"
22 #include "parse_effect_config.h"
23 #include "audio_uhdf_log.h"
24 
25 #define AUDIO_EFFECT_PLAFORM_CONFIG HDF_CONFIG_DIR"/audio_effect.json"
26 #define AUDIO_EFFECT_PRODUCT_CONFIG HDF_CHIP_PROD_CONFIG_DIR"/audio_effect.json"
27 #define HDF_LOG_TAG HDF_AUDIO_EFFECT
28 #define AUDIO_EFFECT_NUM_MAX 10
29 struct ConfigDescriptor *g_cfgDescs = NULL;
30 struct AudioEffectLibInfo {
31     char *libName;
32     uint8_t *libHandle;
33     struct EffectFactory *libEffect;
34     struct ControllerManager *ctrlMgr;
35     int32_t effectCnt;
36 };
37 struct AudioEffectLibInfo *g_libInfos[AUDIO_EFFECT_NUM_MAX] = { NULL };
38 
GetEffectLibInfoByName(const char * libName)39 static struct AudioEffectLibInfo* GetEffectLibInfoByName(const char *libName)
40 {
41     if (libName == NULL) {
42         HDF_LOGE("%{public}s: invailid input params", __func__);
43         return NULL;
44     }
45     struct AudioEffectLibInfo *libInfo = NULL;
46     for (int i = 0; i <= AUDIO_EFFECT_NUM_MAX; i++) {
47         if (i == AUDIO_EFFECT_NUM_MAX) {
48             HDF_LOGE("%{public}s: can not find %{public}s", __func__, libName);
49             return NULL;
50         }
51         if (g_libInfos[i] == NULL || strcmp(g_libInfos[i]->libName, libName) != 0) {
52             continue;
53         }
54         libInfo = g_libInfos[i];
55         break;
56     }
57     return libInfo;
58 }
59 
LoadLibraryByName(const char * libName,uint8_t ** libHandle,struct EffectFactory ** factLib)60 static int32_t LoadLibraryByName(const char *libName, uint8_t **libHandle, struct EffectFactory **factLib)
61 {
62     if (libName == NULL || factLib == NULL || libHandle == NULL) {
63         HDF_LOGE("%{public}s: invailid input params", __func__);
64         return HDF_ERR_INVALID_PARAM;
65     }
66     int32_t ret = 0;
67     struct EffectFactory *(*getFactoryLib)(void);
68     char path[PATH_MAX];
69     char pathBuf[PATH_MAX];
70 #if (defined(__aarch64__) || defined(__x86_64__))
71     ret = snprintf_s(path, PATH_MAX, PATH_MAX, "/vendor/lib64/%s.z.so", libName);
72 #else
73     ret = snprintf_s(path, PATH_MAX, PATH_MAX, "/vendor/lib/%s.z.so", libName);
74 #endif
75     if (ret < 0) {
76         HDF_LOGE("%{public}s: get libPath failed", __func__);
77         return HDF_FAILURE;
78     }
79     if (realpath(path, pathBuf) == NULL) {
80         HDF_LOGE("%{public}s: realpath is null! [%{public}d]", __func__, errno);
81         return HDF_FAILURE;
82     }
83     if (strncmp(HDF_LIBRARY_DIR, pathBuf, strlen(HDF_LIBRARY_DIR)) != 0) {
84         HDF_LOGE("%{public}s: The file path is incorrect", __func__);
85         return HDF_FAILURE;
86     }
87 
88     void *handle = dlopen(pathBuf, RTLD_LAZY);
89     if (handle == NULL) {
90         HDF_LOGE("%{public}s: open so failed, reason:%{public}s", __func__, dlerror());
91         return HDF_FAILURE;
92     }
93 
94     getFactoryLib = dlsym(handle, "GetEffectoyFactoryLib");
95     if (getFactoryLib == NULL) {
96         HDF_LOGE("%{public}s: dlsym failed %{public}s", __func__, dlerror());
97         dlclose(handle);
98         return HDF_FAILURE;
99     }
100     *factLib = getFactoryLib();
101     if (*factLib == NULL) {
102         HDF_LOGE("%{public}s: get fact lib failed %{public}s", __func__, dlerror());
103         dlclose(handle);
104         return HDF_FAILURE;
105     }
106     *libHandle = handle;
107     return HDF_SUCCESS;
108 }
109 
AddEffectLibInfo(const char * libName,uint8_t * libHandle,struct EffectFactory * factLib)110 static struct AudioEffectLibInfo* AddEffectLibInfo(const char *libName, uint8_t *libHandle,
111     struct EffectFactory *factLib)
112 {
113     if (libName == NULL || factLib == NULL || libHandle == NULL) {
114         HDF_LOGE("%{public}s: invailid input params", __func__);
115         return NULL;
116     }
117     struct AudioEffectLibInfo *libInfo = NULL;
118     libInfo = (struct AudioEffectLibInfo *)OsalMemCalloc(sizeof(struct AudioEffectLibInfo));
119     if (libInfo == NULL) {
120         HDF_LOGE("%{public}s: OsalMemCalloc fail", __func__);
121         return NULL;
122     }
123     libInfo->libName = strdup(libName);
124     if (libInfo->libName == NULL) {
125         HDF_LOGE("%{public}s: strdup fail", __func__);
126         OsalMemFree(libInfo);
127         libInfo = NULL;
128         return NULL;
129     }
130     libInfo->libHandle = libHandle;
131     libInfo->libEffect = factLib;
132     libInfo->ctrlMgr = NULL;
133     libInfo->effectCnt = 1;
134     return libInfo;
135 }
136 
LoadEffectLibrary(const char * libName,struct EffectFactory ** factLib,struct ControllerManager ** ctrlMgr)137 static int32_t LoadEffectLibrary(const char *libName, struct EffectFactory **factLib,
138     struct ControllerManager** ctrlMgr)
139 {
140     if (libName == NULL || factLib == NULL || ctrlMgr == NULL) {
141         HDF_LOGE("%{public}s: invailid input params", __func__);
142         return HDF_ERR_INVALID_PARAM;
143     }
144     uint8_t *libHandle = NULL;
145     int32_t index = 0;
146     for (int i = 0; i <= AUDIO_EFFECT_NUM_MAX; i++) {
147         if (i == AUDIO_EFFECT_NUM_MAX) {
148             HDF_LOGE("%{public}s: over effect max num", __func__);
149             return HDF_FAILURE;
150         }
151         if (g_libInfos[i] == NULL) {
152             index = i;
153             break;
154         }
155         if (strcmp(g_libInfos[i]->libName, libName) != 0) {
156             continue;
157         }
158         g_libInfos[i]->effectCnt++;
159         *factLib = g_libInfos[i]->libEffect;
160         *ctrlMgr = g_libInfos[i]->ctrlMgr;
161         HDF_LOGI("%{public}s: %{public}s increase, cnt=[%{public}d]", __func__, libName, g_libInfos[i]->effectCnt);
162         return HDF_SUCCESS;
163     }
164     int32_t ret = LoadLibraryByName(libName, &libHandle, factLib);
165     if (ret != HDF_SUCCESS || libHandle == NULL || *factLib == NULL) {
166         HDF_LOGE("%{public}s: load lib fail, libName:[%{public}s]", __func__, libName);
167         return HDF_FAILURE;
168     }
169     g_libInfos[index] = AddEffectLibInfo(libName, libHandle, *factLib);
170     if (g_libInfos[index] == NULL) {
171         HDF_LOGE("%{public}s: AddEffectLibInfo fail", __func__);
172         dlclose((void *)libHandle);
173         return HDF_FAILURE;
174     }
175     HDF_LOGI("%{public}s: %{public}s create, cnt=[%{public}d]", __func__, libName, g_libInfos[index]->effectCnt);
176     return HDF_SUCCESS;
177 }
178 
DeleteEffectLibrary(const char * libName)179 static int32_t DeleteEffectLibrary(const char *libName)
180 {
181     if (libName == NULL) {
182         HDF_LOGE("%{public}s: invailid input params", __func__);
183         return HDF_ERR_INVALID_PARAM;
184     }
185     for (int i = 0; i <= AUDIO_EFFECT_NUM_MAX; i++) {
186         if (i == AUDIO_EFFECT_NUM_MAX) {
187             HDF_LOGE("%{public}s: fail to destroy effect, can not find %{public}s", __func__, libName);
188             return HDF_FAILURE;
189         }
190         if (g_libInfos[i] == NULL || strcmp(g_libInfos[i]->libName, libName) != 0) {
191             continue;
192         }
193         if (g_libInfos[i]->effectCnt > 1) {
194             g_libInfos[i]->effectCnt--;
195             HDF_LOGI("%{public}s: %{public}s decrease, cnt=[%{public}d]", __func__, libName, g_libInfos[i]->effectCnt);
196             return HDF_SUCCESS;
197         }
198         dlclose((void*)g_libInfos[i]->libHandle);
199         OsalMemFree(g_libInfos[i]->libName);
200         OsalMemFree(g_libInfos[i]->ctrlMgr);
201         OsalMemFree(g_libInfos[i]);
202         g_libInfos[i] = NULL;
203         break;
204     }
205     HDF_LOGI("%{public}s: %{public}s delete", __func__, libName);
206     return HDF_SUCCESS;
207 }
208 
IsSupplyEffect(const char * libName)209 static int32_t IsSupplyEffect(const char *libName)
210 {
211     if (g_cfgDescs == NULL) {
212         HDF_LOGE("%{public}s: point is null!", __func__);
213         return HDF_FAILURE;
214     }
215     for (uint32_t i = 0; i < g_cfgDescs->effectNum; i++) {
216         if (strcmp(g_cfgDescs->effectCfgDescs[i].library, libName) == 0) {
217             return HDF_SUCCESS;
218         }
219     }
220     return HDF_FAILURE;
221 }
222 
EffectModelIsSupplyEffectLibs(struct IEffectModel * self,bool * supply)223 static int32_t EffectModelIsSupplyEffectLibs(struct IEffectModel *self, bool *supply)
224 {
225     if (self == NULL || supply == NULL) {
226         HDF_LOGE("%{public}s: invailid input params", __func__);
227         return HDF_ERR_INVALID_PARAM;
228     }
229 
230     *supply = IsEffectLibExist();
231     return HDF_SUCCESS;
232 }
233 
EffectModelGetAllEffectDescriptors(struct IEffectModel * self,struct EffectControllerDescriptor * descs,uint32_t * descsLen)234 static int32_t EffectModelGetAllEffectDescriptors(struct IEffectModel *self,
235                                                   struct EffectControllerDescriptor *descs, uint32_t *descsLen)
236 {
237     HDF_LOGD("enter to %{public}s", __func__);
238     int32_t ret;
239     uint32_t i;
240     uint32_t descNum = 0;
241     struct EffectFactory *factLib = NULL;
242     struct ControllerManager *ctrlMgr = NULL;
243 
244     if (self == NULL || descs == NULL || descsLen == NULL) {
245         HDF_LOGE("%{public}s: invailid input params", __func__);
246         return HDF_ERR_INVALID_PARAM;
247     }
248 
249     if (g_cfgDescs == NULL) {
250         HDF_LOGE("%{public}s: point is null!", __func__);
251         return HDF_FAILURE;
252     }
253     struct EffectControllerDescriptorVdi *descsVdi = (struct EffectControllerDescriptorVdi *)descs;
254     for (i = 0; i < g_cfgDescs->effectNum; i++) {
255         ret = LoadEffectLibrary(g_cfgDescs->effectCfgDescs[i].library, &factLib, &ctrlMgr);
256         if (ret != HDF_SUCCESS || factLib == NULL) {
257             HDF_LOGE("%{public}s: GetEffectLibFromList fail!", __func__);
258             continue;
259         }
260         ret = factLib->GetDescriptor(factLib, g_cfgDescs->effectCfgDescs[i].effectId, &descsVdi[descNum]);
261         if (ret != HDF_SUCCESS) {
262             DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
263             HDF_LOGE("%{public}s: GetDescriptor fail!", __func__);
264             continue;
265         }
266         DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
267         factLib = NULL;
268         descNum++;
269     }
270     *descsLen = descNum;
271     descs = (struct EffectControllerDescriptor *)descsVdi;
272     HDF_LOGD("%{public}s success", __func__);
273     return HDF_SUCCESS;
274 }
275 
EffectModelGetEffectDescriptor(struct IEffectModel * self,const char * uuid,struct EffectControllerDescriptor * desc)276 static int32_t EffectModelGetEffectDescriptor(struct IEffectModel *self, const char *uuid,
277     struct EffectControllerDescriptor *desc)
278 {
279     HDF_LOGD("enter to %{public}s", __func__);
280     uint32_t i;
281     struct EffectFactory *factLib = NULL;
282     struct ControllerManager *ctrlMgr = NULL;
283     if (self == NULL || uuid == NULL || desc == NULL) {
284         HDF_LOGE("%{public}s: invailid input params", __func__);
285         return HDF_ERR_INVALID_PARAM;
286     }
287     struct EffectControllerDescriptorVdi *descVdi = (struct EffectControllerDescriptorVdi *)desc;
288     for (i = 0; i < g_cfgDescs->effectNum; i++) {
289         if (strcmp(uuid, g_cfgDescs->effectCfgDescs[i].effectId) != 0) {
290             continue;
291         }
292 
293         LoadEffectLibrary(g_cfgDescs->effectCfgDescs[i].library, &factLib, &ctrlMgr);
294         if (factLib == NULL) {
295             HDF_LOGE("%{public}s: GetEffectLibFromList fail!", __func__);
296             return HDF_FAILURE;
297         }
298 
299         if (factLib->GetDescriptor(factLib, uuid, descVdi) != HDF_SUCCESS) {
300             DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
301             HDF_LOGE("%{public}s: GetDescriptor fail!", __func__);
302             return HDF_FAILURE;
303         }
304         DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
305         HDF_LOGD("%{public}s success", __func__);
306         return HDF_SUCCESS;
307     }
308     desc = (struct EffectControllerDescriptor *)descVdi;
309     HDF_LOGE("%{public}s fail!", __func__);
310     return HDF_FAILURE;
311 }
312 
CreateEffectController(const struct EffectInfo * info,struct IEffectControl ** contoller,struct ControllerId * contollerId,struct IEffectControlVdi * ctrlOps)313 static int32_t CreateEffectController(const struct EffectInfo *info, struct IEffectControl **contoller,
314     struct ControllerId *contollerId, struct IEffectControlVdi *ctrlOps)
315 {
316     if (info == NULL || contoller == NULL || contollerId == NULL) {
317         HDF_LOGE("%{public}s: invailid input params", __func__);
318         return HDF_ERR_INVALID_PARAM;
319     }
320     struct ControllerManager *ctrlMgr = (struct ControllerManager *)OsalMemCalloc(sizeof(struct ControllerManager));
321     CHECK_NULL_PTR_RETURN_VALUE(ctrlMgr, HDF_FAILURE);
322     struct AudioEffectLibInfo *libInfo = GetEffectLibInfoByName(info->libName);
323     if (libInfo == NULL) {
324         HDF_LOGE("%{public}s: GetEffectLibInfoByName failed", __func__);
325         OsalMemFree(ctrlMgr);
326         return HDF_FAILURE;
327     }
328     libInfo->ctrlMgr = ctrlMgr;
329     ctrlMgr->ctrlOps = ctrlOps;
330     ctrlMgr->libName = strdup(info->libName);
331     if (ctrlMgr->libName == NULL) {
332         HDF_LOGE("%{public}s: strdup failed, info->effectId = %{public}s", __func__, info->effectId);
333         OsalMemFree(ctrlMgr);
334         return HDF_FAILURE;
335     }
336     ctrlMgr->ctrlImpls.EffectProcess = EffectControlEffectProcess;
337     ctrlMgr->ctrlImpls.SendCommand = EffectControlSendCommand;
338     ctrlMgr->ctrlImpls.GetEffectDescriptor = EffectGetOwnDescriptor;
339     ctrlMgr->ctrlImpls.EffectReverse = EffectControlEffectReverse;
340     *contoller = &ctrlMgr->ctrlImpls;
341     // free after send reply
342     contollerId->libName = strdup(info->libName);
343     contollerId->effectId = strdup(info->effectId);
344     if (contollerId->libName == NULL || contollerId->effectId == NULL) {
345         HDF_LOGE("%{public}s: strdup failed, info->libName = %{public}s", __func__, info->libName);
346         OsalMemFree(ctrlMgr->libName);
347         OsalMemFree(ctrlMgr);
348         *contoller = NULL;
349         return HDF_FAILURE;
350     }
351     return HDF_SUCCESS;
352 }
353 
EffectModelCreateEffectController(struct IEffectModel * self,const struct EffectInfo * info,struct IEffectControl ** contoller,struct ControllerId * contollerId)354 static int32_t EffectModelCreateEffectController(struct IEffectModel *self, const struct EffectInfo *info,
355     struct IEffectControl **contoller, struct ControllerId *contollerId)
356 {
357     if (self == NULL || info == NULL || contoller == NULL || contollerId == NULL) {
358         HDF_LOGE("%{public}s: invailid input params", __func__);
359         return HDF_ERR_INVALID_PARAM;
360     }
361 
362     if (IsSupplyEffect(info->libName) != HDF_SUCCESS) {
363         HDF_LOGE("%{public}s: not support effect [%{public}s]", __func__, info->libName);
364         return HDF_FAILURE;
365     }
366 
367     struct EffectFactory *lib = NULL;
368     struct ControllerManager *ctrlMgr = NULL;
369     struct IEffectControlVdi *ctrlOps = NULL;
370 
371     int32_t ret = LoadEffectLibrary(info->libName, &lib, &ctrlMgr);
372     if (ret != HDF_SUCCESS) {
373         HDF_LOGE("%{public}s: LoadEffectLibrary fail", __func__);
374         return HDF_FAILURE;
375     }
376     if (ctrlMgr != NULL) {
377         contollerId->libName = strdup(info->libName);
378         contollerId->effectId = strdup(info->effectId);
379         if (contollerId->libName == NULL || contollerId->effectId == NULL) {
380             HDF_LOGE("%{public}s: strdup failed", __func__);
381             return HDF_FAILURE;
382         }
383         *contoller = &ctrlMgr->ctrlImpls;
384         return HDF_SUCCESS;
385     }
386     CHECK_NULL_PTR_RETURN_VALUE(lib, HDF_FAILURE);
387     CHECK_NULL_PTR_RETURN_VALUE(lib->CreateController, HDF_FAILURE);
388 
389     struct EffectInfoVdi *infoVdi = (struct EffectInfoVdi *)info;
390     lib->CreateController(lib, infoVdi, &ctrlOps);
391     CHECK_NULL_PTR_RETURN_VALUE(ctrlOps, HDF_FAILURE);
392 
393     ret = CreateEffectController(info, contoller, contollerId, ctrlOps);
394     if (ret != HDF_SUCCESS) {
395         DeleteEffectLibrary(info->libName);
396         return HDF_FAILURE;
397     }
398 
399     HDF_LOGI("%{public}s: create effect succeed, libName = %{public}s", __func__, info->libName);
400     return HDF_SUCCESS;
401 }
402 
EffectModelDestroyEffectController(struct IEffectModel * self,const struct ControllerId * contollerId)403 int32_t EffectModelDestroyEffectController(struct IEffectModel *self, const struct ControllerId *contollerId)
404 {
405     if (self == NULL || contollerId == NULL) {
406         HDF_LOGE("%{public}s: invailid input params", __func__);
407         return HDF_ERR_INVALID_PARAM;
408     }
409 
410     struct AudioEffectLibInfo *libInfo = GetEffectLibInfoByName(contollerId->libName);
411     CHECK_NULL_PTR_RETURN_VALUE(libInfo, HDF_FAILURE);
412     if (libInfo->effectCnt > 1) {
413         libInfo->effectCnt--;
414         return HDF_SUCCESS;
415     }
416     struct EffectFactory *lib = libInfo->libEffect;
417     CHECK_NULL_PTR_RETURN_VALUE(lib, HDF_FAILURE);
418     struct ControllerManager *ctrlMgr = libInfo->ctrlMgr;
419     CHECK_NULL_PTR_RETURN_VALUE(ctrlMgr, HDF_FAILURE);
420 
421     if (ctrlMgr->libName != NULL) {
422         OsalMemFree(ctrlMgr->libName);
423         ctrlMgr->libName = NULL;
424     }
425 
426     if (ctrlMgr->ctrlOps == NULL) {
427         HDF_LOGE("%{public}s: controller has no options", __func__);
428         return HDF_FAILURE;
429     }
430 
431     /* call the lib destroy method,then free controller manager */
432     lib->DestroyController(lib, ctrlMgr->ctrlOps);
433     DeleteEffectLibrary(contollerId->libName);
434     HDF_LOGI("%{public}s: destroy effect succeed, libName = %{public}s", __func__, contollerId->libName);
435     return HDF_SUCCESS;
436 }
437 
ModelInit(void)438 void ModelInit(void)
439 {
440     FILE *file;
441     struct ConfigDescriptor *cfgDesc = NULL;
442     int32_t ret;
443     file = fopen(AUDIO_EFFECT_PRODUCT_CONFIG, "r");
444     if (file == NULL) {
445         ret = AudioEffectGetConfigDescriptor(AUDIO_EFFECT_PLAFORM_CONFIG, &cfgDesc);
446         HDF_LOGI("%{public}s: %{public}s!", __func__, AUDIO_EFFECT_PLAFORM_CONFIG);
447     } else {
448         ret = AudioEffectGetConfigDescriptor(AUDIO_EFFECT_PRODUCT_CONFIG, &cfgDesc);
449         HDF_LOGI("%{public}s: %{public}s!", __func__, AUDIO_EFFECT_PRODUCT_CONFIG);
450         (void)fclose(file);
451     }
452     if (ret != HDF_SUCCESS) {
453         HDF_LOGE("%{public}s: AudioEffectGetConfigDescriptor fail!", __func__);
454         return;
455     }
456 
457     if (cfgDesc == NULL || cfgDesc->effectCfgDescs == NULL || cfgDesc->libCfgDescs == NULL) {
458         HDF_LOGE("cfgDesc is null!");
459         return;
460     }
461     g_cfgDescs = cfgDesc;
462     HDF_LOGD("%{public}s end!", __func__);
463 }
464 
EffectModelImplGetInstance(void)465 struct IEffectModel *EffectModelImplGetInstance(void)
466 {
467     struct EffectModelService *service = (struct EffectModelService *)OsalMemCalloc(sizeof(struct EffectModelService));
468     if (service == NULL) {
469         HDF_LOGE("%{public}s: malloc EffectModelService obj failed!", __func__);
470         return NULL;
471     }
472 
473     ModelInit();
474     service->interface.IsSupplyEffectLibs = EffectModelIsSupplyEffectLibs;
475     service->interface.GetAllEffectDescriptors = EffectModelGetAllEffectDescriptors;
476     service->interface.CreateEffectController = EffectModelCreateEffectController;
477     service->interface.DestroyEffectController = EffectModelDestroyEffectController;
478     service->interface.GetEffectDescriptor = EffectModelGetEffectDescriptor;
479 
480     return &service->interface;
481 }
482 
EffectModelImplRelease(struct IEffectModel * instance)483 void EffectModelImplRelease(struct IEffectModel *instance)
484 {
485     if (instance == NULL) {
486         return;
487     }
488 
489     AudioEffectReleaseCfgDesc(g_cfgDescs);
490     struct EffectModelService *service = CONTAINER_OF(instance, struct EffectModelService, interface);
491     if (service == NULL) {
492         return;
493     }
494     OsalMemFree(service);
495     service = NULL;
496 }
497