From 42060fdd897749c79fcc60ac16bb6fa67e4c8fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Thu, 24 Nov 2011 16:42:37 +0100 Subject: [PATCH] libnm-glib: get devices and their properties in constructor (NMClient, NMDevice) NMClient and NMDevice used a 'lazy' approach for getting stuff from D-Bus, i.e. requesting data from NM when they are asked for. However, for some cases, like removing devices it is not optimal. libnm-glib will never see a device that was removed, but not added during NMClient's lifetime. So let's get devices list in NMClient's constructor and device properties in NMDevice constructor to have the data from the beginning. --- libnm-glib/nm-client.c | 8 ++++++ libnm-glib/nm-device.c | 61 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 0769de1a74..918bc99788 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -1424,6 +1424,14 @@ constructor (GType type, g_signal_connect (object, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS, G_CALLBACK (active_connections_changed_cb), NULL); + /* Get initial devices from NM. It is important to do it early. Else, + * a 'lazy' call won't find removed device. + * Solves this case: DeviceRemoved signal is received, we get devices + * from NM, but the removed object path is not there any more, and + * NMClient doesn't have the device either. + */ + nm_client_get_devices (NM_CLIENT (object)); + return G_OBJECT (object); } diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index 426ded3bfe..8d303e36eb 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -36,6 +36,7 @@ #include "nm-object-private.h" #include "nm-object-cache.h" #include "nm-marshal.h" +#include "nm-dbus-glib-types.h" #include "nm-device-bindings.h" @@ -334,6 +335,60 @@ device_state_changed (DBusGProxy *proxy, } } +static void +get_all_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +{ + NMObject *self = NM_OBJECT (user_data); + GHashTable *props = NULL; + GError *error = NULL; + + if (!dbus_g_proxy_end_call (proxy, call, &error, + DBUS_TYPE_G_MAP_OF_VARIANT, &props, + G_TYPE_INVALID)) { + if (!(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NO_REPLY)) { + g_warning ("%s: couldn't retrieve device properties: (%d) %s.", + __func__, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + } + g_clear_error (&error); + g_object_unref (proxy); + return; + } + g_object_unref (proxy); + + /* Hack: libnm-glib's NMDevice doesn't have ip4-address property. Remove + * it from the hash to prevent warnings. + */ + g_hash_table_remove (props, "Ip4Address"); + + _nm_object_process_properties_changed (NM_OBJECT (self), props); + g_hash_table_destroy (props); + +} + +static void +initialize_properties (NMObject *object) +{ + DBusGProxy *props_proxy; + + /* D-Bus properties proxy */ + props_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), + NM_DBUS_SERVICE, + nm_object_get_path (object), + "org.freedesktop.DBus.Properties"); + g_assert (props_proxy); + + /* Get properties */ + dbus_g_proxy_begin_call (props_proxy, "GetAll", + get_all_cb, + object, + NULL, + G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, + G_TYPE_INVALID); + +} + static GObject* constructor (GType type, guint n_construct_params, @@ -357,6 +412,12 @@ constructor (GType type, register_for_property_changed (NM_DEVICE (object)); + /* Get initial properties, so that we have all properties set even if + * no PropertiesChanged signal is received. + * It has to be called after register_for_property_changed(). + */ + initialize_properties (object); + dbus_g_object_register_marshaller (_nm_marshal_VOID__UINT_UINT_UINT, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,