1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include <dlfcn.h>
17094332d3Sopenharmony_ci#include <hdf_base.h>
18094332d3Sopenharmony_ci#include <hdf_dlist.h>
19094332d3Sopenharmony_ci#include <osal_mem.h>
20094332d3Sopenharmony_ci
21094332d3Sopenharmony_ci#include "v4_0/iaudio_manager.h"
22094332d3Sopenharmony_ci#include "audio_uhdf_log.h"
23094332d3Sopenharmony_ci
24094332d3Sopenharmony_ci#define HDF_LOG_TAG    HDF_AUDIO_PRIMARY_SRV
25094332d3Sopenharmony_ci
26094332d3Sopenharmony_citypedef struct IAudioManager* (*AudioManagerCreateIfInstance)(void);
27094332d3Sopenharmony_citypedef int32_t (*AudioManagerDestroyIfInstance)(struct IAudioManager *);
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_cistruct AudioManagerPriv {
30094332d3Sopenharmony_ci    void *handle;
31094332d3Sopenharmony_ci    AudioManagerCreateIfInstance createIfInstance;
32094332d3Sopenharmony_ci    AudioManagerDestroyIfInstance destroyIfInstance;
33094332d3Sopenharmony_ci};
34094332d3Sopenharmony_ci
35094332d3Sopenharmony_cistatic const char *HDI_AUDIO_LIB_PATH = HDF_LIBRARY_FULL_PATH("libaudio_primary_impl_vendor");
36094332d3Sopenharmony_ci
37094332d3Sopenharmony_cistatic struct AudioManagerPriv *GetAudioManagerPriv(void)
38094332d3Sopenharmony_ci{
39094332d3Sopenharmony_ci    static struct AudioManagerPriv priv;
40094332d3Sopenharmony_ci    return &priv;
41094332d3Sopenharmony_ci}
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_cistatic int32_t AudioManagerLoadPrimaryLib(struct AudioManagerPriv *priv)
44094332d3Sopenharmony_ci{
45094332d3Sopenharmony_ci    char *error = NULL;
46094332d3Sopenharmony_ci
47094332d3Sopenharmony_ci    if (HDI_AUDIO_LIB_PATH == NULL || priv == NULL) {
48094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:para is null", __func__);
49094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
50094332d3Sopenharmony_ci    }
51094332d3Sopenharmony_ci
52094332d3Sopenharmony_ci    priv->handle = dlopen(HDI_AUDIO_LIB_PATH, RTLD_LAZY);
53094332d3Sopenharmony_ci    if (priv->handle == NULL) {
54094332d3Sopenharmony_ci        error = dlerror();
55094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:load path%{public}s, dlopen err=%{public}s", __func__, HDI_AUDIO_LIB_PATH, error);
56094332d3Sopenharmony_ci        return HDF_FAILURE;
57094332d3Sopenharmony_ci    }
58094332d3Sopenharmony_ci
59094332d3Sopenharmony_ci    (void)dlerror(); // clear existing error
60094332d3Sopenharmony_ci
61094332d3Sopenharmony_ci    priv->createIfInstance = dlsym(priv->handle, "AudioManagerCreateIfInstance");
62094332d3Sopenharmony_ci    if (priv->createIfInstance == NULL) {
63094332d3Sopenharmony_ci        error = dlerror();
64094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:dlsym AudioManagerCreateIfInstance err=%{public}s", __func__, error);
65094332d3Sopenharmony_ci        goto ERROR;
66094332d3Sopenharmony_ci    }
67094332d3Sopenharmony_ci
68094332d3Sopenharmony_ci    priv->destroyIfInstance = dlsym(priv->handle, "AudioManagerDestroyIfInstance");
69094332d3Sopenharmony_ci    if (priv->destroyIfInstance == NULL) {
70094332d3Sopenharmony_ci        error = dlerror();
71094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:dlsym AudioManagerDestroyIfInstance err=%{public}s", __func__, error);
72094332d3Sopenharmony_ci        goto ERROR;
73094332d3Sopenharmony_ci    }
74094332d3Sopenharmony_ci
75094332d3Sopenharmony_ci    HDF_LOGI("%{public}s:hdi audio impl lib load success", __func__);
76094332d3Sopenharmony_ci    return HDF_SUCCESS;
77094332d3Sopenharmony_ci
78094332d3Sopenharmony_ciERROR:
79094332d3Sopenharmony_ci    if (priv->handle != NULL) {
80094332d3Sopenharmony_ci        dlclose(priv->handle);
81094332d3Sopenharmony_ci        priv->handle = NULL;
82094332d3Sopenharmony_ci    }
83094332d3Sopenharmony_ci    priv->createIfInstance = NULL;
84094332d3Sopenharmony_ci    priv->destroyIfInstance = NULL;
85094332d3Sopenharmony_ci    return HDF_FAILURE;
86094332d3Sopenharmony_ci}
87094332d3Sopenharmony_ci
88094332d3Sopenharmony_cistruct IAudioManager *AudioManagerImplGetInstance(void)
89094332d3Sopenharmony_ci{
90094332d3Sopenharmony_ci    struct AudioManagerPriv *priv = GetAudioManagerPriv();
91094332d3Sopenharmony_ci
92094332d3Sopenharmony_ci    int32_t ret = AudioManagerLoadPrimaryLib(priv);
93094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
94094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:Audio manager load lib failed, ret[%{public}d]", __func__, ret);
95094332d3Sopenharmony_ci        return NULL;
96094332d3Sopenharmony_ci    }
97094332d3Sopenharmony_ci
98094332d3Sopenharmony_ci    if (priv->createIfInstance == NULL) {
99094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:Audio manager createIfInstance is NULL", __func__);
100094332d3Sopenharmony_ci        dlclose(priv->handle);
101094332d3Sopenharmony_ci        priv->handle = NULL;
102094332d3Sopenharmony_ci        return NULL;
103094332d3Sopenharmony_ci    }
104094332d3Sopenharmony_ci
105094332d3Sopenharmony_ci    struct IAudioManager *interface = priv->createIfInstance();
106094332d3Sopenharmony_ci    if (interface == NULL) {
107094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:call createIfInstance fail", __func__);
108094332d3Sopenharmony_ci        dlclose(priv->handle);
109094332d3Sopenharmony_ci        priv->handle = NULL;
110094332d3Sopenharmony_ci        return NULL;
111094332d3Sopenharmony_ci    }
112094332d3Sopenharmony_ci
113094332d3Sopenharmony_ci    return interface;
114094332d3Sopenharmony_ci}
115094332d3Sopenharmony_ci
116094332d3Sopenharmony_civoid AudioManagerImplRelease(struct IAudioManager *manager)
117094332d3Sopenharmony_ci{
118094332d3Sopenharmony_ci    struct AudioManagerPriv *priv = GetAudioManagerPriv();
119094332d3Sopenharmony_ci
120094332d3Sopenharmony_ci    if (manager == NULL) {
121094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:manager is null", __func__);
122094332d3Sopenharmony_ci        goto ERROR;
123094332d3Sopenharmony_ci    }
124094332d3Sopenharmony_ci
125094332d3Sopenharmony_ci    if (priv->destroyIfInstance == NULL) {
126094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:Audio manager destroyIfInstance is NULL", __func__);
127094332d3Sopenharmony_ci        goto ERROR;
128094332d3Sopenharmony_ci    }
129094332d3Sopenharmony_ci
130094332d3Sopenharmony_ci    int32_t ret = priv->destroyIfInstance(manager);
131094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
132094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:call destroyIfInstance fail, ret=%{public}d", __func__, ret);
133094332d3Sopenharmony_ci    }
134094332d3Sopenharmony_ci
135094332d3Sopenharmony_ciERROR:
136094332d3Sopenharmony_ci    if (priv->handle != NULL) {
137094332d3Sopenharmony_ci        dlclose(priv->handle);
138094332d3Sopenharmony_ci        priv->handle = NULL;
139094332d3Sopenharmony_ci    }
140094332d3Sopenharmony_ci
141094332d3Sopenharmony_ci    priv->createIfInstance = NULL;
142094332d3Sopenharmony_ci    priv->destroyIfInstance = NULL;
143094332d3Sopenharmony_ci}
144