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 }