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