[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.15-test5-36-g3aa3972

Lennart Poettering gitmailer-noreply at 0pointer.de
Fri Mar 20 17:20:14 PDT 2009


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master branch has been updated
      from  f5c8990d1868f30ed3c13945f7bedb83e2093c11 (commit)

- Log -----------------------------------------------------------------
3aa3972 rework device discovery to share a single device list among all modules
20488fb add pa_hook_is_firing
-----------------------------------------------------------------------

Summary of changes:
 src/modules/bluetooth/bluetooth-util.c            |  245 +++++++++------------
 src/modules/bluetooth/bluetooth-util.h            |   19 +-
 src/modules/bluetooth/module-bluetooth-device.c   |   95 ++++----
 src/modules/bluetooth/module-bluetooth-discover.c |   57 +++---
 src/pulsecore/hook-list.c                         |    6 +
 src/pulsecore/hook-list.h                         |    2 +
 6 files changed, 197 insertions(+), 227 deletions(-)

-----------------------------------------------------------------------

commit 20488fbe3ed068d095d637763555e37af8d16322
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Mar 21 01:18:48 2009 +0100

    add pa_hook_is_firing

diff --git a/src/pulsecore/hook-list.c b/src/pulsecore/hook-list.c
index 5f7a866..a00116d 100644
--- a/src/pulsecore/hook-list.c
+++ b/src/pulsecore/hook-list.c
@@ -121,3 +121,9 @@ pa_hook_result_t pa_hook_fire(pa_hook *hook, void *data) {
 
     return result;
 }
+
+pa_bool_t pa_hook_is_firing(pa_hook *hook) {
+    pa_assert(hook);
+
+    return hook->n_firing > 0;
+}
diff --git a/src/pulsecore/hook-list.h b/src/pulsecore/hook-list.h
index 8514cce..86ce9d2 100644
--- a/src/pulsecore/hook-list.h
+++ b/src/pulsecore/hook-list.h
@@ -71,4 +71,6 @@ void pa_hook_slot_free(pa_hook_slot *slot);
 
 pa_hook_result_t pa_hook_fire(pa_hook *hook, void *data);
 
+pa_bool_t pa_hook_is_firing(pa_hook *hook);
+
 #endif

commit 3aa39726dbe824a9f6e85dd429e64271db8b2849
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Mar 21 01:19:49 2009 +0100

    rework device discovery to share a single device list among all modules

diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index 369b08a..3dfc65e 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -24,31 +24,19 @@
 #endif
 
 #include <pulsecore/core-util.h>
+#include <pulsecore/shared.h>
 #include <modules/dbus-util.h>
 
 #include "bluetooth-util.h"
 
-enum mode {
-    MODE_FIND,
-    MODE_GET,
-    MODE_DISCOVER
-};
-
 struct pa_bluetooth_discovery {
-    DBusConnection *connection;
-    PA_LLIST_HEAD(pa_dbus_pending, pending);
+    PA_REFCNT_DECLARE;
 
-    enum mode mode;
-
-    /* If mode == MODE_FIND look for a specific device by its address.
-       If mode == MODE_GET look for a specific device by its path. */
-    const char *looking_for;
-    pa_bluetooth_device *found_device;
-
-    /* If looking_for is NULL we do long-time discovery */
+    pa_core *core;
+    pa_dbus_connection *connection;
+    PA_LLIST_HEAD(pa_dbus_pending, pending);
     pa_hashmap *devices;
-    pa_bluetooth_device_callback_t callback;
-    struct userdata *userdata;
+    pa_hook hook;
 };
 
 static pa_bluetooth_uuid *uuid_new(const char *uuid) {
@@ -73,9 +61,9 @@ static pa_bluetooth_device* device_new(const char *path) {
 
     d = pa_xnew(pa_bluetooth_device, 1);
 
-    d->device_info_valid = d->audio_sink_info_valid = d->headset_info_valid = 0;
+    d->dead = FALSE;
 
-    d->data = NULL;
+    d->device_info_valid = d->audio_sink_info_valid = d->headset_info_valid = 0;
 
     d->name = NULL;
     d->path = pa_xstrdup(path);
@@ -94,7 +82,7 @@ static pa_bluetooth_device* device_new(const char *path) {
     return d;
 }
 
-void pa_bluetooth_device_free(pa_bluetooth_device *d) {
+static void device_free(pa_bluetooth_device *d) {
     pa_bluetooth_uuid *u;
 
     pa_assert(d);
@@ -127,7 +115,8 @@ static pa_bool_t device_is_audio(pa_bluetooth_device *d) {
     pa_assert(d->audio_sink_info_valid);
     pa_assert(d->headset_info_valid);
 
-    return d->device_info_valid > 0 &&
+    return
+        d->device_info_valid > 0 &&
         (d->audio_sink_info_valid > 0 || d->headset_info_valid > 0);
 }
 
@@ -289,20 +278,18 @@ static int parse_audio_property(pa_bluetooth_discovery *u, int *connected, DBusM
     return 0;
 }
 
-static void run_callback(pa_bluetooth_discovery *y, pa_bluetooth_device *d, pa_bool_t good) {
+static void run_callback(pa_bluetooth_discovery *y, pa_bluetooth_device *d, pa_bool_t dead) {
     pa_assert(y);
     pa_assert(d);
 
-    if (y->mode != MODE_DISCOVER)
-        return;
-
     if (!device_is_loaded(d))
         return;
 
     if (!device_is_audio(d))
         return;
 
-    y->callback(y->userdata, d, good);
+    d->dead = dead;
+    pa_hook_fire(&y->hook, d);
 }
 
 static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
@@ -377,7 +364,7 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
     }
 
 finish:
-    run_callback(y, d, TRUE);
+    run_callback(y, d, FALSE);
 
     dbus_message_unref(r);
 
@@ -392,9 +379,9 @@ static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, pa_bl
     pa_assert(y);
     pa_assert(m);
 
-    pa_assert_se(dbus_connection_send_with_reply(y->connection, m, &call, -1));
+    pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(y->connection), m, &call, -1));
 
-    p = pa_dbus_pending_new(y->connection, m, call, y, d);
+    p = pa_dbus_pending_new(pa_dbus_connection_get(y->connection), m, call, y, d);
     PA_LLIST_PREPEND(pa_dbus_pending, y->pending, p);
     dbus_pending_call_set_notify(call, func, p, NULL);
 
@@ -410,13 +397,7 @@ static void found_device(pa_bluetooth_discovery *y, const char* path) {
 
     d = device_new(path);
 
-    if (y->mode == MODE_DISCOVER) {
-        pa_assert(y->devices);
-        pa_hashmap_put(y->devices, d->path, d);
-    } else {
-        pa_assert(!y->found_device);
-        y->found_device = d;
-    }
+    pa_hashmap_put(y->devices, d->path, d);
 
     pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Device", "GetProperties"));
     send_and_add_to_pending(y, d, m, get_properties_reply);
@@ -469,57 +450,11 @@ end:
     pa_dbus_pending_free(p);
 }
 
-static void find_device_reply(DBusPendingCall *pending, void *userdata) {
-    DBusError e;
-    DBusMessage *r;
-    char *path = NULL;
-    pa_dbus_pending *p;
-    pa_bluetooth_discovery *y;
-
-    pa_assert(pending);
-
-    dbus_error_init(&e);
-
-    pa_assert_se(p = userdata);
-    pa_assert_se(y = p->context_data);
-    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
-
-    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
-        pa_log("Error from FindDevice reply: %s", dbus_message_get_error_name(r));
-        goto end;
-    }
-
-    if (!dbus_message_get_args(r, &e, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
-        pa_log("org.bluez.Adapter.FindDevice returned an error: '%s'\n", e.message);
-        dbus_error_free(&e);
-    } else
-        found_device(y, path);
-
-end:
-    dbus_message_unref(r);
-
-    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
-    pa_dbus_pending_free(p);
-}
-
 static void found_adapter(pa_bluetooth_discovery *y, const char *path) {
     DBusMessage *m;
 
-    if (y->mode == MODE_FIND) {
-        pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Adapter", "FindDevice"));
-
-        pa_assert_se(dbus_message_append_args(m,
-                                              DBUS_TYPE_STRING, &y->looking_for,
-                                              DBUS_TYPE_INVALID));
-
-        send_and_add_to_pending(y, NULL, m, find_device_reply);
-
-    } else {
-        pa_assert(y->mode == MODE_DISCOVER);
-
-        pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Adapter", "ListDevices"));
-        send_and_add_to_pending(y, NULL, m, list_devices_reply);
-    }
+    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Adapter", "ListDevices"));
+    send_and_add_to_pending(y, NULL, m, list_devices_reply);
 }
 
 static void list_adapters_reply(DBusPendingCall *pending, void *userdata) {
@@ -599,11 +534,8 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
         pa_log_debug("Device %s removed", path);
 
         if ((d = pa_hashmap_remove(y->devices, path))) {
-
-            pa_assert_se(y->mode == MODE_DISCOVER);
-            run_callback(y, d, FALSE);
-
-            pa_bluetooth_device_free(d);
+            run_callback(y, d, TRUE);
+            device_free(d);
         }
 
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -661,8 +593,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
                     goto fail;
             }
 
-            pa_assert_se(y->mode == MODE_DISCOVER);
-            run_callback(y, d, TRUE);
+            run_callback(y, d, FALSE);
         }
 
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -674,82 +605,81 @@ fail:
     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
-pa_bluetooth_device* pa_bluetooth_find_device(DBusConnection *c, const char* address) {
-    pa_bluetooth_discovery y;
-
-    memset(&y, 0, sizeof(y));
-    y.mode = MODE_FIND;
-    y.looking_for = address;
-    y.connection = c;
-    PA_LLIST_HEAD_INIT(pa_dbus_pending, y.pending);
-
-    list_adapters(&y);
+const pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_discovery *y, const char* address) {
+    pa_bluetooth_device *d;
+    void *state = NULL;
 
-    pa_dbus_sync_pending_list(&y.pending);
-    pa_assert(!y.pending);
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+    pa_assert(address);
 
-    if (y.found_device) {
-        pa_assert(device_is_loaded(y.found_device));
+    if (!pa_hook_is_firing(&y->hook))
+        pa_bluetooth_discovery_sync(y);
 
-        if (!device_is_audio(y.found_device)) {
-            pa_bluetooth_device_free(y.found_device);
-            return NULL;
-        }
-    }
+    while ((d = pa_hashmap_iterate(y->devices, &state, NULL)))
+        if (pa_streq(d->address, address))
+            return d;
 
-    return y.found_device;
+    return NULL;
 }
 
-pa_bluetooth_device* pa_bluetooth_get_device(DBusConnection *c, const char* path) {
-    pa_bluetooth_discovery y;
+const pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_discovery *y, const char* path) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+    pa_assert(path);
 
-    memset(&y, 0, sizeof(y));
-    y.mode = MODE_GET;
-    y.connection = c;
-    PA_LLIST_HEAD_INIT(pa_dbus_pending, y.pending);
+    if (!pa_hook_is_firing(&y->hook))
+        pa_bluetooth_discovery_sync(y);
 
-    found_device(&y, path);
+    return pa_hashmap_get(y->devices, path);
+}
 
-    pa_dbus_sync_pending_list(&y.pending);
-    pa_assert(!y.pending);
+static int setup_dbus(pa_bluetooth_discovery *y) {
+    DBusError err;
 
-    if (y.found_device) {
-        pa_assert(device_is_loaded(y.found_device));
+    dbus_error_init(&err);
 
-        if (!device_is_audio(y.found_device)) {
-            pa_bluetooth_device_free(y.found_device);
-            return NULL;
-        }
+    y->connection = pa_dbus_bus_get(y->core, DBUS_BUS_SYSTEM, &err);
+
+    if (dbus_error_is_set(&err) || !y->connection) {
+        pa_log("Failed to get D-Bus connection: %s", err.message);
+        dbus_error_free(&err);
+        return -1;
     }
 
-    return y.found_device;
+    return 0;
 }
 
-pa_bluetooth_discovery* pa_bluetooth_discovery_new(DBusConnection *c, pa_bluetooth_device_callback_t cb, struct userdata *u) {
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
     DBusError err;
     pa_bluetooth_discovery *y;
 
     pa_assert(c);
-    pa_assert(cb);
 
     dbus_error_init(&err);
 
+    if ((y = pa_shared_get(c, "bluetooth-discovery")))
+        return pa_bluetooth_discovery_ref(y);
+
     y = pa_xnew0(pa_bluetooth_discovery, 1);
-    y->mode = MODE_DISCOVER;
-    y->connection = c;
-    y->callback = cb;
-    y->userdata = u;
+    PA_REFCNT_INIT(y);
+    y->core = c;
     y->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     PA_LLIST_HEAD_INIT(pa_dbus_pending, y->pending);
+    pa_hook_init(&y->hook, y);
+    pa_shared_set(c, "bluetooth-discovery", y);
+
+    if (setup_dbus(y) < 0)
+        goto fail;
 
     /* dynamic detection of bluetooth audio devices */
-    if (!dbus_connection_add_filter(c, filter_cb, y, NULL)) {
+    if (!dbus_connection_add_filter(pa_dbus_connection_get(y->connection), filter_cb, y, NULL)) {
         pa_log_error("Failed to add filter function");
         goto fail;
     }
 
     if (pa_dbus_add_matches(
-                c, &err,
+                pa_dbus_connection_get(y->connection), &err,
                 "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
                 "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
                 "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
@@ -765,28 +695,46 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_new(DBusConnection *c, pa_bluetoo
     return y;
 
 fail:
+
+    if (y)
+        pa_bluetooth_discovery_unref(y);
+
     dbus_error_free(&err);
+
     return NULL;
 }
 
-void pa_bluetooth_discovery_free(pa_bluetooth_discovery *y) {
+pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    PA_REFCNT_INC(y);
+
+    return y;
+}
+
+void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
     pa_bluetooth_device *d;
 
     pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    if (PA_REFCNT_DEC(y) > 0)
+        return;
 
     pa_dbus_free_pending_list(&y->pending);
 
     if (y->devices) {
         while ((d = pa_hashmap_steal_first(y->devices))) {
-            run_callback(y, d, FALSE);
-            pa_bluetooth_device_free(d);
+            run_callback(y, d, TRUE);
+            device_free(d);
         }
 
         pa_hashmap_free(y->devices, NULL, NULL);
     }
 
     if (y->connection) {
-        pa_dbus_remove_matches(y->connection,
+        pa_dbus_remove_matches(pa_dbus_connection_get(y->connection),
                                "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
                                "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterRemoved'",
                                "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
@@ -795,16 +743,31 @@ void pa_bluetooth_discovery_free(pa_bluetooth_discovery *y) {
                                "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
                                "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'", NULL);
 
-        dbus_connection_remove_filter(y->connection, filter_cb, y);
+        dbus_connection_remove_filter(pa_dbus_connection_get(y->connection), filter_cb, y);
+
+        pa_dbus_connection_unref(y->connection);
     }
+
+    pa_hook_done(&y->hook);
+
+    if (y->core)
+        pa_shared_remove(y->core, "bluetooth-discovery");
 }
 
 void pa_bluetooth_discovery_sync(pa_bluetooth_discovery *y) {
     pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
 
     pa_dbus_sync_pending_list(&y->pending);
 }
 
+pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    return &y->hook;
+}
+
 const char*pa_bluetooth_get_form_factor(uint32_t class) {
     unsigned i;
     const char *r;
diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h
index 0364c97..1d05e63 100644
--- a/src/modules/bluetooth/bluetooth-util.h
+++ b/src/modules/bluetooth/bluetooth-util.h
@@ -40,7 +40,7 @@ struct pa_bluetooth_uuid {
 };
 
 struct pa_bluetooth_device {
-    void *data; /* arbitrary information for the one owning the discovery object */
+    pa_bool_t dead;
 
     int device_info_valid;      /* 0: no results yet; 1: good results; -1: bad results ... */
     int audio_sink_info_valid;  /* ... same here ... */
@@ -64,17 +64,18 @@ struct pa_bluetooth_device {
     int headset_connected;
 };
 
-void pa_bluetooth_device_free(pa_bluetooth_device *d);
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core);
+pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y);
+void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *d);
 
-pa_bluetooth_device* pa_bluetooth_get_device(DBusConnection *c, const char* path);
-pa_bluetooth_device* pa_bluetooth_find_device(DBusConnection *c, const char* address);
-
-typedef void (*pa_bluetooth_device_callback_t)(struct userdata *u, pa_bluetooth_device *d, pa_bool_t good);
-pa_bluetooth_discovery* pa_bluetooth_discovery_new(DBusConnection *c, pa_bluetooth_device_callback_t cb, struct userdata *u);
-void pa_bluetooth_discovery_free(pa_bluetooth_discovery *d);
 void pa_bluetooth_discovery_sync(pa_bluetooth_discovery *d);
 
-const char*pa_bluetooth_get_form_factor(uint32_t class);
+const pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_discovery *d, const char* path);
+const pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_discovery *d, const char* address);
+
+pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *d);
+
+const char* pa_bluetooth_get_form_factor(uint32_t class);
 
 char *pa_bluetooth_cleanup_name(const char *name);
 
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 7386f8c..928f33c 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -122,6 +122,8 @@ struct userdata {
     pa_core *core;
     pa_module *module;
 
+    char *address;
+
     pa_card *card;
     pa_sink *sink;
     pa_source *source;
@@ -153,8 +155,6 @@ struct userdata {
 
     pa_modargs *modargs;
 
-    pa_bluetooth_device *device;
-
     int stream_write_type, stream_read_type;
     int service_write_type, service_read_type;
 };
@@ -331,7 +331,7 @@ static int get_caps(struct userdata *u) {
     msg.getcaps_req.h.name = BT_GET_CAPABILITIES;
     msg.getcaps_req.h.length = sizeof(msg.getcaps_req);
 
-    pa_strlcpy(msg.getcaps_req.device, u->device->address, sizeof(msg.getcaps_req.device));
+    pa_strlcpy(msg.getcaps_req.device, u->address, sizeof(msg.getcaps_req.device));
     if (u->profile == PROFILE_A2DP)
         msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_A2DP;
     else {
@@ -613,7 +613,7 @@ static int set_conf(struct userdata *u) {
     msg.setconf_req.h.name = BT_SET_CONFIGURATION;
     msg.setconf_req.h.length = sizeof(msg.setconf_req);
 
-    pa_strlcpy(msg.setconf_req.device, u->device->address, sizeof(msg.setconf_req.device));
+    pa_strlcpy(msg.setconf_req.device, u->address, sizeof(msg.setconf_req.device));
     msg.setconf_req.access_mode = u->profile == PROFILE_A2DP ? BT_CAPABILITIES_ACCESS_MODE_WRITE : BT_CAPABILITIES_ACCESS_MODE_READWRITE;
 
     msg.setconf_req.codec.transport = u->profile == PROFILE_A2DP ? BT_CAPABILITIES_TRANSPORT_A2DP : BT_CAPABILITIES_TRANSPORT_SCO;
@@ -1482,7 +1482,7 @@ static int add_sink(struct userdata *u) {
         pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
         pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile == PROFILE_A2DP ? "a2dp" : "sco");
         data.card = u->card;
-        data.name = get_name("sink", u->modargs, u->device->address, &b);
+        data.name = get_name("sink", u->modargs, u->address, &b);
         data.namereg_fail = b;
 
         u->sink = pa_sink_new(u->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
@@ -1526,7 +1526,7 @@ static int add_source(struct userdata *u) {
         pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
         pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile == PROFILE_A2DP ? "a2dp" : "sco");
         data.card = u->card;
-        data.name = get_name("source", u->modargs, u->device->address, &b);
+        data.name = get_name("source", u->modargs, u->address, &b);
         data.namereg_fail = b;
 
         u->source = pa_source_new(u->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
@@ -1768,7 +1768,7 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
     return 0;
 }
 
-static int add_card(struct userdata *u, const char * default_profile) {
+static int add_card(struct userdata *u, const char *default_profile, const pa_bluetooth_device *device) {
     pa_card_new_data data;
     pa_bool_t b;
     pa_card_profile *p;
@@ -1780,24 +1780,24 @@ static int add_card(struct userdata *u, const char * default_profile) {
     data.driver = __FILE__;
     data.module = u->module;
 
-    n = pa_bluetooth_cleanup_name(u->device->name);
+    n = pa_bluetooth_cleanup_name(device->name);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, n);
     pa_xfree(n);
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device->address);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, device->address);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez");
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth");
-    if ((ff = pa_bluetooth_get_form_factor(u->device->class)))
+    if ((ff = pa_bluetooth_get_form_factor(device->class)))
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, ff);
-    pa_proplist_sets(data.proplist, "bluez.path", u->device->path);
-    pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", (unsigned) u->device->class);
-    pa_proplist_sets(data.proplist, "bluez.name", u->device->name);
-    data.name = get_name("card", u->modargs, u->device->address, &b);
+    pa_proplist_sets(data.proplist, "bluez.path", device->path);
+    pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", (unsigned) device->class);
+    pa_proplist_sets(data.proplist, "bluez.name", device->name);
+    data.name = get_name("card", u->modargs, device->address, &b);
     data.namereg_fail = b;
 
     data.profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
-    if (u->device->audio_sink_info_valid > 0) {
+    if (device->audio_sink_info_valid > 0) {
         p = pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP)"), sizeof(enum profile));
         p->priority = 10;
         p->n_sinks = 1;
@@ -1811,7 +1811,7 @@ static int add_card(struct userdata *u, const char * default_profile) {
         pa_hashmap_put(data.profiles, p->name, p);
     }
 
-    if (u->device->headset_info_valid > 0) {
+    if (device->headset_info_valid > 0) {
         p = pa_card_profile_new("hsp", _("Telephony Duplex (HSP/HFP)"), sizeof(enum profile));
         p->priority = 20;
         p->n_sinks = 1;
@@ -1856,47 +1856,39 @@ static int add_card(struct userdata *u, const char * default_profile) {
     return 0;
 }
 
-static int setup_dbus(struct userdata *u) {
-    DBusError error;
+static const pa_bluetooth_device* find_device(struct userdata *u, pa_bluetooth_discovery *y, const char *address, const char *path) {
+    const pa_bluetooth_device *d = NULL;
 
-    dbus_error_init(&error);
-
-    u->connection = pa_dbus_bus_get(u->core, DBUS_BUS_SYSTEM, &error);
-    if (dbus_error_is_set(&error) || (!u->connection)) {
-        pa_log("Failed to get D-Bus connection: %s", error.message);
-        dbus_error_free(&error);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int find_device(struct userdata *u, const char *address, const char *path) {
     pa_assert(u);
+    pa_assert(y);
 
     if (!address && !path) {
         pa_log_error("Failed to get device address/path from module arguments.");
-        return -1;
+        return NULL;
     }
 
     if (path) {
-        if (!(u->device = pa_bluetooth_get_device(pa_dbus_connection_get(u->connection), path))) {
+        if (!(d = pa_bluetooth_discovery_get_by_path(y, path))) {
             pa_log_error("%s is not a valid BlueZ audio device.", path);
-            return -1;
+            return NULL;
         }
 
-        if (address && !(pa_streq(u->device->address, address))) {
+        if (address && !(pa_streq(d->address, address))) {
             pa_log_error("Passed path %s and address %s don't match.", path, address);
-            return -1;
+            return NULL;
         }
+
     } else {
-        if (!(u->device = pa_bluetooth_find_device(pa_dbus_connection_get(u->connection), address))) {
+        if (!(d = pa_bluetooth_discovery_get_by_address(y, address))) {
             pa_log_error("%s is not known.", address);
-            return -1;
+            return NULL;
         }
     }
 
-    return 0;
+    if (d)
+        u->address = pa_xstrdup(d->address);
+
+    return d;
 }
 
 int pa__init(pa_module* m) {
@@ -1904,6 +1896,8 @@ int pa__init(pa_module* m) {
     uint32_t channels;
     struct userdata *u;
     const char *address, *path;
+    const pa_bluetooth_device *d;
+    pa_bluetooth_discovery *y = NULL;
 
     pa_assert(m);
 
@@ -1948,21 +1942,22 @@ int pa__init(pa_module* m) {
     u->sample_spec.channels = (uint8_t) channels;
     u->requested_sample_spec = u->sample_spec;
 
-    if (setup_dbus(u) < 0)
-        goto fail;
-
     address = pa_modargs_get_value(ma, "address", NULL);
     path = pa_modargs_get_value(ma, "path", NULL);
 
-    if (find_device(u, address, path) < 0)
+    if (!(y = pa_bluetooth_discovery_get(m->core)))
         goto fail;
 
-    pa_assert(u->device);
+    if (!(d = find_device(u, y, address, path)))
+        goto fail;
 
     /* Add the card structure. This will also initialize the default profile */
-    if (add_card(u, pa_modargs_get_value(ma, "profile", NULL)) < 0)
+    if (add_card(u, pa_modargs_get_value(ma, "profile", NULL), d) < 0)
         goto fail;
 
+    pa_bluetooth_discovery_unref(y);
+    y = NULL;
+
     /* Connect to the BT service and query capabilities */
     if (init_bt(u) < 0)
         goto fail;
@@ -2014,7 +2009,12 @@ int pa__init(pa_module* m) {
     return 0;
 
 fail:
+
+    if (y)
+        pa_bluetooth_discovery_unref(y);
+
     pa__done(m);
+
     return -1;
 }
 
@@ -2080,9 +2080,6 @@ void pa__done(pa_module *m) {
 
     shutdown_bt(u);
 
-    if (u->device)
-        pa_bluetooth_device_free(u->device);
-
     if (u->a2dp.buffer)
         pa_xfree(u->a2dp.buffer);
 
@@ -2091,5 +2088,7 @@ void pa__done(pa_module *m) {
     if (u->modargs)
         pa_modargs_free(u->modargs);
 
+    pa_xfree(u->address);
+
     pa_xfree(u);
 }
diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c
index 4586d8c..22e8ea3 100644
--- a/src/modules/bluetooth/module-bluetooth-discover.c
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -57,19 +57,28 @@ struct userdata {
     pa_module *module;
     pa_modargs *modargs;
     pa_core *core;
-    pa_dbus_connection *connection;
     pa_bluetooth_discovery *discovery;
+    pa_hook_slot *slot;
+    pa_hashmap *hashmap;
 };
 
-static void load_module_for_device(struct userdata *u, pa_bluetooth_device *d, pa_bool_t good) {
+static pa_hook_result_t load_module_for_device(pa_bluetooth_discovery *y, const pa_bluetooth_device *d, struct userdata *u) {
+    uint32_t midx;
+
     pa_assert(u);
     pa_assert(d);
 
-    if (good &&
+
+    if (!(midx = PA_PTR_TO_UINT(pa_hashmap_get(u->hashmap, d->path))))
+        midx = PA_INVALID_INDEX;
+    else
+        midx--;
+
+    if (!d->dead &&
         d->device_connected > 0 &&
         (d->audio_sink_connected > 0 || d->headset_connected > 0)) {
 
-        if (((uint32_t) PA_PTR_TO_UINT(d->data))-1 == PA_INVALID_INDEX) {
+        if (midx == PA_INVALID_INDEX) {
             pa_module *m = NULL;
             char *args;
 
@@ -93,38 +102,25 @@ static void load_module_for_device(struct userdata *u, pa_bluetooth_device *d, p
             pa_xfree(args);
 
             if (m)
-                d->data = PA_UINT_TO_PTR((uint32_t) (m->index+1));
+                pa_hashmap_put(u->hashmap, d->path, PA_UINT_TO_PTR((uint32_t) (m->index+1)));
             else
                 pa_log_debug("Failed to load module for device %s", d->path);
         }
 
     } else {
 
-        if (((uint32_t) PA_PTR_TO_UINT(d->data))-1 != PA_INVALID_INDEX) {
+        if (midx != PA_INVALID_INDEX) {
 
             /* Hmm, disconnection? Then let's unload our module */
 
             pa_log_debug("Unloading module for %s", d->path);
-            pa_module_unload_request_by_index(u->core, (uint32_t) (PA_PTR_TO_UINT(d->data))-1, TRUE);
-            d->data = NULL;
-        }
-    }
-}
-
-static int setup_dbus(struct userdata *u) {
-    DBusError err;
+            pa_module_unload_request_by_index(u->core, midx, TRUE);
 
-    dbus_error_init(&err);
-
-    u->connection = pa_dbus_bus_get(u->core, DBUS_BUS_SYSTEM, &err);
-
-    if (dbus_error_is_set(&err) || !u->connection) {
-        pa_log("Failed to get D-Bus connection: %s", err.message);
-        dbus_error_free(&err);
-        return -1;
+            pa_hashmap_remove(u->hashmap, d->path);
+        }
     }
 
-    return 0;
+    return PA_HOOK_OK;
 }
 
 int pa__init(pa_module* m) {
@@ -149,12 +145,12 @@ int pa__init(pa_module* m) {
     u->core = m->core;
     u->modargs = ma;
     ma = NULL;
+    u->hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
-    if (setup_dbus(u) < 0)
+    if (!(u->discovery = pa_bluetooth_discovery_get(u->core)))
         goto fail;
 
-    if (!(u->discovery = pa_bluetooth_discovery_new(pa_dbus_connection_get(u->connection), load_module_for_device, u)))
-        goto fail;
+    u->slot = pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery), PA_HOOK_NORMAL, (pa_hook_cb_t) load_module_for_device, u);
 
     if (!async)
         pa_bluetooth_discovery_sync(u->discovery);
@@ -178,11 +174,14 @@ void pa__done(pa_module* m) {
     if (!(u = m->userdata))
         return;
 
+    if (u->slot)
+        pa_hook_slot_free(u->slot);
+
     if (u->discovery)
-        pa_bluetooth_discovery_free(u->discovery);
+        pa_bluetooth_discovery_unref(u->discovery);
 
-    if (u->connection)
-        pa_dbus_connection_unref(u->connection);
+    if (u->hashmap)
+        pa_hashmap_free(u->hashmap, NULL, NULL);
 
     if (u->modargs)
         pa_modargs_free(u->modargs);

-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list