mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-30 10:50:11 +01:00
libnm-glib: don't expose NMRemoteConnetions until they are valid
Give them time to get their settings from the remote settings service first, then let subclasses/users/whatever know about them.
This commit is contained in:
parent
cff9205ebd
commit
cb0303180d
3 changed files with 89 additions and 7 deletions
|
|
@ -84,6 +84,7 @@ libnm_glib_la_SOURCES = \
|
|||
nm-active-connection.c \
|
||||
nm-dhcp4-config.c \
|
||||
nm-remote-connection.c \
|
||||
nm-remote-connection-private.h \
|
||||
nm-settings-interface.c \
|
||||
nm-settings-system-interface.c \
|
||||
nm-remote-settings.c \
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <nm-utils.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#include "nm-remote-connection.h"
|
||||
#include "nm-remote-connection-private.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-exported-connection-bindings.h"
|
||||
#include "nm-settings-connection-interface.h"
|
||||
|
|
@ -41,6 +42,7 @@ G_DEFINE_TYPE_EXTENDED (NMRemoteConnection, nm_remote_connection, NM_TYPE_CONNEC
|
|||
enum {
|
||||
PROP_0,
|
||||
PROP_BUS,
|
||||
PROP_INIT_RESULT,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -60,6 +62,7 @@ typedef struct {
|
|||
DBusGProxy *secrets_proxy;
|
||||
GSList *calls;
|
||||
|
||||
NMRemoteConnectionInitResult init_result;
|
||||
gboolean disposed;
|
||||
} NMRemoteConnectionPrivate;
|
||||
|
||||
|
|
@ -227,6 +230,7 @@ get_settings_cb (DBusGProxy *proxy,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMRemoteConnection *self = user_data;
|
||||
NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
if (error) {
|
||||
g_warning ("%s: error getting %s connection %s settings: (%d) %s",
|
||||
|
|
@ -236,9 +240,13 @@ get_settings_cb (DBusGProxy *proxy,
|
|||
error ? error->code : -1,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_error_free (error);
|
||||
priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_ERROR;
|
||||
g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_INIT_RESULT);
|
||||
} else {
|
||||
replace_settings (self, new_settings);
|
||||
g_hash_table_destroy (new_settings);
|
||||
priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_SUCCESS;
|
||||
g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_INIT_RESULT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,8 +373,8 @@ get_property (GObject *object, guint prop_id,
|
|||
NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_BUS:
|
||||
g_value_set_boxed (value, priv->bus);
|
||||
case PROP_INIT_RESULT:
|
||||
g_value_set_uint (value, priv->init_result);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
|
@ -414,6 +422,16 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
|
|||
"DBusGConnection",
|
||||
"DBusGConnection",
|
||||
DBUS_TYPE_G_CONNECTION,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_INIT_RESULT,
|
||||
g_param_spec_uint (NM_REMOTE_CONNECTION_INIT_RESULT,
|
||||
"Initialization result (PRIVATE)",
|
||||
"Initialization result (PRIVATE)",
|
||||
NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN,
|
||||
NM_REMOTE_CONNECTION_INIT_RESULT_ERROR,
|
||||
NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "nm-remote-settings.h"
|
||||
#include "nm-settings-bindings.h"
|
||||
#include "nm-settings-interface.h"
|
||||
#include "nm-remote-connection-private.h"
|
||||
|
||||
static void settings_interface_init (NMSettingsInterface *class);
|
||||
|
||||
|
|
@ -43,6 +44,7 @@ typedef struct {
|
|||
|
||||
DBusGProxy *proxy;
|
||||
GHashTable *connections;
|
||||
GHashTable *pending; /* Connections we don't have settings for yet */
|
||||
|
||||
DBusGProxy *dbus_proxy;
|
||||
|
||||
|
|
@ -68,8 +70,58 @@ get_connection_by_path (NMSettingsInterface *settings, const char *path)
|
|||
static void
|
||||
connection_removed_cb (NMRemoteConnection *remote, gpointer user_data)
|
||||
{
|
||||
g_hash_table_remove (NM_REMOTE_SETTINGS_GET_PRIVATE (user_data)->connections,
|
||||
nm_connection_get_path (NM_CONNECTION (remote)));
|
||||
NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
const char *path;
|
||||
|
||||
path = nm_connection_get_path (NM_CONNECTION (remote));
|
||||
g_hash_table_remove (priv->connections, path);
|
||||
g_hash_table_remove (priv->pending, path);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_init_result_cb (NMRemoteConnection *remote,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
guint32 init_result = NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN;
|
||||
const char *path;
|
||||
|
||||
/* Disconnect from the init-result signal just to be safe */
|
||||
g_signal_handlers_disconnect_matched (remote,
|
||||
G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
G_CALLBACK (connection_init_result_cb),
|
||||
self);
|
||||
|
||||
path = nm_connection_get_path (NM_CONNECTION (remote));
|
||||
|
||||
g_object_get (G_OBJECT (remote),
|
||||
NM_REMOTE_CONNECTION_INIT_RESULT, &init_result,
|
||||
NULL);
|
||||
|
||||
switch (init_result) {
|
||||
case NM_REMOTE_CONNECTION_INIT_RESULT_SUCCESS:
|
||||
/* ref it when adding to ->connections, since removing it from ->pending
|
||||
* will unref it.
|
||||
*/
|
||||
g_hash_table_insert (priv->connections, g_strdup (path), g_object_ref (remote));
|
||||
|
||||
/* Finally, let users know of the new connection now that it has all
|
||||
* its settings and is valid.
|
||||
*/
|
||||
g_signal_emit_by_name (self, "new-connection", remote);
|
||||
break;
|
||||
case NM_REMOTE_CONNECTION_INIT_RESULT_ERROR:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_hash_table_remove (priv->pending, path);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -85,8 +137,15 @@ new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data)
|
|||
G_CALLBACK (connection_removed_cb),
|
||||
self);
|
||||
|
||||
g_hash_table_insert (priv->connections, g_strdup (path), connection);
|
||||
g_signal_emit_by_name (self, "new-connection", connection);
|
||||
g_signal_connect (connection, "notify::" NM_REMOTE_CONNECTION_INIT_RESULT,
|
||||
G_CALLBACK (connection_init_result_cb),
|
||||
self);
|
||||
|
||||
/* Add the connection to the pending table to wait for it to retrieve
|
||||
* it's settings asynchronously over D-Bus. The connection isn't
|
||||
* really valid until it has all its settings, so hide it until it does.
|
||||
*/
|
||||
g_hash_table_insert (priv->pending, g_strdup (path), connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -269,6 +328,7 @@ nm_remote_settings_init (NMRemoteSettings *self)
|
|||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
|
||||
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
priv->pending = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
|
|
@ -344,6 +404,9 @@ dispose (GObject *object)
|
|||
if (priv->connections)
|
||||
g_hash_table_destroy (priv->connections);
|
||||
|
||||
if (priv->pending)
|
||||
g_hash_table_destroy (priv->pending);
|
||||
|
||||
g_object_unref (priv->dbus_proxy);
|
||||
g_object_unref (priv->proxy);
|
||||
dbus_g_connection_unref (priv->bus);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue