From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx> 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. --- src/modules/bluetooth/module-bluetooth-device.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 76af4f2..e8c571e 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1307,6 +1307,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); @@ -1385,6 +1386,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); @@ -1400,6 +1402,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); @@ -1412,6 +1415,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); @@ -1424,6 +1428,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); } } @@ -1436,6 +1441,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); -- 1.7.7.6