[pulseaudio-discuss] [PATCH] profile-switcher: Deal with new Bluetooth cards
Arun Raghavan
arun.raghavan at collabora.co.uk
Thu Feb 9 05:43:17 PST 2012
This makes sure that when a new Bluetooth device turns up, we set it to
the appropriate profile depending on the current list of streams.
---
src/modules/module-profile-switcher.c | 48 ++++++++++++++++++++++++++++++++-
1 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/src/modules/module-profile-switcher.c b/src/modules/module-profile-switcher.c
index 4607ac6..56bc2c1 100644
--- a/src/modules/module-profile-switcher.c
+++ b/src/modules/module-profile-switcher.c
@@ -32,6 +32,7 @@
#include <pulsecore/sink.h>
#include <pulsecore/sink-input.h>
#include <pulsecore/source-output.h>
+#include <pulsecore/card.h>
#include <pulsecore/modargs.h>
#include <pulsecore/log.h>
@@ -50,7 +51,8 @@ struct userdata {
pa_hook_slot
*sink_input_put_slot,
*sink_input_unlink_post_slot,
- *source_output_unlink_post_slot;
+ *source_output_unlink_post_slot,
+ *card_new_slot;
};
#define GET_ROLE(i) \
@@ -189,6 +191,47 @@ static pa_hook_result_t source_output_unlink_post_cb(pa_core *c, pa_source_outpu
return PA_HOOK_OK;
}
+/* Set the inital profile for the card based on currently available
+ * sink-inputs and source-outputs. */
+static pa_hook_result_t card_new_cb(pa_core *c, pa_card_new_data *data, void *userdata) {
+ const char *device_api;
+ pa_sink_input *input;
+ pa_source_output *output;
+ pa_bool_t use_a2dp = TRUE;
+ uint32_t idx;
+
+ device_api = pa_proplist_gets(data->proplist, PA_PROP_DEVICE_API);
+ if (!device_api || !pa_streq(device_api, "bluez"))
+ return PA_HOOK_OK;
+
+ PA_IDXSET_FOREACH(input, c->sink_inputs, idx) {
+ if (pa_streq(GET_ROLE(input), "phone")) {
+ use_a2dp = FALSE;
+ goto done;
+ }
+ }
+
+ PA_IDXSET_FOREACH(output, c->source_outputs, idx) {
+ if (pa_streq(GET_ROLE(output), "phone")) {
+ use_a2dp = FALSE;
+ break;
+ }
+ }
+
+done:
+ if (use_a2dp) {
+ pa_log_info("No phone streams, switching card '%s' to A2DP profile", data->name);
+ pa_card_new_data_set_profile(data, "a2dp");
+ data->save_profile = FALSE;
+ } else {
+ pa_log_info("Have a phone stream, switching card '%s' to HSP/HFP profile", data->name);
+ pa_card_new_data_set_profile(data, "hsp");
+ data->save_profile = FALSE;
+ }
+
+ return PA_HOOK_OK;
+}
+
int pa__init(pa_module*m) {
pa_modargs *ma;
struct userdata *u;
@@ -206,6 +249,7 @@ int pa__init(pa_module*m) {
u->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_put_cb, u);
u->sink_input_unlink_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_unlink_post_cb, u);
u->source_output_unlink_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_unlink_post_cb, u);
+ u->card_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CARD_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) card_new_cb, u);
pa_modargs_free(ma);
return 0;
@@ -225,6 +269,8 @@ void pa__done(pa_module*m) {
pa_hook_slot_free(u->sink_input_unlink_post_slot);
if (u->source_output_unlink_post_slot)
pa_hook_slot_free(u->source_output_unlink_post_slot);
+ if (u->card_new_slot)
+ pa_hook_slot_free(u->card_new_slot);
pa_xfree(u);
}
--
1.7.8.4
More information about the pulseaudio-discuss
mailing list