1 /*
2  * Copyright (c) 2021-2022 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 
16 #include <config.h>
17 #include <pulsecore/log.h>
18 #include <pulsecore/modargs.h>
19 #include <pulsecore/module.h>
20 #include <pulsecore/source.h>
21 #include <stddef.h>
22 #include <stdbool.h>
23 
24 #include <pulsecore/core.h>
25 #include <pulsecore/core-util.h>
26 #include <pulsecore/namereg.h>
27 #include "securec.h"
28 #include "audio_hdi_log.h"
29 #include "audio_enhance_chain_adapter.h"
30 
31 pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver);
32 void PaHdiSourceFree(pa_source *s);
33 
34 PA_MODULE_AUTHOR("OpenHarmony");
35 PA_MODULE_DESCRIPTION("OpenHarmony HDI Source");
36 PA_MODULE_VERSION(PACKAGE_VERSION);
37 PA_MODULE_LOAD_ONCE(false);
38 PA_MODULE_USAGE(
39         "source_name=<name for the source> "
40         "device_class=<name for the device class> "
41         "source_properties=<properties for the source> "
42         "format=<sample format> "
43         "rate=<sample rate> "
44         "channels=<number of channels> "
45         "channel_map=<channel map>"
46         "buffer_size=<custom buffer size>"
47         "file_path=<file path for data reading>"
48         "adapter_name=<primary>"
49         "open_mic_speaker<open mic>"
50         "network_id<device network id>"
51         "device_type<device type or port>"
52         "source_type<source type or port>"
53     );
54 
55 static const char * const VALID_MODARGS[] = {
56     "source_name",
57     "device_class",
58     "source_properties",
59     "format",
60     "rate",
61     "channels",
62     "channel_map",
63     "buffer_size",
64     "file_path",
65     "adapter_name",
66     "open_mic_speaker",
67     "network_id",
68     "device_type",
69     "source_type",
70     NULL
71 };
72 
SourceOutputNewCb(pa_core * c,pa_source_output * so)73 static pa_hook_result_t SourceOutputNewCb(pa_core *c, pa_source_output *so)
74 {
75     pa_assert(c);
76     const char *sceneMode = pa_proplist_gets(so->proplist, "scene.mode");
77     const char *sceneType = pa_proplist_gets(so->proplist, "scene.type");
78     const char *upAndDownDevice = pa_proplist_gets(so->proplist, "device.upAndDown");
79     EnhanceChainManagerCreateCb(sceneType, sceneMode, upAndDownDevice);
80     return PA_HOOK_OK;
81 }
82 
SourceOutputUnlinkCb(pa_core * c,pa_source_output * so)83 static pa_hook_result_t SourceOutputUnlinkCb(pa_core *c, pa_source_output *so)
84 {
85     pa_assert(c);
86     const char *sceneMode = pa_proplist_gets(so->proplist, "scene.mode");
87     const char *sceneType = pa_proplist_gets(so->proplist, "scene.type");
88     const char *upAndDownDevice = pa_proplist_gets(so->proplist, "device.upAndDown");
89     EnhanceChainManagerReleaseCb(sceneType, sceneMode, upAndDownDevice);
90     return PA_HOOK_OK;
91 }
92 
pa__init(pa_module * m)93 int pa__init(pa_module *m)
94 {
95     pa_modargs *ma = NULL;
96 
97     pa_assert(m);
98 
99     if (!(ma = pa_modargs_new(m->argument, VALID_MODARGS))) {
100         pa_log("Failed to parse module arguments");
101         goto fail;
102     }
103 
104     if (!(m->userdata = PaHdiSourceNew(m, ma, __FILE__))) {
105         goto fail;
106     }
107 
108     pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], PA_HOOK_LATE,
109         (pa_hook_cb_t)SourceOutputNewCb, NULL);
110     pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_LATE,
111         (pa_hook_cb_t)SourceOutputUnlinkCb, NULL);
112 
113     pa_modargs_free(ma);
114 
115     return 0;
116 
117 fail:
118 
119     if (ma) {
120         pa_modargs_free(ma);
121     }
122 
123     pa__done(m);
124 
125     return -1;
126 }
127 
pa__get_n_used(pa_module * m)128 int pa__get_n_used(pa_module *m)
129 {
130     pa_source *source = NULL;
131 
132     pa_assert(m);
133     pa_assert_se(source = m->userdata);
134 
135     return pa_source_linked_by(source);
136 }
137 
pa__done(pa_module * m)138 void pa__done(pa_module *m)
139 {
140     pa_source *source = NULL;
141 
142     pa_assert(m);
143 
144     if ((source = m->userdata)) {
145         PaHdiSourceFree(source);
146     }
147 }
148