2 * module-stream-policy-mfld -- PulseAudio module for stream policy check
4 * Copyright (c) 2012, Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU Lesser General Public License,
8 * version 2.1, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
26 #include <pulsecore/core.h>
27 #include <pulsecore/module.h>
28 #include <pulsecore/core-util.h>
29 #include <pulsecore/log.h>
30 #include <pulsecore/sink-input.h>
31 #include <pulsecore/namereg.h>
32 #include "module-stream-policy-mfld-symdef.h"
34 PA_MODULE_AUTHOR("vivian zhang");
35 PA_MODULE_DESCRIPTION("stream policy check on MFLD platform");
36 PA_MODULE_VERSION(PACKAGE_VERSION);
37 PA_MODULE_LOAD_ONCE(TRUE);
42 pa_hook_slot *sink_input_new_hook_slot;
46 #define POLICY_AUTO "auto"
47 #define POLICY_PHONE "phone"
48 #define POLICY_ALL "all"
49 #define SINK_ALSA "alsa_output.0.analog-stereo"
50 #define SINK_COMBINED "combined"
51 #define BLUEZ_API "bluez"
53 /* Get sink by name */
54 static pa_sink* get_sink_by_name (pa_core *c, const char* sink_name)
59 if (c == NULL || sink_name == NULL) {
60 pa_log_warn ("input param is null");
63 PA_IDXSET_FOREACH(s, c->sinks, idx) {
64 if (pa_streq (s->name, sink_name)) {
71 /* check if this sink is bluez */
72 static pa_bool_t check_is_bluez (pa_sink* sink)
74 const char* api_name = NULL;
76 pa_log_warn ("input param sink is null");
79 api_name = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_API);
81 if (pa_streq (api_name, BLUEZ_API)) {
82 pa_log_debug("[MFLD] [%s] exists and it is [%s]...TRUE", PA_PROP_DEVICE_API, api_name);
89 /* Get bt sink if available */
90 static pa_sink* get_bt_sink (pa_core *c)
94 const char* api_name = NULL;
97 pa_log_warn ("input param is null");
100 PA_IDXSET_FOREACH(s, c->sinks, idx) {
101 if (check_is_bluez (s)) {
102 pa_log_debug ("[POLICY][%s] return [%p] for [%s]\n", __func__, s, s->name);
109 /* Called when new sink-input is creating */
110 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u)
112 const char *policy = NULL;
113 pa_sink* sink = NULL;
114 pa_sink* bt_sink = NULL;
120 if (!new_data->proplist) {
121 pa_log_debug("[MFLD] New stream lacks property data.");
124 /* If sink-input has already sink, skip */
125 if (new_data->sink) {
126 /* sink-input with filter role will be also here because sink is already set */
127 pa_log_debug("[MFLD] Sink already set");
131 /* If no policy exists, skip */
132 if (!(policy = pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_POLICY)))
135 pa_log_debug("[MFLD] Policy for stream [%s] = [%s]",
136 pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)), policy);
137 /* If policy == all */
138 if (pa_streq(policy, POLICY_ALL)) {
139 pa_log_debug("[MFLD] Change policy to auto");
140 pa_proplist_sets(new_data->proplist, PA_PROP_MEDIA_POLICY, POLICY_AUTO);
143 bt_sink = get_bt_sink(c);
145 sink = get_sink_by_name(c, SINK_COMBINED);
147 /* check default sink */
148 def = pa_namereg_get_default_sink(c);
149 if (def && strstr(def->name,"alsa_")) {
150 pa_log_debug("[MFLD] default sink is %s, set to default", def->name);
153 pa_log_debug("[MFLD] set sink to alsa speaker");
154 sink = get_sink_by_name(c, SINK_ALSA);
157 new_data->sink = sink;
162 int pa__init(pa_module *m)
166 m->userdata = u = pa_xnew0(struct userdata, 1);
169 /* A little bit later than module-stream-restore and before module-policy */
170 u->sink_input_new_hook_slot =
171 pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY+6, (pa_hook_cb_t) sink_input_new_hook_callback, u);
173 pa_log_info("[MFLD] stream policy check module is loaded\n");
177 void pa__done(pa_module *m)
181 if (!(u = m->userdata))
183 if (u->sink_input_new_hook_slot)
184 pa_hook_slot_free(u->sink_input_new_hook_slot);