Search
SailfishOS Open Build Service
>
Projects
>
home:kimmoli
:
testing
>
pulseaudio
> _service:tar_git:1007-bluez4-device-Allow-leaving-transport-running-while-.patch
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File _service:tar_git:1007-bluez4-device-Allow-leaving-transport-running-while-.patch of Package pulseaudio
From 62ac5075d6ba2f2c03e90c66f45885231e52ba47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?= <juho.hamalainen@tieto.com> Date: Thu, 10 Apr 2014 10:26:42 +0300 Subject: [PATCH 1007/1015] bluez4-device: Allow leaving transport running while sink and source are suspended. There are some cases where keeping the SCO transport running even when SCO sink and source are suspended is needed. This patch allows keeping the transport running when SCO sink has property bluetooth.hsp.prevent.suspend.transport set as true. Corner-case specific patch, not upstreamable. --- src/modules/bluetooth/module-bluez4-device.c | 77 +++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c index 83e603f..28ddced 100644 --- a/src/modules/bluetooth/module-bluez4-device.c +++ b/src/modules/bluetooth/module-bluez4-device.c @@ -189,6 +189,9 @@ struct userdata { pa_modargs *modargs; int stream_write_type; + + pa_hook_slot *sco_sink_proplist_changed_slot; + bool prevent_suspend_transport; }; enum { @@ -382,6 +385,67 @@ static int bt_transport_acquire(struct userdata *u, bool optional) { return 0; } +#define HSP_PREVENT_SUSPEND_STR "bluetooth.hsp.prevent.suspend.transport" + +/* Check and update prevent_suspend_transport value from sco sink proplist. + * + * Return < 0 if sink proplist doesn't contain HSP_PREVENT_SUSPEND_STR value, + * 1 if value is 'true' + * 0 if value is something else. */ +static int check_proplist(struct userdata *u) { + int ret; + const char *str; + + pa_assert(u); + pa_assert(u->hsp.sco_sink); + + if ((str = pa_proplist_gets(u->hsp.sco_sink->proplist, HSP_PREVENT_SUSPEND_STR))) { + if (pa_streq(str, "true")) + ret = 1; + else + ret = 0; + } else + ret = -1; + + u->prevent_suspend_transport = ret == 1; + + pa_log_debug("Set %s %s", HSP_PREVENT_SUSPEND_STR, u->prevent_suspend_transport ? "true" : "false"); + + return ret; +} + +/* There are cases where keeping the transport running even when sco sink and source are suspended + * is needed. + * To work with these cases, check sco.sink for bluetooth.hsp.prevent.suspend.transport value, and + * when set to true prevent closing the transport when sink suspends. + * Also, if the sink&source are suspended when sco-sink suspend.transport value changes to true, + * bring sco transport up. When suspend.transport value changes to false while sink&source are suspended, + * tear down the transport. */ +static pa_hook_result_t update_allow_release_cb(pa_core *c, pa_sink *s, struct userdata *u) { + pa_assert(u); + pa_assert(s); + + if (!u->hsp.sco_sink || u->hsp.sco_sink != s) + return PA_HOOK_OK; + + if (check_proplist(u) < 0) + return PA_HOOK_OK; + + if (!USE_SCO_OVER_PCM(u)) { + pa_log_debug("SCO sink not available."); + return PA_HOOK_OK; + } + + if (!PA_SINK_IS_OPENED(pa_sink_get_state(u->hsp.sco_sink)) && + !PA_SOURCE_IS_OPENED(pa_source_get_state(u->hsp.sco_source))) { + + /* Clear all suspend bits, effectively resuming SCO sink for a while. */ + pa_sink_suspend(s, FALSE, PA_SUSPEND_ALL); + } + + return PA_HOOK_OK; +} + /* Run from IO thread */ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; @@ -1423,6 +1487,10 @@ static int sco_over_pcm_state_update(struct userdata *u, bool changed) { if (u->stream_fd < 0) return 0; + if (check_proplist(u) == 1) { + pa_log_debug("Suspend prevention active, not closing SCO over PCM"); + return 0; + } pa_log_debug("Closing SCO over PCM"); bt_transport_release(u); @@ -1828,7 +1896,7 @@ static int setup_transport(struct userdata *u) { pa_bluez4_transport *t; pa_assert(u); - pa_assert(!u->transport); + pa_assert(!u->transport_acquired); pa_assert(u->profile != PA_BLUEZ4_PROFILE_OFF); /* check if profile has a transport */ @@ -2513,6 +2581,10 @@ int pa__init(pa_module *m) { pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED), PA_HOOK_NORMAL, (pa_hook_cb_t) transport_speaker_gain_changed_cb, u); + u->sco_sink_proplist_changed_slot = + pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], + PA_HOOK_NORMAL, (pa_hook_cb_t) update_allow_release_cb, u); + /* Add the card structure. This will also initialize the default profile */ if (add_card(u) < 0) goto fail; @@ -2592,6 +2664,9 @@ void pa__done(pa_module *m) { if (u->transport_speaker_changed_slot) pa_hook_slot_free(u->transport_speaker_changed_slot); + if (u->sco_sink_proplist_changed_slot) + pa_hook_slot_free(u->sco_sink_proplist_changed_slot); + if (USE_SCO_OVER_PCM(u)) restore_sco_volume_callbacks(u); -- 1.9.1