From cb2a6d34f606308b5fbb31b8d938027213e17378 Mon Sep 17 00:00:00 2001 From: Mikel Astiz Date: Fri, 31 Aug 2012 12:51:07 +0200 Subject: [PATCH] bluetooth: Release transport when not available Handle the Playing->Connected transition gracefully by releasing the transport and setting the sink and sources as suspended. This is necessary since the IO thread might not encounter a HUP always. --- .../bluetooth/module-bluetooth-device.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 369622148..d2c0d2bc5 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1308,6 +1308,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us DBusError err; struct userdata *u; bool acquire = FALSE; + bool release = FALSE; pa_assert(bus); pa_assert(m); @@ -1386,6 +1387,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_device_port_set_available(port, available); acquire = (available == PA_PORT_AVAILABLE_YES && u->profile == PROFILE_HFGW); + release = (available != PA_PORT_AVAILABLE_YES && u->profile == PROFILE_HFGW); } } else if (dbus_message_is_signal(m, "org.bluez.Headset", "PropertyChanged")) { pa_bt_audio_state_t state = parse_state_property_change(m); @@ -1401,6 +1403,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_device_port_set_available(port, available); acquire = (available == PA_PORT_AVAILABLE_YES && u->profile == PROFILE_HSP); + release = (available != PA_PORT_AVAILABLE_YES && u->profile == PROFILE_HSP); } } else if (dbus_message_is_signal(m, "org.bluez.AudioSource", "PropertyChanged")) { pa_bt_audio_state_t state = parse_state_property_change(m); @@ -1413,6 +1416,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_device_port_set_available(port, available); acquire = (available == PA_PORT_AVAILABLE_YES && u->profile == PROFILE_A2DP_SOURCE); + release = (available != PA_PORT_AVAILABLE_YES && u->profile == PROFILE_A2DP_SOURCE); } } else if (dbus_message_is_signal(m, "org.bluez.AudioSink", "PropertyChanged")) { pa_bt_audio_state_t state = parse_state_property_change(m); @@ -1425,6 +1429,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_device_port_set_available(port, available); acquire = (available == PA_PORT_AVAILABLE_YES && u->profile == PROFILE_A2DP); + release = (available != PA_PORT_AVAILABLE_YES && u->profile == PROFILE_A2DP); } } @@ -1437,6 +1442,20 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_sink_suspend(u->sink, FALSE, PA_SUSPEND_IDLE|PA_SUSPEND_USER); } + if (release && bt_transport_is_acquired(u)) { + /* FIXME: this release is racy, since the audio stream might have + been set up again in the meantime (but not processed yet by PA). + BlueZ should probably release the transport automatically, and + in that case we would just mark the transport as released */ + + /* Remote side closed the stream so we consider it PA_SUSPEND_USER */ + if (u->source) + pa_source_suspend(u->source, TRUE, PA_SUSPEND_USER); + + if (u->sink) + pa_sink_suspend(u->sink, TRUE, PA_SUSPEND_USER); + } + fail: dbus_error_free(&err);