summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2014-08-18 18:12:01 -0400
committerDan Winship <danw@gnome.org>2014-09-18 11:51:08 -0400
commitb3c4917b0fb58bdcf91531fa85a1ee2a57a7285d (patch)
tree2d0df9264f0370457e73e1f01370c6db478053af
parentb728d1fb706cb686d5a36bd6d3b10ad1289dae8c (diff)
downloadNetworkManager-b3c4917b0fb58bdcf91531fa85a1ee2a57a7285d.tar.gz
libnm: move most of the subclass-type-deciding code into NMObject
NMObject has a system that lets devices and active connections get created as the correct subtypes (NMDeviceFoo / NMActiveConnection vs NMVpnConnection). But it was much more generic than it needed to be, because NMDevice and NMActiveConnection both did the same thing (fetch a D-Bus property and then look at its value). So move the property-fetching part into NMObject, and only use the callback for converting the property value to a GType.
-rw-r--r--libnm/nm-active-connection.c108
-rw-r--r--libnm/nm-device.c98
-rw-r--r--libnm/nm-object-private.h10
-rw-r--r--libnm/nm-object.c120
4 files changed, 116 insertions, 220 deletions
diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c
index 667fbe1bb6..8e94f954dd 100644
--- a/libnm/nm-active-connection.c
+++ b/libnm/nm-active-connection.c
@@ -32,17 +32,13 @@
#include "nm-glib-compat.h"
#include "nm-dbus-helpers-private.h"
-static GType _nm_active_connection_type_for_path (DBusGConnection *connection,
- const char *path);
-static void _nm_active_connection_type_for_path_async (DBusGConnection *connection,
- const char *path,
- NMObjectTypeCallbackFunc callback,
- gpointer user_data);
+static GType _nm_active_connection_decide_type (GValue *value);
G_DEFINE_TYPE_WITH_CODE (NMActiveConnection, nm_active_connection, NM_TYPE_OBJECT,
_nm_object_register_type_func (g_define_type_id,
- _nm_active_connection_type_for_path,
- _nm_active_connection_type_for_path_async);
+ _nm_active_connection_decide_type,
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ "Vpn");
)
#define NM_ACTIVE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate))
@@ -87,97 +83,13 @@ enum {
};
static GType
-_nm_active_connection_type_for_path (DBusGConnection *connection,
- const char *path)
+_nm_active_connection_decide_type (GValue *value)
{
- DBusGProxy *proxy;
- GError *error = NULL;
- GValue value = G_VALUE_INIT;
- GType type;
-
- proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
- if (!proxy) {
- g_warning ("%s: couldn't create D-Bus object proxy.", __func__);
- return G_TYPE_INVALID;
- }
-
- /* Have to create an NMVpnConnection if it's a VPN connection, otherwise
- * a plain NMActiveConnection.
- */
- if (dbus_g_proxy_call (proxy,
- "Get", &error,
- G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
- G_TYPE_STRING, "Vpn",
- G_TYPE_INVALID,
- G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
- if (g_value_get_boolean (&value))
- type = NM_TYPE_VPN_CONNECTION;
- else
- type = NM_TYPE_ACTIVE_CONNECTION;
- } else {
- g_warning ("Error in getting active connection 'Vpn' property: (%d) %s",
- error->code, error->message);
- g_error_free (error);
- type = G_TYPE_INVALID;
- }
-
- g_object_unref (proxy);
- return type;
-}
-
-typedef struct {
- DBusGConnection *connection;
- NMObjectTypeCallbackFunc callback;
- gpointer user_data;
-} NMActiveConnectionAsyncData;
-
-static void
-async_got_type (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
-{
- NMActiveConnectionAsyncData *async_data = user_data;
- GValue value = G_VALUE_INIT;
- const char *path = dbus_g_proxy_get_path (proxy);
- GError *error = NULL;
- GType type;
-
- if (dbus_g_proxy_end_call (proxy, call, &error,
- G_TYPE_VALUE, &value,
- G_TYPE_INVALID)) {
- if (g_value_get_boolean (&value))
- type = NM_TYPE_VPN_CONNECTION;
- else
- type = NM_TYPE_ACTIVE_CONNECTION;
- } else {
- g_warning ("%s: could not read properties for %s: %s", __func__, path, error->message);
- type = G_TYPE_INVALID;
- }
-
- async_data->callback (type, async_data->user_data);
-
- g_object_unref (proxy);
- g_slice_free (NMActiveConnectionAsyncData, async_data);
-}
-
-static void
-_nm_active_connection_type_for_path_async (DBusGConnection *connection,
- const char *path,
- NMObjectTypeCallbackFunc callback,
- gpointer user_data)
-{
- NMActiveConnectionAsyncData *async_data;
- DBusGProxy *proxy;
-
- async_data = g_slice_new (NMActiveConnectionAsyncData);
- async_data->connection = connection;
- async_data->callback = callback;
- async_data->user_data = user_data;
-
- proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
- dbus_g_proxy_begin_call (proxy, "Get",
- async_got_type, async_data, NULL,
- G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
- G_TYPE_STRING, "Vpn",
- G_TYPE_INVALID);
+ /* @value is the value of the o.fd.NM.ActiveConnection property "VPN" */
+ if (g_value_get_boolean (value))
+ return NM_TYPE_VPN_CONNECTION;
+ else
+ return NM_TYPE_ACTIVE_CONNECTION;
}
/**
diff --git a/libnm/nm-device.c b/libnm/nm-device.c
index 25d7298f85..f5cd053268 100644
--- a/libnm/nm-device.c
+++ b/libnm/nm-device.c
@@ -49,17 +49,14 @@
#include "nm-utils.h"
#include "nm-dbus-helpers-private.h"
-static GType _nm_device_type_for_path (DBusGConnection *connection,
- const char *path);
-static void _nm_device_type_for_path_async (DBusGConnection *connection,
- const char *path,
- NMObjectTypeCallbackFunc callback,
- gpointer user_data);
+static GType _nm_device_decide_type (GValue *value);
gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error);
G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT,
- _nm_object_register_type_func (g_define_type_id, _nm_device_type_for_path,
- _nm_device_type_for_path_async);
+ _nm_object_register_type_func (g_define_type_id,
+ _nm_device_decide_type,
+ NM_DBUS_INTERFACE_DEVICE,
+ "DeviceType");
)
#define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
@@ -865,90 +862,9 @@ _nm_device_set_device_type (NMDevice *device, NMDeviceType dtype)
}
static GType
-_nm_device_type_for_path (DBusGConnection *connection,
- const char *path)
+_nm_device_decide_type (GValue *value)
{
- DBusGProxy *proxy;
- GError *err = NULL;
- GValue value = G_VALUE_INIT;
- NMDeviceType nm_dtype;
-
- proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
- if (!proxy) {
- g_warning ("%s: couldn't create D-Bus object proxy.", __func__);
- return G_TYPE_INVALID;
- }
-
- if (!dbus_g_proxy_call (proxy,
- "Get", &err,
- G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE,
- G_TYPE_STRING, "DeviceType",
- G_TYPE_INVALID,
- G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
- g_warning ("Error in get_property: %s\n", err->message);
- g_error_free (err);
- g_object_unref (proxy);
- return G_TYPE_INVALID;
- }
- g_object_unref (proxy);
-
- nm_dtype = g_value_get_uint (&value);
- return _nm_device_gtype_from_dtype (nm_dtype);
-}
-
-typedef struct {
- DBusGConnection *connection;
- NMObjectTypeCallbackFunc callback;
- gpointer user_data;
-} NMDeviceAsyncData;
-
-static void
-async_got_type (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
-{
- NMDeviceAsyncData *async_data = user_data;
- GValue value = G_VALUE_INIT;
- const char *path = dbus_g_proxy_get_path (proxy);
- GError *error = NULL;
- GType type;
-
- if (dbus_g_proxy_end_call (proxy, call, &error,
- G_TYPE_VALUE, &value,
- G_TYPE_INVALID)) {
- NMDeviceType dtype;
-
- dtype = g_value_get_uint (&value);
- type = _nm_device_gtype_from_dtype (dtype);
- } else {
- g_warning ("%s: could not read properties for %s: %s", __func__, path, error->message);
- g_error_free (error);
- type = G_TYPE_INVALID;
- }
-
- async_data->callback (type, async_data->user_data);
- g_object_unref (proxy);
- g_slice_free (NMDeviceAsyncData, async_data);
-}
-
-static void
-_nm_device_type_for_path_async (DBusGConnection *connection,
- const char *path,
- NMObjectTypeCallbackFunc callback,
- gpointer user_data)
-{
- NMDeviceAsyncData *async_data;
- DBusGProxy *proxy;
-
- async_data = g_slice_new (NMDeviceAsyncData);
- async_data->connection = connection;
- async_data->callback = callback;
- async_data->user_data = user_data;
-
- proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
- dbus_g_proxy_begin_call (proxy, "Get",
- async_got_type, async_data, NULL,
- G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE,
- G_TYPE_STRING, "DeviceType",
- G_TYPE_INVALID);
+ return _nm_device_gtype_from_dtype (g_value_get_uint (value));
}
/**
diff --git a/libnm/nm-object-private.h b/libnm/nm-object-private.h
index f8e70d389a..e5aad9d734 100644
--- a/libnm/nm-object-private.h
+++ b/libnm/nm-object-private.h
@@ -65,12 +65,12 @@ void _nm_object_set_property (NMObject *object,
GValue *value);
/* object demarshalling support */
-typedef GType (*NMObjectTypeFunc) (DBusGConnection *, const char *);
-typedef void (*NMObjectTypeCallbackFunc) (GType, gpointer);
-typedef void (*NMObjectTypeAsyncFunc) (DBusGConnection *, const char *, NMObjectTypeCallbackFunc, gpointer);
+typedef GType (*NMObjectDecideTypeFunc) (GValue *);
-void _nm_object_register_type_func (GType base_type, NMObjectTypeFunc type_func,
- NMObjectTypeAsyncFunc type_async_func);
+void _nm_object_register_type_func (GType base_type,
+ NMObjectDecideTypeFunc type_func,
+ const char *interface,
+ const char *property);
#define NM_OBJECT_NM_RUNNING "nm-running-internal"
gboolean _nm_object_get_nm_running (NMObject *self);
diff --git a/libnm/nm-object.c b/libnm/nm-object.c
index 2bd9707d9a..1ddf195c4e 100644
--- a/libnm/nm-object.c
+++ b/libnm/nm-object.c
@@ -39,7 +39,13 @@ static gboolean debug = FALSE;
static void nm_object_initable_iface_init (GInitableIface *iface);
static void nm_object_async_initable_iface_init (GAsyncInitableIface *iface);
-static GHashTable *type_funcs, *type_async_funcs;
+typedef struct {
+ NMObjectDecideTypeFunc type_func;
+ char *interface;
+ char *property;
+} NMObjectTypeFuncData;
+
+static GHashTable *type_funcs;
typedef struct {
GSList *interfaces;
@@ -49,7 +55,6 @@ typedef struct {
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMObject, nm_object, G_TYPE_OBJECT,
type_funcs = g_hash_table_new (NULL, NULL);
- type_async_funcs = g_hash_table_new (NULL, NULL);
g_type_add_class_private (g_define_type_id, sizeof (NMObjectClassPrivate));
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_object_initable_iface_init);
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_object_async_initable_iface_init);
@@ -586,27 +591,63 @@ _nm_object_queue_notify (NMObject *object, const char *property)
}
void
-_nm_object_register_type_func (GType base_type, NMObjectTypeFunc type_func,
- NMObjectTypeAsyncFunc type_async_func)
+_nm_object_register_type_func (GType base_type,
+ NMObjectDecideTypeFunc type_func,
+ const char *interface,
+ const char *property)
{
+ NMObjectTypeFuncData *type_data;
+
+ g_return_if_fail (type_func != NULL);
+ g_return_if_fail (interface != NULL);
+ g_return_if_fail (property != NULL);
+
+ type_data = g_slice_new (NMObjectTypeFuncData);
+ type_data->type_func = type_func;
+ type_data->interface = g_strdup (interface);
+ type_data->property = g_strdup (property);
+
g_hash_table_insert (type_funcs,
GSIZE_TO_POINTER (base_type),
- type_func);
- g_hash_table_insert (type_async_funcs,
- GSIZE_TO_POINTER (base_type),
- type_async_func);
+ type_data);
}
static GObject *
_nm_object_create (GType type, DBusGConnection *connection, const char *path)
{
- NMObjectTypeFunc type_func;
+ NMObjectTypeFuncData *type_data;
GObject *object;
GError *error = NULL;
- type_func = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
- if (type_func)
- type = type_func (connection, path);
+ type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
+ if (type_data) {
+ DBusGProxy *proxy;
+ GValue value = G_VALUE_INIT;
+
+ proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
+ if (!proxy) {
+ g_warning ("Could not create proxy for %s.", path);
+ return G_TYPE_INVALID;
+ }
+
+ if (!dbus_g_proxy_call (proxy,
+ "Get", &error,
+ G_TYPE_STRING, type_data->interface,
+ G_TYPE_STRING, type_data->property,
+ G_TYPE_INVALID,
+ G_TYPE_VALUE, &value,
+ G_TYPE_INVALID)) {
+ g_warning ("Could not fetch property '%s' of interface '%s' on %s: %s\n",
+ type_data->property, type_data->interface, path, error->message);
+ g_error_free (error);
+ g_object_unref (proxy);
+ return G_TYPE_INVALID;
+ }
+ g_object_unref (proxy);
+
+ type = type_data->type_func (&value);
+ g_value_unset (&value);
+ }
if (type == G_TYPE_INVALID) {
dbgmsg ("Could not create object for %s: unknown object type", path);
@@ -638,6 +679,7 @@ typedef struct {
char *path;
NMObjectCreateCallbackFunc callback;
gpointer user_data;
+ NMObjectTypeFuncData *type_data;
} NMObjectTypeAsyncData;
static void
@@ -650,7 +692,7 @@ create_async_complete (GObject *object, NMObjectTypeAsyncData *async_data)
}
static void
-async_inited (GObject *object, GAsyncResult *result, gpointer user_data)
+create_async_inited (GObject *object, GAsyncResult *result, gpointer user_data)
{
NMObjectTypeAsyncData *async_data = user_data;
GError *error = NULL;
@@ -681,9 +723,8 @@ async_inited (GObject *object, GAsyncResult *result, gpointer user_data)
}
static void
-async_got_type (GType type, gpointer user_data)
+create_async_got_type (NMObjectTypeAsyncData *async_data, GType type)
{
- NMObjectTypeAsyncData *async_data = user_data;
GObject *object;
if (type == G_TYPE_INVALID) {
@@ -696,15 +737,39 @@ async_got_type (GType type, gpointer user_data)
NM_OBJECT_PATH, async_data->path,
NULL);
g_async_initable_init_async (G_ASYNC_INITABLE (object), G_PRIORITY_DEFAULT,
- NULL, async_inited, async_data);
+ NULL, create_async_inited, async_data);
+}
+
+static void
+create_async_got_property (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ NMObjectTypeAsyncData *async_data = user_data;
+ NMObjectTypeFuncData *type_data = async_data->type_data;
+ GValue value = G_VALUE_INIT;
+ GError *error = NULL;
+ GType type;
+
+ if (dbus_g_proxy_end_call (proxy, call, &error,
+ G_TYPE_VALUE, &value,
+ G_TYPE_INVALID)) {
+ type = type_data->type_func (&value);
+ g_value_unset (&value);
+ } else {
+ const char *path = dbus_g_proxy_get_path (proxy);
+
+ g_warning ("Could not fetch property '%s' of interface '%s' on %s: %s\n",
+ type_data->property, type_data->interface, path, error->message);
+ g_clear_error (&error);
+ type = G_TYPE_INVALID;
+ }
+
+ create_async_got_type (async_data, type);
}
static void
_nm_object_create_async (GType type, DBusGConnection *connection, const char *path,
NMObjectCreateCallbackFunc callback, gpointer user_data)
{
- NMObjectTypeAsyncFunc type_async_func;
- NMObjectTypeFunc type_func;
NMObjectTypeAsyncData *async_data;
async_data = g_slice_new (NMObjectTypeAsyncData);
@@ -712,17 +777,20 @@ _nm_object_create_async (GType type, DBusGConnection *connection, const char *pa
async_data->callback = callback;
async_data->user_data = user_data;
- type_async_func = g_hash_table_lookup (type_async_funcs, GSIZE_TO_POINTER (type));
- if (type_async_func) {
- type_async_func (connection, path, async_got_type, async_data);
+ async_data->type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
+ if (async_data->type_data) {
+ DBusGProxy *proxy;
+
+ proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
+ dbus_g_proxy_begin_call (proxy, "Get",
+ create_async_got_property, async_data, NULL,
+ G_TYPE_STRING, async_data->type_data->interface,
+ G_TYPE_STRING, async_data->type_data->property,
+ G_TYPE_INVALID);
return;
}
- type_func = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
- if (type_func)
- type = type_func (connection, path);
-
- async_got_type (type, async_data);
+ create_async_got_type (async_data, type);
}
/* Stolen from dbus-glib */