mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-23 11:14:29 +00:00
libnm-glib: add "pseudoproperties" for things like Client.GetDevices
Add generic handling for "properties" that consist of a "Get" method, an "Added" signal, and a "Removed" signal, reusing some of the code for handling object-array-valued properties. And load the values of pseudo properties from _nm_object_reload/ensure_properties as well.
This commit is contained in:
parent
cc90f1010e
commit
ad5daa098c
|
@ -106,8 +106,8 @@ static void proxy_name_owner_changed (DBusGProxy *proxy,
|
|||
const char *new_owner,
|
||||
gpointer user_data);
|
||||
|
||||
static void client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data);
|
||||
static void client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data);
|
||||
static void client_device_added (NMObject *client, NMObject *device);
|
||||
static void client_device_removed (NMObject *client, NMObject *device);
|
||||
|
||||
static void
|
||||
nm_client_init (NMClient *client)
|
||||
|
@ -256,6 +256,14 @@ register_properties (NMClient *client)
|
|||
_nm_object_register_properties (NM_OBJECT (client),
|
||||
priv->client_proxy,
|
||||
property_info);
|
||||
|
||||
_nm_object_register_pseudo_property (NM_OBJECT (client),
|
||||
priv->client_proxy,
|
||||
"Devices",
|
||||
&priv->devices,
|
||||
NM_TYPE_DEVICE,
|
||||
client_device_added,
|
||||
client_device_removed);
|
||||
}
|
||||
|
||||
#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network"
|
||||
|
@ -421,34 +429,10 @@ client_recheck_permissions (DBusGProxy *proxy, gpointer user_data)
|
|||
const GPtrArray *
|
||||
nm_client_get_devices (NMClient *client)
|
||||
{
|
||||
NMClientPrivate *priv;
|
||||
DBusGConnection *connection;
|
||||
GValue value = { 0, };
|
||||
GError *error = NULL;
|
||||
GPtrArray *temp;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
|
||||
|
||||
priv = NM_CLIENT_GET_PRIVATE (client);
|
||||
if (priv->devices)
|
||||
return handle_ptr_array_return (priv->devices);
|
||||
|
||||
if (!dbus_g_proxy_call (priv->client_proxy, "GetDevices", &error,
|
||||
G_TYPE_INVALID,
|
||||
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp,
|
||||
G_TYPE_INVALID)) {
|
||||
g_warning ("%s: error getting devices: %s\n", __func__, error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH);
|
||||
g_value_take_boxed (&value, temp);
|
||||
connection = nm_object_get_connection (NM_OBJECT (client));
|
||||
_nm_object_array_demarshal (&value, &priv->devices, connection, nm_device_new);
|
||||
g_value_unset (&value);
|
||||
|
||||
return handle_ptr_array_return (priv->devices);
|
||||
_nm_object_ensure_inited (NM_OBJECT (client));
|
||||
return handle_ptr_array_return (NM_CLIENT_GET_PRIVATE (client)->devices);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1182,43 +1166,15 @@ proxy_name_owner_changed (DBusGProxy *proxy,
|
|||
}
|
||||
|
||||
static void
|
||||
client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
|
||||
client_device_added (NMObject *client, NMObject *device)
|
||||
{
|
||||
NMClient *client = NM_CLIENT (user_data);
|
||||
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
|
||||
GObject *device;
|
||||
|
||||
device = G_OBJECT (nm_client_get_device_by_path (client, path));
|
||||
if (!device) {
|
||||
DBusGConnection *connection = nm_object_get_connection (NM_OBJECT (client));
|
||||
|
||||
device = G_OBJECT (_nm_object_cache_get (path));
|
||||
if (device) {
|
||||
g_ptr_array_add (priv->devices, device);
|
||||
} else {
|
||||
device = G_OBJECT (nm_device_new (connection, path));
|
||||
if (device)
|
||||
g_ptr_array_add (priv->devices, device);
|
||||
}
|
||||
}
|
||||
|
||||
if (device)
|
||||
g_signal_emit (client, signals[DEVICE_ADDED], 0, device);
|
||||
g_signal_emit (client, signals[DEVICE_ADDED], 0, device);
|
||||
}
|
||||
|
||||
static void
|
||||
client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
|
||||
client_device_removed (NMObject *client, NMObject *device)
|
||||
{
|
||||
NMClient *client = NM_CLIENT (user_data);
|
||||
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
|
||||
NMDevice *device;
|
||||
|
||||
device = nm_client_get_device_by_path (client, path);
|
||||
if (device) {
|
||||
g_signal_emit (client, signals[DEVICE_REMOVED], 0, device);
|
||||
g_ptr_array_remove (priv->devices, device);
|
||||
g_object_unref (device);
|
||||
}
|
||||
g_signal_emit (client, signals[DEVICE_REMOVED], 0, device);
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
@ -1279,20 +1235,6 @@ constructor (GType type,
|
|||
|
||||
register_properties (NM_CLIENT (object));
|
||||
|
||||
dbus_g_proxy_add_signal (priv->client_proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->client_proxy,
|
||||
"DeviceAdded",
|
||||
G_CALLBACK (client_device_added_proxy),
|
||||
object,
|
||||
NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->client_proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->client_proxy,
|
||||
"DeviceRemoved",
|
||||
G_CALLBACK (client_device_removed_proxy),
|
||||
object,
|
||||
NULL);
|
||||
|
||||
/* Permissions */
|
||||
dbus_g_proxy_add_signal (priv->client_proxy, "CheckPermissions", G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->client_proxy,
|
||||
|
|
|
@ -255,34 +255,10 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
|
|||
const GPtrArray *
|
||||
nm_device_wifi_get_access_points (NMDeviceWifi *device)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv;
|
||||
DBusGConnection *connection;
|
||||
GValue value = { 0, };
|
||||
GError *error = NULL;
|
||||
GPtrArray *temp;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
|
||||
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
|
||||
if (priv->aps)
|
||||
return handle_ptr_array_return (priv->aps);
|
||||
|
||||
if (!dbus_g_proxy_call (priv->proxy, "GetAccessPoints", &error,
|
||||
G_TYPE_INVALID,
|
||||
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp,
|
||||
G_TYPE_INVALID)) {
|
||||
g_warning ("%s: error getting access points: %s", __func__, error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH);
|
||||
g_value_take_boxed (&value, temp);
|
||||
connection = nm_object_get_connection (NM_OBJECT (device));
|
||||
_nm_object_array_demarshal (&value, &priv->aps, connection, nm_access_point_new);
|
||||
g_value_unset (&value);
|
||||
|
||||
return handle_ptr_array_return (priv->aps);
|
||||
_nm_object_ensure_inited (NM_OBJECT (device));
|
||||
return handle_ptr_array_return (NM_DEVICE_WIFI_GET_PRIVATE (device)->aps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -321,57 +297,28 @@ nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device,
|
|||
}
|
||||
|
||||
static void
|
||||
access_point_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
|
||||
access_point_added (NMObject *self, NMObject *ap)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
|
||||
NMDeviceWifiPrivate *priv;
|
||||
GObject *ap;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
ap = G_OBJECT (nm_device_wifi_get_access_point_by_path (self, path));
|
||||
if (!ap) {
|
||||
DBusGConnection *connection = nm_object_get_connection (NM_OBJECT (self));
|
||||
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
ap = G_OBJECT (_nm_object_cache_get (path));
|
||||
if (ap) {
|
||||
g_ptr_array_add (priv->aps, ap);
|
||||
} else {
|
||||
ap = G_OBJECT (nm_access_point_new (connection, path));
|
||||
if (ap)
|
||||
g_ptr_array_add (priv->aps, ap);
|
||||
}
|
||||
}
|
||||
|
||||
if (ap)
|
||||
g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, NM_ACCESS_POINT (ap));
|
||||
g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, ap);
|
||||
}
|
||||
|
||||
static void
|
||||
access_point_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
|
||||
access_point_removed (NMObject *self_obj, NMObject *ap_obj)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (self_obj);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMAccessPoint *ap;
|
||||
NMAccessPoint *ap = NM_ACCESS_POINT (ap_obj);
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
if (ap == priv->active_ap) {
|
||||
g_object_unref (priv->active_ap);
|
||||
priv->active_ap = NULL;
|
||||
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
|
||||
|
||||
ap = nm_device_wifi_get_access_point_by_path (self, path);
|
||||
if (ap) {
|
||||
if (ap == priv->active_ap) {
|
||||
g_object_unref (priv->active_ap);
|
||||
priv->active_ap = NULL;
|
||||
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
|
||||
|
||||
priv->rate = 0;
|
||||
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE);
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap);
|
||||
g_ptr_array_remove (priv->aps, ap);
|
||||
g_object_unref (G_OBJECT (ap));
|
||||
priv->rate = 0;
|
||||
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE);
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -581,6 +528,14 @@ register_properties (NMDeviceWifi *device)
|
|||
_nm_object_register_properties (NM_OBJECT (device),
|
||||
priv->proxy,
|
||||
property_info);
|
||||
|
||||
_nm_object_register_pseudo_property (NM_OBJECT (device),
|
||||
priv->proxy,
|
||||
"AccessPoints",
|
||||
&priv->aps,
|
||||
NM_TYPE_ACCESS_POINT,
|
||||
access_point_added,
|
||||
access_point_removed);
|
||||
}
|
||||
|
||||
static GObject*
|
||||
|
@ -604,20 +559,6 @@ constructor (GType type,
|
|||
nm_object_get_path (NM_OBJECT (object)),
|
||||
NM_DBUS_INTERFACE_DEVICE_WIRELESS);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "AccessPointAdded",
|
||||
DBUS_TYPE_G_OBJECT_PATH,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "AccessPointAdded",
|
||||
G_CALLBACK (access_point_added_proxy),
|
||||
object, NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "AccessPointRemoved",
|
||||
DBUS_TYPE_G_OBJECT_PATH,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "AccessPointRemoved",
|
||||
G_CALLBACK (access_point_removed_proxy),
|
||||
object, NULL);
|
||||
|
||||
register_properties (NM_DEVICE_WIFI (object));
|
||||
|
||||
g_signal_connect (NM_DEVICE (object),
|
||||
|
|
|
@ -172,34 +172,10 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax)
|
|||
const GPtrArray *
|
||||
nm_device_wimax_get_nsps (NMDeviceWimax *wimax)
|
||||
{
|
||||
NMDeviceWimaxPrivate *priv;
|
||||
DBusGConnection *connection;
|
||||
GValue value = { 0, };
|
||||
GError *error = NULL;
|
||||
GPtrArray *temp;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL);
|
||||
|
||||
priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax);
|
||||
if (priv->nsps)
|
||||
return handle_ptr_array_return (priv->nsps);
|
||||
|
||||
if (!dbus_g_proxy_call (priv->proxy, "GetNspList", &error,
|
||||
G_TYPE_INVALID,
|
||||
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp,
|
||||
G_TYPE_INVALID)) {
|
||||
g_warning ("%s: error getting NSPs: %s", __func__, error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH);
|
||||
g_value_take_boxed (&value, temp);
|
||||
connection = nm_object_get_connection (NM_OBJECT (wimax));
|
||||
_nm_object_array_demarshal (&value, &priv->nsps, connection, nm_wimax_nsp_new);
|
||||
g_value_unset (&value);
|
||||
|
||||
return handle_ptr_array_return (priv->nsps);
|
||||
_nm_object_ensure_inited (NM_OBJECT (wimax));
|
||||
return handle_ptr_array_return (NM_DEVICE_WIMAX_GET_PRIVATE (wimax)->nsps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -238,54 +214,25 @@ nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax,
|
|||
}
|
||||
|
||||
static void
|
||||
nsp_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
|
||||
nsp_added (NMObject *self, NMObject *nsp)
|
||||
{
|
||||
NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
|
||||
NMDeviceWimaxPrivate *priv;
|
||||
GObject *nsp;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
nsp = G_OBJECT (nm_device_wimax_get_nsp_by_path (self, path));
|
||||
if (!nsp) {
|
||||
DBusGConnection *connection = nm_object_get_connection (NM_OBJECT (self));
|
||||
|
||||
priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
|
||||
nsp = G_OBJECT (_nm_object_cache_get (path));
|
||||
if (nsp) {
|
||||
g_ptr_array_add (priv->nsps, nsp);
|
||||
} else {
|
||||
nsp = G_OBJECT (nm_wimax_nsp_new (connection, path));
|
||||
if (nsp)
|
||||
g_ptr_array_add (priv->nsps, nsp);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsp)
|
||||
g_signal_emit (self, signals[NSP_ADDED], 0, nsp);
|
||||
g_signal_emit (self, signals[NSP_ADDED], 0, nsp);
|
||||
}
|
||||
|
||||
static void
|
||||
nsp_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
|
||||
nsp_removed (NMObject *self_obj, NMObject *nsp_obj)
|
||||
{
|
||||
NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
|
||||
NMDeviceWimax *self = NM_DEVICE_WIMAX (self_obj);
|
||||
NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
|
||||
NMWimaxNsp *nsp;
|
||||
NMWimaxNsp *nsp = NM_WIMAX_NSP (nsp_obj);
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
nsp = nm_device_wimax_get_nsp_by_path (self, path);
|
||||
if (nsp) {
|
||||
if (nsp == priv->active_nsp) {
|
||||
g_object_unref (priv->active_nsp);
|
||||
priv->active_nsp = NULL;
|
||||
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP);
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
|
||||
g_ptr_array_remove (priv->nsps, nsp);
|
||||
g_object_unref (G_OBJECT (nsp));
|
||||
if (nsp == priv->active_nsp) {
|
||||
g_object_unref (priv->active_nsp);
|
||||
priv->active_nsp = NULL;
|
||||
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP);
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -568,6 +515,14 @@ register_properties (NMDeviceWimax *wimax)
|
|||
_nm_object_register_properties (NM_OBJECT (wimax),
|
||||
priv->proxy,
|
||||
property_info);
|
||||
|
||||
_nm_object_register_pseudo_property (NM_OBJECT (wimax),
|
||||
priv->proxy,
|
||||
"NspList",
|
||||
&priv->nsps,
|
||||
NM_TYPE_WIMAX_NSP,
|
||||
nsp_added,
|
||||
nsp_removed);
|
||||
}
|
||||
|
||||
static GObject*
|
||||
|
@ -591,20 +546,6 @@ constructor (GType type,
|
|||
nm_object_get_path (NM_OBJECT (object)),
|
||||
NM_DBUS_INTERFACE_DEVICE_WIMAX);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "NspAdded",
|
||||
DBUS_TYPE_G_OBJECT_PATH,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "NspAdded",
|
||||
G_CALLBACK (nsp_added_proxy),
|
||||
object, NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "NspRemoved",
|
||||
DBUS_TYPE_G_OBJECT_PATH,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "NspRemoved",
|
||||
G_CALLBACK (nsp_removed_proxy),
|
||||
object, NULL);
|
||||
|
||||
register_properties (NM_DEVICE_WIMAX (object));
|
||||
|
||||
g_signal_connect (object,
|
||||
|
|
|
@ -49,6 +49,17 @@ gboolean _nm_object_reload_properties (NMObject *object, GError **error);
|
|||
|
||||
void _nm_object_process_properties_changed (NMObject *self, GHashTable *properties);
|
||||
|
||||
typedef void (*NMPseudoPropertyChangedFunc) (NMObject *self, NMObject *changed);
|
||||
void _nm_object_register_pseudo_property (NMObject *object,
|
||||
DBusGProxy *proxy,
|
||||
const char *name,
|
||||
gpointer field,
|
||||
GType object_type,
|
||||
NMPseudoPropertyChangedFunc added_func,
|
||||
NMPseudoPropertyChangedFunc removed_func);
|
||||
void _nm_object_reload_pseudo_property (NMObject *object,
|
||||
const char *name);
|
||||
|
||||
void _nm_object_queue_notify (NMObject *object, const char *property);
|
||||
|
||||
/* DBus property accessors */
|
||||
|
|
|
@ -47,12 +47,24 @@ typedef struct {
|
|||
gpointer field;
|
||||
} PropertyInfo;
|
||||
|
||||
typedef struct {
|
||||
PropertyInfo pi;
|
||||
|
||||
NMObject *self;
|
||||
DBusGProxy *proxy;
|
||||
|
||||
char *get_method;
|
||||
NMPseudoPropertyChangedFunc added_func;
|
||||
NMPseudoPropertyChangedFunc removed_func;
|
||||
} PseudoPropertyInfo;
|
||||
|
||||
typedef struct {
|
||||
DBusGConnection *connection;
|
||||
char *path;
|
||||
DBusGProxy *properties_proxy;
|
||||
GSList *property_interfaces;
|
||||
GSList *property_tables;
|
||||
GHashTable *pseudo_properties;
|
||||
NMObject *parent;
|
||||
|
||||
GSList *notify_props;
|
||||
|
@ -143,6 +155,9 @@ finalize (GObject *object)
|
|||
g_slist_free (priv->property_tables);
|
||||
g_free (priv->path);
|
||||
|
||||
if (priv->pseudo_properties)
|
||||
g_hash_table_destroy (priv->pseudo_properties);
|
||||
|
||||
G_OBJECT_CLASS (nm_object_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -752,6 +767,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)
|
||||
return TRUE;
|
||||
|
@ -770,6 +787,12 @@ _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;
|
||||
}
|
||||
|
||||
|
@ -850,3 +873,156 @@ _nm_object_set_property (NMObject *object,
|
|||
*/
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pseudo_property_object_created (GObject *obj, 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 ();
|
||||
g_ptr_array_add (*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;
|
||||
|
||||
obj = _nm_object_cache_get (path);
|
||||
if (obj)
|
||||
pseudo_property_object_created (G_OBJECT (obj), 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;
|
||||
GPtrArray *list = *(GPtrArray **)ppi->pi.field;
|
||||
NMObject *obj = NULL;
|
||||
int i;
|
||||
|
||||
if (!list)
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue