[gnome-bluetooth] lib: Fix agent re-registration by removing duplicate registration



commit a143c87e12401f149f2c14288ffdf577b2a5ff24
Author: Benjamin Berg <bberg redhat com>
Date:   Wed Nov 22 18:11:06 2017 +0100

    lib: Fix agent re-registration by removing duplicate registration
    
    bluetooth_agent_setup() would register the object at a user chosen
    location as bluetooth_agent_register() did the same for a fixed location
    (also registering the agent with bluez) the object would only be removed
    from one of the two locations.
    
    Effectively, the only thing that bluetooth_agent_setup() did was setting
    custom DBus path for the object. So remove bluetooth_agent_setup() and
    instead make the path a construct only property.
    
    This fixes agent registration when switching away and back to the
    bluetooth panel in gnome-control-center. Before the following warning
    would be printed and the agent registration would fail:
    
    Bluetooth-WARNING **: Failed to register object: An object is already exported for the interface 
org.bluez.Agent1 at /org/bluez/agent/gnome
    
    https://bugzilla.gnome.org/show_bug.cgi?id=790720

 lib/bluetooth-agent.c           |  102 ++++++++++++++++++++++++++-------------
 lib/bluetooth-agent.h           |    2 +-
 lib/bluetooth-settings-widget.c |    4 +-
 lib/test-agent.c                |    2 +-
 4 files changed, 72 insertions(+), 38 deletions(-)
---
diff --git a/lib/bluetooth-agent.c b/lib/bluetooth-agent.c
index b2303fa..1ce37e8 100644
--- a/lib/bluetooth-agent.c
+++ b/lib/bluetooth-agent.c
@@ -110,6 +110,14 @@ struct _BluetoothAgentPrivate {
        gpointer cancel_data;
 };
 
+enum {
+  PROP_0,
+  PROP_PATH,
+  PROP_LAST
+};
+
+static GParamSpec *props[PROP_LAST];
+
 static GDBusProxy *get_device_from_path (const char *path)
 {
        Device1 *device;
@@ -306,6 +314,42 @@ name_vanished_cb (GDBusConnection *connection,
        priv->busname = NULL;
 }
 
+static void
+bluetooth_agent_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+       BluetoothAgent *agent = BLUETOOTH_AGENT (object);
+       BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE (agent);
+
+       switch (prop_id) {
+       case PROP_PATH:
+               g_value_set_string (value, priv->path);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+       }
+}
+
+static void
+bluetooth_agent_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+       BluetoothAgent *agent = BLUETOOTH_AGENT (object);
+       BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE (agent);
+
+       switch (prop_id) {
+       case PROP_PATH:
+               priv->path = g_value_dup_string (value);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+       }
+}
+
 static void bluetooth_agent_init(BluetoothAgent *agent)
 {
        BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
@@ -343,12 +387,31 @@ static void bluetooth_agent_class_init(BluetoothAgentClass *klass)
        g_type_class_add_private(klass, sizeof(BluetoothAgentPrivate));
 
        object_class->finalize = bluetooth_agent_finalize;
+       object_class->set_property = bluetooth_agent_set_property;
+       object_class->get_property = bluetooth_agent_get_property;
+
+       props[PROP_PATH] =
+               g_param_spec_string ("path", "Path",
+                                    "Object path for the agent",
+                                    BLUEZ_AGENT_PATH,
+                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+       g_object_class_install_properties (object_class,
+                                          PROP_LAST,
+                                          props);
+
 }
 
 BluetoothAgent *
-bluetooth_agent_new (void)
+bluetooth_agent_new (const char *path)
 {
-       return BLUETOOTH_AGENT (g_object_new (BLUETOOTH_TYPE_AGENT, NULL));
+       if (path != NULL)
+               return BLUETOOTH_AGENT (g_object_new (BLUETOOTH_TYPE_AGENT,
+                                                     "path", path,
+                                                     NULL));
+       else
+               return BLUETOOTH_AGENT (g_object_new (BLUETOOTH_TYPE_AGENT,
+                                                     NULL));
 }
 
 static void
@@ -426,33 +489,6 @@ static const GDBusInterfaceVTable interface_vtable =
        NULL, /* SetProperty */
 };
 
-gboolean bluetooth_agent_setup(BluetoothAgent *agent, const char *path)
-{
-       BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
-       GError *error = NULL;
-
-       if (priv->path != NULL) {
-               g_warning ("Agent already setup on '%s'", priv->path);
-               return FALSE;
-       }
-
-       priv->path = g_strdup(path);
-
-       priv->reg_id = g_dbus_connection_register_object (priv->conn,
-                                                     priv->path,
-                                                     priv->introspection_data->interfaces[0],
-                                                     &interface_vtable,
-                                                     agent,
-                                                     NULL,
-                                                     &error);
-       if (priv->reg_id == 0) {
-               g_warning ("Failed to register object: %s", error->message);
-               g_error_free (error);
-       }
-
-       return TRUE;
-}
-
 gboolean bluetooth_agent_register(BluetoothAgent *agent)
 {
        BluetoothAgentPrivate *priv;
@@ -468,7 +504,7 @@ gboolean bluetooth_agent_register(BluetoothAgent *agent)
                      BLUEZ_SERVICE, "/org/bluez", NULL, NULL);
 
        priv->reg_id = g_dbus_connection_register_object (priv->conn,
-                                                     BLUEZ_AGENT_PATH,
+                                                     priv->path,
                                                      priv->introspection_data->interfaces[0],
                                                      &interface_vtable,
                                                      agent,
@@ -482,7 +518,7 @@ gboolean bluetooth_agent_register(BluetoothAgent *agent)
        }
 
        ret = agent_manager1_call_register_agent_sync (priv->agent_manager,
-                                                      BLUEZ_AGENT_PATH,
+                                                      priv->path,
                                                       "DisplayYesNo",
                                                       NULL, &error);
        if (ret == FALSE) {
@@ -492,7 +528,7 @@ gboolean bluetooth_agent_register(BluetoothAgent *agent)
        }
 
        ret = agent_manager1_call_request_default_agent_sync (priv->agent_manager,
-                                                             BLUEZ_AGENT_PATH,
+                                                             priv->path,
                                                              NULL, &error);
        if (ret == FALSE) {
                g_printerr ("Agent registration as default failed: %s\n", error->message);
@@ -516,7 +552,7 @@ gboolean bluetooth_agent_unregister(BluetoothAgent *agent)
                return FALSE;
 
        if (agent_manager1_call_unregister_agent_sync (priv->agent_manager,
-                                                      BLUEZ_AGENT_PATH,
+                                                      priv->path,
                                                       NULL, &error) == FALSE) {
                /* Ignore errors if the adapter is gone */
                if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD) == FALSE) {
diff --git a/lib/bluetooth-agent.h b/lib/bluetooth-agent.h
index 9a90196..077d6e5 100644
--- a/lib/bluetooth-agent.h
+++ b/lib/bluetooth-agent.h
@@ -54,7 +54,7 @@ struct _BluetoothAgentClass {
 
 GType bluetooth_agent_get_type(void);
 
-BluetoothAgent *bluetooth_agent_new(void);
+BluetoothAgent *bluetooth_agent_new(const char *path);
 
 gboolean bluetooth_agent_setup(BluetoothAgent *agent, const char *path);
 
diff --git a/lib/bluetooth-settings-widget.c b/lib/bluetooth-settings-widget.c
index 2472ae1..cd4b89b 100644
--- a/lib/bluetooth-settings-widget.c
+++ b/lib/bluetooth-settings-widget.c
@@ -1802,7 +1802,7 @@ setup_pairing_agent (BluetoothSettingsWidget *self)
 {
        BluetoothSettingsWidgetPrivate *priv = BLUETOOTH_SETTINGS_WIDGET_GET_PRIVATE (self);
 
-       priv->agent = bluetooth_agent_new ();
+       priv->agent = bluetooth_agent_new (AGENT_PATH);
        if (bluetooth_agent_register (priv->agent) == FALSE) {
                g_clear_object (&priv->agent);
                return;
@@ -1816,8 +1816,6 @@ setup_pairing_agent (BluetoothSettingsWidget *self)
        bluetooth_agent_set_confirm_func (priv->agent, confirm_callback, self);
        bluetooth_agent_set_authorize_func (priv->agent, authorize_callback, self);
        bluetooth_agent_set_authorize_service_func (priv->agent, authorize_service_callback, self);
-
-       bluetooth_agent_setup (priv->agent, AGENT_PATH);
 }
 
 static void
diff --git a/lib/test-agent.c b/lib/test-agent.c
index 6878774..2e32dec 100644
--- a/lib/test-agent.c
+++ b/lib/test-agent.c
@@ -68,7 +68,7 @@ int main (int argc, char **argv)
 
        mainloop = g_main_loop_new(NULL, FALSE);
 
-       agent = bluetooth_agent_new();
+       agent = bluetooth_agent_new(NULL);
 
        bluetooth_agent_set_confirm_func(agent, agent_confirm, NULL);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]