diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index b4342f4b22..4b5fc909ec 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -213,11 +213,15 @@ global: nm_object_get_path; nm_object_get_type; nm_remote_connection_commit_changes; + nm_remote_connection_commit_changes_unsaved; nm_remote_connection_delete; nm_remote_connection_get_secrets; nm_remote_connection_get_type; + nm_remote_connection_get_unsaved; nm_remote_connection_new; + nm_remote_connection_save; nm_remote_settings_add_connection; + nm_remote_settings_add_connection_unsaved; nm_remote_settings_error_get_type; nm_remote_settings_error_quark; nm_remote_settings_get_connection_by_path; diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 140f79636c..f72b71e91f 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -51,6 +51,7 @@ enum { PROP_BUS, PROP_DBUS_CONNECTION, PROP_DBUS_PATH, + PROP_UNSAVED, LAST_PROP }; @@ -75,8 +76,12 @@ typedef struct { typedef struct { DBusGConnection *bus; DBusGProxy *proxy; + DBusGProxy *props_proxy; GSList *calls; + gboolean inited; + gboolean unsaved; + gboolean visible; } NMRemoteConnectionPrivate; @@ -84,6 +89,29 @@ typedef struct { /****************************************************************/ +static void +_nm_remote_connection_ensure_inited (NMRemoteConnection *self) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + GError *error = NULL; + + if (!priv->inited) { + if (!g_initable_init (G_INITABLE (self), NULL, &error)) { + /* Don't warn when the call times out because the settings service can't + * be activated or whatever. + */ + if (!g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) { + g_warning ("%s: (NMRemoteConnection) error initializing: %s\n", + __func__, error->message); + } + g_error_free (error); + } + priv->inited = TRUE; + } +} + +/****************************************************************/ + static void remote_call_complete (NMRemoteConnection *self, RemoteCall *call) { @@ -99,16 +127,15 @@ remote_call_complete (NMRemoteConnection *self, RemoteCall *call) } static void -update_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) +result_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) { RemoteCall *call = user_data; - NMRemoteConnectionCommitFunc func = (NMRemoteConnectionCommitFunc) call->callback; + NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; GError *error = NULL; - dbus_g_proxy_end_call (proxy, proxy_call, &error, - G_TYPE_INVALID); - if (func != NULL) - (*func)(call->self, error, call->user_data); + dbus_g_proxy_end_call (proxy, proxy_call, &error, G_TYPE_INVALID); + if (func) + (*func) (call->self, error, call->user_data); g_clear_error (&error); remote_call_complete (call->self, call); } @@ -120,12 +147,12 @@ update_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) * commit completes * @user_data: (closure): caller-specific data to be passed to @callback * - * Save any local changes to the settings and properties of this connection and - * save them in the settings service. + * Send any local changes to the settings and properties of this connection to + * NetworkManager, which will immediately save them to disk. **/ void nm_remote_connection_commit_changes (NMRemoteConnection *self, - NMRemoteConnectionCommitFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data) { NMRemoteConnectionPrivate *priv; @@ -145,7 +172,7 @@ nm_remote_connection_commit_changes (NMRemoteConnection *self, settings = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ALL); call->call = dbus_g_proxy_begin_call (priv->proxy, "Update", - update_cb, call, NULL, + result_cb, call, NULL, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, settings, G_TYPE_INVALID); g_assert (call->call); @@ -154,19 +181,84 @@ nm_remote_connection_commit_changes (NMRemoteConnection *self, g_hash_table_destroy (settings); } -static void -delete_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) +/** + * nm_remote_connection_commit_changes_unsaved: + * @connection: the #NMRemoteConnection + * @callback: (scope async) (allow-none): a function to be called when the + * commit completes + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Send any local changes to the settings and properties of this connection to + * NetworkManager. The changes are not saved to disk until either + * nm_remote_connection_save() or nm_remote_connection_commit_changes() is + * called. + * + * Since: 0.9.10 + **/ +void +nm_remote_connection_commit_changes_unsaved (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data) { - RemoteCall *call = user_data; - NMRemoteConnectionDeleteFunc func = (NMRemoteConnectionDeleteFunc) call->callback; - GError *error = NULL; + NMRemoteConnectionPrivate *priv; + GHashTable *settings = NULL; + RemoteCall *call; - dbus_g_proxy_end_call (proxy, proxy_call, &error, - G_TYPE_INVALID); - if (func != NULL) - (*func)(call->self, error, call->user_data); - g_clear_error (&error); - remote_call_complete (call->self, call); + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + g_return_if_fail (callback != NULL); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + call = g_malloc0 (sizeof (RemoteCall)); + call->self = connection; + call->callback = (GFunc) callback; + call->user_data = user_data; + + settings = nm_connection_to_hash (NM_CONNECTION (connection), NM_SETTING_HASH_FLAG_ALL); + + call->call = dbus_g_proxy_begin_call (priv->proxy, "UpdateUnsaved", + result_cb, call, NULL, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, settings, + G_TYPE_INVALID); + g_assert (call->call); + priv->calls = g_slist_append (priv->calls, call); + + g_hash_table_destroy (settings); +} + +/** + * nm_remote_connection_save: + * @connection: the #NMRemoteConnection + * @callback: (scope async) (allow-none): a function to be called when the + * save completes + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Saves the connection to disk if the connection has changes that have not yet + * been written to disk, or if the connection has never been saved. + * + * Since: 0.9.10 + **/ +void +nm_remote_connection_save (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data) +{ + NMRemoteConnectionPrivate *priv; + RemoteCall *call; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + g_return_if_fail (callback != NULL); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + call = g_malloc0 (sizeof (RemoteCall)); + call->self = connection; + call->callback = (GFunc) callback; + call->user_data = user_data; + + call->call = dbus_g_proxy_begin_call (priv->proxy, "Save", result_cb, call, NULL, G_TYPE_INVALID); + g_assert (call->call); + priv->calls = g_slist_append (priv->calls, call); } /** @@ -179,7 +271,7 @@ delete_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) **/ void nm_remote_connection_delete (NMRemoteConnection *self, - NMRemoteConnectionDeleteFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data) { NMRemoteConnectionPrivate *priv; @@ -195,7 +287,7 @@ nm_remote_connection_delete (NMRemoteConnection *self, call->user_data = user_data; call->call = dbus_g_proxy_begin_call (priv->proxy, "Delete", - delete_cb, call, NULL, + result_cb, call, NULL, G_TYPE_INVALID); g_assert (call->call); priv->calls = g_slist_append (priv->calls, call); @@ -254,6 +346,25 @@ nm_remote_connection_get_secrets (NMRemoteConnection *self, priv->calls = g_slist_append (priv->calls, call); } +/** + * nm_remote_connection_get_unsaved: + * @connection: the #NMRemoteConnection + * + * Returns: %TRUE if the remote connection contains changes that have not + * been saved to disk, %FALSE if the connection is the same as its on-disk + * representation. + * + * Since: 0.9.10 + **/ +gboolean +nm_remote_connection_get_unsaved (NMRemoteConnection *connection) +{ + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + _nm_remote_connection_ensure_inited (connection); + return NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->unsaved; +} + /****************************************************************/ static void @@ -334,6 +445,25 @@ removed_cb (DBusGProxy *proxy, gpointer user_data) g_signal_emit (G_OBJECT (user_data), signals[REMOVED], 0); } +static void +properties_changed_cb (DBusGProxy *proxy, + GHashTable *properties, + gpointer user_data) +{ + NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data); + GHashTableIter iter; + const char *key; + GValue *value; + + g_hash_table_iter_init (&iter, properties); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + if (!strcmp (key, "Unsaved")) { + NM_REMOTE_CONNECTION_GET_PRIVATE (self)->unsaved = g_value_get_boolean (value); + g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_UNSAVED); + } + } +} + /****************************************************************/ /** @@ -377,23 +507,52 @@ constructed (GObject *object) dbus_g_proxy_add_signal (priv->proxy, "Removed", G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, "Removed", G_CALLBACK (removed_cb), object, NULL); + + /* Monitor properties */ + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->proxy, "PropertiesChanged", + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->proxy, "PropertiesChanged", + G_CALLBACK (properties_changed_cb), + object, + NULL); + + priv->props_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + nm_connection_get_path (NM_CONNECTION (object)), + DBUS_INTERFACE_PROPERTIES); + g_assert (priv->props_proxy); } static gboolean init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable); - GHashTable *settings; + GHashTable *hash; if (!dbus_g_proxy_call (priv->proxy, "GetSettings", error, G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &hash, G_TYPE_INVALID)) return FALSE; - priv->visible = TRUE; - replace_settings (NM_REMOTE_CONNECTION (initable), settings); - g_hash_table_destroy (settings); + replace_settings (NM_REMOTE_CONNECTION (initable), hash); + g_hash_table_destroy (hash); + + /* Get properties */ + hash = NULL; + if (!dbus_g_proxy_call (priv->props_proxy, "GetAll", error, + G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_CONNECTION, + G_TYPE_INVALID, + DBUS_TYPE_G_MAP_OF_VARIANT, &hash, + G_TYPE_INVALID)) + return FALSE; + properties_changed_cb (priv->props_proxy, hash, NM_REMOTE_CONNECTION (initable)); + g_hash_table_destroy (hash); + return TRUE; } @@ -402,6 +561,38 @@ typedef struct { GSimpleAsyncResult *result; } NMRemoteConnectionInitData; +static void +init_async_complete (NMRemoteConnectionInitData *init_data, GError *error) +{ + if (error) + g_simple_async_result_take_error (init_data->result, error); + else { + g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection)->inited = TRUE; + } + + g_simple_async_result_complete (init_data->result); + g_object_unref (init_data->result); + g_slice_free (NMRemoteConnectionInitData, init_data); +} + +static void +init_async_got_properties (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +{ + NMRemoteConnectionInitData *init_data = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection); + GHashTable *props; + GError *error = NULL; + + if (dbus_g_proxy_end_call (proxy, call, &error, + DBUS_TYPE_G_MAP_OF_VARIANT, &props, + G_TYPE_INVALID)) { + properties_changed_cb (priv->props_proxy, props, init_data->connection); + g_hash_table_destroy (props); + } + init_async_complete (init_data, error); +} + static void init_get_settings_cb (DBusGProxy *proxy, DBusGProxyCall *call, @@ -416,17 +607,19 @@ init_get_settings_cb (DBusGProxy *proxy, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, G_TYPE_INVALID); if (error) { - g_simple_async_result_take_error (init_data->result, error); - } else { - priv->visible = TRUE; - replace_settings (init_data->connection, settings); - g_hash_table_destroy (settings); - g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + init_async_complete (init_data, error); + return; } - g_simple_async_result_complete (init_data->result); - g_object_unref (init_data->result); - g_slice_free (NMRemoteConnectionInitData, init_data); + priv->visible = TRUE; + replace_settings (init_data->connection, settings); + g_hash_table_destroy (settings); + + /* Grab properties */ + dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", + init_async_got_properties, init_data, NULL, + G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_CONNECTION, + G_TYPE_INVALID); } static void @@ -446,7 +639,6 @@ init_async (GAsyncInitable *initable, int io_priority, dbus_g_proxy_begin_call (priv->proxy, "GetSettings", init_get_settings_cb, init_data, NULL, G_TYPE_INVALID); - } static gboolean @@ -502,6 +694,22 @@ constructor (GType type, guint n_construct_properties, constructor (type, n_construct_properties, construct_properties); } +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + _nm_remote_connection_ensure_inited (NM_REMOTE_CONNECTION (object)); + + switch (prop_id) { + case PROP_UNSAVED: + g_value_set_boolean (value, NM_REMOTE_CONNECTION_GET_PRIVATE (object)->unsaved); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -541,6 +749,7 @@ dispose (GObject *object) remote_call_complete (self, priv->calls->data); g_clear_object (&priv->proxy); + g_clear_object (&priv->props_proxy); if (priv->bus) { dbus_g_connection_unref (priv->bus); @@ -559,6 +768,7 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) /* virtual methods */ object_class->constructor = constructor; + object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; object_class->constructed = constructed; @@ -588,6 +798,21 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + /** + * NMRemoteConnection:unsaved: + * + * %TRUE if the remote connection contains changes that have not been saved + * to disk, %FALSE if the connection is the same as its on-disk representation. + * + * Since: 0.9.10 + **/ + g_object_class_install_property (object_class, PROP_UNSAVED, + g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, + "Unsaved", + "Unsaved", + FALSE, + G_PARAM_READABLE)); + /* Signals */ /** * NMRemoteConnection::updated: diff --git a/libnm-glib/nm-remote-connection.h b/libnm-glib/nm-remote-connection.h index eebf916053..3e5ae0553f 100644 --- a/libnm-glib/nm-remote-connection.h +++ b/libnm-glib/nm-remote-connection.h @@ -38,6 +38,10 @@ G_BEGIN_DECLS #define NM_IS_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_REMOTE_CONNECTION)) #define NM_REMOTE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) +/* Properties */ +#define NM_REMOTE_CONNECTION_UNSAVED "unsaved" + +/* Signals */ #define NM_REMOTE_CONNECTION_UPDATED "updated" #define NM_REMOTE_CONNECTION_REMOVED "removed" @@ -64,30 +68,21 @@ typedef struct { } NMRemoteConnectionClass; /** - * NMRemoteConnectionCommitFunc: - * @connection: the connection for which updates are to be committed + * NMRemoteConnectionResultFunc: + * @connection: the connection for which an operation was performed * @error: on failure, a descriptive error - * @user_data: user data passed to nm_remote_connection_commit_changes() + * @user_data: user data passed to function which began the operation * - * Called when NetworkManager has committed outstanding changes to a connection - * to backing storage as a result of nm_remote_connection_commit_changes(). + * Called when NetworkManager has finished an asynchronous operation on a + * connection, like commit changes, deleting, saving, etc. */ -typedef void (*NMRemoteConnectionCommitFunc) (NMRemoteConnection *connection, +typedef void (*NMRemoteConnectionResultFunc) (NMRemoteConnection *connection, GError *error, gpointer user_data); -/** - * NMRemoteConnectionDeleteFunc: - * @connection: the connection to be deleted - * @error: on failure, a descriptive error - * @user_data: user data passed to nm_remote_connection_delete() - * - * Called when NetworkManager has deleted a connection as a result of - * nm_remote_connection_delete(). - */ -typedef void (*NMRemoteConnectionDeleteFunc) (NMRemoteConnection *connection, - GError *error, - gpointer user_data); +/* Backwards compatibility */ +typedef NMRemoteConnectionResultFunc NMRemoteConnectionCommitFunc; +typedef NMRemoteConnectionResultFunc NMRemoteConnectionDeleteFunc; /** * NMRemoteConnectionGetSecretsFunc: @@ -112,17 +107,28 @@ NMRemoteConnection *nm_remote_connection_new (DBusGConnection *bus, const char *path); void nm_remote_connection_commit_changes (NMRemoteConnection *connection, - NMRemoteConnectionCommitFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data); +void nm_remote_connection_commit_changes_unsaved (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data); + +void nm_remote_connection_save (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data); + void nm_remote_connection_delete (NMRemoteConnection *connection, - NMRemoteConnectionDeleteFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data); void nm_remote_connection_get_secrets (NMRemoteConnection *connection, const char *setting_name, NMRemoteConnectionGetSecretsFunc callback, gpointer user_data); + +gboolean nm_remote_connection_get_unsaved (NMRemoteConnection *connection); + G_END_DECLS #endif /* __NM_REMOTE_CONNECTION__ */ diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index a911866919..9dc74ef934 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -363,9 +363,10 @@ connection_inited (GObject *source, GAsyncResult *result, gpointer user_data) g_signal_emit (self, signals[NEW_CONNECTION], 0, remote); } else { if (addinfo) { - local = g_error_new_literal (NM_REMOTE_SETTINGS_ERROR, - NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, - "Connection not visible or not available"); + local = g_error_new (NM_REMOTE_SETTINGS_ERROR, + NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, + "Connection not visible or not available: %s", + error ? error->message : "(unknown)"); add_connection_info_complete (self, addinfo, local); g_error_free (local); } @@ -527,7 +528,7 @@ add_connection_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data * @user_data: (closure): caller-specific data passed to @callback * * Requests that the remote settings service add the given settings to a new - * connection. + * connection. The connection is immediately written to disk. * * Returns: TRUE if the request was successful, FALSE if it failed **/ @@ -571,6 +572,63 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, return TRUE; } +/** + * nm_remote_settings_add_connection_unsaved: + * @settings: the %NMRemoteSettings + * @connection: the connection to add. Note that this object's settings will be + * added, not the object itself + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service add the given settings to a new + * connection. The connection is not written to disk, which may be done at + * a later time by calling the connection's nm_remote_connection_commit_changes() + * method. + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + * + * Since: 0.9.10 + **/ +gboolean +nm_remote_settings_add_connection_unsaved (NMRemoteSettings *settings, + NMConnection *connection, + NMRemoteSettingsAddConnectionFunc callback, + gpointer user_data) +{ + NMRemoteSettingsPrivate *priv; + AddConnectionInfo *info; + GHashTable *new_settings; + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + _nm_remote_settings_ensure_inited (settings); + + if (!priv->service_running) + return FALSE; + + info = g_malloc0 (sizeof (AddConnectionInfo)); + info->self = settings; + info->callback = callback; + info->callback_data = user_data; + + new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + dbus_g_proxy_begin_call (priv->proxy, "AddConnectionUnsaved", + add_connection_done, + info, + NULL, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, + G_TYPE_INVALID); + g_hash_table_destroy (new_settings); + + priv->add_list = g_slist_append (priv->add_list, info); + + return TRUE; +} + static void clear_one_hash (GHashTable *table) { diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index 20235c0d1b..c8d1b3e5b4 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -127,6 +127,11 @@ gboolean nm_remote_settings_add_connection (NMRemoteSettings *settings, NMRemoteSettingsAddConnectionFunc callback, gpointer user_data); +gboolean nm_remote_settings_add_connection_unsaved (NMRemoteSettings *settings, + NMConnection *connection, + NMRemoteSettingsAddConnectionFunc callback, + gpointer user_data); + gboolean nm_remote_settings_save_hostname (NMRemoteSettings *settings, const char *hostname, NMRemoteSettingsSaveHostnameFunc callback, diff --git a/libnm-glib/tests/test-remote-settings-service.py b/libnm-glib/tests/test-remote-settings-service.py index f0103b97e2..439073ad28 100755 --- a/libnm-glib/tests/test-remote-settings-service.py +++ b/libnm-glib/tests/test-remote-settings-service.py @@ -31,7 +31,25 @@ class Connection(dbus.service.Object): self.settings = settings self.remove_func = remove_func self.visible = True + self.props = {} + self.props['Unsaved'] = False + # Properties interface + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') + def GetAll(self, iface): + if iface != IFACE_CONNECTION: + raise UnknownInterfaceException() + return self.props + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') + def Get(self, iface, name): + if iface != IFACE_CONNECTION: + raise UnknownInterfaceException() + if not name in self.props.keys(): + raise UnknownPropertyException() + return self.props[name] + + # Connection methods @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}') def GetSettings(self): if not self.visible: