[-]
[+]
|
Added |
_service:tar_git:pulseaudio.changes
|
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio.spec
^
|
|
[-]
[+]
|
Added |
_service:tar_git:1001-core-make-dependencies-compile-for-64bit.patch
^
|
@@ -0,0 +1,29 @@
+From 345fb6f1acf1d6b90d10b6c323a6ff7747f6f187 Mon Sep 17 00:00:00 2001
+From: Simonas Leleiva <simonas.leleiva@jollamobile.com>
+Date: Mon, 6 Jan 2014 11:30:06 +0000
+Subject: [PATCH 1001/1015] core: make dependencies compile for 64bit
+
+E.g. pulseaudio-policy-enforcement fails on:
+/usr/include/pulsecore/atomic.h:289:2: error: invalid preprocessing directive #warn
+
+Signed-off-by: Simonas Leleiva <simonas.leleiva@jollamobile.com>
+---
+ src/pulsecore/atomic.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h
+index 419783d..c8a59f2 100644
+--- a/src/pulsecore/atomic.h
++++ b/src/pulsecore/atomic.h
+@@ -286,7 +286,7 @@ static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* n
+
+ #elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
+
+-#warn "The native atomic operations implementation for AMD64 has not been tested thoroughly. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: test the native atomic operations implementation for AMD64, fix libatomic_ops, or upgrade your GCC."
++#warning "The native atomic operations implementation for AMD64 has not been tested thoroughly. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: test the native atomic operations implementation for AMD64, fix libatomic_ops, or upgrade your GCC."
+
+ /* Adapted from glibc */
+
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1003-daemon-Disable-automatic-shutdown-by-default.patch
^
|
@@ -0,0 +1,35 @@
+From 851ac7d1b7c196719ead85b17c83b466954d3f40 Mon Sep 17 00:00:00 2001
+From: Tanu Kaskinen <tanu.kaskinen@jollamobile.com>
+Date: Wed, 10 Oct 2012 11:17:04 +0300
+Subject: [PATCH 1003/1015] daemon: Disable automatic shutdown by default.
+
+Mer (or rather Nemo) specific patch, not upstreamable.
+---
+ src/daemon/daemon.conf.in | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
+index 2089058..35c13a4 100644
+--- a/src/daemon/daemon.conf.in
++++ b/src/daemon/daemon.conf.in
+@@ -41,6 +41,17 @@ ifelse(@HAVE_DBUS@, 1, [dnl
+ ; realtime-priority = 5
+
+ ; exit-idle-time = 20
++
++# exit-idle-time is enabled by default in upstream, because it makes
++# console logins work nicely (the daemon is not left around forever
++# after logout). Graphical sessions are expected to somehow disable
++# the automatic shutdown for the duration of the session, but at least
++# Nemo doesn't currently do that, and since console logins are not
++# that important, we can disable the automatic shutdown here. With
++# systemd user sessions it should be possible to handle this properly,
++# so this change should be eventually dropped.
++exit-idle-time = -1
++
+ ; scache-idle-time = 20
+
+ ; dl-search-path = (depends on architecture)
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1004-daemon-Set-default-resampler-to-speex-fixed-2.patch
^
|
@@ -0,0 +1,42 @@
+From 8e6391c5453fd250bcec4db72a7ec1da8d8dab7d 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 09:41:00 +0300
+Subject: [PATCH 1004/1015] daemon: Set default resampler to speex fixed 2.
+
+---
+ src/daemon/daemon.conf.in | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
+index 35c13a4..20b1bfd 100644
+--- a/src/daemon/daemon.conf.in
++++ b/src/daemon/daemon.conf.in
+@@ -65,7 +65,23 @@ exit-idle-time = -1
+ ; log-time = no
+ ; log-backtrace = 0
+
+-; resample-method = speex-float-1
++# speex-float-x is arguably too heavy resampler to be the default.
++# Ubuntu, for example, patches this to speex-float-2. Mer is targeted
++# at mobile devices, and speex-float-2 may still be a bit too heavy
++# for that purpose. Ideally the default resampler would be decided by
++# hardware adaptations, but for now we patch this in Mer.
++#
++# Why ffmpeg, why not e.g. speex-fixed-1? I don't know, I'm not aware
++# of the history of that decision. If you think something else would
++# be better, feel free to change this (and document the rationale
++# here).
++#
++# Changed from ffmpeg to speex-fixed-2 due to ffmpeg producing broken
++# audio data in some cases (mono samples). No good other rationale
++# for choosing the resampling method as of yet. Benchmarking different
++# resamplers would be a good starting point to decide properly.
++resample-method = speex-fixed-2
++
+ ; enable-remixing = yes
+ ; enable-lfe-remixing = no
+
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1005-module-rescue-streams-Add-parameters-to-define-defau.patch
^
|
@@ -0,0 +1,216 @@
+From 714927eca8fdaf07d142bf6ce96f364de6535683 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 09:44:24 +0300
+Subject: [PATCH 1005/1015] module-rescue-streams: Add parameters to define
+ default targets.
+
+If sink_name or source_name are defined for the module, when streams'
+sink our source is destroyed, try to move the stream first to
+{sink,source} defined in module arguments. If defined {sink,source}
+doesn't exist, use old logic of moving the stream to
+default {sink,source}.
+---
+ src/modules/module-rescue-streams.c | 63 ++++++++++++++++++++++++++++++-------
+ 1 file changed, 52 insertions(+), 11 deletions(-)
+
+diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
+index 7035a35..e7e96b3 100644
+--- a/src/modules/module-rescue-streams.c
++++ b/src/modules/module-rescue-streams.c
+@@ -39,12 +39,20 @@ PA_MODULE_AUTHOR("Lennart Poettering");
+ PA_MODULE_DESCRIPTION("When a sink/source is removed, try to move its streams to the default sink/source");
+ PA_MODULE_VERSION(PACKAGE_VERSION);
+ PA_MODULE_LOAD_ONCE(true);
++PA_MODULE_USAGE(
++ "sink_name=<name for sink that is tried first when rescuing sinks."
++ "source_name=<name for source that is tried first when rescuing sources.");
+
+ static const char* const valid_modargs[] = {
++ "sink_name",
++ "source_name",
+ NULL,
+ };
+
+ struct userdata {
++ char *default_sink_name;
++ char *default_source_name;
++
+ pa_hook_slot
+ *sink_unlink_slot,
+ *source_unlink_slot,
+@@ -52,13 +60,21 @@ struct userdata {
+ *source_output_move_fail_slot;
+ };
+
+-static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip) {
++static pa_sink* find_evacuation_sink(struct userdata *u, pa_core *c, pa_sink_input *i, pa_sink *skip) {
+ pa_sink *target, *def;
+ uint32_t idx;
+
++ pa_assert(u);
+ pa_assert(c);
+ pa_assert(i);
+
++ if (u->default_sink_name) {
++ if ((target = pa_namereg_get(c, u->default_sink_name, PA_NAMEREG_SINK))) {
++ if (target != skip)
++ return target;
++ }
++ }
++
+ def = pa_namereg_get_default_sink(c);
+
+ if (def && def != skip && pa_sink_input_may_move_to(i, def))
+@@ -82,12 +98,13 @@ static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip
+ return NULL;
+ }
+
+-static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
++static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
+ pa_sink_input *i;
+ uint32_t idx;
+
+ pa_assert(c);
+ pa_assert(sink);
++ pa_assert(u);
+
+ /* There's no point in doing anything if the core is shut down anyway */
+ if (c->state == PA_CORE_SHUTDOWN)
+@@ -101,7 +118,7 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, voi
+ PA_IDXSET_FOREACH(i, sink->inputs, idx) {
+ pa_sink *target;
+
+- if (!(target = find_evacuation_sink(c, i, sink)))
++ if (!(target = find_evacuation_sink(u, c, i, sink)))
+ continue;
+
+ if (pa_sink_input_move_to(i, target, false) < 0)
+@@ -115,17 +132,18 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, voi
+ return PA_HOOK_OK;
+ }
+
+-static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_input *i, void *userdata) {
++static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_input *i, struct userdata *u) {
+ pa_sink *target;
+
+ pa_assert(c);
+ pa_assert(i);
++ pa_assert(u);
+
+ /* There's no point in doing anything if the core is shut down anyway */
+ if (c->state == PA_CORE_SHUTDOWN)
+ return PA_HOOK_OK;
+
+- if (!(target = find_evacuation_sink(c, i, NULL)))
++ if (!(target = find_evacuation_sink(u, c, i, NULL)))
+ return PA_HOOK_OK;
+
+ if (pa_sink_input_finish_move(i, target, false) < 0) {
+@@ -140,13 +158,22 @@ static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_i
+ }
+ }
+
+-static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_source *skip) {
++static pa_source* find_evacuation_source(struct userdata *u, pa_core *c, pa_source_output *o, pa_source *skip) {
+ pa_source *target, *def;
+ uint32_t idx;
+
++ pa_assert(u);
+ pa_assert(c);
+ pa_assert(o);
+
++ if (u->default_source_name) {
++ if ((target = pa_namereg_get(c, u->default_source_name, PA_NAMEREG_SOURCE))) {
++ if (target != skip)
++ return target;
++ }
++ }
++
++
+ def = pa_namereg_get_default_source(c);
+
+ if (def && def != skip && pa_source_output_may_move_to(o, def))
+@@ -173,12 +200,13 @@ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_sou
+ return NULL;
+ }
+
+-static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, void* userdata) {
++static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
+ pa_source_output *o;
+ uint32_t idx;
+
+ pa_assert(c);
+ pa_assert(source);
++ pa_assert(u);
+
+ /* There's no point in doing anything if the core is shut down anyway */
+ if (c->state == PA_CORE_SHUTDOWN)
+@@ -192,7 +220,7 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
+ PA_IDXSET_FOREACH(o, source->outputs, idx) {
+ pa_source *target;
+
+- if (!(target = find_evacuation_source(c, o, source)))
++ if (!(target = find_evacuation_source(u, c, o, source)))
+ continue;
+
+ if (pa_source_output_move_to(o, target, false) < 0)
+@@ -206,17 +234,18 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
+ return PA_HOOK_OK;
+ }
+
+-static pa_hook_result_t source_output_move_fail_hook_callback(pa_core *c, pa_source_output *i, void *userdata) {
++static pa_hook_result_t source_output_move_fail_hook_callback(pa_core *c, pa_source_output *i, struct userdata *u) {
+ pa_source *target;
+
+ pa_assert(c);
+ pa_assert(i);
++ pa_assert(u);
+
+ /* There's no point in doing anything if the core is shut down anyway */
+ if (c->state == PA_CORE_SHUTDOWN)
+ return PA_HOOK_OK;
+
+- if (!(target = find_evacuation_source(c, i, NULL)))
++ if (!(target = find_evacuation_source(u, c, i, NULL)))
+ return PA_HOOK_OK;
+
+ if (pa_source_output_finish_move(i, target, false) < 0) {
+@@ -234,6 +263,7 @@ static pa_hook_result_t source_output_move_fail_hook_callback(pa_core *c, pa_sou
+ int pa__init(pa_module*m) {
+ pa_modargs *ma;
+ struct userdata *u;
++ const char *tmp;
+
+ pa_assert(m);
+
+@@ -242,7 +272,13 @@ int pa__init(pa_module*m) {
+ return -1;
+ }
+
+- m->userdata = u = pa_xnew(struct userdata, 1);
++ m->userdata = u = pa_xnew0(struct userdata, 1);
++
++ if ((tmp = pa_modargs_get_value(ma, "sink_name", NULL)))
++ u->default_sink_name = pa_xstrdup(tmp);
++
++ if ((tmp = pa_modargs_get_value(ma, "source_name", NULL)))
++ u->default_source_name = pa_xstrdup(tmp);
+
|
[-]
[+]
|
Added |
_service:tar_git:1006-client-Disable-client-autospawn-by-default.patch
^
|
@@ -0,0 +1,33 @@
+From 59a1f6ac58db069334e89a0d6633b6c7bc7d9c51 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?=
+ <juho.hamalainen@tieto.com>
+Date: Fri, 4 Oct 2013 12:41:15 +0300
+Subject: [PATCH 1006/1015] client: Disable client autospawn by default.
+
+Not upstreamable.
+---
+ src/pulse/client.conf.in | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/src/pulse/client.conf.in b/src/pulse/client.conf.in
+index 17753b0..86b70b7 100644
+--- a/src/pulse/client.conf.in
++++ b/src/pulse/client.conf.in
+@@ -24,7 +24,13 @@
+ ; default-server =
+ ; default-dbus-server =
+
+-; autospawn = yes
++# Autospawning daemon if daemon is not running is enabled by default.
++# With Mer we want to control daemon startup and stopping using user session
++# and to prevent other clients autospawning daemon before systemd starts
++# PulseAudio we change the default to disabling autospawn alltogether.
++# If/when PulseAudio startup is tied to some other session this can be
++# reverted back to default.
++autospawn = no
+ ; daemon-binary = @PA_BINARY@
+ ; extra-arguments = --log-target=syslog
+
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1007-bluez4-device-Allow-leaving-transport-running-while-.patch
^
|
@@ -0,0 +1,143 @@
+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
+
|
[-]
[+]
|
Added |
_service:tar_git:1008-bluez4-device-Do-not-lose-transport-pointer-after-ge.patch
^
|
@@ -0,0 +1,28 @@
+From 8e812f90473fbc13ec9b7ae7daf61d0ab52014f8 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:27:45 +0300
+Subject: [PATCH 1008/1015] bluez4-device: Do not lose transport pointer after
+ getting it.
+
+---
+ src/modules/bluetooth/module-bluez4-device.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c
+index 28ddced..12453e1 100644
+--- a/src/modules/bluetooth/module-bluez4-device.c
++++ b/src/modules/bluetooth/module-bluez4-device.c
+@@ -1976,7 +1976,8 @@ static void stop_thread(struct userdata *u) {
+
+ if (u->transport) {
+ bt_transport_release(u);
+- u->transport = NULL;
++ /* Do not set transport pointer to NULL. When failing to switch
++ * profile NULL u->transport would assert. */
+ }
+
+ if (u->sink) {
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1009-bluez4-device-Default-to-using-A2DP-profile-initiall.patch
^
|
@@ -0,0 +1,101 @@
+From b58fef2f1ab4a336fc33d74d17cb432752ead534 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:34:06 +0300
+Subject: [PATCH 1009/1015] bluez4-device: Default to using A2DP profile
+ initially.
+
+By default have A2DP profiles with higher priority than HFP profiles,
+since usually when A2DP+HFP-capable device is connected, it's meant for
+A2DP streaming. This behavior can be dynamically overridden by setting
+property bluetooth.prefer.hsp as true to SCO sink. When this property is
+found in SCO sink upon bluez4-device startup, HFP profiles have
+higher priority than A2DP to select HFP initially.
+---
+ src/modules/bluetooth/module-bluez4-device.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c
+index 12453e1..efd0589 100644
+--- a/src/modules/bluetooth/module-bluez4-device.c
++++ b/src/modules/bluetooth/module-bluez4-device.c
+@@ -208,6 +208,8 @@ enum {
+
+ #define USE_SCO_OVER_PCM(u) (u->profile == PA_BLUEZ4_PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source))
+
++#define BLUETOOTH_PREFER_HSP "bluetooth.prefer.hsp"
++
+ static int init_profile(struct userdata *u);
+
+ /* from IO thread */
+@@ -2228,6 +2230,22 @@ static void create_card_ports(struct userdata *u, pa_hashmap *ports) {
+ pa_device_port_new_data_done(&port_data);
+ }
+
++static int check_prefer_hsp(struct userdata *u) {
++ const char *tmp;
++ int prefer_hsp = 0;
++
++ pa_assert(u);
++
++ if (u->hsp.sco_sink) {
++ if ((tmp = pa_proplist_gets(u->hsp.sco_sink->proplist, BLUETOOTH_PREFER_HSP))) {
++ if (pa_streq(tmp, "true"))
++ prefer_hsp = 20;
++ }
++ }
++
++ return prefer_hsp;
++}
++
+ /* Run from main thread */
+ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid, pa_hashmap *ports) {
+ pa_device_port *input_port, *output_port;
+@@ -2241,7 +2259,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid
+
+ if (pa_streq(uuid, A2DP_SINK_UUID)) {
+ p = pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP)"), sizeof(pa_bluez4_profile_t));
+- p->priority = 10;
++ p->priority = 20;
+ p->n_sinks = 1;
+ p->n_sources = 0;
+ p->max_sink_channels = 2;
+@@ -2252,7 +2270,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid
+ *d = PA_BLUEZ4_PROFILE_A2DP;
+ } else if (pa_streq(uuid, A2DP_SOURCE_UUID)) {
+ p = pa_card_profile_new("a2dp_source", _("High Fidelity Capture (A2DP)"), sizeof(pa_bluez4_profile_t));
+- p->priority = 10;
++ p->priority = 20;
+ p->n_sinks = 0;
+ p->n_sources = 1;
+ p->max_sink_channels = 0;
+@@ -2263,7 +2281,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid
+ *d = PA_BLUEZ4_PROFILE_A2DP_SOURCE;
+ } else if (pa_streq(uuid, HSP_HS_UUID) || pa_streq(uuid, HFP_HS_UUID)) {
+ p = pa_card_profile_new("hsp", _("Telephony Duplex (HSP/HFP)"), sizeof(pa_bluez4_profile_t));
+- p->priority = 20;
++ p->priority = 10 + check_prefer_hsp(u);
+ p->n_sinks = 1;
+ p->n_sources = 1;
+ p->max_sink_channels = 1;
+@@ -2275,7 +2293,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid
+ *d = PA_BLUEZ4_PROFILE_HSP;
+ } else if (pa_streq(uuid, HFP_AG_UUID)) {
+ p = pa_card_profile_new("hfgw", _("Handsfree Gateway"), sizeof(pa_bluez4_profile_t));
+- p->priority = 20;
++ p->priority = 10 + check_prefer_hsp(u);
+ p->n_sinks = 1;
+ p->n_sources = 1;
+ p->max_sink_channels = 1;
+@@ -2385,6 +2403,8 @@ static int add_card(struct userdata *u) {
+
+ d = PA_CARD_PROFILE_DATA(u->card->active_profile);
+
++ pa_log_debug("Select initial profile (%s)", *d == PA_BLUEZ4_PROFILE_OFF ? "off" : pa_bluez4_profile_to_string(*d));
++
+ if (*d != PA_BLUEZ4_PROFILE_OFF && (!device->transports[*d] ||
+ device->transports[*d]->state == PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED)) {
+ pa_log_warn("Default profile not connected, selecting off profile");
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1010-bluez4-util-Detect-transport-acquire-release-loop.patch
^
|
@@ -0,0 +1,67 @@
+From 357814a1c4a1305cbd5d6055ff88c52db613c1c2 Mon Sep 17 00:00:00 2001
+From: Timo Honkonen <timo.honkonen@oss.tieto.com>
+Date: Thu, 10 Apr 2014 10:39:06 +0300
+Subject: [PATCH 1010/1015] bluez4-util: Detect transport acquire-release loop.
+
+---
+ src/modules/bluetooth/bluez4-util.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/src/modules/bluetooth/bluez4-util.c b/src/modules/bluetooth/bluez4-util.c
+index f047b73..6081fd0 100644
+--- a/src/modules/bluetooth/bluez4-util.c
++++ b/src/modules/bluetooth/bluez4-util.c
+@@ -28,6 +28,7 @@
+ #include <pulsecore/core-util.h>
+ #include <pulsecore/shared.h>
+ #include <pulsecore/dbus-shared.h>
++#include <pulse/rtclock.h>
+
+ #include "bluez4-util.h"
+ #include "a2dp-codecs.h"
+@@ -61,6 +62,8 @@
+ " </interface>" \
+ "</node>"
+
++#define RACE_CONDITION_TIME 1000000 // 1 second
++
+ struct pa_bluez4_discovery {
+ PA_REFCNT_DECLARE;
+
+@@ -506,6 +509,9 @@ static int parse_audio_property(pa_bluez4_device *d, const char *interface, DBus
+ DBusMessageIter variant_i;
+ bool is_audio_interface;
+ pa_bluez4_profile_t p = PA_BLUEZ4_PROFILE_OFF;
++ pa_usec_t tstamp_now;
++ static pa_usec_t tstamp_prev = 0;
++ DBusMessage *m;
+
+ pa_assert(d);
+ pa_assert(interface);
+@@ -537,6 +543,23 @@ static int parse_audio_property(pa_bluez4_device *d, const char *interface, DBus
+ pa_bluez4_transport_state_t old_state;
+
+ pa_log_debug("Device %s interface %s property 'State' changed to value '%s'", d->path, interface, value);
++ /* Device may change state again (e.g. suspend itself) before previous state change
++ * message has been parsed here. When this take place sink state in here and bluez
++ * will be out-of-sync. This may generate endless transport acquire/release loop
++ * which will be sustained by this module. When we notice this to be ongoing
++ * message is ignored and current state is queried with GetProperties. */
++ if(pa_streq(interface, "org.bluez.AudioSink") && state == PA_BLUEZ4_AUDIO_STATE_CONNECTED) {
++ tstamp_now = pa_rtclock_now();
++ if (tstamp_prev != 0 && tstamp_now - tstamp_prev < RACE_CONDITION_TIME) {
++ pa_log_debug("Race condition. Message ignored.");
++ tstamp_prev = 0;
++ pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.AudioSink", "GetProperties"));
++ send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
++
++ return 0;
++ }
++ tstamp_prev = tstamp_now;
++ }
+
+ if (state == PA_BLUEZ4_AUDIO_STATE_INVALID)
+ return -1;
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1011-daemon-Exit-with-0-on-SIGINT-or-SIGTERM.patch
^
|
@@ -0,0 +1,26 @@
+From 50638b839d72adab6b2ef79f02a6ab077afe9b6e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?=
+ <juho.hamalainen@tieto.com>
+Date: Mon, 9 Jun 2014 14:11:46 +0300
+Subject: [PATCH 1011/1015] daemon: Exit with 0 on SIGINT or SIGTERM.
+
+---
+ src/daemon/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/daemon/main.c b/src/daemon/main.c
+index e01371e..a8897bd 100644
+--- a/src/daemon/main.c
++++ b/src/daemon/main.c
+@@ -164,7 +164,7 @@ static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void
+ case SIGTERM:
+ default:
+ pa_log_info(_("Exiting."));
+- m->quit(m, 1);
++ m->quit(m, 0);
+ break;
+ }
+ }
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1012-bluez4-device-Fix-assert-when-source-doesn-t-exist-w.patch
^
|
@@ -0,0 +1,30 @@
+From ce456c0c6699109bc9c5ddcfb8a2d2f6ca8a0318 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, 17 Jul 2014 09:53:14 +0300
+Subject: [PATCH 1012/1015] bluez4-device: Fix assert when source doesn't exist
+ when changing properties.
+
+---
+ src/modules/bluetooth/module-bluez4-device.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c
+index efd0589..32392bf 100644
+--- a/src/modules/bluetooth/module-bluez4-device.c
++++ b/src/modules/bluetooth/module-bluez4-device.c
+@@ -1536,6 +1536,11 @@ static pa_hook_result_t transport_nrec_changed_cb(pa_bluez4_discovery *y, pa_blu
+ if (t != u->transport)
+ return PA_HOOK_OK;
+
++ if (!u->source) {
++ pa_log_warn("trying to change bluez4 source property, but source doesn't exist.");
++ return PA_HOOK_OK;
++ }
++
+ p = pa_proplist_new();
+ pa_proplist_sets(p, "bluetooth.nrec", t->nrec ? "1" : "0");
+ pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, p);
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1013-core-Use-XDG_RUNTIME_DIR-only-if-owned-by-us.patch
^
|
@@ -0,0 +1,35 @@
+From 82957a704331f5fac13a7550e66fd86114ef5458 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?=
+ <juho.hamalainen@tieto.com>
+Date: Fri, 15 Aug 2014 12:30:00 +0300
+Subject: [PATCH 1013/1015] core: Use XDG_RUNTIME_DIR only if owned by us.
+
+If for some reason XDG_RUNTIME_DIR points to runtime dir not owned by
+our uid, fail. Having wrong XDG_RUNTIME_DIR is especially bad with root,
+since then the pulse runtime directory's ownership is changed,
+preventing clients from connecting etc bad things.
+---
+ src/pulsecore/core-util.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
+index 0d9e354..83cd40d 100644
+--- a/src/pulsecore/core-util.c
++++ b/src/pulsecore/core-util.c
+@@ -1789,6 +1789,13 @@ char *pa_get_runtime_dir(void) {
+ /* Use the XDG standard for the runtime directory. */
+ d = getenv("XDG_RUNTIME_DIR");
+ if (d) {
++#ifdef HAVE_FSTAT
++ struct stat st;
++ if (stat(d, &st) == 0 && st.st_uid != getuid()) {
++ pa_log("XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d.", d, getuid(), st.st_uid);
++ goto fail;
++ }
++#endif
+ k = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", d);
+
+ if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1, true) < 0) {
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1014-bluez-device-Check-for-transport-suspend-on-profile-.patch
^
|
@@ -0,0 +1,71 @@
+From 6c0eb114ee95e892b87d013d33d8aef0ac6ddb20 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?=
+ <juho.hamalainen@tieto.com>
+Date: Mon, 30 Mar 2015 12:27:41 +0300
+Subject: [PATCH 1014/1015] bluez-device: Check for transport suspend on
+ profile change.
+
+---
+ src/modules/bluetooth/module-bluez4-device.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c
+index 32392bf..67f985b 100644
+--- a/src/modules/bluetooth/module-bluez4-device.c
++++ b/src/modules/bluetooth/module-bluez4-device.c
+@@ -423,27 +423,36 @@ static int check_proplist(struct userdata *u) {
+ * 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) {
++static void update_allow_release(struct userdata *u) {
+ pa_assert(u);
+- pa_assert(s);
+
+- if (!u->hsp.sco_sink || u->hsp.sco_sink != s)
+- return PA_HOOK_OK;
++ if (!u->hsp.sco_sink)
++ return;
+
+ if (check_proplist(u) < 0)
+- return PA_HOOK_OK;
++ return;
+
+ if (!USE_SCO_OVER_PCM(u)) {
+ pa_log_debug("SCO sink not available.");
+- return PA_HOOK_OK;
++ return;
+ }
+
+ 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);
++ pa_sink_suspend(u->hsp.sco_sink, FALSE, PA_SUSPEND_ALL);
+ }
++}
++
++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;
++
++ update_allow_release(u);
+
+ return PA_HOOK_OK;
+ }
+@@ -2131,6 +2140,8 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
+ if (start_thread(u) < 0)
+ goto off;
+
++ update_allow_release(u);
++
+ return 0;
+
+ off:
+--
+1.9.1
+
|
[-]
[+]
|
Added |
_service:tar_git:1015-bluez4-device-Don-t-acquire-transport-when-connectin.patch
^
|
@@ -0,0 +1,237 @@
+From f74c97d5526557661955d967f84d7ea690e5f404 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?=
+ <juho.hamalainen@tieto.com>
+Date: Mon, 30 Mar 2015 11:28:09 +0300
+Subject: [PATCH 1015/1015] bluez4-device: Don't acquire transport when
+ connecting device.
+
+When creating module-bluez4-device do not acquire transport but start
+the sink and source in suspended state. Then acquire transport normally
+upon first and subsequent use.
+
+Without this change PTS test A2DP TC_SRC_AS_BV_01_I fails.
+
+From bug JB#27276:
+
+PTS takes the AVDTP streaming start for the silence as a sign that IUT
+proceeds with the test case and after idle timeout stream suspend comes
+along, PTS disconnects the audio connection, so trying to stream
+something from the media player after that doesn't have any effect on
+the test case.
+
+Technically speaking the test case does work, but since there's no
+audible sound to check streaming takes place the qualification engineer
+would fail the verification.
+---
+ src/modules/bluetooth/module-bluez4-device.c | 82 +++++++++++++++-------------
+ 1 file changed, 43 insertions(+), 39 deletions(-)
+
+diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c
+index 67f985b..2555b85 100644
+--- a/src/modules/bluetooth/module-bluez4-device.c
++++ b/src/modules/bluetooth/module-bluez4-device.c
+@@ -141,6 +141,7 @@ struct userdata {
+ char *path;
+ pa_bluez4_transport *transport;
+ bool transport_acquired;
++ bool transport_configured;
+ pa_hook_slot *discovery_slot;
+ pa_hook_slot *sink_state_changed_slot;
+ pa_hook_slot *source_state_changed_slot;
+@@ -211,6 +212,9 @@ enum {
+ #define BLUETOOTH_PREFER_HSP "bluetooth.prefer.hsp"
+
+ static int init_profile(struct userdata *u);
++static int bt_transport_setup(struct userdata *u);
++static int bt_transport_acquire(struct userdata *u, bool optional);
++static void bt_transport_config(struct userdata *u);
+
+ /* from IO thread */
+ static void a2dp_set_bitpool(struct userdata *u, uint8_t bitpool) {
+@@ -363,13 +367,10 @@ static void bt_transport_release(struct userdata *u) {
+ teardown_stream(u);
+ }
+
+-static int bt_transport_acquire(struct userdata *u, bool optional) {
++static int transport_acquire(struct userdata *u, bool optional) {
+ pa_assert(u->transport);
+
+- if (u->transport_acquired)
+- return 0;
+-
+- pa_log_debug("Acquiring transport %s", u->transport->path);
++ pa_log_debug("Acquiring transport %s%s", u->transport->path, optional ? " (optional)" : "");
+
+ u->stream_fd = pa_bluez4_transport_acquire(u->transport, optional, &u->read_link_mtu, &u->write_link_mtu);
+ if (u->stream_fd < 0) {
+@@ -495,8 +496,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
+ if (!u->source || !PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
+ if (bt_transport_acquire(u, false) < 0)
+ failed = true;
+- else
++ else {
++ bt_transport_config(u);
+ setup_stream(u);
++ }
+ }
+ break;
+
+@@ -572,8 +575,10 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
+ if (!u->sink || !PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+ if (bt_transport_acquire(u, false) < 0)
+ failed = true;
+- else
++ else {
++ bt_transport_config(u);
+ setup_stream(u);
++ }
+ }
+ /* We don't resume the smoother here. Instead we
+ * wait until the first packet arrives */
+@@ -1357,6 +1362,7 @@ static void handle_transport_state_change(struct userdata *u, struct pa_bluez4_t
+
+ if (acquire)
+ if (bt_transport_acquire(u, true) >= 0) {
++ bt_transport_config(u);
+ if (u->source) {
+ pa_log_debug("Resuming source %s, because the bluetooth audio state changed to 'playing'.", u->source->name);
+ pa_source_suspend(u->source, false, PA_SUSPEND_IDLE|PA_SUSPEND_USER);
+@@ -1489,6 +1495,8 @@ static int sco_over_pcm_state_update(struct userdata *u, bool changed) {
+ if (bt_transport_acquire(u, false) < 0)
+ return -1;
+
++ bt_transport_config(u);
++
+ setup_stream(u);
+
+ return 0;
+@@ -1649,6 +1657,7 @@ static int add_sink(struct userdata *u) {
+ data.card = u->card;
+ data.name = get_name("sink", u->modargs, u->address, &b);
+ data.namereg_fail = b;
++ data.suspend_cause = PA_SUSPEND_IDLE;
+
+ if (pa_modargs_get_proplist(u->modargs, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
+ pa_log("Invalid properties");
+@@ -1657,19 +1666,8 @@ static int add_sink(struct userdata *u) {
+ }
+ connect_ports(u, &data, PA_DIRECTION_OUTPUT);
+
+- if (!u->transport_acquired)
+- switch (u->profile) {
+- case PA_BLUEZ4_PROFILE_A2DP:
+- case PA_BLUEZ4_PROFILE_HSP:
+- pa_assert_not_reached(); /* Profile switch should have failed */
+- break;
+- case PA_BLUEZ4_PROFILE_HFGW:
+- data.suspend_cause = PA_SUSPEND_USER;
+- break;
+- case PA_BLUEZ4_PROFILE_A2DP_SOURCE:
+- case PA_BLUEZ4_PROFILE_OFF:
+- pa_assert_not_reached();
+- }
++ if (!u->transport_acquired && u->profile == PA_BLUEZ4_PROFILE_HFGW)
++ data.suspend_cause |= PA_SUSPEND_USER;
+
+ u->sink = pa_sink_new(u->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
+ pa_sink_new_data_done(&data);
+@@ -1720,6 +1718,7 @@ static int add_source(struct userdata *u) {
+ data.card = u->card;
+ data.name = get_name("source", u->modargs, u->address, &b);
+ data.namereg_fail = b;
++ data.suspend_cause = PA_SUSPEND_IDLE;
+
+ if (pa_modargs_get_proplist(u->modargs, "source_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
+ pa_log("Invalid properties");
+@@ -1729,19 +1728,8 @@ static int add_source(struct userdata *u) {
+
+ connect_ports(u, &data, PA_DIRECTION_INPUT);
+
+- if (!u->transport_acquired)
+- switch (u->profile) {
+- case PA_BLUEZ4_PROFILE_HSP:
+- pa_assert_not_reached(); /* Profile switch should have failed */
+- break;
+- case PA_BLUEZ4_PROFILE_A2DP_SOURCE:
+- case PA_BLUEZ4_PROFILE_HFGW:
+- data.suspend_cause = PA_SUSPEND_USER;
+- break;
+- case PA_BLUEZ4_PROFILE_A2DP:
+- case PA_BLUEZ4_PROFILE_OFF:
+- pa_assert_not_reached();
+- }
++ if (!u->transport_acquired && u->profile == PA_BLUEZ4_PROFILE_HFGW)
++ data.suspend_cause |= PA_SUSPEND_USER;
+
+ u->source = pa_source_new(u->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
+ pa_source_new_data_done(&data);
+@@ -1885,12 +1873,17 @@ static void bt_transport_config_a2dp(struct userdata *u) {
+ }
+
+ static void bt_transport_config(struct userdata *u) {
++ if (u->transport_configured)
++ return;
++
+ if (u->profile == PA_BLUEZ4_PROFILE_HSP || u->profile == PA_BLUEZ4_PROFILE_HFGW) {
+ u->sample_spec.format = PA_SAMPLE_S16LE;
+ u->sample_spec.channels = 1;
+ u->sample_spec.rate = 8000;
+ } else
+ bt_transport_config_a2dp(u);
++
++ u->transport_configured = true;
+ }
+
+ /* Run from main thread */
+@@ -1908,7 +1901,7 @@ static pa_hook_result_t transport_state_changed_cb(pa_bluez4_discovery *y, pa_bl
+ }
+
+ /* Run from main thread */
+-static int setup_transport(struct userdata *u) {
++static int bt_transport_setup(struct userdata *u) {
+ pa_bluez4_transport *t;
+
+ pa_assert(u);
+@@ -1924,13 +1917,22 @@ static int setup_transport(struct userdata *u) {
+
+ u->transport = t;
+
++ return 0;
|
[-]
[+]
|
Added |
_service:tar_git:2001-dbus-Use-correct-initialization-for-source-ports-has.patch
^
|
@@ -0,0 +1,33 @@
+From 433fd29a1f5ee75527343ff7299c59f58c0b2dc6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?=
+ <juho.hamalainen@tieto.com>
+Date: Tue, 15 Apr 2014 15:45:03 +0300
+Subject: [PATCH] dbus: Use correct initialization for source ports hashmap.
+
+Source ports hashmap is created without value freeing function, which
+results in (hashmap values) device ports not being freed when source
+ports are removed or module is unloaded. This results in memory leak
+during normal operation and during daemon shutdown dbus_protocol shared
+object isn't unreferenced correctly, leaving dbus_protocol object in
+core->shared, which causes assert when shared hashmap is checked for
+isempty() before freeing.
+---
+ src/modules/dbus/iface-device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/modules/dbus/iface-device.c b/src/modules/dbus/iface-device.c
+index 34b370b..625f057 100644
+--- a/src/modules/dbus/iface-device.c
++++ b/src/modules/dbus/iface-device.c
+@@ -1248,7 +1248,7 @@ pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_
+ d->volume = *pa_source_get_volume(source, false);
+ d->mute = pa_source_get_mute(source, false);
+ d->source_state = pa_source_get_state(source);
+- d->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++ d->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_device_port_free);
+ d->next_port_index = 0;
+ d->active_port = source->active_port;
+ d->proplist = pa_proplist_copy(source->proplist);
+--
+1.8.5.2
+
|
[-]
[+]
|
Changed |
_service
^
|
@@ -3,4 +3,11 @@
<param name="repourl">https://github.com/kimmoli/pulseaudio.git</param>
<param name="branch">master</param>
</service>
-</services>
+<service name="tar_git">
+ <param name="url">https://github.com/kimmoli/pulseaudio.git</param>
+ <param name="branch">master</param>
+ <param name="revision"/>
+ <param name="token"/>
+ <param name="debian">N</param>
+ <param name="dumb">N</param>
+</service></services>
|
[-]
[+]
|
Added |
_service:tar_git:90-pulse.conf
^
|
@@ -0,0 +1,2 @@
+@audio - rtprio 20
+@audio - nice -20
|
|
Added |
_service:tar_git:pulseaudio-5.0+git9.tar.xz
^
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio.service
^
|
@@ -0,0 +1,15 @@
+[Unit]
+Description=PulseAudio
+After=pre-user-session.target
+Requires=dbus.socket
+
+[Service]
+Type=forking
+PIDFile=%t/pulse/pid
+EnvironmentFile=-/etc/sysconfig/pulseaudio
+ExecStart=/usr/bin/pulseaudio --start $CONFIG
+Restart=always
+RestartSec=1
+
+[Install]
+WantedBy=user-session.target
|