about summary refs log tree commit diff
path: root/libnm/nm-remote-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm/nm-remote-connection.c')
-rw-r--r--libnm/nm-remote-connection.c828
1 files changed, 313 insertions, 515 deletions
diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c
index 0a46befa..d1cc90d6 100644
--- a/libnm/nm-remote-connection.c
+++ b/libnm/nm-remote-connection.c
@@ -1,27 +1,14 @@
+// SPDX-License-Identifier: LGPL-2.1+
 /*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright 2007 - 2008 Novell, Inc.
- * Copyright 2007 - 2011 Red Hat, Inc.
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
  */
 
 #include "nm-default.h"
 
 #include "nm-remote-connection.h"
 
+#include "nm-glib-aux/nm-dbus-aux.h"
 #include "nm-dbus-interface.h"
 #include "nm-utils.h"
 #include "nm-setting-connection.h"
@@ -30,8 +17,6 @@
 #include "nm-object-private.h"
 #include "nm-dbus-helpers.h"
 
-#include "introspection/org.freedesktop.NetworkManager.Settings.Connection.h"
-
 /**
  * SECTION:nm-remote-connection
  * @short_description: A connection managed by NetworkManager server
@@ -40,63 +25,44 @@
  * NetworkManager D-Bus interface.
  **/
 
-static void nm_remote_connection_connection_iface_init (NMConnectionInterface *iface);
-static void nm_remote_connection_initable_iface_init (GInitableIface *iface);
-static void nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface);
-static GInitableIface *nm_remote_connection_parent_initable_iface;
-static GAsyncInitableIface *nm_remote_connection_parent_async_initable_iface;
-
-G_DEFINE_TYPE_WITH_CODE (NMRemoteConnection, nm_remote_connection, NM_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_remote_connection_connection_iface_init);
-                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_remote_connection_initable_iface_init);
-                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_remote_connection_async_initable_iface_init);
-                         )
+/*****************************************************************************/
 
-enum {
-	PROP_0,
+NM_GOBJECT_PROPERTIES_DEFINE (NMRemoteConnection,
 	PROP_UNSAVED,
 	PROP_FLAGS,
 	PROP_FILENAME,
 	PROP_VISIBLE,
-
-	LAST_PROP
-};
+);
 
 typedef struct {
-	NMDBusSettingsConnection *proxy;
+	GCancellable *get_settings_cancellable;
 
-	gboolean unsaved;
-	guint32 flags;
 	char *filename;
+	guint32 flags;
+	bool unsaved;
 
-	gboolean visible;
+	bool visible:1;
+	bool is_initialized:1;
 } NMRemoteConnectionPrivate;
 
-#define NM_REMOTE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionPrivate))
+struct _NMRemoteConnection {
+	NMObject parent;
+	NMRemoteConnectionPrivate _priv;
+};
 
-/*****************************************************************************/
+struct _NMRemoteConnectionClass {
+	NMObjectClass parent_class;
+};
 
-static void
-update2_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
-{
-	GSimpleAsyncResult *simple = user_data;
-	GError *error = NULL;
-	GVariant *v;
-
-	if (nmdbus_settings_connection_call_update2_finish (NMDBUS_SETTINGS_CONNECTION (proxy),
-	                                                    &v,
-	                                                    result,
-	                                                    &error))
-		g_simple_async_result_set_op_res_gpointer (simple,
-		                                           v,
-		                                           (GDestroyNotify) g_variant_unref);
-	else {
-		g_dbus_error_strip_remote_error (error);
-		g_simple_async_result_take_error (simple, error);
-	}
-	g_simple_async_result_complete (simple);
-	g_object_unref (simple);
-}
+static void nm_remote_connection_connection_iface_init (NMConnectionInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (NMRemoteConnection, nm_remote_connection, NM_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_remote_connection_connection_iface_init);
+                         )
+
+#define NM_REMOTE_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMRemoteConnection, NM_IS_REMOTE_CONNECTION, NMObject)
+
+/*****************************************************************************/
 
 /**
  * nm_remote_connection_update2:
@@ -121,37 +87,33 @@ nm_remote_connection_update2 (NMRemoteConnection *connection,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
 {
-	NMRemoteConnectionPrivate *priv;
-	GSimpleAsyncResult *simple;
-	GVariantBuilder builder;
-
 	g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
 	g_return_if_fail (!settings || g_variant_is_of_type (settings, NM_VARIANT_TYPE_CONNECTION));
 	g_return_if_fail (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
 	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data,
-	                                    nm_remote_connection_update2);
-	if (cancellable)
-		g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-	if (!settings) {
-		g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION);
-		settings = g_variant_builder_end (&builder);
-	}
-	if (!args) {
-		g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
-		args = g_variant_builder_end (&builder);
-	}
-	nmdbus_settings_connection_call_update2 (priv->proxy,
-	                                         settings,
-	                                         flags,
-	                                         args,
-	                                         cancellable,
-	                                         update2_cb,
-	                                         simple);
+	if (!settings)
+		settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
+	if (!args)
+		args = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+
+	_nm_client_dbus_call (_nm_object_get_client (connection),
+	                      connection,
+	                      nm_remote_connection_update2,
+	                      cancellable,
+	                      callback,
+	                      user_data,
+	                      _nm_object_get_path (connection),
+	                      NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                      "Update2",
+	                      g_variant_new ("(@a{sa{sv}}u@a{sv})",
+	                                     settings,
+	                                     (guint32) flags,
+	                                     args),
+	                      G_VARIANT_TYPE ("(a{sv})"),
+	                      G_DBUS_CALL_FLAGS_NONE,
+	                      NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                      nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
 }
 
 /**
@@ -162,7 +124,7 @@ nm_remote_connection_update2 (NMRemoteConnection *connection,
  *
  * Gets the result of a call to nm_remote_connection_commit_changes_async().
  *
- * Returns: on success, a #GVariant of type "a{sv}" with the result. On failure,
+ * Returns: (transfer full): on success, a #GVariant of type "a{sv}" with the result. On failure,
  *   %NULL.
  **/
 GVariant *
@@ -170,15 +132,21 @@ nm_remote_connection_update2_finish (NMRemoteConnection *connection,
                                      GAsyncResult *result,
                                      GError **error)
 {
-	GSimpleAsyncResult *simple;
+	gs_unref_variant GVariant *ret = NULL;
+	GVariant *v_result;
 
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_update2), FALSE);
+	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), NULL);
+	g_return_val_if_fail (nm_g_task_is_valid (result, connection, nm_remote_connection_update2), NULL);
 
-	simple = G_SIMPLE_ASYNC_RESULT (result);
-	if (g_simple_async_result_propagate_error (simple, error))
+	ret = g_task_propagate_pointer (G_TASK (result), error);
+	if (!ret)
 		return NULL;
-	else
-		return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple));
+
+	g_variant_get (ret,
+	               "(@a{sv})",
+	               &v_result);
+
+	return v_result;
 }
 
 /*****************************************************************************/
@@ -195,6 +163,8 @@ nm_remote_connection_update2_finish (NMRemoteConnection *connection,
  * disk; if %FALSE, then only the in-memory representation will be changed.
  *
  * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ *
+ * Deprecated: 1.22, use nm_remote_connection_commit_changes_async() or GDBusConnection
  **/
 gboolean
 nm_remote_connection_commit_changes (NMRemoteConnection *connection,
@@ -202,49 +172,32 @@ nm_remote_connection_commit_changes (NMRemoteConnection *connection,
                                      GCancellable *cancellable,
                                      GError **error)
 {
-	NMRemoteConnectionPrivate *priv;
-	gs_unref_variant GVariant *result = NULL;
-	gboolean ret;
-	GVariantBuilder args;
+	gs_unref_variant GVariant *ret = NULL;
 
 	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
+	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
+
+	ret = _nm_client_dbus_call_sync (_nm_object_get_client (connection),
+	                                 cancellable,
+	                                 _nm_object_get_path (connection),
+	                                 NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                                 "Update2",
+	                                 g_variant_new ("(@a{sa{sv}}u@a{sv})",
+	                                                nm_connection_to_dbus (NM_CONNECTION (connection),
+	                                                                       NM_CONNECTION_SERIALIZE_ALL),
+	                                                (guint32) (  save_to_disk
+	                                                           ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK
+	                                                           : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY),
+	                                                g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0)),
+	                                 G_VARIANT_TYPE ("(a{sv})"),
+	                                 G_DBUS_CALL_FLAGS_NONE,
+	                                 NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                                 TRUE,
+	                                 error);
+	if (!ret)
+		return FALSE;
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	g_variant_builder_init (&args, G_VARIANT_TYPE ("a{sv}"));
-	ret = nmdbus_settings_connection_call_update2_sync (priv->proxy,
-	                                                    nm_connection_to_dbus (NM_CONNECTION (connection),
-	                                                                           NM_CONNECTION_SERIALIZE_ALL),
-	                                                    save_to_disk
-	                                                      ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK
-	                                                      : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
-	                                                    g_variant_builder_end (&args),
-	                                                    &result,
-	                                                    cancellable,
-	                                                    error);
-	if (error && *error)
-		g_dbus_error_strip_remote_error (*error);
-	return ret;
-}
-
-static void
-update_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
-{
-	GSimpleAsyncResult *simple = user_data;
-	GError *error = NULL;
-	gs_unref_variant GVariant *v = NULL;
-
-	if (nmdbus_settings_connection_call_update2_finish (NMDBUS_SETTINGS_CONNECTION (proxy),
-	                                                    &v,
-	                                                    result,
-	                                                    &error))
-		g_simple_async_result_set_op_res_gboolean (simple, TRUE);
-	else {
-		g_dbus_error_strip_remote_error (error);
-		g_simple_async_result_take_error (simple, error);
-	}
-	g_simple_async_result_complete (simple);
-	g_object_unref (simple);
+	return TRUE;
 }
 
 /**
@@ -267,30 +220,19 @@ nm_remote_connection_commit_changes_async (NMRemoteConnection *connection,
                                            GAsyncReadyCallback callback,
                                            gpointer user_data)
 {
-	NMRemoteConnectionPrivate *priv;
-	GSimpleAsyncResult *simple;
-	GVariantBuilder args;
-
 	g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
+	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data,
-	                                    nm_remote_connection_commit_changes_async);
-	if (cancellable)
-		g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-	g_variant_builder_init (&args, G_VARIANT_TYPE ("a{sv}"));
-	nmdbus_settings_connection_call_update2 (priv->proxy,
-	                                         nm_connection_to_dbus (NM_CONNECTION (connection),
-	                                                                NM_CONNECTION_SERIALIZE_ALL),
-	                                         save_to_disk
-	                                           ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK
-	                                           : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
-	                                         g_variant_builder_end (&args),
-	                                         cancellable,
-	                                         update_cb,
-	                                         simple);
+	nm_remote_connection_update2 (connection,
+	                              nm_connection_to_dbus (NM_CONNECTION (connection),
+	                                                     NM_CONNECTION_SERIALIZE_ALL),
+	                                save_to_disk
+	                              ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK
+	                              : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
+	                              NULL,
+	                              cancellable,
+	                              callback,
+	                              user_data);
 }
 
 /**
@@ -308,15 +250,10 @@ nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection,
                                             GAsyncResult *result,
                                             GError **error)
 {
-	GSimpleAsyncResult *simple;
-
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_commit_changes_async), FALSE);
+	gs_unref_variant GVariant *v_result = NULL;
 
-	simple = G_SIMPLE_ASYNC_RESULT (result);
-	if (g_simple_async_result_propagate_error (simple, error))
-		return FALSE;
-	else
-		return g_simple_async_result_get_op_res_gboolean (simple);
+	v_result = nm_remote_connection_update2_finish (connection, result, error);
+	return !!v_result;
 }
 
 /*****************************************************************************/
@@ -331,40 +268,27 @@ nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection,
  * been written to disk, or if the connection has never been saved.
  *
  * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ *
+ * Deprecated: 1.22, use nm_remote_connection_save_async() or GDBusConnection
  **/
 gboolean
 nm_remote_connection_save (NMRemoteConnection *connection,
                            GCancellable *cancellable,
                            GError **error)
 {
-	NMRemoteConnectionPrivate *priv;
-	gboolean ret;
-
 	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
+	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	ret = nmdbus_settings_connection_call_save_sync (priv->proxy, cancellable, error);
-	if (error && *error)
-		g_dbus_error_strip_remote_error (*error);
-	return ret;
-}
-
-static void
-save_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
-{
-	GSimpleAsyncResult *simple = user_data;
-	GError *error = NULL;
-
-	if (nmdbus_settings_connection_call_save_finish (NMDBUS_SETTINGS_CONNECTION (proxy),
-	                                                 result, &error))
-		g_simple_async_result_set_op_res_gboolean (simple, TRUE);
-	else {
-		g_dbus_error_strip_remote_error (error);
-		g_simple_async_result_take_error (simple, error);
-	}
-	g_simple_async_result_complete (simple);
-	g_object_unref (simple);
+	return _nm_client_dbus_call_sync_void (_nm_object_get_client (connection),
+	                                       cancellable,
+	                                       _nm_object_get_path (connection),
+	                                       NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                                       "Save",
+	                                       g_variant_new ("()"),
+	                                       G_DBUS_CALL_FLAGS_NONE,
+	                                       NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                                       TRUE,
+	                                       error);
 }
 
 /**
@@ -383,18 +307,23 @@ nm_remote_connection_save_async (NMRemoteConnection *connection,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
 {
-	NMRemoteConnectionPrivate *priv;
-	GSimpleAsyncResult *simple;
-
 	g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
+	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data,
-	                                    nm_remote_connection_save_async);
-	if (cancellable)
-		g_simple_async_result_set_check_cancellable (simple, cancellable);
-	nmdbus_settings_connection_call_save (priv->proxy, cancellable, save_cb, simple);
+	_nm_client_dbus_call (_nm_object_get_client (connection),
+	                      connection,
+	                      nm_remote_connection_save_async,
+	                      cancellable,
+	                      callback,
+	                      user_data,
+	                      _nm_object_get_path (connection),
+	                      NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                      "Save",
+	                      g_variant_new ("()"),
+	                      G_VARIANT_TYPE ("()"),
+	                      G_DBUS_CALL_FLAGS_NONE,
+	                      NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                      nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
 }
 
 /**
@@ -412,15 +341,10 @@ nm_remote_connection_save_finish (NMRemoteConnection *connection,
                                   GAsyncResult *result,
                                   GError **error)
 {
-	GSimpleAsyncResult *simple;
-
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_save_async), FALSE);
+	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
+	g_return_val_if_fail (nm_g_task_is_valid (result, connection, nm_remote_connection_save_async), FALSE);
 
-	simple = G_SIMPLE_ASYNC_RESULT (result);
-	if (g_simple_async_result_propagate_error (simple, error))
-		return FALSE;
-	else
-		return g_simple_async_result_get_op_res_gboolean (simple);
+	return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 /*****************************************************************************/
@@ -434,40 +358,26 @@ nm_remote_connection_save_finish (NMRemoteConnection *connection,
  * Deletes the connection.
  *
  * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ *
+ * Deprecated: 1.22, use nm_remote_connection_delete_async() or GDBusConnection
  **/
 gboolean
 nm_remote_connection_delete (NMRemoteConnection *connection,
                              GCancellable *cancellable,
                              GError **error)
 {
-	NMRemoteConnectionPrivate *priv;
-	gboolean ret;
-
 	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	ret = nmdbus_settings_connection_call_delete_sync (priv->proxy, cancellable, error);
-	if (error && *error)
-		g_dbus_error_strip_remote_error (*error);
-	return ret;
-}
-
-static void
-delete_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
-{
-	GSimpleAsyncResult *simple = user_data;
-	GError *error = NULL;
-
-	if (nmdbus_settings_connection_call_delete_finish (NMDBUS_SETTINGS_CONNECTION (proxy),
-	                                                   result, &error))
-		g_simple_async_result_set_op_res_gboolean (simple, TRUE);
-	else {
-		g_dbus_error_strip_remote_error (error);
-		g_simple_async_result_take_error (simple, error);
-	}
-	g_simple_async_result_complete (simple);
-	g_object_unref (simple);
+	return _nm_client_dbus_call_sync_void (_nm_object_get_client (connection),
+	                                       cancellable,
+	                                       _nm_object_get_path (connection),
+	                                       NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                                       "Delete",
+	                                       g_variant_new ("()"),
+	                                       G_DBUS_CALL_FLAGS_NONE,
+	                                       NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                                       TRUE,
+	                                       error);
 }
 
 /**
@@ -485,18 +395,23 @@ nm_remote_connection_delete_async (NMRemoteConnection *connection,
                                    GAsyncReadyCallback callback,
                                    gpointer user_data)
 {
-	NMRemoteConnectionPrivate *priv;
-	GSimpleAsyncResult *simple;
-
 	g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
+	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data,
-	                                    nm_remote_connection_delete_async);
-	if (cancellable)
-		g_simple_async_result_set_check_cancellable (simple, cancellable);
-	nmdbus_settings_connection_call_delete (priv->proxy, cancellable, delete_cb, simple);
+	_nm_client_dbus_call (_nm_object_get_client (connection),
+	                      connection,
+	                      nm_remote_connection_delete_async,
+	                      cancellable,
+	                      callback,
+	                      user_data,
+	                      _nm_object_get_path (connection),
+	                      NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                      "Delete",
+	                      g_variant_new ("()"),
+	                      G_VARIANT_TYPE ("()"),
+	                      G_DBUS_CALL_FLAGS_NONE,
+	                      NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                      nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
 }
 
 /**
@@ -514,15 +429,10 @@ nm_remote_connection_delete_finish (NMRemoteConnection *connection,
                                     GAsyncResult *result,
                                     GError **error)
 {
-	GSimpleAsyncResult *simple;
-
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_delete_async), FALSE);
+	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
+	g_return_val_if_fail (nm_g_task_is_valid (result, connection, nm_remote_connection_delete_async), FALSE);
 
-	simple = G_SIMPLE_ASYNC_RESULT (result);
-	if (g_simple_async_result_propagate_error (simple, error))
-		return FALSE;
-	else
-		return g_simple_async_result_get_op_res_gboolean (simple);
+	return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 /**
@@ -535,8 +445,10 @@ nm_remote_connection_delete_finish (NMRemoteConnection *connection,
  * Request the connection's secrets. Note that this is a blocking D-Bus call,
  * not a simple property accessor.
  *
- * Returns: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing
+ * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing
  * @connection's secrets, or %NULL on error.
+ *
+ * Deprecated: 1.22, use nm_remote_connection_get_secrets_async() or GDBusConnection
  **/
 GVariant *
 nm_remote_connection_get_secrets (NMRemoteConnection *connection,
@@ -544,42 +456,32 @@ nm_remote_connection_get_secrets (NMRemoteConnection *connection,
                                   GCancellable *cancellable,
                                   GError **error)
 {
-	NMRemoteConnectionPrivate *priv;
+	gs_unref_variant GVariant *ret = NULL;
 	GVariant *secrets;
 
 	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), NULL);
-
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	if (nmdbus_settings_connection_call_get_secrets_sync (priv->proxy,
-	                                                      setting_name,
-	                                                      &secrets,
-	                                                      cancellable, error))
-		return secrets;
-	else {
-		if (error && *error)
-			g_dbus_error_strip_remote_error (*error);
+	g_return_val_if_fail (setting_name, NULL);
+	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
+
+	ret = _nm_client_dbus_call_sync (_nm_object_get_client (connection),
+	                                 cancellable,
+	                                 _nm_object_get_path (connection),
+	                                 NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                                 "GetSecrets",
+	                                 g_variant_new ("(s)", setting_name),
+	                                 G_VARIANT_TYPE ("(a{sa{sv}})"),
+	                                 G_DBUS_CALL_FLAGS_NONE,
+	                                 NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                                 TRUE,
+	                                 error);
+	if (!ret)
 		return NULL;
-	}
-}
 
-static void
-get_secrets_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
-{
-	GSimpleAsyncResult *simple = user_data;
-	GVariant *secrets = NULL;
-	GError *error = NULL;
-
-	if (nmdbus_settings_connection_call_get_secrets_finish (NMDBUS_SETTINGS_CONNECTION (proxy),
-	                                                        &secrets, result, &error))
-		g_simple_async_result_set_op_res_gpointer (simple, secrets, (GDestroyNotify) g_variant_unref);
-	else {
-		g_dbus_error_strip_remote_error (error);
-		g_simple_async_result_take_error (simple, error);
-	}
+	g_variant_get (ret,
+	               "(@a{sa{sv}})",
+	               &secrets);
 
-	g_simple_async_result_complete (simple);
-	g_object_unref (simple);
+	return secrets;
 }
 
 /**
@@ -599,22 +501,24 @@ nm_remote_connection_get_secrets_async (NMRemoteConnection *connection,
                                         GAsyncReadyCallback callback,
                                         gpointer user_data)
 {
-	NMRemoteConnectionPrivate *priv;
-	GSimpleAsyncResult *simple;
-
 	g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
+	g_return_if_fail (setting_name);
+	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
-	priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
-
-	simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data,
-	                                    nm_remote_connection_get_secrets_async);
-	if (cancellable)
-		g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-	nmdbus_settings_connection_call_get_secrets (priv->proxy,
-	                                             setting_name,
-	                                             cancellable,
-	                                             get_secrets_cb, simple);
+	_nm_client_dbus_call (_nm_object_get_client (connection),
+	                      connection,
+	                      nm_remote_connection_get_secrets_async,
+	                      cancellable,
+	                      callback,
+	                      user_data,
+	                      _nm_object_get_path (connection),
+	                      NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	                      "GetSecrets",
+	                      g_variant_new ("(s)", setting_name),
+	                      G_VARIANT_TYPE ("(a{sa{sv}})"),
+	                      G_DBUS_CALL_FLAGS_NONE,
+	                      NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+	                      nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
 }
 
 /**
@@ -633,15 +537,21 @@ nm_remote_connection_get_secrets_finish (NMRemoteConnection *connection,
                                          GAsyncResult *result,
                                          GError **error)
 {
-	GSimpleAsyncResult *simple;
+	gs_unref_variant GVariant *ret = NULL;
+	GVariant *secrets;
 
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_get_secrets_async), FALSE);
+	g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), NULL);
+	g_return_val_if_fail (nm_g_task_is_valid (result, connection, nm_remote_connection_get_secrets_async), FALSE);
 
-	simple = G_SIMPLE_ASYNC_RESULT (result);
-	if (g_simple_async_result_propagate_error (simple, error))
+	ret = g_task_propagate_pointer (G_TASK (result), error);
+	if (!ret)
 		return NULL;
-	else
-		return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple));
+
+	g_variant_get (ret,
+	               "(@a{sa{sv}})",
+	               &secrets);
+
+	return secrets;
 }
 
 /**
@@ -718,193 +628,94 @@ nm_remote_connection_get_visible (NMRemoteConnection *connection)
 
 /*****************************************************************************/
 
-static void
-replace_settings (NMRemoteConnection *self, GVariant *new_settings)
+GCancellable *
+_nm_remote_settings_get_settings_prepare (NMRemoteConnection *self)
 {
-	GError *error = NULL;
+	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
 
-	if (!_nm_connection_replace_settings ((NMConnection *) self,
-	                                      new_settings,
-	                                      NM_SETTING_PARSE_FLAGS_BEST_EFFORT,
-	                                      &error))
-		g_clear_error (&error);
+	nm_clear_g_cancellable (&priv->get_settings_cancellable);
+	priv->get_settings_cancellable = g_cancellable_new ();
+	return priv->get_settings_cancellable;
 }
 
-static void
-updated_get_settings_cb (GObject *proxy,
-                         GAsyncResult *result,
-                         gpointer user_data)
+void
+_nm_remote_settings_get_settings_commit (NMRemoteConnection *self,
+                                         GVariant *settings)
 {
-	NMRemoteConnection *self = user_data;
 	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
-	GVariant *new_settings;
-	gboolean visible;
-
-	if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &new_settings,
-	                                                          result, NULL)) {
-		/* Connection is no longer visible to this user. */
-		nm_connection_clear_settings (NM_CONNECTION (self));
+	GError *error = NULL;
+	gboolean visible = FALSE;
+	gboolean changed = FALSE;
 
-		visible = FALSE;
-	} else {
-		replace_settings (self, new_settings);
-		g_variant_unref (new_settings);
+	g_clear_object (&priv->get_settings_cancellable);
 
-		visible = TRUE;
+	if (!priv->is_initialized) {
+		changed = TRUE;
+		priv->is_initialized = TRUE;
 	}
 
-	if (visible != priv->visible) {
+	if (settings) {
+		if (!_nm_connection_replace_settings ((NMConnection *) self,
+		                                      settings,
+		                                      NM_SETTING_PARSE_FLAGS_BEST_EFFORT,
+		                                      &error)) {
+			NML_NMCLIENT_LOG_E (_nm_object_get_client (self), "[%s] failure to update settings: %s",
+			                    _nm_object_get_path (self),
+			                    error->message);
+			g_clear_error (&error);
+		} else
+			visible = TRUE;
+	} else
+		nm_connection_clear_settings (NM_CONNECTION (self));
+
+	if (priv->visible != visible) {
 		priv->visible = visible;
-		g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_VISIBLE);
+		_nm_client_queue_notify_object (_nm_object_get_client (self),
+		                                self,
+		                                obj_properties[PROP_VISIBLE]);
+		changed = TRUE;
 	}
 
-	g_object_unref (self);
-}
-
-static void
-updated_cb (NMDBusSettingsConnection *proxy, gpointer user_data)
-{
-	NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data);
-	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
-
-	/* The connection got updated; request the replacement settings */
-	nmdbus_settings_connection_call_get_settings (priv->proxy,
-	                                              NULL,
-	                                              updated_get_settings_cb,
-	                                              g_object_ref (self));
+	if (changed)
+		_nm_client_notify_object_changed (_nm_object_get_client (self), _nm_object_get_dbobj (self));
 }
 
 /*****************************************************************************/
 
-static void
-init_dbus (NMObject *object)
-{
-	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
-	const NMPropertiesInfo property_info[] = {
-		{ NM_REMOTE_CONNECTION_UNSAVED, &priv->unsaved },
-		{ NM_REMOTE_CONNECTION_FLAGS, &priv->flags },
-		{ NM_REMOTE_CONNECTION_FILENAME, &priv->filename },
-		{ NULL },
-	};
-
-	NM_OBJECT_CLASS (nm_remote_connection_parent_class)->init_dbus (object);
-
-	_nm_object_register_properties (object,
-	                                NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
-	                                property_info);
-}
-
 static gboolean
-init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
+is_ready (NMObject *nmobj)
 {
-	NMRemoteConnection *self = NM_REMOTE_CONNECTION (initable);
-	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable);
-	GVariant *settings;
-
-	priv->proxy = NMDBUS_SETTINGS_CONNECTION (_nm_object_get_proxy (NM_OBJECT (initable), NM_DBUS_INTERFACE_SETTINGS_CONNECTION));
-	g_signal_connect_object (priv->proxy, "updated", G_CALLBACK (updated_cb), initable, 0);
-
-	if (nmdbus_settings_connection_call_get_settings_sync (priv->proxy,
-	                                                       &settings,
-	                                                       cancellable,
-	                                                       NULL)) {
-		priv->visible = TRUE;
-		replace_settings (self, settings);
-		g_variant_unref (settings);
-	}
+	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (nmobj);
 
-	if (!nm_remote_connection_parent_initable_iface->init (initable, cancellable, error))
-		return FALSE;
+	if (!priv->is_initialized)
+		return FALSE;;
 
-	return TRUE;
+	return NM_OBJECT_CLASS (nm_remote_connection_parent_class)->is_ready (nmobj);
 }
 
-typedef struct {
-	NMRemoteConnection *connection;
-	GCancellable *cancellable;
-	GSimpleAsyncResult *result;
-	GAsyncInitable *initable;
-	int io_priority;
-} 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);
-
-	g_simple_async_result_complete (init_data->result);
-	g_object_unref (init_data->result);
-	g_clear_object (&init_data->cancellable);
-	g_slice_free (NMRemoteConnectionInitData, init_data);
-}
-
-static void
-init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_data)
-{
-	NMRemoteConnectionInitData *init_data = user_data;
-	GError *error = NULL;
-
-	init_async_complete (init_data, error);
-}
+/*****************************************************************************/
 
 static void
-init_get_settings_cb (GObject *proxy,
-                      GAsyncResult *result,
-                      gpointer user_data)
+register_client (NMObject *nmobj,
+                 NMClient *client,
+                 NMLDBusObject *dbobj)
 {
-	NMRemoteConnectionInitData *init_data = user_data;
-	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->initable);
-	GVariant *settings;
-	GError *error = NULL;
-
-	if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &settings,
-	                                                          result, &error)) {
-		g_error_free (error);
-	} else {
-		priv->visible = TRUE;
-		replace_settings (NM_REMOTE_CONNECTION (init_data->initable), settings);
-		g_variant_unref (settings);
-	}
-
-	nm_remote_connection_parent_async_initable_iface->
-		init_async (init_data->initable, init_data->io_priority, init_data->cancellable, init_async_parent_inited, init_data);
+	NM_OBJECT_CLASS (nm_remote_connection_parent_class)->register_client (nmobj, client, dbobj);
+	nm_connection_set_path (NM_CONNECTION (nmobj),
+	                        dbobj->dbus_path->str);
+	_nm_client_get_settings_call (client, dbobj);
 }
 
 static void
-init_async (GAsyncInitable *initable, int io_priority,
-            GCancellable *cancellable, GAsyncReadyCallback callback,
-            gpointer user_data)
+unregister_client (NMObject *nmobj,
+                   NMClient *client,
+                   NMLDBusObject *dbobj)
 {
-	NMRemoteConnectionInitData *init_data;
-	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable);
-
-	init_data = g_slice_new0 (NMRemoteConnectionInitData);
-	init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
-	init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
-	                                               user_data, init_async);
-	if (cancellable)
-		g_simple_async_result_set_check_cancellable (init_data->result, cancellable);
-	init_data->initable = initable;
-	init_data->io_priority = io_priority;
-
-	priv->proxy = NMDBUS_SETTINGS_CONNECTION (_nm_object_get_proxy (NM_OBJECT (initable),
-	                                          NM_DBUS_INTERFACE_SETTINGS_CONNECTION));
-
-	g_signal_connect_object (priv->proxy, "updated",
-	                         G_CALLBACK (updated_cb), initable, 0);
-
-	nmdbus_settings_connection_call_get_settings (NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->initable)->proxy,
-	                                              init_data->cancellable,
-	                                              init_get_settings_cb, init_data);
+	nm_clear_g_cancellable (&NM_REMOTE_CONNECTION_GET_PRIVATE (nmobj)->get_settings_cancellable);
+	NM_OBJECT_CLASS (nm_remote_connection_parent_class)->unregister_client (nmobj, client, dbobj);
 }
 
-static void
-nm_remote_connection_init (NMRemoteConnection *self)
-{
-}
+/*****************************************************************************/
 
 static void
 get_property (GObject *object, guint prop_id,
@@ -929,13 +740,11 @@ get_property (GObject *object, guint prop_id,
 	}
 }
 
+/*****************************************************************************/
+
 static void
-constructed (GObject *object)
+nm_remote_connection_init (NMRemoteConnection *self)
 {
-	G_OBJECT_CLASS (nm_remote_connection_parent_class)->constructed (object);
-
-	nm_connection_set_path (NM_CONNECTION (object),
-	                        nm_object_get_path (NM_OBJECT (object)));
 }
 
 static void
@@ -943,40 +752,46 @@ dispose (GObject *object)
 {
 	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
 
-	g_clear_object (&priv->proxy);
 	nm_clear_g_free (&priv->filename);
 
 	G_OBJECT_CLASS (nm_remote_connection_parent_class)->dispose (object);
 }
 
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings_connection = NML_DBUS_META_IFACE_INIT_PROP (
+	NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+	nm_remote_connection_get_type,
+	NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+	NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+		NML_DBUS_META_PROPERTY_INIT_S ("Filename", PROP_FILENAME, NMRemoteConnection, _priv.filename ),
+		NML_DBUS_META_PROPERTY_INIT_U ("Flags",    PROP_FLAGS,    NMRemoteConnection, _priv.flags    ),
+		NML_DBUS_META_PROPERTY_INIT_B ("Unsaved",  PROP_UNSAVED,  NMRemoteConnection, _priv.unsaved  ),
+	),
+);
+
 static void
-nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
+nm_remote_connection_class_init (NMRemoteConnectionClass *klass)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (remote_class);
-	NMObjectClass *nm_object_class = NM_OBJECT_CLASS (remote_class);
-
-	g_type_class_add_private (object_class, sizeof (NMRemoteConnectionPrivate));
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
 
-	/* virtual methods */
-	object_class->constructed = constructed;
 	object_class->get_property = get_property;
-	object_class->dispose = dispose;
+	object_class->dispose      = dispose;
 
-	nm_object_class->init_dbus = init_dbus;
+	nm_object_class->is_ready          = is_ready;
+	nm_object_class->register_client   = register_client;
+	nm_object_class->unregister_client = unregister_client;
 
-	/* Properties */
 	/**
 	 * 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.
 	 **/
-	g_object_class_install_property
-		(object_class, PROP_UNSAVED,
-		 g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, "", "",
-		                       FALSE,
-		                       G_PARAM_READABLE |
-		                       G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_UNSAVED] =
+	    g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, "", "",
+	                          FALSE,
+	                          G_PARAM_READABLE |
+	                          G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMRemoteConnection:flags:
@@ -986,12 +801,11 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
 	 *
 	 * Since: 1.12
 	 **/
-	g_object_class_install_property
-		(object_class, PROP_FLAGS,
-		 g_param_spec_uint (NM_REMOTE_CONNECTION_FLAGS, "", "",
-		                    0, G_MAXUINT32, 0,
-		                    G_PARAM_READABLE |
-		                    G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_FLAGS] =
+	    g_param_spec_uint (NM_REMOTE_CONNECTION_FLAGS, "", "",
+	                       0, G_MAXUINT32, 0,
+	                       G_PARAM_READABLE |
+	                       G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMRemoteConnection:filename:
@@ -1001,12 +815,11 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
 	 *
 	 * Since: 1.12
 	 **/
-	g_object_class_install_property
-	        (object_class, PROP_FILENAME,
-	         g_param_spec_string (NM_REMOTE_CONNECTION_FILENAME, "", "",
-	                              NULL,
-	                              G_PARAM_READABLE |
-	                              G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_FILENAME] =
+	    g_param_spec_string (NM_REMOTE_CONNECTION_FILENAME, "", "",
+	                         NULL,
+	                         G_PARAM_READABLE |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMRemoteConnection:visible:
@@ -1019,31 +832,16 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
 	 * to callers, but it is possible for a connection's visibility to change
 	 * after you already have a reference to it.)
 	 **/
-	g_object_class_install_property
-		(object_class, PROP_VISIBLE,
-		 g_param_spec_boolean (NM_REMOTE_CONNECTION_VISIBLE, "", "",
-		                       FALSE,
-		                       G_PARAM_READABLE |
-		                       G_PARAM_STATIC_STRINGS));
-}
+	obj_properties[PROP_VISIBLE] =
+	    g_param_spec_boolean (NM_REMOTE_CONNECTION_VISIBLE, "", "",
+	                          FALSE,
+	                          G_PARAM_READABLE |
+	                          G_PARAM_STATIC_STRINGS);
 
-static void
-nm_remote_connection_connection_iface_init (NMConnectionInterface *iface)
-{
-}
-
-static void
-nm_remote_connection_initable_iface_init (GInitableIface *iface)
-{
-	nm_remote_connection_parent_initable_iface = g_type_interface_peek_parent (iface);
-
-	iface->init = init_sync;
+	_nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_settings_connection);
 }
 
 static void
-nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface)
+nm_remote_connection_connection_iface_init (NMConnectionInterface *iface)
 {
-	nm_remote_connection_parent_async_initable_iface = g_type_interface_peek_parent (iface);
-
-	iface->init_async = init_async;
 }