lbalhar / rpms / pulseaudio

Forked from rpms/pulseaudio 3 years ago
Clone
Blob Blame History Raw
From 31318274ff84e2d359aa762ffcde09eae115d2d4 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.dentz@openbossa.org>
Date: Mon, 6 Oct 2008 14:59:15 -0300
Subject: [PATCH] Unload module-bluetooth-device if the remote device disconnects.

---
 src/modules/bluetooth/module-bluetooth-discover.c |   55 ++++++++++++++++----
 1 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c
index 0601e9a..a33ca64 100644
--- a/src/modules/bluetooth/module-bluetooth-discover.c
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -91,6 +91,16 @@ static void module_free(struct module *m) {
     pa_xfree(m);
 }
 
+static struct module* module_find(struct device *d, const char *profile) {
+    struct module *m;
+
+    for (m = d->module_list; d; d = d->next)
+        if (pa_streq(m->profile, profile))
+            return m;
+
+    return NULL;
+}
+
 static struct uuid *uuid_new(const char *uuid) {
     struct uuid *node;
 
@@ -345,6 +355,21 @@ static void load_module_for_device(struct userdata *u, struct device *d, const c
     PA_LLIST_PREPEND(struct module, d->module_list, m);
 }
 
+static void unload_module_for_device(struct userdata *u, struct device *d, const char *profile) {
+    struct module *m;
+
+    pa_assert(u);
+    pa_assert(d);
+
+    if (!(m = module_find(d, profile)))
+        return;
+
+    pa_module_unload_request(m->pa_m, TRUE);
+
+    PA_LLIST_REMOVE(struct module, d->module_list, m);
+    module_free(m);
+}
+
 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void *userdata) {
     DBusMessageIter arg_i;
     DBusError err;
@@ -387,6 +412,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void *
         struct device *d;
         const char *profile;
         DBusMessageIter variant_i;
+        dbus_bool_t connected;
 
         if (!dbus_message_iter_init(msg, &arg_i)) {
             pa_log("dbus: message has no parameters");
@@ -400,6 +426,9 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void *
 
         dbus_message_iter_get_basic(&arg_i, &value);
 
+        if (!pa_streq(value, "Connected"))
+            goto done;
+
         if (!dbus_message_iter_next(&arg_i)) {
             pa_log("Property value missing");
             goto done;
@@ -412,25 +441,29 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void *
 
         dbus_message_iter_recurse(&arg_i, &variant_i);
 
-        if (dbus_message_iter_get_arg_type(&variant_i) == DBUS_TYPE_BOOLEAN) {
-            dbus_bool_t connected;
-            dbus_message_iter_get_basic(&variant_i, &connected);
-
-            if (!pa_streq(value, "Connected") || !connected)
-                goto done;
+        if (dbus_message_iter_get_arg_type(&variant_i) != DBUS_TYPE_BOOLEAN) {
+            pa_log("Property value not a boolean.");
+            goto done;
         }
 
-        if (!(d = device_find(u, dbus_message_get_path(msg)))) {
-                d = device_new(dbus_message_get_path(msg));
-                PA_LLIST_PREPEND(struct device, u->device_list, d);
-        }
+        dbus_message_iter_get_basic(&variant_i, &connected);
 
         if (dbus_message_is_signal(msg, "org.bluez.Headset", "PropertyChanged"))
             profile = "hsp";
         else
             profile = "a2dp";
 
-        load_module_for_device(u, d, profile);
+        d = device_find(u, dbus_message_get_path(msg));
+
+        if (connected) {
+            if (!d) {
+                    d = device_new(dbus_message_get_path(msg));
+                    PA_LLIST_PREPEND(struct device, u->device_list, d);
+            }
+
+            load_module_for_device(u, d, profile);
+        } else if (d)
+            unload_module_for_device(u, d, profile);
     }
 
 done:
-- 
1.6.0.3