diff options
Diffstat (limited to 'src/devices/bluetooth/nm-bluez4-manager.c')
| -rw-r--r-- | src/devices/bluetooth/nm-bluez4-manager.c | 154 |
1 files changed, 105 insertions, 49 deletions
diff --git a/src/devices/bluetooth/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c index a9079a2f..1fe02f18 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.c +++ b/src/devices/bluetooth/nm-bluez4-manager.c @@ -47,6 +47,7 @@ typedef struct { NMSettings *settings; GDBusProxy *proxy; + GCancellable *proxy_cancellable; NMBluez4Adapter *adapter; } NMBluez4ManagerPrivate; @@ -66,6 +67,11 @@ G_DEFINE_TYPE (NMBluez4Manager, nm_bluez4_manager, G_TYPE_OBJECT) /*****************************************************************************/ +#define _NMLOG_DOMAIN LOGD_BT +#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "bluez4-manager", __VA_ARGS__) + +/*****************************************************************************/ + static void emit_bdaddr_added (NMBluez4Manager *self, NMBluezDevice *device) { @@ -119,8 +125,10 @@ adapter_initialized (NMBluez4Adapter *adapter, gboolean success, gpointer user_d emit_bdaddr_added (self, NM_BLUEZ_DEVICE (iter->data)); g_slist_free (devices); - g_signal_connect (adapter, "device-added", G_CALLBACK (device_added), self); - g_signal_connect (adapter, "device-removed", G_CALLBACK (device_removed), self); + g_signal_connect (adapter, NM_BLUEZ4_ADAPTER_DEVICE_ADDED, + G_CALLBACK (device_added), self); + g_signal_connect (adapter, NM_BLUEZ4_ADAPTER_DEVICE_REMOVED, + G_CALLBACK (device_removed), self); } else { g_object_unref (priv->adapter); priv->adapter = NULL; @@ -169,49 +177,70 @@ default_adapter_changed (GDBusProxy *proxy, const char *path, NMBluez4Manager *s /* Add the new default adapter */ if (path) { priv->adapter = nm_bluez4_adapter_new (path, priv->settings); - g_signal_connect (priv->adapter, "initialized", G_CALLBACK (adapter_initialized), self); + g_signal_connect (priv->adapter, NM_BLUEZ4_ADAPTER_INITIALIZED, + G_CALLBACK (adapter_initialized), self); } } static void default_adapter_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - NMBluez4Manager *self = NM_BLUEZ4_MANAGER (user_data); - NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); - GVariant *ret; - GError *err = NULL; + NMBluez4Manager *self; + NMBluez4ManagerPrivate *priv; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + const char *default_adapter; ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, - G_VARIANT_TYPE ("(o)"), &err); - if (ret) { - const char *default_adapter; + G_VARIANT_TYPE ("(o)"), &error); + if ( !ret + && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - g_variant_get (ret, "(&o)", &default_adapter); - default_adapter_changed (priv->proxy, default_adapter, self); - g_variant_unref (ret); - } else { + self = NM_BLUEZ4_MANAGER (user_data); + priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); + + g_clear_object (&priv->proxy_cancellable); + + if (!ret) { /* Ignore "No such adapter" errors; just means bluetooth isn't active */ - if ( !_nm_dbus_error_has_name (err, "org.bluez.Error.NoSuchAdapter") - && !_nm_dbus_error_has_name (err, "org.freedesktop.systemd1.LoadFailed") - && !g_error_matches (err, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { - g_dbus_error_strip_remote_error (err); - nm_log_warn (LOGD_BT, "bluez error getting default adapter: %s", - err->message); + if ( !_nm_dbus_error_has_name (error, "org.bluez.Error.NoSuchAdapter") + && !_nm_dbus_error_has_name (error, "org.freedesktop.systemd1.LoadFailed") + && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { + g_dbus_error_strip_remote_error (error); + _LOGW ("bluez error getting default adapter: %s", + error->message); } - g_error_free (err); + return; } + + g_variant_get (ret, "(&o)", &default_adapter); + default_adapter_changed (priv->proxy, default_adapter, self); } static void -query_default_adapter (NMBluez4Manager *self) +name_owner_changed (NMBluez4Manager *self) { NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); + gs_free char *owner = NULL; + + nm_clear_g_cancellable (&priv->proxy_cancellable); + + owner = g_dbus_proxy_get_name_owner (priv->proxy); + if (!owner) { + /* Throwing away the adapter removes all devices too */ + g_clear_object (&priv->adapter); + return; + } + + priv->proxy_cancellable = g_cancellable_new (); g_dbus_proxy_call (priv->proxy, "DefaultAdapter", NULL, G_DBUS_CALL_FLAGS_NONE, -1, - NULL, - default_adapter_cb, self); + priv->proxy_cancellable, + default_adapter_cb, + self); } static void @@ -219,34 +248,35 @@ name_owner_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data) { - NMBluez4Manager *self = NM_BLUEZ4_MANAGER (user_data); - NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); - char *owner; - - owner = g_dbus_proxy_get_name_owner (priv->proxy); - if (owner) { - query_default_adapter (self); - g_free (owner); - } else { - /* Throwing away the adapter removes all devices too */ - g_clear_object (&priv->adapter); - } + name_owner_changed (user_data); } -/*****************************************************************************/ - static void -nm_bluez4_manager_init (NMBluez4Manager *self) +_proxy_new_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { - NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); + NMBluez4Manager *self; + NMBluez4ManagerPrivate *priv; + gs_free_error GError *error = NULL; + GDBusProxy *proxy; + + proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + if ( !proxy + && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = user_data; + priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); + + if (!proxy) { + _LOGW ("bluez error creating D-Bus proxy: %s", error->message); + g_clear_object (&priv->proxy_cancellable); + return; + } + + priv->proxy = proxy; - priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - BLUEZ_SERVICE, - BLUEZ_MANAGER_PATH, - BLUEZ4_MANAGER_INTERFACE, - NULL, NULL); _nm_dbus_signal_connect (priv->proxy, "AdapterRemoved", G_VARIANT_TYPE ("(o)"), G_CALLBACK (adapter_removed), self); _nm_dbus_signal_connect (priv->proxy, "DefaultAdapterChanged", G_VARIANT_TYPE ("(o)"), @@ -254,7 +284,27 @@ nm_bluez4_manager_init (NMBluez4Manager *self) g_signal_connect (priv->proxy, "notify::g-name-owner", G_CALLBACK (name_owner_changed_cb), self); - query_default_adapter (self); + name_owner_changed (self); +} + +/*****************************************************************************/ + +static void +nm_bluez4_manager_init (NMBluez4Manager *self) +{ + NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); + + priv->proxy_cancellable = g_cancellable_new (); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_BLUEZ_SERVICE, + NM_BLUEZ_MANAGER_PATH, + NM_BLUEZ4_MANAGER_INTERFACE, + priv->proxy_cancellable, + _proxy_new_cb, + self); } NMBluez4Manager * @@ -275,7 +325,13 @@ dispose (GObject *object) NMBluez4Manager *self = NM_BLUEZ4_MANAGER (object); NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self); - g_clear_object (&priv->proxy); + nm_clear_g_cancellable (&priv->proxy_cancellable); + + if (priv->proxy) { + g_signal_handlers_disconnect_by_data (priv->proxy, self); + g_clear_object (&priv->proxy); + } + g_clear_object (&priv->adapter); G_OBJECT_CLASS (nm_bluez4_manager_parent_class)->dispose (object); |