summary refs log tree commit diff
path: root/libnm-glib/nm-object.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-glib/nm-object.c')
-rw-r--r--libnm-glib/nm-object.c526
1 files changed, 251 insertions, 275 deletions
diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c
index 93919d61..61282cfb 100644
--- a/libnm-glib/nm-object.c
+++ b/libnm-glib/nm-object.c
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <gio/gio.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <nm-utils.h>
 #include "NetworkManager.h"
 #include "nm-object.h"
@@ -32,7 +33,7 @@
 #include "nm-dbus-glib-types.h"
 #include "nm-glib-compat.h"
 #include "nm-types.h"
-#include "nm-glib-marshal.h"
+#include "nm-dbus-helpers-private.h"
 
 static gboolean debug = FALSE;
 #define dbgmsg(f,...) if (G_UNLIKELY (debug)) { g_message (f, ## __VA_ARGS__ ); }
@@ -52,30 +53,21 @@ static GHashTable *type_funcs, *type_async_funcs;
 typedef struct {
 	PropertyMarshalFunc func;
 	GType object_type;
-
 	gpointer field;
+	const char *signal_prefix;
 } PropertyInfo;
 
 static void reload_complete (NMObject *object);
 
 typedef struct {
-	PropertyInfo pi;
-
-	NMObject *self;
-	DBusGProxy *proxy;
-
-	char *get_method;
-	NMPseudoPropertyChangedFunc added_func;
-	NMPseudoPropertyChangedFunc removed_func;
-} PseudoPropertyInfo;
-
-typedef struct {
 	DBusGConnection *connection;
+	DBusGProxy *bus_proxy;
+	gboolean nm_running;
+
 	char *path;
 	DBusGProxy *properties_proxy;
 	GSList *property_interfaces;
 	GSList *property_tables;
-	GHashTable *pseudo_properties;
 	NMObject *parent;
 	gboolean suppress_property_updates;
 
@@ -122,21 +114,42 @@ nm_object_error_quark (void)
 }
 
 static void
+proxy_name_owner_changed (DBusGProxy *proxy,
+                          const char *name,
+                          const char *old_owner,
+                          const char *new_owner,
+                          gpointer user_data)
+{
+	NMObject *self = NM_OBJECT (user_data);
+	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
+
+	if (g_strcmp0 (name, NM_DBUS_SERVICE) == 0) {
+		gboolean old_good = (old_owner && old_owner[0]);
+		gboolean new_good = (new_owner && new_owner[0]);
+
+		if (!old_good && new_good)
+			priv->nm_running = TRUE;
+		else if (old_good && !new_good)
+			priv->nm_running = FALSE;
+	}
+}
+
+static void
 nm_object_init (NMObject *object)
 {
 }
 
 static GObject*
 constructor (GType type,
-			 guint n_construct_params,
-			 GObjectConstructParam *construct_params)
+             guint n_construct_params,
+             GObjectConstructParam *construct_params)
 {
 	GObject *object;
 	NMObjectPrivate *priv;
 
 	object = G_OBJECT_CLASS (nm_object_parent_class)->constructor (type,
-																   n_construct_params,
-																   construct_params);
+	                                                               n_construct_params,
+	                                                               construct_params);
 
 	priv = NM_OBJECT_GET_PRIVATE (object);
 
@@ -154,15 +167,31 @@ constructor (GType type,
 static void
 constructed (GObject *object)
 {
+	NMObject *self = NM_OBJECT (object);
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
 
 	if (G_OBJECT_CLASS (nm_object_parent_class)->constructed)
 		G_OBJECT_CLASS (nm_object_parent_class)->constructed (object);
 
-	priv->properties_proxy = dbus_g_proxy_new_for_name (priv->connection,
-	                                                    NM_DBUS_SERVICE,
-	                                                    priv->path,
-	                                                    "org.freedesktop.DBus.Properties");
+	priv->properties_proxy = _nm_object_new_proxy (self, NULL, "org.freedesktop.DBus.Properties");
+
+	if (_nm_object_is_connection_private (self))
+		priv->nm_running = TRUE;
+	else {
+		priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
+		                                             DBUS_SERVICE_DBUS,
+		                                             DBUS_PATH_DBUS,
+		                                             DBUS_INTERFACE_DBUS);
+		g_assert (priv->bus_proxy);
+
+		dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
+		                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+		                         G_TYPE_INVALID);
+		dbus_g_proxy_connect_signal (priv->bus_proxy,
+		                             "NameOwnerChanged",
+		                             G_CALLBACK (proxy_name_owner_changed),
+		                             object, NULL);
+	}
 }
 
 static gboolean
@@ -170,25 +199,68 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
 {
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable);
 
+	if (priv->bus_proxy) {
+		if (!dbus_g_proxy_call (priv->bus_proxy,
+		                        "NameHasOwner", error,
+		                        G_TYPE_STRING, NM_DBUS_SERVICE,
+		                        G_TYPE_INVALID,
+		                        G_TYPE_BOOLEAN, &priv->nm_running,
+		                        G_TYPE_INVALID))
+			return FALSE;
+	}
+
 	priv->inited = TRUE;
 	return _nm_object_reload_properties (NM_OBJECT (initable), error);
 }
 
+/* Takes ownership of @error */
+static void
+init_async_complete (GSimpleAsyncResult *simple, GError *error)
+{
+	if (error)
+		g_simple_async_result_take_error (simple, error);
+	else
+		g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+	g_simple_async_result_complete (simple);
+	g_object_unref (simple);
+}
+
 static void
 init_async_got_properties (GObject *object, GAsyncResult *result, gpointer user_data)
 {
-	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
 	GSimpleAsyncResult *simple = user_data;
 	GError *error = NULL;
 
-	priv->inited = TRUE;
-	if (_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error))
-		g_simple_async_result_set_op_res_gboolean (simple, TRUE);
-	else
-		g_simple_async_result_take_error (simple, error);
+	NM_OBJECT_GET_PRIVATE (object)->inited = TRUE;
+	if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error))
+		g_assert (error);
+	init_async_complete (simple, error);
+}
 
-	g_simple_async_result_complete (simple);
-	g_object_unref (simple);
+static void
+init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call,
+                                gpointer user_data)
+{
+	GSimpleAsyncResult *simple = user_data;
+	NMObject *self;
+	NMObjectPrivate *priv;
+	GError *error = NULL;
+
+	self = NM_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+	priv = NM_OBJECT_GET_PRIVATE (self);
+
+	if (!dbus_g_proxy_end_call (proxy, call, &error,
+	                            G_TYPE_BOOLEAN, &priv->nm_running,
+	                            G_TYPE_INVALID)) {
+		init_async_complete (simple, error);
+	} else if (!priv->nm_running) {
+		priv->inited = TRUE;
+		init_async_complete (simple, NULL);
+	} else
+		_nm_object_reload_properties_async (self, init_async_got_properties, simple);
+
+	/* g_async_result_get_source_object() adds a ref */
+	g_object_unref (self);
 }
 
 static void
@@ -196,10 +268,21 @@ init_async (GAsyncInitable *initable, int io_priority,
             GCancellable *cancellable, GAsyncReadyCallback callback,
             gpointer user_data)
 {
+	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable);
 	GSimpleAsyncResult *simple;
 
 	simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async);
-	_nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple);
+
+	if (_nm_object_is_connection_private (NM_OBJECT (initable)))
+		_nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple);
+	else {
+		/* Check if NM is running */
+		dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
+		                         init_async_got_manager_running,
+		                         simple, NULL,
+		                         G_TYPE_STRING, NM_DBUS_SERVICE,
+		                         G_TYPE_INVALID);
+	}
 }
 
 static gboolean
@@ -223,15 +306,14 @@ dispose (GObject *object)
 		priv->notify_id = 0;
 	}
 
-	g_slist_foreach (priv->notify_props, (GFunc) g_free, NULL);
-	g_slist_free (priv->notify_props);
+	g_slist_free_full (priv->notify_props, g_free);
 	priv->notify_props = NULL;
 
-	g_slist_foreach (priv->property_interfaces, (GFunc) g_free, NULL);
-	g_slist_free (priv->property_interfaces);
+	g_slist_free_full (priv->property_interfaces, g_free);
 	priv->property_interfaces = NULL;
 
 	g_clear_object (&priv->properties_proxy);
+	g_clear_object (&priv->bus_proxy);
 
 	if (priv->connection) {
 		dbus_g_connection_unref (priv->connection);
@@ -246,13 +328,9 @@ finalize (GObject *object)
 {
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
 
-	g_slist_foreach (priv->property_tables, (GFunc) g_hash_table_destroy, NULL);
-	g_slist_free (priv->property_tables);
+	g_slist_free_full (priv->property_tables, (GDestroyNotify) g_hash_table_destroy);
 	g_free (priv->path);
 
-	if (priv->pseudo_properties)
-		g_hash_table_destroy (priv->pseudo_properties);
-
 	G_OBJECT_CLASS (nm_object_parent_class)->finalize (object);
 }
 
@@ -261,15 +339,13 @@ set_property (GObject *object, guint prop_id,
 			  const GValue *value, GParamSpec *pspec)
 {
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-	DBusGConnection *connection;
 
 	switch (prop_id) {
 	case PROP_CONNECTION:
 		/* Construct only */
-		connection = (DBusGConnection *) g_value_get_boxed (value);
-		if (!connection)
-			connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
-		priv->connection = dbus_g_connection_ref (connection);
+		priv->connection = g_value_dup_boxed (value);
+		if (!priv->connection)
+			priv->connection = _nm_dbus_new_connection (NULL);
 		break;
 	case PROP_PATH:
 		/* Construct only */
@@ -367,8 +443,7 @@ nm_object_class_init (NMObjectClass *nm_object_class)
 		              G_OBJECT_CLASS_TYPE (object_class),
 		              G_SIGNAL_RUN_FIRST,
 		              G_STRUCT_OFFSET (NMObjectClass, object_creation_failed),
-		              NULL, NULL,
-		              _nm_glib_marshal_VOID__POINTER_POINTER,
+		              NULL, NULL, NULL,
 		              G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
 }
 
@@ -669,31 +744,120 @@ typedef struct {
 	const char *property_name;
 } ObjectCreatedData;
 
+/* Places items from 'needles' that are not in 'haystack' into 'diff' */
+static void
+array_diff (GPtrArray *needles, GPtrArray *haystack, GPtrArray *diff)
+{
+	guint i, j;
+	GObject *obj;
+
+	g_assert (needles);
+	g_assert (haystack);
+	g_assert (diff);
+
+	for (i = 0; i < needles->len; i++) {
+		obj = g_ptr_array_index (needles, i);
+
+		for (j = 0; j < haystack->len; j++) {
+			if (g_ptr_array_index (haystack, j) == obj)
+				break;
+		}
+
+		if (j == haystack->len)
+			g_ptr_array_add (diff, obj);
+	}
+}
+
+static void
+emit_added_removed_signal (NMObject *self,
+                           const char *signal_prefix,
+                           NMObject *changed,
+                           gboolean added)
+{
+	char buf[50];
+	int ret;
+
+	ret = g_snprintf (buf, sizeof (buf), "%s-%s", signal_prefix, added ? "added" : "removed");
+	g_assert (ret < sizeof (buf));
+	g_signal_emit_by_name (self, buf, changed);
+}
+
 static void
 object_property_complete (ObjectCreatedData *odata)
 {
 	NMObject *self = odata->self;
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
 	PropertyInfo *pi = odata->pi;
+	gboolean different = TRUE;
 
 	if (odata->array) {
-		GPtrArray **array = pi->field;
+		GPtrArray *old = *((GPtrArray **) pi->field);
+		GPtrArray *new;
 		int i;
 
-		if (*array)
-			g_boxed_free (NM_TYPE_OBJECT_ARRAY, *array);
-		*array = g_ptr_array_sized_new (odata->length);
+		/* Build up new array */
+		new = g_ptr_array_sized_new (odata->length);
 		for (i = 0; i < odata->length; i++)
-			add_to_object_array_unique (*array, odata->objects[i]);
+			add_to_object_array_unique (new, odata->objects[i]);
+
+		if (pi->signal_prefix) {
+			GPtrArray *added = g_ptr_array_sized_new (3);
+			GPtrArray *removed = g_ptr_array_sized_new (3);
+
+			if (old) {
+				/* Find objects in 'old' that do not exist in 'new' */
+				array_diff (old, new, removed);
+
+				/* Find objects in 'new' that do not exist in old */
+				array_diff (new, old, added);
+			} else {
+				for (i = 0; i < new->len; i++)
+					g_ptr_array_add (added, g_ptr_array_index (new, i));
+			}
+
+			*((GPtrArray **) pi->field) = new;
+
+			/* Emit added & removed */
+			for (i = 0; i < removed->len; i++) {
+				emit_added_removed_signal (self,
+				                           pi->signal_prefix,
+				                           g_ptr_array_index (removed, i),
+				                           FALSE);
+			}
+
+			for (i = 0; i < added->len; i++) {
+				emit_added_removed_signal (self,
+				                           pi->signal_prefix,
+				                           g_ptr_array_index (added, i),
+				                           TRUE);
+			}
+
+			different = removed->len || added->len;
+			g_ptr_array_free (added, TRUE);
+			g_ptr_array_free (removed, TRUE);
+		} else {
+			/* No added/removed signals to send, just replace the property with
+			 * the new values.
+			 */
+			*((GPtrArray **) pi->field) = new;
+			different = TRUE;
+		}
+
+		/* Free old array last since it will release references, thus freeing
+		 * any objects in the 'removed' array.
+		 */
+		if (old)
+			g_boxed_free (NM_TYPE_OBJECT_ARRAY, old);
 	} else {
 		GObject **obj_p = pi->field;
 
+		different = (*obj_p != odata->objects[0]);
 		if (*obj_p)
 			g_object_unref (*obj_p);
 		*obj_p = odata->objects[0];
 	}
 
-	if (odata->property_name)
+	if (different && odata->property_name)
 		_nm_object_queue_notify (self, odata->property_name);
 
 	if (priv->reload_results && --priv->reload_remaining == 0)
@@ -1045,6 +1209,7 @@ _nm_object_register_properties (NMObject *object,
 		pi->func = tmp->func ? tmp->func : demarshal_generic;
 		pi->object_type = tmp->object_type;
 		pi->field = tmp->field;
+		pi->signal_prefix = tmp->signal_prefix;
 		g_hash_table_insert (instance, g_strdup (tmp->name), pi);
 	}
 }
@@ -1055,10 +1220,8 @@ _nm_object_reload_properties (NMObject *object, GError **error)
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
 	GHashTable *props = NULL;
 	GSList *p;
-	GHashTableIter pp;
-	gpointer name, info;
 
-	if (!priv->property_interfaces)
+	if (!priv->property_interfaces || !priv->nm_running)
 		return TRUE;
 
 	for (p = priv->property_interfaces; p; p = p->next) {
@@ -1073,12 +1236,6 @@ _nm_object_reload_properties (NMObject *object, GError **error)
 		g_hash_table_destroy (props);
 	}
 
-	if (priv->pseudo_properties) {
-		g_hash_table_iter_init (&pp, priv->pseudo_properties);
-		while (g_hash_table_iter_next (&pp, &name, &info))
-			_nm_object_reload_pseudo_property (object, name);
-	}
-
 	return TRUE;
 }
 
@@ -1116,20 +1273,23 @@ _nm_object_reload_property (NMObject *object,
                             const char *interface,
                             const char *prop_name)
 {
-	GValue value = { 0, };
+	GValue value = G_VALUE_INIT;
 	GError *err = NULL;
 
 	g_return_if_fail (NM_IS_OBJECT (object));
 	g_return_if_fail (interface != NULL);
 	g_return_if_fail (prop_name != NULL);
 
+	if (!NM_OBJECT_GET_PRIVATE (object)->nm_running)
+		return;
+
 	if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy,
-							"Get", 15000, &err,
-							G_TYPE_STRING, interface,
-							G_TYPE_STRING, prop_name,
-							G_TYPE_INVALID,
-							G_TYPE_VALUE, &value,
-							G_TYPE_INVALID)) {
+	                                     "Get", 15000, &err,
+	                                     G_TYPE_STRING, interface,
+	                                     G_TYPE_STRING, prop_name,
+	                                     G_TYPE_INVALID,
+	                                     G_TYPE_VALUE, &value,
+	                                     G_TYPE_INVALID)) {
 		dbgmsg ("%s: Error getting '%s' for %s: (%d) %s\n",
 		        __func__,
 		        prop_name,
@@ -1146,15 +1306,18 @@ _nm_object_reload_property (NMObject *object,
 
 void
 _nm_object_set_property (NMObject *object,
-						const char *interface,
-						const char *prop_name,
-						GValue *value)
+                         const char *interface,
+                         const char *prop_name,
+                         GValue *value)
 {
 	g_return_if_fail (NM_IS_OBJECT (object));
 	g_return_if_fail (interface != NULL);
 	g_return_if_fail (prop_name != NULL);
 	g_return_if_fail (G_IS_VALUE (value));
 
+	if (!NM_OBJECT_GET_PRIVATE (object)->nm_running)
+		return;
+
 	if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy,
 	                                     "Set", 2000, NULL,
 	                                     G_TYPE_STRING, interface,
@@ -1169,163 +1332,6 @@ _nm_object_set_property (NMObject *object,
 }
 
 static void
-pseudo_property_object_created (GObject *obj, const char *path, gpointer user_data)
-{
-	PseudoPropertyInfo *ppi = user_data;
-
-	if (obj) {
-		GPtrArray **list_p = (GPtrArray **)ppi->pi.field;
-
-		if (!*list_p)
-			*list_p = g_ptr_array_new ();
-		add_to_object_array_unique (*list_p, obj);
-		ppi->added_func (ppi->self, NM_OBJECT (obj));
-	}
-}
-
-static void
-pseudo_property_added (DBusGProxy *proxy, const char *path, gpointer user_data)
-{
-	PseudoPropertyInfo *ppi = user_data;
-	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (ppi->self);
-	NMObject *obj;
-
-	if (priv->suppress_property_updates)
-		return;
-
-	obj = _nm_object_cache_get (path);
-	if (obj)
-		pseudo_property_object_created (G_OBJECT (obj), path, ppi);
-	else {
-		_nm_object_create_async (ppi->pi.object_type, priv->connection, path,
-		                         pseudo_property_object_created, ppi);
-	}
-}
-
-static void
-pseudo_property_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
-{
-	PseudoPropertyInfo *ppi = user_data;
-	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (ppi->self);
-	GPtrArray *list = *(GPtrArray **)ppi->pi.field;
-	NMObject *obj = NULL;
-	int i;
-
-	if (!list || priv->suppress_property_updates)
-		return;
-
-	for (i = 0; i < list->len; i++) {
-		obj = list->pdata[i];
-		if (!strcmp (path, nm_object_get_path (obj))) {
-			g_ptr_array_remove_index (list, i);
-			ppi->removed_func (ppi->self, obj);
-			g_object_unref (obj);
-			return;
-		}
-	}
-}
-
-static void
-free_pseudo_property (PseudoPropertyInfo *ppi)
-{
-	g_object_unref (ppi->proxy);
-	g_free (ppi->get_method);
-	g_slice_free (PseudoPropertyInfo, ppi);
-}
-
-void
-_nm_object_register_pseudo_property (NMObject *object,
-                                     DBusGProxy *proxy,
-                                     const char *name,
-                                     gpointer field,
-                                     GType object_type,
-                                     NMPseudoPropertyChangedFunc added_func,
-                                     NMPseudoPropertyChangedFunc removed_func)
-{
-	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-	PseudoPropertyInfo *ppi;
-	int basename_len;
-	char *added_signal, *removed_signal;
-
-	g_return_if_fail (NM_IS_OBJECT (object));
-	g_return_if_fail (proxy != NULL);
-
-	ppi = g_slice_new0 (PseudoPropertyInfo);
-	ppi->pi.field = field;
-	ppi->pi.object_type = object_type;
-	ppi->self = object;
-	ppi->proxy = g_object_ref (proxy);
-	ppi->added_func = added_func;
-	ppi->removed_func = removed_func;
-
-	basename_len = strlen (name);
-	if (basename_len > 4 && !strcmp (name + basename_len - 4, "List"))
-		basename_len -= 4;
-	else if (basename_len > 1 && name[basename_len - 1] == 's')
-		basename_len--;
-	else
-		g_assert_not_reached ();
-
-	ppi->get_method = g_strdup_printf ("Get%s", name);
-	added_signal = g_strdup_printf ("%.*sAdded", basename_len, name);
-	removed_signal = g_strdup_printf ("%.*sRemoved", basename_len, name);
-
-	if (!priv->pseudo_properties) {
-		priv->pseudo_properties = g_hash_table_new_full (g_str_hash, g_str_equal,
-		                                                 g_free, (GDestroyNotify) free_pseudo_property);
-	}
-	g_hash_table_insert (priv->pseudo_properties, g_strdup (name), ppi);
-
-	dbus_g_proxy_add_signal (proxy, added_signal,
-	                         DBUS_TYPE_G_OBJECT_PATH,
-	                         G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal (proxy, added_signal,
-	                             G_CALLBACK (pseudo_property_added),
-	                             ppi, NULL);
-
-	dbus_g_proxy_add_signal (proxy, removed_signal,
-	                         DBUS_TYPE_G_OBJECT_PATH,
-	                         G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal (proxy, removed_signal,
-	                             G_CALLBACK (pseudo_property_removed),
-	                             ppi, NULL);
-
-	g_free (added_signal);
-	g_free (removed_signal);
-}
-
-void
-_nm_object_reload_pseudo_property (NMObject *object,
-                                   const char *name)
-{
-	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-	PseudoPropertyInfo *ppi;
-	GPtrArray *temp;
-	GError *error = NULL;
-	GValue value = { 0, };
-
-	g_return_if_fail (NM_IS_OBJECT (object));
-	g_return_if_fail (name != NULL);
-
-	ppi = g_hash_table_lookup (priv->pseudo_properties, name);
-	g_return_if_fail (ppi != NULL);
-
-	if (!dbus_g_proxy_call (ppi->proxy, ppi->get_method, &error,
-	                        G_TYPE_INVALID,
-	                        DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp,
-	                        G_TYPE_INVALID)) {
-		g_warning ("%s: error calling %s: %s", __func__, ppi->get_method, error->message);
-		g_error_free (error);
-		return;
-	}
-
-	g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH);
-	g_value_take_boxed (&value, temp);
-	handle_object_array_property (object, NULL, &value, &ppi->pi, TRUE);
-	g_value_unset (&value);
-}
-
-static void
 reload_complete (NMObject *object)
 {
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
@@ -1378,36 +1384,6 @@ reload_got_properties (DBusGProxy *proxy, DBusGProxyCall *call,
 		reload_complete (object);
 }
 
-static void
-reload_got_pseudo_property (DBusGProxy *proxy, DBusGProxyCall *call,
-                            gpointer user_data)
-{
-	PseudoPropertyInfo *ppi = user_data;
-	NMObject *object = ppi->self;
-	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-	GPtrArray *temp;
-	GValue value = { 0, };
-	GError *error = NULL;
-
-	if (dbus_g_proxy_end_call (proxy, call, &error,
-	                           DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp,
-	                           G_TYPE_INVALID)) {
-		g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH);
-		g_value_take_boxed (&value, temp);
-		if (!priv->suppress_property_updates)
-			handle_object_array_property (object, NULL, &value, &ppi->pi, FALSE);
-		g_value_unset (&value);
-	} else {
-		if (priv->reload_error)
-			g_error_free (error);
-		else
-			priv->reload_error = error;
-	}
-
-	if (--priv->reload_remaining == 0)
-		reload_complete (object);
-}
-
 void
 _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callback, gpointer user_data)
 {
@@ -1418,7 +1394,7 @@ _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callba
 	simple = g_simple_async_result_new (G_OBJECT (object), callback,
 	                                    user_data, _nm_object_reload_properties_async);
 
-	if (!priv->property_interfaces && !priv->pseudo_properties) {
+	if (!priv->property_interfaces) {
 		g_simple_async_result_complete_in_idle (simple);
 		g_object_unref (simple);
 		return;
@@ -1440,21 +1416,6 @@ _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callba
 		                         G_TYPE_STRING, p->data,
 		                         G_TYPE_INVALID);
 	}
-
-	if (priv->pseudo_properties) {
-		GHashTableIter iter;
-		gpointer key, value;
-		PseudoPropertyInfo *ppi;
-
-		g_hash_table_iter_init (&iter, priv->pseudo_properties);
-		while (g_hash_table_iter_next (&iter, &key, &value)) {
-			ppi = value;
-			priv->reload_remaining++;
-			dbus_g_proxy_begin_call (ppi->proxy, ppi->get_method,
-			                         reload_got_pseudo_property, ppi, NULL,
-			                         G_TYPE_INVALID);
-		}
-	}
 }
 
 gboolean
@@ -1471,3 +1432,18 @@ _nm_object_reload_properties_finish (NMObject *object, GAsyncResult *result, GEr
 
 	return g_simple_async_result_get_op_res_gboolean (simple);
 }
+
+DBusGProxy *
+_nm_object_new_proxy (NMObject *self, const char *path, const char *interface)
+{
+	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
+
+	return _nm_dbus_new_proxy_for_connection (priv->connection, path ? path : priv->path, interface);
+}
+
+gboolean
+_nm_object_is_connection_private (NMObject *self)
+{
+	return _nm_dbus_is_connection_private (NM_OBJECT_GET_PRIVATE (self)->connection);
+}
+