* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dlfcn.h>
#include <hdf_base.h>
#include <hdf_dlist.h>
#include <osal_mem.h>
#include "v6_1/iaudio_manager.h"
#include "audio_uhdf_log.h"
#define HDF_LOG_TAG HDF_AUDIO_PRIMARY_SRV
typedef struct IAudioManager* (*AudioManagerCreateIfInstance)(void);
typedef int32_t (*AudioManagerDestroyIfInstance)(struct IAudioManager *);
struct AudioManagerPriv {
void *handle;
AudioManagerCreateIfInstance createIfInstance;
AudioManagerDestroyIfInstance destroyIfInstance;
};
static const char *HDI_AUDIO_LIB_PATH = HDF_LIBRARY_FULL_PATH("libaudio_primary_impl_vendor");
static struct AudioManagerPriv *GetAudioManagerPriv(void)
{
static struct AudioManagerPriv priv;
return &priv;
}
static int32_t AudioManagerLoadPrimaryLib(struct AudioManagerPriv *priv)
{
char *error = NULL;
if (HDI_AUDIO_LIB_PATH == NULL || priv == NULL) {
HDF_LOGE("%{public}s:para is null", __func__);
return HDF_ERR_INVALID_PARAM;
}
priv->handle = dlopen(HDI_AUDIO_LIB_PATH, RTLD_LAZY);
if (priv->handle == NULL) {
error = dlerror();
HDF_LOGE("%{public}s:load path%{public}s, dlopen err=%{public}s", __func__, HDI_AUDIO_LIB_PATH, error);
return HDF_FAILURE;
}
(void)dlerror();
priv->createIfInstance = dlsym(priv->handle, "AudioManagerCreateIfInstance");
if (priv->createIfInstance == NULL) {
error = dlerror();
HDF_LOGE("%{public}s:dlsym AudioManagerCreateIfInstance err=%{public}s", __func__, error);
goto ERROR;
}
priv->destroyIfInstance = dlsym(priv->handle, "AudioManagerDestroyIfInstance");
if (priv->destroyIfInstance == NULL) {
error = dlerror();
HDF_LOGE("%{public}s:dlsym AudioManagerDestroyIfInstance err=%{public}s", __func__, error);
goto ERROR;
}
HDF_LOGI("%{public}s:hdi audio impl lib load success", __func__);
return HDF_SUCCESS;
ERROR:
if (priv->handle != NULL) {
dlclose(priv->handle);
priv->handle = NULL;
}
priv->createIfInstance = NULL;
priv->destroyIfInstance = NULL;
return HDF_FAILURE;
}
struct IAudioManager *AudioManagerImplGetInstance(void)
{
struct AudioManagerPriv *priv = GetAudioManagerPriv();
int32_t ret = AudioManagerLoadPrimaryLib(priv);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s:Audio manager load lib failed, ret[%{public}d]", __func__, ret);
return NULL;
}
if (priv->createIfInstance == NULL) {
HDF_LOGE("%{public}s:Audio manager createIfInstance is NULL", __func__);
dlclose(priv->handle);
priv->handle = NULL;
return NULL;
}
struct IAudioManager *interface = priv->createIfInstance();
if (interface == NULL) {
HDF_LOGE("%{public}s:call createIfInstance fail", __func__);
dlclose(priv->handle);
priv->handle = NULL;
return NULL;
}
return interface;
}
void AudioManagerImplRelease(struct IAudioManager *manager)
{
struct AudioManagerPriv *priv = GetAudioManagerPriv();
if (manager == NULL) {
HDF_LOGE("%{public}s:manager is null", __func__);
goto ERROR;
}
if (priv->destroyIfInstance == NULL) {
HDF_LOGE("%{public}s:Audio manager destroyIfInstance is NULL", __func__);
goto ERROR;
}
int32_t ret = priv->destroyIfInstance(manager);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s:call destroyIfInstance fail, ret=%{public}d", __func__, ret);
}
ERROR:
if (priv->handle != NULL) {
dlclose(priv->handle);
priv->handle = NULL;
}
priv->createIfInstance = NULL;
priv->destroyIfInstance = NULL;
}