• 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 "audio_manager_vdi.h"
16 
17 #include <dlfcn.h>
18 #include <malloc.h>
19 #include "osal_mem.h"
20 #include <hdf_base.h>
21 #include "audio_uhdf_log.h"
22 #include "audio_adapter_vdi.h"
23 #include "v1_0/iaudio_adapter.h"
24 
25 #define HDF_LOG_TAG    HDF_AUDIO_PRIMARY_IMPL
26 
27 typedef struct IAudioManagerVdi* (*AudioManagerCreateIfInstanceVdi)(void);
28 
29 struct AudioManagerPrivVdi {
30     struct IAudioManager interface;
31     void *handle;
32     AudioManagerCreateIfInstanceVdi managerFuncs;
33     struct IAudioManagerVdi *vdiManager;
34     struct AudioAdapterDescriptor descs[AUDIO_VDI_ADAPTER_NUM_MAX];
35     uint32_t descsCount;
36     struct AudioAdapterDescriptorVdi *vdiDescs;
37     uint32_t vdiDescsCount;
38 };
39 
AudioManagerReleasePort(struct AudioPort ** ports,uint32_t portsLen)40 static void AudioManagerReleasePort(struct AudioPort **ports, uint32_t portsLen)
41 {
42     CHECK_NULL_PTR_RETURN(ports);
43 
44     if (portsLen == 0 || portsLen > AUDIO_VDI_PORT_NUM_MAX) {
45         AUDIO_FUNC_LOGE("audio vdiManager portsLen is invalid");
46         return;
47     }
48 
49     struct AudioPort *portsTmp = *ports;
50     for (uint32_t i = 0; i < portsLen; i++) {
51         OsalMemFree((void *)portsTmp[i].portName);
52     }
53     OsalMemFree((void *)portsTmp);
54     *ports = NULL;
55 }
56 
AudioManagerReleaseVdiPort(struct AudioPortVdi ** vdiPorts,uint32_t portsLen)57 static void AudioManagerReleaseVdiPort(struct AudioPortVdi **vdiPorts, uint32_t portsLen)
58 {
59     CHECK_NULL_PTR_RETURN(vdiPorts);
60 
61     if (portsLen == 0 || portsLen > AUDIO_VDI_PORT_NUM_MAX) {
62         AUDIO_FUNC_LOGE("audio vdiManager portsLen is invalid");
63         return;
64     }
65 
66     struct AudioPortVdi *portsTmp = *vdiPorts;
67     for (uint32_t i = 0; i < portsLen; i++) {
68         OsalMemFree((void *)portsTmp[i].portName);
69     }
70     OsalMemFree((void *)portsTmp);
71     *vdiPorts = NULL;
72 }
73 
AudioManagerReleaseDesc(struct AudioAdapterDescriptor * desc)74 static void AudioManagerReleaseDesc(struct AudioAdapterDescriptor *desc)
75 {
76     OsalMemFree((void *)desc->adapterName);
77     desc->adapterName = NULL;
78     if (desc->ports != NULL) {
79         AudioManagerReleasePort(&desc->ports, desc->portsLen);
80         desc->portsLen = 0;
81     }
82 }
83 
AudioManagerReleaseVdiDesc(struct AudioAdapterDescriptorVdi * vdiDesc)84 static void AudioManagerReleaseVdiDesc(struct AudioAdapterDescriptorVdi *vdiDesc)
85 {
86     OsalMemFree((void *)vdiDesc->adapterName);
87     vdiDesc->adapterName = NULL;
88     if (vdiDesc->ports != NULL) {
89         AudioManagerReleaseVdiPort(&vdiDesc->ports, vdiDesc->portsLen);
90         vdiDesc->portsLen = 0;
91     }
92 #if defined CONFIG_USE_JEMALLOC_DFX_INTF
93     int err = mallopt(M_FLUSH_THREAD_CACHE, 0);
94     if (err != HDF_SUCCESS) {
95         AUDIO_FUNC_LOGE("%{public}s :release cache error, m_purge = %{public}d", __func__, err);
96     }
97 #endif
98 }
99 
AudioManagerReleaseDescs(struct AudioAdapterDescriptor * descs,uint32_t descsCount)100 static void AudioManagerReleaseDescs(struct AudioAdapterDescriptor *descs, uint32_t descsCount)
101 {
102     if (descsCount == 0 || descsCount > AUDIO_VDI_PORT_NUM_MAX) {
103         AUDIO_FUNC_LOGE("audio vdiManager descsCount is invalid");
104         return;
105     }
106 
107     for (uint32_t i = 0; i < descsCount; i++) {
108         AudioManagerReleaseDesc(&descs[i]);
109     }
110 }
111 
AudioManagerPortToVdiPort(const struct AudioAdapterDescriptor * desc,struct AudioAdapterDescriptorVdi * vdiDesc)112 static int32_t AudioManagerPortToVdiPort(const struct AudioAdapterDescriptor *desc,
113     struct AudioAdapterDescriptorVdi *vdiDesc)
114 {
115     if (desc->portsLen == 0 || desc->portsLen > AUDIO_VDI_PORT_NUM_MAX) {
116         AUDIO_FUNC_LOGE("audio desc portsLen is invalid");
117         return HDF_ERR_NOT_SUPPORT;
118     }
119 
120     struct AudioPortVdi *vdiPorts = (struct AudioPortVdi *)OsalMemCalloc(sizeof(*vdiPorts) * desc->portsLen);
121     if (vdiPorts == NULL) {
122         AUDIO_FUNC_LOGE("OsalMemCalloc AudioPortVdi fail");
123         return HDF_ERR_MALLOC_FAIL;
124     }
125 
126     for (uint32_t i = 0; i < desc->portsLen; i++) {
127         vdiPorts[i].portName = strdup(desc->ports[i].portName);
128         vdiPorts[i].portId = desc->ports[i].portId;
129         vdiPorts[i].dir = (enum AudioPortDirectionVdi)desc->ports[i].dir;
130     }
131 
132     vdiDesc->ports = vdiPorts;
133     vdiDesc->portsLen = desc->portsLen;
134 
135     return HDF_SUCCESS;
136 }
137 
AudioManagerVdiPortToPort(struct AudioAdapterDescriptorVdi * vdiDesc,struct AudioAdapterDescriptor * desc)138 static int32_t AudioManagerVdiPortToPort(struct AudioAdapterDescriptorVdi *vdiDesc, struct AudioAdapterDescriptor *desc)
139 {
140     if (vdiDesc->portsLen == 0 || vdiDesc->portsLen > AUDIO_VDI_PORT_NUM_MAX) {
141         AUDIO_FUNC_LOGE("audio vdiDesc portsLen is invalid");
142         return HDF_ERR_NOT_SUPPORT;
143     }
144 
145     /* audio stub free ports */
146     struct AudioPort *ports = (struct AudioPort *)OsalMemCalloc(sizeof(*ports) * vdiDesc->portsLen);
147     if (ports == NULL) {
148         AUDIO_FUNC_LOGE("OsalMemCalloc AudioPort fail");
149         return HDF_ERR_MALLOC_FAIL;
150     }
151 
152     for (uint32_t i = 0; i < vdiDesc->portsLen; i++) {
153         ports[i].portName = strdup(vdiDesc->ports[i].portName);
154         ports[i].portId = vdiDesc->ports[i].portId;
155         ports[i].dir = (enum AudioPortDirection)vdiDesc->ports[i].dir;
156     }
157 
158     desc->ports = ports;
159     desc->portsLen = vdiDesc->portsLen;
160 
161     return HDF_SUCCESS;
162 }
163 
AudioManagerDescToVdiDesc(const struct AudioAdapterDescriptor * desc,struct AudioAdapterDescriptorVdi * vdiDesc)164 static int32_t AudioManagerDescToVdiDesc(const struct AudioAdapterDescriptor *desc,
165     struct AudioAdapterDescriptorVdi *vdiDesc)
166 {
167     int32_t ret = AudioManagerPortToVdiPort(desc, vdiDesc);
168     if (ret != HDF_SUCCESS) {
169         AUDIO_FUNC_LOGE("audio vdiManager vdiPort fail");
170         return HDF_FAILURE;
171     }
172 
173     vdiDesc->adapterName = strdup(desc->adapterName);
174     AUDIO_FUNC_LOGI("audio vdiManager load adapterName=%{public}s", vdiDesc->adapterName);
175 
176     return HDF_SUCCESS;
177 }
178 
AudioManagerVdiDescsToDescs(struct AudioAdapterDescriptorVdi * vdiDescs,uint32_t vdiDescsCount,struct AudioAdapterDescriptor * descs,uint32_t * descsCount)179 static int32_t AudioManagerVdiDescsToDescs(struct AudioAdapterDescriptorVdi *vdiDescs, uint32_t vdiDescsCount,
180     struct AudioAdapterDescriptor *descs, uint32_t *descsCount)
181 {
182     if (vdiDescsCount == 0 || vdiDescsCount > AUDIO_VDI_ADAPTER_NUM_MAX) {
183         AUDIO_FUNC_LOGE("audio vdiDescsCount=%{public}d is error", vdiDescsCount);
184         return HDF_ERR_NOT_SUPPORT;
185     }
186 
187     uint32_t count = (*descsCount <= (uint32_t)vdiDescsCount) ? (*descsCount) : (uint32_t)vdiDescsCount;
188     AUDIO_FUNC_LOGI("audio vdiManager all adapter count=%{public}u, vdiCount=%{public}d", count, vdiDescsCount);
189 
190     for (uint32_t i = 0; i < count; i++) {
191         int32_t ret = AudioManagerVdiPortToPort(&vdiDescs[i], &descs[i]);
192         if (ret != HDF_SUCCESS) {
193             AUDIO_FUNC_LOGE("audio vdiManager port fail");
194             return HDF_FAILURE;
195         }
196         descs[i].adapterName = strdup(vdiDescs[i].adapterName); // audio stub free adapterName
197         AUDIO_FUNC_LOGI("audio vdiManager get adapterName=%{public}s", descs[i].adapterName);
198     }
199 
200     *descsCount = count;
201     return HDF_SUCCESS;
202 }
203 
AudioManagerVendorGetAllAdapters(struct IAudioManager * manager,struct AudioAdapterDescriptor * descs,uint32_t * descsLen)204 int32_t AudioManagerVendorGetAllAdapters(struct IAudioManager *manager,
205     struct AudioAdapterDescriptor *descs, uint32_t *descsLen)
206 {
207     AUDIO_FUNC_LOGD("enter to %{public}s", __func__);
208     int32_t ret;
209     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
210     CHECK_NULL_PTR_RETURN_VALUE(descs, HDF_ERR_INVALID_PARAM);
211     CHECK_NULL_PTR_RETURN_VALUE(descsLen, HDF_ERR_INVALID_PARAM);
212 
213     struct AudioManagerPrivVdi *priv = (struct AudioManagerPrivVdi *)manager;
214     if (priv->vdiManager == NULL) {
215         AUDIO_FUNC_LOGE("audio vdiManager is null");
216         return HDF_ERR_INVALID_PARAM;
217     }
218 
219     if (priv->vdiDescsCount != 0 && priv->vdiDescs != NULL) {
220         ret = AudioManagerVdiDescsToDescs(priv->vdiDescs, priv->vdiDescsCount, descs, descsLen);
221         if (ret != HDF_SUCCESS) {
222             AUDIO_FUNC_LOGE("audio vdiManager DescsVdi To Descs fail, ret=%{public}d", ret);
223             AudioManagerReleaseDescs(descs, *descsLen);
224             return HDF_FAILURE;
225         }
226         return HDF_SUCCESS;
227     }
228     priv->vdiDescs = (struct AudioAdapterDescriptorVdi *)OsalMemCalloc
229     (sizeof(struct AudioAdapterDescriptorVdi) * (*descsLen));
230     ret = priv->vdiManager->GetAllAdapters(priv->vdiManager, priv->vdiDescs, &priv->vdiDescsCount);
231     if (ret != HDF_SUCCESS) {
232         AUDIO_FUNC_LOGE("audio vdiManager call GetAllAdapters fail, ret=%{public}d", ret);
233         return HDF_FAILURE;
234     }
235 
236     CHECK_NULL_PTR_RETURN_VALUE(priv->vdiDescs, HDF_ERR_NOT_SUPPORT);
237 
238     ret = AudioManagerVdiDescsToDescs(priv->vdiDescs, priv->vdiDescsCount, descs, descsLen);
239     if (ret != HDF_SUCCESS) {
240         AUDIO_FUNC_LOGE("audio vdiManager DescsVdi To Descs fail, ret=%{public}d", ret);
241         AudioManagerReleaseDescs(descs, *descsLen);
242         return HDF_FAILURE;
243     }
244 
245     priv->descsCount = AUDIO_VDI_ADAPTER_NUM_MAX;
246     ret = AudioManagerVdiDescsToDescs(priv->vdiDescs, priv->vdiDescsCount, priv->descs, &priv->descsCount);
247     if (ret != HDF_SUCCESS) {
248         AUDIO_FUNC_LOGE("audio vdiManager DescsVdi To Descs fail, ret=%{public}d", ret);
249         AudioManagerReleaseDescs(descs, *descsLen);
250         AudioManagerReleaseDescs(priv->descs, priv->descsCount);
251         priv->descsCount = 0;
252         return HDF_FAILURE;
253     }
254 
255     return HDF_SUCCESS;
256 }
257 
AudioManagerVendorFindAdapterPos(struct IAudioManager * manager,const char * adapterName)258 static uint32_t AudioManagerVendorFindAdapterPos(struct IAudioManager *manager, const char *adapterName)
259 {
260     CHECK_NULL_PTR_RETURN_VALUE(adapterName, AUDIO_VDI_ADAPTER_NUM_MAX);
261     struct AudioManagerPrivVdi *priv = (struct AudioManagerPrivVdi *)manager;
262     CHECK_NULL_PTR_RETURN_VALUE(priv->vdiManager, AUDIO_VDI_ADAPTER_NUM_MAX);
263 
264     for (uint32_t descIndex = 0; descIndex < priv->descsCount; descIndex++) {
265         if (strcmp(adapterName, priv->descs[descIndex].adapterName) == 0) {
266             return descIndex;
267         }
268     }
269 
270     AUDIO_FUNC_LOGI("can not find adapterName(%{public}s) pos", adapterName);
271     return AUDIO_VDI_ADAPTER_NUM_MAX;
272 }
273 
AudioManagerVendorLoadAdapter(struct IAudioManager * manager,const struct AudioAdapterDescriptor * desc,struct IAudioAdapter ** adapter)274 int32_t AudioManagerVendorLoadAdapter(struct IAudioManager *manager, const struct AudioAdapterDescriptor *desc,
275     struct IAudioAdapter **adapter)
276 {
277     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
278     CHECK_NULL_PTR_RETURN_VALUE(desc, HDF_ERR_INVALID_PARAM);
279     CHECK_NULL_PTR_RETURN_VALUE(adapter, HDF_ERR_INVALID_PARAM);
280 
281     struct AudioManagerPrivVdi *priv = (struct AudioManagerPrivVdi *)manager;
282     CHECK_NULL_PTR_RETURN_VALUE(priv->vdiManager, HDF_ERR_INVALID_PARAM);
283     CHECK_NULL_PTR_RETURN_VALUE(priv->vdiManager->LoadAdapter, HDF_ERR_INVALID_PARAM);
284 
285     uint32_t descIndex = AudioManagerVendorFindAdapterPos(manager, desc->adapterName);
286     if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
287         AUDIO_FUNC_LOGE("audio vdiManager find adapter pos");
288         return HDF_FAILURE;
289     }
290 
291     uint32_t count = AudioGetAdapterRefCntVdi(descIndex);
292     if (count > 0 && count != UINT_MAX) {
293         return AudioIncreaseAdapterRefVdi(descIndex, adapter);
294     }
295 
296     struct AudioAdapterDescriptorVdi vdiDesc;
297     int32_t ret = AudioManagerDescToVdiDesc(desc, &vdiDesc);
298     if (ret != HDF_SUCCESS) {
299         AudioManagerReleaseVdiDesc(&vdiDesc);
300         AUDIO_FUNC_LOGE("audio vdiManager desc To vdiDesc fail, ret=%{public}d", ret);
301         return HDF_FAILURE;
302     }
303 
304     struct IAudioAdapterVdi *vdiAdapter = NULL;
305     ret = priv->vdiManager->LoadAdapter(priv->vdiManager, &vdiDesc, &vdiAdapter);
306     AudioManagerReleaseVdiDesc(&vdiDesc);
307     if (ret != HDF_SUCCESS) {
308         AUDIO_FUNC_LOGE("audio vdiManager call LoadAdapter fail, ret=%{public}d", ret);
309         return HDF_FAILURE;
310     }
311 
312     *adapter = AudioCreateAdapterVdi(descIndex, vdiAdapter);
313     if (*adapter == NULL) {
314         AUDIO_FUNC_LOGE("audio vdiManager create adapter fail");
315         priv->vdiManager->UnloadAdapter(priv->vdiManager, vdiAdapter);
316         return HDF_FAILURE;
317     }
318 
319     AUDIO_FUNC_LOGD("audio vdiManager load vdiAdapter success");
320     return HDF_SUCCESS;
321 }
322 
AudioManagerVendorUnloadAdapter(struct IAudioManager * manager,const char * adapterName)323 static int32_t AudioManagerVendorUnloadAdapter(struct IAudioManager *manager, const char *adapterName)
324 {
325     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
326     CHECK_NULL_PTR_RETURN_VALUE(adapterName, HDF_ERR_INVALID_PARAM);
327 
328     struct AudioManagerPrivVdi *priv = (struct AudioManagerPrivVdi *)manager;
329     CHECK_NULL_PTR_RETURN_VALUE(priv->vdiManager, HDF_ERR_INVALID_PARAM);
330     CHECK_NULL_PTR_RETURN_VALUE(priv->vdiManager->UnloadAdapter, HDF_ERR_INVALID_PARAM);
331 
332     uint32_t descIndex = AudioManagerVendorFindAdapterPos(manager, adapterName);
333     if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
334         AUDIO_FUNC_LOGE("AudioManagerVendorUnloadAdapter descIndex error");
335         return HDF_ERR_INVALID_PARAM;
336     }
337 
338     struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterByDescIndexVdi(descIndex);
339     if (vdiAdapter == NULL) {
340         AUDIO_FUNC_LOGW("audio vdiManager vdiAdapter had unloaded, index=%{public}d", descIndex);
341         return HDF_SUCCESS;
342     }
343 
344     uint32_t count = AudioGetAdapterRefCntVdi(descIndex);
345     if (count > 1 && count != UINT_MAX) {
346         AudioDecreaseAdapterRefVdi(descIndex);
347         return HDF_SUCCESS;
348     }
349 
350     priv->vdiManager->UnloadAdapter(priv->vdiManager, vdiAdapter);
351 
352     AudioReleaseAdapterVdi(descIndex);
353     AUDIO_FUNC_LOGD("audio vdiManager unload vdiAdapter success");
354     return HDF_SUCCESS;
355 }
356 
ReleaseAudioManagerVendorObject(struct IAudioManager * manager)357 int32_t ReleaseAudioManagerVendorObject(struct IAudioManager *manager)
358 {
359     uint32_t descIndex;
360 
361     if (manager == NULL) {
362         AUDIO_FUNC_LOGI("auido manager had released");
363         return HDF_SUCCESS;
364     }
365 
366     struct AudioManagerPrivVdi *priv = (struct AudioManagerPrivVdi *)manager;
367     if (priv->handle != NULL) {
368         dlclose(priv->handle);
369         priv->handle = NULL;
370     }
371 
372     for (descIndex = 0; descIndex < priv->descsCount; descIndex++) {
373         AudioEnforceClearAdapterRefCntVdi(descIndex);
374         int32_t ret = AudioManagerVendorUnloadAdapter(manager, priv->descs[descIndex].adapterName);
375         if (ret != HDF_SUCCESS) {
376             AUDIO_FUNC_LOGW("audio unload adapter error, ret=%{pulbic}d, adaptername=%{pulbic}s", ret,
377                 priv->descs[descIndex].adapterName);
378         }
379     }
380 
381     AudioManagerReleaseDescs(priv->descs, priv->descsCount);
382     OsalMemFree((void *)priv);
383     return HDF_SUCCESS;
384 }
385 
AudioManagerLoadVendorLib(struct AudioManagerPrivVdi * priv)386 static int32_t AudioManagerLoadVendorLib(struct AudioManagerPrivVdi *priv)
387 {
388     char *error = NULL;
389     const char *hdiAudioVendorLibPath = HDF_LIBRARY_FULL_PATH("libaudio_primary_impl");
390 
391     priv->handle = dlopen(hdiAudioVendorLibPath, RTLD_LAZY);
392     if (priv->handle == NULL) {
393         error = dlerror();
394         AUDIO_FUNC_LOGE("audio vdiManager load path%{public}s, dlopen err=%{public}s", hdiAudioVendorLibPath, error);
395         return HDF_FAILURE;
396     }
397 
398     (void)dlerror(); // clear existing error
399 
400     priv->managerFuncs = dlsym(priv->handle, "AudioManagerCreateIfInstance");
401     if (priv->managerFuncs == NULL) {
402         error = dlerror();
403         AUDIO_FUNC_LOGE("dlsym AudioManagerCreateIfInstance err=%{public}s", error);
404         dlclose(priv->handle);
405         priv->handle = NULL;
406         return HDF_FAILURE;
407     }
408 
409     AUDIO_FUNC_LOGD("audio load vendor lib success");
410     return HDF_SUCCESS;
411 }
412 
AudioManagerCreateIfInstance(void)413 struct IAudioManager *AudioManagerCreateIfInstance(void)
414 {
415     AUDIO_FUNC_LOGD("audio vdiManager create instance");
416 
417     struct AudioManagerPrivVdi *priv = (struct AudioManagerPrivVdi *)OsalMemCalloc(sizeof(*priv));
418     if (priv == NULL) {
419         AUDIO_FUNC_LOGE("OsalMemCalloc AudioManagerPrivVdi failed");
420         return NULL;
421     }
422 
423     int32_t ret = AudioManagerLoadVendorLib(priv);
424     if (ret != HDF_SUCCESS) {
425         AUDIO_FUNC_LOGE("audio load lib failed ret=%{pulbic}d", ret);
426         OsalMemFree((void *)priv);
427         return NULL;
428     }
429 
430     priv->vdiManager = (struct IAudioManagerVdi *)priv->managerFuncs();
431     if (priv->vdiManager == NULL) {
432         AUDIO_FUNC_LOGE("audio call vdi manager func failed");
433         OsalMemFree((void *)priv);
434         return NULL;
435     }
436 
437     priv->interface.GetAllAdapters = AudioManagerVendorGetAllAdapters;
438     priv->interface.LoadAdapter = AudioManagerVendorLoadAdapter;
439     priv->interface.UnloadAdapter = AudioManagerVendorUnloadAdapter;
440     priv->interface.ReleaseAudioManagerObject = ReleaseAudioManagerVendorObject;
441 
442     return &(priv->interface);
443 }
444 
AudioManagerDestroyIfInstance(struct IAudioManager * manager)445 int32_t AudioManagerDestroyIfInstance(struct IAudioManager *manager)
446 {
447     return ReleaseAudioManagerVendorObject(manager);
448 }