• 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_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 }