Replace EGdbusBook with EDBusAddressBook.
authorMatthew Barnes <mbarnes@redhat.com>
Fri, 25 Jan 2013 01:04:14 +0000 (20:04 -0500)
committerMatthew Barnes <mbarnes@redhat.com>
Tue, 29 Jan 2013 22:19:23 +0000 (17:19 -0500)
addressbook/libebook/e-book-client.c
addressbook/libebook/e-book-client.h
addressbook/libedata-book/e-book-backend.c
addressbook/libedata-book/e-book-backend.h
addressbook/libedata-book/e-data-book.c
addressbook/libedata-book/e-data-book.h
addressbook/libegdbus/Makefile.am
addressbook/libegdbus/e-gdbus-book.c [deleted file]
addressbook/libegdbus/e-gdbus-book.h [deleted file]
docs/reference/addressbook/libedata-book/libedata-book-sections.txt

index 4767464..c2e4130 100644 (file)
@@ -27,6 +27,7 @@
 #include <gio/gio.h>
 
 /* Private D-Bus classes. */
+#include <e-dbus-address-book.h>
 #include <e-dbus-address-book-factory.h>
 
 #include <libedataserver/libedataserver.h>
 #include "e-contact.h"
 #include "e-name-western.h"
 
-#include "e-gdbus-book.h"
-
 #define E_BOOK_CLIENT_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_BOOK_CLIENT, EBookClientPrivate))
 
+/* Set this to a sufficiently large value
+ * to cover most long-running operations. */
+#define DBUS_PROXY_TIMEOUT_MS (3 * 60 * 1000)  /* 3 minutes */
+
+typedef struct _AsyncContext AsyncContext;
+typedef struct _SignalClosure SignalClosure;
+typedef struct _RunInThreadClosure RunInThreadClosure;
+
 struct _EBookClientPrivate {
-       GDBusProxy *dbus_proxy;
+       EDBusAddressBook *dbus_proxy;
+       GMainContext *main_context;
        guint gone_signal_id;
+
+       gulong dbus_proxy_error_handler_id;
+       gulong dbus_proxy_notify_handler_id;
+};
+
+struct _AsyncContext {
+       EContact *contact;
+       EBookClientView *client_view;
+       GSList *object_list;
+       GSList *string_list;
+       gchar *sexp;
+       gchar *uid;
+};
+
+struct _SignalClosure {
+       EClient *client;
+       gchar *property_name;
+       gchar *error_message;
+};
+
+struct _RunInThreadClosure {
+       GSimpleAsyncThreadFunc func;
+       GSimpleAsyncResult *simple;
+       GCancellable *cancellable;
 };
 
-G_DEFINE_TYPE (EBookClient, e_book_client, E_TYPE_CLIENT)
+/* Forward Declarations */
+static void    e_book_client_initable_init
+                                       (GInitableIface *interface);
+static void    e_book_client_async_initable_init
+                                       (GAsyncInitableIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+       EBookClient,
+       e_book_client,
+       E_TYPE_CLIENT,
+       G_IMPLEMENT_INTERFACE (
+               G_TYPE_INITABLE,
+               e_book_client_initable_init)
+       G_IMPLEMENT_INTERFACE (
+               G_TYPE_ASYNC_INITABLE,
+               e_book_client_async_initable_init))
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+       if (async_context->contact != NULL)
+               g_object_unref (async_context->contact);
+
+       if (async_context->client_view != NULL)
+               g_object_unref (async_context->client_view);
+
+       g_slist_free_full (
+               async_context->object_list,
+               (GDestroyNotify) g_object_unref);
+
+       g_slist_free_full (
+               async_context->string_list,
+               (GDestroyNotify) g_free);
+
+       g_free (async_context->sexp);
+       g_free (async_context->uid);
+
+       g_slice_free (AsyncContext, async_context);
+}
+
+static void
+signal_closure_free (SignalClosure *signal_closure)
+{
+       g_object_unref (signal_closure->client);
+
+       g_free (signal_closure->property_name);
+       g_free (signal_closure->error_message);
+
+       g_slice_free (SignalClosure, signal_closure);
+}
+
+static void
+run_in_thread_closure_free (RunInThreadClosure *run_in_thread_closure)
+{
+       if (run_in_thread_closure->simple != NULL)
+               g_object_unref (run_in_thread_closure->simple);
+
+       if (run_in_thread_closure->cancellable != NULL)
+               g_object_unref (run_in_thread_closure->cancellable);
+
+       g_slice_free (RunInThreadClosure, run_in_thread_closure);
+}
 
 /*
  * Well-known book backend properties:
@@ -285,6 +378,107 @@ gdbus_book_factory_activate (GCancellable *cancellable,
        return TRUE;
 }
 
+static gpointer
+book_client_dbus_thread (gpointer user_data)
+{
+       GMainContext *main_context = user_data;
+       GMainLoop *main_loop;
+
+       g_main_context_push_thread_default (main_context);
+
+       main_loop = g_main_loop_new (main_context, FALSE);
+       g_main_loop_run (main_loop);
+       g_main_loop_unref (main_loop);
+
+       g_main_context_pop_thread_default (main_context);
+
+       g_main_context_unref (main_context);
+
+       return NULL;
+}
+
+static gpointer
+book_client_dbus_thread_init (gpointer unused)
+{
+       GMainContext *main_context;
+
+       main_context = g_main_context_new ();
+
+       /* This thread terminates when the process itself terminates, so
+        * no need to worry about unreferencing the returned GThread. */
+       g_thread_new (
+               "book-client-dbus-thread",
+               book_client_dbus_thread,
+               g_main_context_ref (main_context));
+
+       return main_context;
+}
+
+static GMainContext *
+book_client_ref_dbus_main_context (void)
+{
+       static GOnce book_client_dbus_thread_once = G_ONCE_INIT;
+
+       g_once (
+               &book_client_dbus_thread_once,
+               book_client_dbus_thread_init, NULL);
+
+       return g_main_context_ref (book_client_dbus_thread_once.retval);
+}
+
+static gboolean
+book_client_run_in_dbus_thread_idle_cb (gpointer user_data)
+{
+       RunInThreadClosure *closure = user_data;
+       GObject *source_object;
+       GAsyncResult *result;
+
+       result = G_ASYNC_RESULT (closure->simple);
+       source_object = g_async_result_get_source_object (result);
+
+       closure->func (
+               closure->simple,
+               source_object,
+               closure->cancellable);
+
+       if (source_object != NULL)
+               g_object_unref (source_object);
+
+       g_simple_async_result_complete_in_idle (closure->simple);
+
+       return FALSE;
+}
+
+static void
+book_client_run_in_dbus_thread (GSimpleAsyncResult *simple,
+                                GSimpleAsyncThreadFunc func,
+                                gint io_priority,
+                                GCancellable *cancellable)
+{
+       RunInThreadClosure *closure;
+       GMainContext *main_context;
+       GSource *idle_source;
+
+       main_context = book_client_ref_dbus_main_context ();
+
+       closure = g_slice_new0 (RunInThreadClosure);
+       closure->func = func;
+       closure->simple = g_object_ref (simple);
+
+       if (G_IS_CANCELLABLE (cancellable))
+               closure->cancellable = g_object_ref (cancellable);
+
+       idle_source = g_idle_source_new ();
+       g_source_set_priority (idle_source, io_priority);
+       g_source_set_callback (
+               idle_source, book_client_run_in_dbus_thread_idle_cb,
+               closure, (GDestroyNotify) run_in_thread_closure_free);
+       g_source_attach (idle_source, main_context);
+       g_source_unref (idle_source);
+
+       g_main_context_unref (main_context);
+}
+
 static void gdbus_book_client_disconnect (EBookClient *client);
 
 /*
@@ -344,7 +538,7 @@ gdbus_book_client_disconnect (EBookClient *client)
                g_dbus_connection_signal_unsubscribe (connection, client->priv->gone_signal_id);
                client->priv->gone_signal_id = 0;
 
-               e_gdbus_book_call_close_sync (
+               e_dbus_address_book_call_close_sync (
                        client->priv->dbus_proxy, NULL, NULL);
                g_object_unref (client->priv->dbus_proxy);
                client->priv->dbus_proxy = NULL;
@@ -353,131 +547,167 @@ gdbus_book_client_disconnect (EBookClient *client)
        UNLOCK_FACTORY ();
 }
 
-static void
-backend_error_cb (EGdbusBook *dbus_proxy,
-                  const gchar *message,
-                  EBookClient *client)
+static gboolean
+book_client_emit_backend_error_idle_cb (gpointer user_data)
 {
-       g_return_if_fail (E_IS_BOOK_CLIENT (client));
-       g_return_if_fail (message != NULL);
+       SignalClosure *signal_closure = user_data;
+
+       g_signal_emit_by_name (
+               signal_closure->client,
+               "backend-error",
+               signal_closure->error_message);
 
-       e_client_emit_backend_error (E_CLIENT (client), message);
+       return FALSE;
 }
 
-static void
-readonly_cb (EGdbusBook *dbus_proxy,
-             gboolean readonly,
-             EBookClient *client)
-{
-       g_return_if_fail (E_IS_BOOK_CLIENT (client));
+static gboolean
+book_client_emit_backend_property_changed_idle_cb (gpointer user_data)
+{
+       SignalClosure *signal_closure = user_data;
+       gchar *prop_value = NULL;
+
+       /* XXX Despite appearances, this function does not block. */
+       e_client_get_backend_property_sync (
+               signal_closure->client,
+               signal_closure->property_name,
+               &prop_value, NULL, NULL);
+
+       if (prop_value != NULL) {
+               g_signal_emit_by_name (
+                       signal_closure->client,
+                       "backend-property-changed",
+                       signal_closure->property_name,
+                       prop_value);
+               g_free (prop_value);
+       }
 
-       e_client_set_readonly (E_CLIENT (client), readonly);
+       return FALSE;
 }
 
 static void
-online_cb (EGdbusBook *dbus_proxy,
-           gboolean is_online,
-           EBookClient *client)
+book_client_dbus_proxy_error_cb (EDBusAddressBook *dbus_proxy,
+                                 const gchar *error_message,
+                                 EBookClient *book_client)
 {
-       g_return_if_fail (E_IS_BOOK_CLIENT (client));
+       GSource *idle_source;
+       SignalClosure *signal_closure;
+
+       signal_closure = g_slice_new0 (SignalClosure);
+       signal_closure->client = g_object_ref (book_client);
+       signal_closure->error_message = g_strdup (error_message);
 
-       e_client_set_online (E_CLIENT (client), is_online);
+       idle_source = g_idle_source_new ();
+       g_source_set_callback (
+               idle_source,
+               book_client_emit_backend_error_idle_cb,
+               signal_closure,
+               (GDestroyNotify) signal_closure_free);
+       g_source_attach (idle_source, book_client->priv->main_context);
+       g_source_unref (idle_source);
 }
 
 static void
-opened_cb (EGdbusBook *dbus_proxy,
-           const gchar * const *error_strv,
-           EBookClient *client)
+book_client_dbus_proxy_notify_cb (EDBusAddressBook *dbus_proxy,
+                                  GParamSpec *pspec,
+                                  EBookClient *book_client)
 {
-       GError *error = NULL;
+       const gchar *backend_prop_name = NULL;
 
-       g_return_if_fail (E_IS_BOOK_CLIENT (client));
-       g_return_if_fail (error_strv != NULL);
-       g_return_if_fail (e_gdbus_templates_decode_error (error_strv, &error));
-
-       e_client_emit_opened (E_CLIENT (client), error);
+       if (g_str_equal (pspec->name, "cache-dir")) {
+               backend_prop_name = CLIENT_BACKEND_PROPERTY_CACHE_DIR;
+       }
 
-       if (error)
-               g_error_free (error);
-}
+       if (g_str_equal (pspec->name, "capabilities")) {
+               gchar **strv;
+               gchar *csv;
 
-static void
-backend_property_changed_cb (EGdbusBook *dbus_proxy,
-                             const gchar * const *name_value_strv,
-                             EBookClient *client)
-{
-       gchar *prop_name = NULL, *prop_value = NULL;
+               backend_prop_name = CLIENT_BACKEND_PROPERTY_CAPABILITIES;
 
-       g_return_if_fail (E_IS_BOOK_CLIENT (client));
-       g_return_if_fail (name_value_strv != NULL);
-       g_return_if_fail (e_gdbus_templates_decode_two_strings (name_value_strv, &prop_name, &prop_value));
-       g_return_if_fail (prop_name != NULL);
-       g_return_if_fail (*prop_name);
-       g_return_if_fail (prop_value != NULL);
+               strv = e_dbus_address_book_dup_capabilities (dbus_proxy);
+               csv = g_strjoinv (",", strv);
+               e_client_set_capabilities (E_CLIENT (book_client), csv);
+               g_free (csv);
+               g_free (strv);
+       }
 
-       e_client_emit_backend_property_changed (E_CLIENT (client), prop_name, prop_value);
+       if (g_str_equal (pspec->name, "online")) {
+               gboolean online;
 
-       g_free (prop_name);
-       g_free (prop_value);
-}
+               backend_prop_name = CLIENT_BACKEND_PROPERTY_ONLINE;
 
-/*
- * Converts a GSList of EContact objects into a NULL-terminated array of
- * valid UTF-8 vcard strings, suitable for sending over DBus.
- */
-static gchar **
-contact_slist_to_utf8_vcard_array (GSList *contacts)
-{
-       gchar **array;
-       const GSList *l;
-       gint i = 0;
+               online = e_dbus_address_book_get_online (dbus_proxy);
+               e_client_set_online (E_CLIENT (book_client), online);
+       }
 
-       array = g_new0 (gchar *, g_slist_length (contacts) + 1);
-       for (l = contacts; l != NULL; l = l->next) {
-               gchar *vcard = e_vcard_to_string (E_VCARD (l->data), EVC_FORMAT_VCARD_30);
-               array[i++] = e_util_utf8_make_valid (vcard);
-               g_free (vcard);
+       if (g_str_equal (pspec->name, "required-fields")) {
+               backend_prop_name = BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS;
        }
 
-       return array;
-}
+       if (g_str_equal (pspec->name, "revision")) {
+               backend_prop_name = CLIENT_BACKEND_PROPERTY_REVISION;
+       }
 
-static gboolean
-book_client_get_backend_property_from_cache_finish (EClient *client,
-                                                    GAsyncResult *result,
-                                                    gchar **prop_value,
-                                                    GError **error)
-{
-       GSimpleAsyncResult *simple;
-       GError *local_error = NULL;
+       if (g_str_equal (pspec->name, "supported-fields")) {
+               backend_prop_name = BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS;
+       }
 
-       g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
-       g_return_val_if_fail (result != NULL, FALSE);
-       g_return_val_if_fail (prop_value != NULL, FALSE);
-       g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), book_client_get_backend_property_from_cache_finish), FALSE);
+       if (g_str_equal (pspec->name, "writable")) {
+               gboolean writable;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+               backend_prop_name = CLIENT_BACKEND_PROPERTY_READONLY;
 
-       if (g_simple_async_result_propagate_error (simple, &local_error)) {
-               e_client_unwrap_dbus_error (client, local_error, error);
-               return FALSE;
+               writable = e_dbus_address_book_get_writable (dbus_proxy);
+               e_client_set_readonly (E_CLIENT (book_client), !writable);
        }
 
-       *prop_value = g_strdup (g_simple_async_result_get_op_res_gpointer (simple));
-
-       return *prop_value != NULL;
+       if (backend_prop_name != NULL) {
+               GSource *idle_source;
+               SignalClosure *signal_closure;
+
+               signal_closure = g_slice_new0 (SignalClosure);
+               signal_closure->client = g_object_ref (book_client);
+               signal_closure->property_name = g_strdup (backend_prop_name);
+
+               idle_source = g_idle_source_new ();
+               g_source_set_callback (
+                       idle_source,
+                       book_client_emit_backend_property_changed_idle_cb,
+                       signal_closure,
+                       (GDestroyNotify) signal_closure_free);
+               g_source_attach (idle_source, book_client->priv->main_context);
+               g_source_unref (idle_source);
+       }
 }
 
 static void
 book_client_dispose (GObject *object)
 {
-       EClient *client;
+       EBookClientPrivate *priv;
+
+       priv = E_BOOK_CLIENT_GET_PRIVATE (object);
+
+       e_client_cancel_all (E_CLIENT (object));
+
+       if (priv->dbus_proxy_error_handler_id > 0) {
+               g_signal_handler_disconnect (
+                       priv->dbus_proxy,
+                       priv->dbus_proxy_error_handler_id);
+               priv->dbus_proxy_error_handler_id = 0;
+       }
 
-       client = E_CLIENT (object);
+       if (priv->dbus_proxy_notify_handler_id > 0) {
+               g_signal_handler_disconnect (
+                       priv->dbus_proxy,
+                       priv->dbus_proxy_notify_handler_id);
+               priv->dbus_proxy_notify_handler_id = 0;
+       }
 
-       e_client_cancel_all (client);
+       gdbus_book_client_disconnect (E_BOOK_CLIENT (object));
 
-       gdbus_book_client_disconnect (E_BOOK_CLIENT (client));
+       if (priv->main_context != NULL) {
+               g_main_context_unref (priv->main_context);
+               priv->main_context = NULL;
+       }
 
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_book_client_parent_class)->dispose (object);
@@ -514,94 +744,15 @@ book_client_unwrap_dbus_error (EClient *client,
        unwrap_dbus_error (dbus_error, out_error);
 }
 
-static void
-book_client_retrieve_capabilities (EClient *client,
-                                   GCancellable *cancellable,
-                                   GAsyncReadyCallback callback,
-                                   gpointer user_data)
-{
-       g_return_if_fail (E_IS_BOOK_CLIENT (client));
-
-       e_client_get_backend_property (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, cancellable, callback, user_data);
-}
-
-static gboolean
-book_client_retrieve_capabilities_finish (EClient *client,
-                                          GAsyncResult *result,
-                                          gchar **capabilities,
-                                          GError **error)
-{
-       g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
-
-       return e_client_get_backend_property_finish (client, result, capabilities, error);
-}
-
 static gboolean
 book_client_retrieve_capabilities_sync (EClient *client,
                                         gchar **capabilities,
                                         GCancellable *cancellable,
                                         GError **error)
 {
-       g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
-
-       return e_client_get_backend_property_sync (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, capabilities, cancellable, error);
-}
-
-static void
-book_client_get_backend_property (EClient *client,
-                                  const gchar *prop_name,
-                                  GCancellable *cancellable,
-                                  GAsyncReadyCallback callback,
-                                  gpointer user_data)
-{
-       gchar *prop_value;
-
-       prop_value = e_client_get_backend_property_from_cache (client, prop_name);
-       if (prop_value) {
-               e_client_finish_async_without_dbus (
-                       client, cancellable, callback, user_data,
-                       book_client_get_backend_property_from_cache_finish,
-                       prop_value, g_free);
-       } else {
-               e_client_proxy_call_string_with_res_op_data (
-                       client, prop_name,
-                       cancellable, callback, user_data,
-                       book_client_get_backend_property, prop_name,
-                       e_gdbus_book_call_get_backend_property,
-                       NULL, NULL,
-                       e_gdbus_book_call_get_backend_property_finish,
-                       NULL, NULL);
-       }
-}
-
-static gboolean
-book_client_get_backend_property_finish (EClient *client,
-                                         GAsyncResult *result,
-                                         gchar **prop_value,
-                                         GError **error)
-{
-       gchar *str = NULL;
-       gboolean res;
-
-       g_return_val_if_fail (prop_value != NULL, FALSE);
-
-       if (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result)) == book_client_get_backend_property_from_cache_finish) {
-               res = book_client_get_backend_property_from_cache_finish (client, result, &str, error);
-       } else {
-               res = e_client_proxy_call_finish_string (
-                       client, result, &str, error,
-                       book_client_get_backend_property);
-               if (res && str) {
-                       const gchar *prop_name = g_object_get_data (G_OBJECT (result), "res-op-data");
-
-                       if (prop_name && *prop_name)
-                               e_client_update_backend_property_cache (client, prop_name, str);
-               }
-       }
-
-       *prop_value = str;
-
-       return res;
+       return e_client_get_backend_property_sync (
+               client, CLIENT_BACKEND_PROPERTY_CAPABILITIES,
+               capabilities, cancellable, error);
 }
 
 static gboolean
@@ -612,36 +763,74 @@ book_client_get_backend_property_sync (EClient *client,
                                        GError **error)
 {
        EBookClient *book_client;
-       gchar *prop_val;
-       gboolean res;
-
-       g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+       EDBusAddressBook *dbus_proxy;
+       gchar **strv;
 
        book_client = E_BOOK_CLIENT (client);
+       dbus_proxy = book_client->priv->dbus_proxy;
 
-       if (book_client->priv->dbus_proxy == NULL) {
-               set_proxy_gone_error (error);
-               return FALSE;
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENED)) {
+               *prop_value = g_strdup ("TRUE");
+               return TRUE;
        }
 
-       prop_val = e_client_get_backend_property_from_cache (client, prop_name);
-       if (prop_val) {
-               g_return_val_if_fail (prop_value != NULL, FALSE);
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENING)) {
+               *prop_value = g_strdup ("FALSE");
+               return TRUE;
+       }
 
-               *prop_value = prop_val;
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_ONLINE)) {
+               if (e_dbus_address_book_get_online (dbus_proxy))
+                       *prop_value = g_strdup ("TRUE");
+               else
+                       *prop_value = g_strdup ("FALSE");
+               return TRUE;
+       }
 
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_READONLY)) {
+               if (e_dbus_address_book_get_writable (dbus_proxy))
+                       *prop_value = g_strdup ("FALSE");
+               else
+                       *prop_value = g_strdup ("TRUE");
                return TRUE;
        }
 
-       res = e_client_proxy_call_sync_string__string (
-               client, prop_name, prop_value, cancellable, error,
-               e_gdbus_book_call_get_backend_property_sync);
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CACHE_DIR)) {
+               *prop_value = e_dbus_address_book_dup_cache_dir (dbus_proxy);
+               return TRUE;
+       }
 
-       if (res && prop_value)
-               e_client_update_backend_property_cache (
-                       client, prop_name, *prop_value);
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_REVISION)) {
+               *prop_value = e_dbus_address_book_dup_revision (dbus_proxy);
+               return TRUE;
+       }
+
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+               strv = e_dbus_address_book_dup_capabilities (dbus_proxy);
+               *prop_value = g_strjoinv (",", strv);
+               g_strfreev (strv);
+               return TRUE;
+       }
+
+       if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
+               strv = e_dbus_address_book_dup_required_fields (dbus_proxy);
+               *prop_value = g_strjoinv (",", strv);
+               g_strfreev (strv);
+               return TRUE;
+       }
 
-       return res;
+       if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
+               strv = e_dbus_address_book_dup_supported_fields (dbus_proxy);
+               *prop_value = g_strjoinv (",", strv);
+               g_strfreev (strv);
+               return TRUE;
+       }
+
+       g_set_error (
+               error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED,
+               _("Unknown book property '%s'"), prop_name);
+
+       return TRUE;
 }
 
 static gboolean
@@ -660,31 +849,6 @@ book_client_set_backend_property_sync (EClient *client,
        return FALSE;
 }
 
-static void
-book_client_open (EClient *client,
-                  gboolean only_if_exists,
-                  GCancellable *cancellable,
-                  GAsyncReadyCallback callback,
-                  gpointer user_data)
-{
-       e_client_proxy_call_boolean (
-               client, only_if_exists,
-               cancellable, callback, user_data,
-               book_client_open,
-               e_gdbus_book_call_open,
-               e_gdbus_book_call_open_finish,
-               NULL, NULL, NULL, NULL);
-}
-
-static gboolean
-book_client_open_finish (EClient *client,
-                         GAsyncResult *result,
-                         GError **error)
-{
-       return e_client_proxy_call_finish_void (
-               client, result, error, book_client_open);
-}
-
 static gboolean
 book_client_open_sync (EClient *client,
                        gboolean only_if_exists,
@@ -702,32 +866,8 @@ book_client_open_sync (EClient *client,
                return FALSE;
        }
 
-       return e_client_proxy_call_sync_boolean__void (
-               client, only_if_exists, cancellable, error,
-               e_gdbus_book_call_open_sync);
-}
-
-static void
-book_client_refresh (EClient *client,
-                     GCancellable *cancellable,
-                     GAsyncReadyCallback callback,
-                     gpointer user_data)
-{
-       e_client_proxy_call_void (
-               client, cancellable, callback, user_data,
-               book_client_refresh,
-               e_gdbus_book_call_refresh,
-               e_gdbus_book_call_refresh_finish,
-               NULL, NULL, NULL, NULL);
-}
-
-static gboolean
-book_client_refresh_finish (EClient *client,
-                            GAsyncResult *result,
-                            GError **error)
-{
-       return e_client_proxy_call_finish_void (
-               client, result, error, book_client_refresh);
+       return e_dbus_address_book_call_open_sync (
+               book_client->priv->dbus_proxy, cancellable, error);
 }
 
 static gboolean
@@ -746,9 +886,168 @@ book_client_refresh_sync (EClient *client,
                return FALSE;
        }
 
-       return e_client_proxy_call_sync_void__void (
-               client, cancellable, error,
-               e_gdbus_book_call_refresh_sync);
+       return e_dbus_address_book_call_refresh_sync (
+               book_client->priv->dbus_proxy, cancellable, error);
+}
+
+static void
+book_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
+                                 GObject *source_object,
+                                 GCancellable *cancellable)
+{
+       EBookClientPrivate *priv;
+       EClient *client;
+       ESource *source;
+       GDBusConnection *connection;
+       const gchar *uid;
+       gchar *object_path = NULL;
+       gulong handler_id;
+       GError *error = NULL;
+
+       priv = E_BOOK_CLIENT_GET_PRIVATE (source_object);
+
+       client = E_CLIENT (source_object);
+       source = e_client_get_source (client);
+       uid = e_source_get_uid (source);
+
+       LOCK_FACTORY ();
+       gdbus_book_factory_activate (cancellable, &error);
+       UNLOCK_FACTORY ();
+
+       if (error != NULL) {
+               unwrap_dbus_error (error, &error);
+               g_simple_async_result_take_error (simple, error);
+               return;
+       }
+
+       e_dbus_address_book_factory_call_open_address_book_sync (
+               book_factory, uid, &object_path, cancellable, &error);
+
+       /* Sanity check. */
+       g_return_if_fail (
+               ((object_path != NULL) && (error == NULL)) ||
+               ((object_path == NULL) && (error != NULL)));
+
+       if (object_path == NULL) {
+               unwrap_dbus_error (error, &error);
+               g_simple_async_result_take_error (simple, error);
+               return;
+       }
+
+       connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
+
+       priv->dbus_proxy = e_dbus_address_book_proxy_new_sync (
+               connection,
+               G_DBUS_PROXY_FLAGS_NONE,
+               ADDRESS_BOOK_DBUS_SERVICE_NAME,
+               object_path,
+               cancellable, &error);
+
+       g_free (object_path);
+
+       /* Sanity check. */
+       g_return_if_fail (
+               ((priv->dbus_proxy != NULL) && (error == NULL)) ||
+               ((priv->dbus_proxy == NULL) && (error != NULL)));
+
+       if (error != NULL) {
+               unwrap_dbus_error (error, &error);
+               g_simple_async_result_take_error (simple, error);
+               return;
+       }
+
+       g_dbus_proxy_set_default_timeout (
+               G_DBUS_PROXY (priv->dbus_proxy), DBUS_PROXY_TIMEOUT_MS);
+
+       priv->gone_signal_id = g_dbus_connection_signal_subscribe (
+               connection,
+               "org.freedesktop.DBus",                         /* sender */
+               "org.freedesktop.DBus",                         /* interface */
+               "NameOwnerChanged",                             /* member */
+               "/org/freedesktop/DBus",                        /* object_path */
+               "org.gnome.evolution.dataserver.AddressBook",   /* arg0 */
+               G_DBUS_SIGNAL_FLAGS_NONE,
+               gdbus_book_client_connection_gone_cb, client, NULL);
+
+       g_signal_connect (
+               connection, "closed",
+               G_CALLBACK (gdbus_book_client_closed_cb), client);
+
+       handler_id = g_signal_connect (
+               priv->dbus_proxy, "error",
+               G_CALLBACK (book_client_dbus_proxy_error_cb), client);
+       priv->dbus_proxy_error_handler_id = handler_id;
+
+       handler_id = g_signal_connect (
+               priv->dbus_proxy, "notify",
+               G_CALLBACK (book_client_dbus_proxy_notify_cb), client);
+       priv->dbus_proxy_notify_handler_id = handler_id;
+}
+
+static gboolean
+book_client_initable_init (GInitable *initable,
+                           GCancellable *cancellable,
+                           GError **error)
+{
+       EAsyncClosure *closure;
+       GAsyncResult *result;
+       gboolean success;
+
+       closure = e_async_closure_new ();
+
+       g_async_initable_init_async (
+               G_ASYNC_INITABLE (initable),
+               G_PRIORITY_DEFAULT, cancellable,
+               e_async_closure_callback, closure);
+
+       result = e_async_closure_wait (closure);
+
+       success = g_async_initable_init_finish (
+               G_ASYNC_INITABLE (initable), result, error);
+
+       e_async_closure_free (closure);
+
+       return success;
+}
+
+static void
+book_client_initable_init_async (GAsyncInitable *initable,
+                                 gint io_priority,
+                                 GCancellable *cancellable,
+                                 GAsyncReadyCallback callback,
+                                 gpointer user_data)
+{
+       GSimpleAsyncResult *simple;
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (initable), callback, user_data,
+               book_client_initable_init_async);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       book_client_run_in_dbus_thread (
+               simple, book_client_init_in_dbus_thread,
+               io_priority, cancellable);
+
+       g_object_unref (simple);
+}
+
+static gboolean
+book_client_initable_init_finish (GAsyncInitable *initable,
+                                  GAsyncResult *result,
+                                  GError **error)
+{
+       GSimpleAsyncResult *simple;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (initable),
+               book_client_initable_init_async), FALSE);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+
+       /* Assume success unless a GError is set. */
+       return !g_simple_async_result_propagate_error (simple, error);
 }
 
 static void
@@ -764,21 +1063,26 @@ e_book_client_class_init (EBookClientClass *class)
        object_class->finalize = book_client_finalize;
 
        client_class = E_CLIENT_CLASS (class);
-       client_class->get_dbus_proxy                    = book_client_get_dbus_proxy;
-       client_class->unwrap_dbus_error                 = book_client_unwrap_dbus_error;
-       client_class->retrieve_capabilities             = book_client_retrieve_capabilities;
-       client_class->retrieve_capabilities_finish      = book_client_retrieve_capabilities_finish;
-       client_class->retrieve_capabilities_sync        = book_client_retrieve_capabilities_sync;
-       client_class->get_backend_property              = book_client_get_backend_property;
-       client_class->get_backend_property_finish       = book_client_get_backend_property_finish;
-       client_class->get_backend_property_sync         = book_client_get_backend_property_sync;
-       client_class->set_backend_property_sync         = book_client_set_backend_property_sync;
-       client_class->open                              = book_client_open;
-       client_class->open_finish                       = book_client_open_finish;
-       client_class->open_sync                         = book_client_open_sync;
-       client_class->refresh                           = book_client_refresh;
-       client_class->refresh_finish                    = book_client_refresh_finish;
-       client_class->refresh_sync                      = book_client_refresh_sync;
+       client_class->get_dbus_proxy = book_client_get_dbus_proxy;
+       client_class->unwrap_dbus_error = book_client_unwrap_dbus_error;
+       client_class->retrieve_capabilities_sync = book_client_retrieve_capabilities_sync;
+       client_class->get_backend_property_sync = book_client_get_backend_property_sync;
+       client_class->set_backend_property_sync = book_client_set_backend_property_sync;
+       client_class->open_sync = book_client_open_sync;
+       client_class->refresh_sync = book_client_refresh_sync;
+}
+
+static void
+e_book_client_initable_init (GInitableIface *interface)
+{
+       interface->init = book_client_initable_init;
+}
+
+static void
+e_book_client_async_initable_init (GAsyncInitableIface *interface)
+{
+       interface->init_async = book_client_initable_init_async;
+       interface->init_finish = book_client_initable_init_finish;
 }
 
 static void
@@ -789,6 +1093,10 @@ e_book_client_init (EBookClient *client)
        UNLOCK_FACTORY ();
 
        client->priv = E_BOOK_CLIENT_GET_PRIVATE (client);
+
+       /* This is so the D-Bus thread can schedule signal emissions
+        * on the thread-default context for this thread. */
+       client->priv->main_context = g_main_context_ref_thread_default ();
 }
 
 /**
@@ -808,105 +1116,11 @@ EBookClient *
 e_book_client_new (ESource *source,
                    GError **error)
 {
-       EBookClient *client;
-       GError *err = NULL;
-       GDBusConnection *connection;
-       const gchar *uid;
-       gchar *object_path = NULL;
-
-       g_return_val_if_fail (source != NULL, NULL);
        g_return_val_if_fail (E_IS_SOURCE (source), NULL);
 
-       LOCK_FACTORY ();
-       /* XXX Oops, e_book_client_new() forgot to take a GCancellable. */
-       if (!gdbus_book_factory_activate (NULL, &err)) {
-               UNLOCK_FACTORY ();
-               if (err) {
-                       unwrap_dbus_error (err, &err);
-                       g_warning ("%s: Failed to run book factory: %s", G_STRFUNC, err->message);
-                       g_propagate_error (error, err);
-               } else {
-                       g_warning ("%s: Failed to run book factory: Unknown error", G_STRFUNC);
-                       g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Failed to run book factory"));
-               }
-
-               return NULL;
-       }
-
-       uid = e_source_get_uid (source);
-
-       client = g_object_new (E_TYPE_BOOK_CLIENT, "source", source, NULL);
-       UNLOCK_FACTORY ();
-
-       e_dbus_address_book_factory_call_open_address_book_sync (
-               book_factory, uid, &object_path, NULL, &err);
-
-       /* Sanity check. */
-       g_return_val_if_fail (
-               ((object_path != NULL) && (err == NULL)) ||
-               ((object_path == NULL) && (err != NULL)), NULL);
-
-       if (err != NULL) {
-               unwrap_dbus_error (err, &err);
-               g_propagate_error (error, err);
-               g_object_unref (client);
-               return NULL;
-       }
-
-       connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
-
-       client->priv->dbus_proxy = G_DBUS_PROXY (e_gdbus_book_proxy_new_sync (
-               connection,
-               G_DBUS_PROXY_FLAGS_NONE,
-               ADDRESS_BOOK_DBUS_SERVICE_NAME,
-               object_path,
-               NULL, &err));
-
-       g_free (object_path);
-
-       /* Sanity check. */
-       g_return_val_if_fail (
-               ((client->priv->dbus_proxy != NULL) && (err == NULL)) ||
-               ((client->priv->dbus_proxy == NULL) && (err != NULL)), NULL);
-
-       if (err != NULL) {
-               unwrap_dbus_error (err, &err);
-               g_propagate_error (error, err);
-               g_object_unref (client);
-               return NULL;
-       }
-
-       client->priv->gone_signal_id = g_dbus_connection_signal_subscribe (
-               connection,
-               "org.freedesktop.DBus",                         /* sender */
-               "org.freedesktop.DBus",                         /* interface */
-               "NameOwnerChanged",                             /* member */
-               "/org/freedesktop/DBus",                        /* object_path */
-               "org.gnome.evolution.dataserver.AddressBook",   /* arg0 */
-               G_DBUS_SIGNAL_FLAGS_NONE,
-               gdbus_book_client_connection_gone_cb, client, NULL);
-
-       g_signal_connect (
-               connection, "closed",
-               G_CALLBACK (gdbus_book_client_closed_cb), client);
-
-       g_signal_connect (
-               client->priv->dbus_proxy, "backend_error",
-               G_CALLBACK (backend_error_cb), client);
-       g_signal_connect (
-               client->priv->dbus_proxy, "readonly",
-               G_CALLBACK (readonly_cb), client);
-       g_signal_connect (
-               client->priv->dbus_proxy, "online",
-               G_CALLBACK (online_cb), client);
-       g_signal_connect (
-               client->priv->dbus_proxy, "opened",
-               G_CALLBACK (opened_cb), client);
-       g_signal_connect (
-               client->priv->dbus_proxy, "backend-property-changed",
-               G_CALLBACK (backend_property_changed_cb), client);
-
-       return client;
+       return g_initable_new (
+               E_TYPE_BOOK_CLIENT, NULL, error,
+               "source", source, NULL);
 }
 
 #define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
@@ -953,12 +1167,12 @@ make_me_card (void)
 /**
  * e_book_client_get_self:
  * @registry: an #ESourceRegistry
- * @contact: (out): an #EContact pointer to set
- * @client: (out): an #EBookClient pointer to set
+ * @out_contact: (out): an #EContact pointer to set
+ * @out_client: (out): an #EBookClient pointer to set
  * @error: a #GError to set on failure
  *
  * Get the #EContact referring to the user of the address book
- * and set it in @contact and @client.
+ * and set it in @out_contact and @out_client.
  *
  * Returns: %TRUE if successful, otherwise %FALSE.
  *
@@ -966,67 +1180,74 @@ make_me_card (void)
  **/
 gboolean
 e_book_client_get_self (ESourceRegistry *registry,
-                        EContact **contact,
-                        EBookClient **client,
+                        EContact **out_contact,
+                        EBookClient **out_client,
                         GError **error)
 {
+       EBookClient *book_client;
        ESource *source;
-       GError *local_error = NULL;
+       EContact *contact = NULL;
        GSettings *settings;
        gchar *uid;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
-       g_return_val_if_fail (contact != NULL, FALSE);
-       g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+       g_return_val_if_fail (out_contact != NULL, FALSE);
+       g_return_val_if_fail (out_client != NULL, FALSE);
 
        source = e_source_registry_ref_builtin_address_book (registry);
-       *client = e_book_client_new (source, &local_error);
+       book_client = e_book_client_new (source, error);
        g_object_unref (source);
 
-       if (!*client) {
-               g_propagate_error (error, local_error);
+       if (book_client == NULL)
                return FALSE;
-       }
-
-       if (!e_client_open_sync (E_CLIENT (*client), FALSE, NULL, &local_error)) {
-               g_object_unref (*client);
-               *client = NULL;
-               g_propagate_error (error, local_error);
 
+       success = e_client_open_sync (
+               E_CLIENT (book_client), FALSE, NULL, error);
+       if (!success) {
+               g_object_unref (book_client);
                return FALSE;
        }
 
+       *out_client = book_client;
+
        settings = g_settings_new (SELF_UID_PATH_ID);
        uid = g_settings_get_string (settings, SELF_UID_KEY);
        g_object_unref (settings);
 
        if (uid) {
-               gboolean got;
-
-               /* Don't care about errors because we'll create a new card on failure */
-               got = e_book_client_get_contact_sync (*client, uid, contact, NULL, NULL);
+               /* Don't care about errors because
+                * we'll create a new card on failure. */
+               e_book_client_get_contact_sync (
+                       book_client, uid, &contact, NULL, NULL);
                g_free (uid);
-               if (got)
+
+               if (contact != NULL) {
+                       *out_client = book_client;
+                       *out_contact = contact;
                        return TRUE;
+               }
        }
 
        uid = NULL;
-       *contact = make_me_card ();
-       if (!e_book_client_add_contact_sync (*client, *contact, &uid, NULL, &local_error)) {
-               g_object_unref (*client);
-               *client = NULL;
-               g_object_unref (*contact);
-               *contact = NULL;
-               g_propagate_error (error, local_error);
+       contact = make_me_card ();
+       success = e_book_client_add_contact_sync (
+               book_client, contact, &uid, NULL, error);
+       if (!success) {
+               g_object_unref (book_client);
+               g_object_unref (contact);
                return FALSE;
        }
 
-       if (uid) {
-               e_contact_set (*contact, E_CONTACT_UID, uid);
+       if (uid != NULL) {
+               e_contact_set (contact, E_CONTACT_UID, uid);
                g_free (uid);
        }
 
-       e_book_client_set_self (*client, *contact, NULL);
+       e_book_client_set_self (book_client, contact, NULL);
+
+       *out_client = book_client;
+       *out_contact = contact;
 
        return TRUE;
 }
@@ -1092,6 +1313,27 @@ e_book_client_is_self (EContact *contact)
        return is_self;
 }
 
+/* Helper for e_book_client_add_contact() */
+static void
+book_client_add_contact_thread (GSimpleAsyncResult *simple,
+                                GObject *source_object,
+                                GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
+
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       e_book_client_add_contact_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->contact,
+               &async_context->uid,
+               cancellable, &error);
+
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
+}
+
 /**
  * e_book_client_add_contact:
  * @client: an #EBookClient
@@ -1108,45 +1350,45 @@ e_book_client_is_self (EContact *contact)
  **/
 void
 e_book_client_add_contact (EBookClient *client,
-                           /* const */ EContact *contact,
+                           EContact *contact,
                            GCancellable *cancellable,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
 {
-       gchar *vcard, *gdbus_vcard = NULL;
-       const gchar *strv[2];
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       g_return_if_fail (contact != NULL);
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (E_IS_CONTACT (contact));
 
-       vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-       strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
-       strv[1] = NULL;
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->contact = g_object_ref (contact);
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_add_contact);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       g_return_if_fail (strv[0] != NULL);
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       e_client_proxy_call_strv (
-               E_CLIENT (client),
-               strv, cancellable, callback, user_data,
-               e_book_client_add_contact,
-               e_gdbus_book_call_add_contacts,
-               NULL, NULL, NULL,
-               e_gdbus_book_call_add_contacts_finish,
-               NULL);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_add_contact_thread,
+               G_PRIORITY_DEFAULT, cancellable);
 
-       g_free (vcard);
-       g_free (gdbus_vcard);
+       g_object_unref (simple);
 }
 
 /**
  * e_book_client_add_contact_finish:
  * @client: an #EBookClient
  * @result: a #GAsyncResult
- * @added_uid: (out): UID of a newly added contact; can be %NULL
+ * @out_added_uid: (out): UID of a newly added contact; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_book_client_add_contact() and
- * sets @added_uid to a UID of a newly added contact.
+ * sets @out_added_uid to a UID of a newly added contact.
  * This string should be freed with g_free().
  *
  * Note: This is not modifying original #EContact.
@@ -1158,37 +1400,43 @@ e_book_client_add_contact (EBookClient *client,
 gboolean
 e_book_client_add_contact_finish (EBookClient *client,
                                   GAsyncResult *result,
-                                  gchar **added_uid,
+                                  gchar **out_added_uid,
                                   GError **error)
 {
-       gboolean res;
-       gchar **out_uids = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       res = e_client_proxy_call_finish_strv (
-               E_CLIENT (client), result, &out_uids, error,
-               e_book_client_add_contact);
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_add_contact), FALSE);
 
-       if (res && out_uids && added_uid) {
-               *added_uid = g_strdup (out_uids[0]);
-       } else {
-               if (added_uid)
-                       *added_uid = NULL;
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       if (g_simple_async_result_propagate_error (simple, error))
+               return FALSE;
+
+       g_return_val_if_fail (async_context->uid != NULL, FALSE);
+
+       if (out_added_uid != NULL) {
+               *out_added_uid = async_context->uid;
+               async_context->uid = NULL;
        }
-       g_strfreev (out_uids);
 
-       return res;
+       return TRUE;
 }
 
 /**
  * e_book_client_add_contact_sync:
  * @client: an #EBookClient
  * @contact: an #EContact
- * @added_uid: (out): UID of a newly added contact; can be %NULL
+ * @out_added_uid: (out): UID of a newly added contact; can be %NULL
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Adds @contact to @client and
- * sets @added_uid to a UID of a newly added contact.
+ * sets @out_added_uid to a UID of a newly added contact.
  * This string should be freed with g_free().
  *
  * Note: This is not modifying original @contact, thus if it's needed,
@@ -1200,44 +1448,60 @@ e_book_client_add_contact_finish (EBookClient *client,
  **/
 gboolean
 e_book_client_add_contact_sync (EBookClient *client,
-                                /* const */ EContact *contact,
-                                gchar **added_uid,
+                                EContact *contact,
+                                gchar **out_added_uid,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       gboolean res;
-       gchar *vcard, *gdbus_vcard = NULL, **out_uids = NULL;
-       const gchar *strv[2];
+       GSList link = { contact, NULL };
+       GSList *uids = NULL;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+       g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
 
        if (client->priv->dbus_proxy == NULL) {
                set_proxy_gone_error (error);
                return FALSE;
        }
 
-       vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-       strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
-       strv[1] = NULL;
+       success = e_book_client_add_contacts_sync (
+               client, &link, &uids, cancellable, error);
 
-       g_return_val_if_fail (strv[0] != NULL, FALSE);
+       /* Sanity check. */
+       g_return_val_if_fail (
+               (success && (uids != NULL)) ||
+               (!success && (uids == NULL)), FALSE);
 
-       res = e_client_proxy_call_sync_strv__strv (
-               E_CLIENT (client), strv, &out_uids, cancellable, error,
-               e_gdbus_book_call_add_contacts_sync);
+       if (uids != NULL) {
+               if (out_added_uid != NULL)
+                       *out_added_uid = g_strdup (uids->data);
 
-       if (res && out_uids && added_uid) {
-               *added_uid = g_strdup (out_uids[0]);
-       } else {
-               if (added_uid)
-                       *added_uid = NULL;
+               g_slist_free_full (uids, (GDestroyNotify) g_free);
        }
 
-       g_strfreev (out_uids);
-       g_free (vcard);
-       g_free (gdbus_vcard);
+       return success;
+}
+
+/* Helper for e_book_client_add_contacts() */
+static void
+book_client_add_contacts_thread (GSimpleAsyncResult *simple,
+                                 GObject *source_object,
+                                 GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
+
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-       return res;
+       e_book_client_add_contacts_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->object_list,
+               &async_context->string_list,
+               cancellable, &error);
+
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -1256,40 +1520,47 @@ e_book_client_add_contact_sync (EBookClient *client,
  **/
 void
 e_book_client_add_contacts (EBookClient *client,
-                            /* const */ GSList *contacts,
+                            GSList *contacts,
                             GCancellable *cancellable,
                             GAsyncReadyCallback callback,
                             gpointer user_data)
 {
-       gchar **array;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (contacts != NULL);
 
-       array = contact_slist_to_utf8_vcard_array (contacts);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->object_list = g_slist_copy_deep (
+               contacts, (GCopyFunc) g_object_ref, NULL);
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_add_contacts);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       e_client_proxy_call_strv (
-               E_CLIENT (client),
-               (const gchar * const *) array,
-               cancellable, callback, user_data,
-               e_book_client_add_contacts,
-               e_gdbus_book_call_add_contacts,
-               NULL, NULL, NULL,
-               e_gdbus_book_call_add_contacts_finish,
-               NULL);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_add_contacts_thread,
+               G_PRIORITY_DEFAULT, cancellable);
 
-       g_strfreev (array);
+       g_object_unref (simple);
 }
 
 /**
  * e_book_client_add_contacts_finish:
  * @client: an #EBookClient
  * @result: a #GAsyncResult
- * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
- * contacts; can be %NULL
+ * @out_added_uids: (out) (element-type utf8) (allow-none): UIDs of
+ *                  newly added contacts; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_book_client_add_contacts() and
- * sets @added_uids to the UIDs of newly added contacts if successful.
+ * sets @out_added_uids to the UIDs of newly added contacts if successful.
  * This #GSList should be freed with e_client_util_free_string_slist().
  *
  * If any of the contacts cannot be inserted, all of the insertions will be
@@ -1304,39 +1575,42 @@ e_book_client_add_contacts (EBookClient *client,
 gboolean
 e_book_client_add_contacts_finish (EBookClient *client,
                                    GAsyncResult *result,
-                                   GSList **added_uids,
+                                   GSList **out_added_uids,
                                    GError **error)
 {
-       gboolean res;
-       gchar **out_uids = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       res = e_client_proxy_call_finish_strv (
-               E_CLIENT (client), result, &out_uids, error,
-               e_book_client_add_contacts);
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_add_contacts), FALSE);
 
-       if (res && out_uids && added_uids) {
-               *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
-       } else {
-               if (added_uids)
-                       *added_uids = NULL;
-       }
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       if (g_simple_async_result_propagate_error (simple, error))
+               return FALSE;
 
-       g_strfreev (out_uids);
+       if (out_added_uids != NULL) {
+               *out_added_uids = async_context->string_list;
+               async_context->string_list = NULL;
+       }
 
-       return res;
+       return TRUE;
 }
 
 /**
  * e_book_client_add_contacts_sync:
  * @client: an #EBookClient
  * @contacts: (element-type EContact): a #GSList of #EContact objects to add
- * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
- * contacts; can be %NULL
+ * @out_added_uids: (out) (element-type utf8) (allow-none): UIDs of newly
+ *                  added contacts; can be %NULL
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Adds @contacts to @client and
- * sets @added_uids to the UIDs of newly added contacts if successful.
+ * sets @out_added_uids to the UIDs of newly added contacts if successful.
  * This #GSList should be freed with e_client_util_free_string_slist().
  *
  * If any of the contacts cannot be inserted, all of the insertions will be
@@ -1351,40 +1625,91 @@ e_book_client_add_contacts_finish (EBookClient *client,
  **/
 gboolean
 e_book_client_add_contacts_sync (EBookClient *client,
-                                 /* const */ GSList *contacts,
-                                 GSList **added_uids,
+                                 GSList *contacts,
+                                 GSList **out_added_uids,
                                  GCancellable *cancellable,
                                  GError **error)
 {
-       gboolean res;
-       gchar **array, **out_uids = NULL;
+       GSList *link;
+       gchar **strv;
+       gchar **uids = NULL;
+       gboolean success;
+       gint ii = 0;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+       g_return_val_if_fail (contacts != NULL, FALSE);
 
        if (client->priv->dbus_proxy == NULL) {
                set_proxy_gone_error (error);
                return FALSE;
        }
 
-       array = contact_slist_to_utf8_vcard_array (contacts);
+       /* Build a string array, ensuring each element is valid UTF-8. */
+       strv = g_new0 (gchar *, g_slist_length (contacts) + 1);
+       for (link = contacts; link != NULL; link = g_slist_next (link)) {
+               EVCard *vcard;
+               gchar *string;
+
+               vcard = E_VCARD (link->data);
+               string = e_vcard_to_string (vcard, EVC_FORMAT_VCARD_30);
+               strv[ii++] = e_util_utf8_make_valid (string);
+               g_free (string);
+       }
+
+       success = e_dbus_address_book_call_create_contacts_sync (
+               client->priv->dbus_proxy,
+               (const gchar * const *) strv,
+               &uids, cancellable, error);
 
-       res = e_client_proxy_call_sync_strv__strv (
-               E_CLIENT (client),
-               (const gchar * const *) array,
-               &out_uids, cancellable, error,
-               e_gdbus_book_call_add_contacts_sync);
+       g_strfreev (strv);
 
-       if (res && out_uids && added_uids) {
-               *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
-       } else {
-               if (added_uids)
-                       *added_uids = NULL;
+       /* Sanity check. */
+       g_return_val_if_fail (
+               (success && (uids != NULL)) ||
+               (!success && (uids == NULL)), FALSE);
+
+       if (!success)
+               return FALSE;
+
+       /* XXX We should have passed the string array directly
+        *     back to the caller instead of building a linked
+        *     list.  This is unnecessary work. */
+       if (out_added_uids != NULL) {
+               GSList *tmp = NULL;
+               gint ii;
+
+               /* Take ownership of the string array elements. */
+               for (ii = 0; uids[ii] != NULL; ii++) {
+                       tmp = g_slist_prepend (tmp, uids[ii]);
+                       uids[ii] = NULL;
+               }
+
+               *out_added_uids = g_slist_reverse (tmp);
        }
 
-       g_strfreev (out_uids);
-       g_strfreev (array);
+       g_strfreev (uids);
 
-       return res;
+       return TRUE;
+}
+
+/* Helper for e_book_client_modify_contact() */
+static void
+book_client_modify_contact_thread (GSimpleAsyncResult *simple,
+                                   GObject *source_object,
+                                   GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
+
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       e_book_client_modify_contact_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->contact,
+               cancellable, &error);
+
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -1403,33 +1728,34 @@ e_book_client_add_contacts_sync (EBookClient *client,
  **/
 void
 e_book_client_modify_contact (EBookClient *client,
-                              /* const */ EContact *contact,
+                              EContact *contact,
                               GCancellable *cancellable,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
 {
-       gchar *vcard, *gdbus_vcard = NULL;
-       const gchar *strv[2];
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       g_return_if_fail (contact != NULL);
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (E_IS_CONTACT (contact));
 
-       vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-       strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
-       strv[1] = NULL;
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->contact = g_object_ref (contact);
 
-       g_return_if_fail (strv[0] != NULL);
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_modify_contact);
 
-       e_client_proxy_call_strv (
-               E_CLIENT (client),
-               strv, cancellable, callback, user_data,
-               e_book_client_modify_contact,
-               e_gdbus_book_call_modify_contacts,
-               e_gdbus_book_call_modify_contacts_finish,
-               NULL, NULL, NULL, NULL);
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       g_free (vcard);
-       g_free (gdbus_vcard);
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
+
+       g_simple_async_result_run_in_thread (
+               simple, book_client_modify_contact_thread,
+               G_PRIORITY_DEFAULT, cancellable);
+
+       g_object_unref (simple);
 }
 
 /**
@@ -1449,9 +1775,17 @@ e_book_client_modify_contact_finish (EBookClient *client,
                                      GAsyncResult *result,
                                      GError **error)
 {
-       return e_client_proxy_call_finish_void (
-               E_CLIENT (client), result, error,
-               e_book_client_modify_contact);
+       GSimpleAsyncResult *simple;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_modify_contact), FALSE);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+
+       /* Assume success unless a GError is set. */
+       return !g_simple_async_result_propagate_error (simple, error);
 }
 
 /**
@@ -1469,36 +1803,37 @@ e_book_client_modify_contact_finish (EBookClient *client,
  **/
 gboolean
 e_book_client_modify_contact_sync (EBookClient *client,
-                                   /* const */ EContact *contact,
+                                   EContact *contact,
                                    GCancellable *cancellable,
                                    GError **error)
 {
-       gboolean res;
-       gchar *vcard, *gdbus_vcard = NULL;
-       const gchar *strv[2];
+       GSList link = { contact, NULL };
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+       g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
 
-       if (client->priv->dbus_proxy == NULL) {
-               set_proxy_gone_error (error);
-               return FALSE;
-       }
-
-       vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-       strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
-       strv[1] = NULL;
+       return e_book_client_modify_contacts_sync (
+               client, &link, cancellable, error);
+}
 
-       g_return_val_if_fail (strv[0] != NULL, FALSE);
+/* Helper for e_book_client_modify_contacts() */
+static void
+book_client_modify_contacts_thread (GSimpleAsyncResult *simple,
+                                    GObject *source_object,
+                                    GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
 
-       res = e_client_proxy_call_sync_strv__void (
-               E_CLIENT (client),
-               strv, cancellable, error,
-               e_gdbus_book_call_modify_contacts_sync);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-       g_free (vcard);
-       g_free (gdbus_vcard);
+       e_book_client_modify_contacts_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->object_list,
+               cancellable, &error);
 
-       return res;
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -1517,27 +1852,35 @@ e_book_client_modify_contact_sync (EBookClient *client,
  **/
 void
 e_book_client_modify_contacts (EBookClient *client,
-                               /* const */ GSList *contacts,
+                               GSList *contacts,
                                GCancellable *cancellable,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
 {
-       gchar **array;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (contacts != NULL);
 
-       array = contact_slist_to_utf8_vcard_array (contacts);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->object_list = g_slist_copy_deep (
+               contacts, (GCopyFunc) g_object_ref, NULL);
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_modify_contacts);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       e_client_proxy_call_strv (
-               E_CLIENT (client),
-               (const gchar * const *) array,
-               cancellable, callback, user_data,
-               e_book_client_modify_contacts,
-               e_gdbus_book_call_modify_contacts,
-               e_gdbus_book_call_modify_contacts_finish,
-               NULL, NULL, NULL, NULL);
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       g_strfreev (array);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_modify_contacts_thread,
+               G_PRIORITY_DEFAULT, cancellable);
+
+       g_object_unref (simple);
 }
 
 /**
@@ -1557,9 +1900,17 @@ e_book_client_modify_contacts_finish (EBookClient *client,
                                       GAsyncResult *result,
                                       GError **error)
 {
-       return e_client_proxy_call_finish_void (
-               E_CLIENT (client), result, error,
-               e_book_client_modify_contacts);
+       GSimpleAsyncResult *simple;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_modify_contacts), FALSE);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+
+       /* Assume success unless a GError is set. */
+       return !g_simple_async_result_propagate_error (simple, error);
 }
 
 /**
@@ -1577,12 +1928,14 @@ e_book_client_modify_contacts_finish (EBookClient *client,
  **/
 gboolean
 e_book_client_modify_contacts_sync (EBookClient *client,
-                                    /* const */ GSList *contacts,
+                                    GSList *contacts,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       gboolean res;
-       gchar **array;
+       GSList *link;
+       gchar **strv;
+       gboolean success;
+       gint ii = 0;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (contacts != NULL, FALSE);
@@ -1592,17 +1945,46 @@ e_book_client_modify_contacts_sync (EBookClient *client,
                return FALSE;
        }
 
-       array = contact_slist_to_utf8_vcard_array (contacts);
+       /* Build a string array, ensuring each element is valid UTF-8. */
+       strv = g_new0 (gchar *, g_slist_length (contacts) + 1);
+       for (link = contacts; link != NULL; link = g_slist_next (link)) {
+               EVCard *vcard;
+               gchar *string;
+
+               vcard = E_VCARD (link->data);
+               string = e_vcard_to_string (vcard, EVC_FORMAT_VCARD_30);
+               strv[ii++] = e_util_utf8_make_valid (string);
+               g_free (string);
+       }
+
+       success = e_dbus_address_book_call_modify_contacts_sync (
+               client->priv->dbus_proxy,
+               (const gchar * const *) strv,
+               cancellable, error);
+
+       g_strfreev (strv);
+
+       return success;
+}
+
+/* Helper for e_book_client_remove_contact() */
+static void
+book_client_remove_contact_thread (GSimpleAsyncResult *simple,
+                                   GObject *source_object,
+                                   GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
 
-       res = e_client_proxy_call_sync_strv__void (
-               E_CLIENT (client),
-               (const gchar * const *) array,
-               cancellable, error,
-               e_gdbus_book_call_modify_contacts_sync);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-       g_strfreev (array);
+       e_book_client_remove_contact_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->contact,
+               cancellable, &error);
 
-       return res;
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -1626,31 +2008,29 @@ e_book_client_remove_contact (EBookClient *client,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
 {
-       const gchar *uid, *safe_uid;
-       const gchar *strv[2];
-       gchar *gdbus_uid = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       g_return_if_fail (contact != NULL);
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (E_IS_CONTACT (contact));
 
-       uid = e_contact_get_const ( E_CONTACT (contact), E_CONTACT_UID);
-       g_return_if_fail (uid != NULL);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->contact = g_object_ref (contact);
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_remove_contact);
 
-       safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
-       g_return_if_fail (safe_uid != NULL);
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       strv[0] = safe_uid;
-       strv[1] = NULL;
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       e_client_proxy_call_strv (
-               E_CLIENT (client),
-               strv, cancellable, callback, user_data,
-               e_book_client_remove_contact,
-               e_gdbus_book_call_remove_contacts,
-               e_gdbus_book_call_remove_contacts_finish,
-               NULL, NULL, NULL, NULL);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_remove_contact_thread,
+               G_PRIORITY_DEFAULT, cancellable);
 
-       g_free (gdbus_uid);
+       g_object_unref (simple);
 }
 
 /**
@@ -1670,9 +2050,17 @@ e_book_client_remove_contact_finish (EBookClient *client,
                                      GAsyncResult *result,
                                      GError **error)
 {
-       return e_client_proxy_call_finish_void (
-               E_CLIENT (client), result, error,
-               e_book_client_remove_contact);
+       GSimpleAsyncResult *simple;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_remove_contact), FALSE);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+
+       /* Assume success unless a GError is set. */
+       return !g_simple_async_result_propagate_error (simple, error);
 }
 
 /**
@@ -1690,40 +2078,40 @@ e_book_client_remove_contact_finish (EBookClient *client,
  **/
 gboolean
 e_book_client_remove_contact_sync (EBookClient *client,
-                                   /* const */ EContact *contact,
+                                   EContact *contact,
                                    GCancellable *cancellable,
                                    GError **error)
 {
-       gboolean res;
-       const gchar *strv[2];
-       const gchar *uid, *safe_uid;
-       gchar *gdbus_uid = NULL;
+       const gchar *uid;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
 
-       if (client->priv->dbus_proxy == NULL) {
-               set_proxy_gone_error (error);
-               return FALSE;
-       }
-
-       uid = e_contact_get_const (E_CONTACT (contact), E_CONTACT_UID);
+       uid = e_contact_get_const (contact, E_CONTACT_UID);
        g_return_val_if_fail (uid != NULL, FALSE);
 
-       safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
-       g_return_val_if_fail (safe_uid != NULL, FALSE);
+       return e_book_client_remove_contact_by_uid_sync (
+               client, uid, cancellable, error);
+}
 
-       strv[0] = safe_uid;
-       strv[1] = NULL;
+/* Helper for e_book_client_remove_contact_by_uid() */
+static void
+book_client_remove_contact_by_uid_thread (GSimpleAsyncResult *simple,
+                                          GObject *source_object,
+                                          GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
 
-       res = e_client_proxy_call_sync_strv__void (
-               E_CLIENT (client),
-               strv, cancellable, error,
-               e_gdbus_book_call_remove_contacts_sync);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-       g_free (gdbus_uid);
+       e_book_client_remove_contact_by_uid_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->uid,
+               cancellable, &error);
 
-       return res;
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -1747,27 +2135,29 @@ e_book_client_remove_contact_by_uid (EBookClient *client,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
 {
-       const gchar *safe_uid;
-       gchar *gdbus_uid = NULL;
-       const gchar *strv[2];
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (uid != NULL);
 
-       safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
-       g_return_if_fail (safe_uid != NULL);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->uid = g_strdup (uid);
 
-       strv[0] = safe_uid;
-       strv[1] = NULL;
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_remove_contact_by_uid);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       e_client_proxy_call_strv (
-               E_CLIENT (client),
-               strv, cancellable, callback, user_data,
-               e_book_client_remove_contact_by_uid,
-               e_gdbus_book_call_remove_contacts,
-               e_gdbus_book_call_remove_contacts_finish,
-               NULL, NULL, NULL, NULL);
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       g_free (gdbus_uid);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_remove_contact_by_uid_thread,
+               G_PRIORITY_DEFAULT, cancellable);
+
+       g_object_unref (simple);
 }
 
 /**
@@ -1787,9 +2177,17 @@ e_book_client_remove_contact_by_uid_finish (EBookClient *client,
                                             GAsyncResult *result,
                                             GError **error)
 {
-       return e_client_proxy_call_finish_void (
-               E_CLIENT (client), result, error,
-               e_book_client_remove_contact_by_uid);
+       GSimpleAsyncResult *simple;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_remove_contact_by_uid), FALSE);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+
+       /* Assume success unless a GError is set. */
+       return !g_simple_async_result_propagate_error (simple, error);
 }
 
 /**
@@ -1811,32 +2209,33 @@ e_book_client_remove_contact_by_uid_sync (EBookClient *client,
                                           GCancellable *cancellable,
                                           GError **error)
 {
-       gboolean res;
-       const gchar *safe_uid;
-       gchar *gdbus_uid = NULL;
-       const gchar *strv[2];
+       GSList link = { (gpointer) uid, NULL };
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (uid != NULL, FALSE);
 
-       if (client->priv->dbus_proxy == NULL) {
-               set_proxy_gone_error (error);
-               return FALSE;
-       }
-
-       safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
-       g_return_val_if_fail (safe_uid != NULL, FALSE);
+       return e_book_client_remove_contacts_sync (
+               client, &link, cancellable, error);
+}
 
-       strv[0] = safe_uid;
-       strv[1] = NULL;
+/* Helper for e_book_client_remove_contacts() */
+static void
+book_client_remove_contacts_thread (GSimpleAsyncResult *simple,
+                                    GObject *source_object,
+                                    GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
 
-       res = e_client_proxy_call_sync_strv__void (
-               E_CLIENT (client), strv, cancellable, error,
-               e_gdbus_book_call_remove_contacts_sync);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-       g_free (gdbus_uid);
+       e_book_client_remove_contacts_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->string_list,
+               cancellable, &error);
 
-       return res;
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -1863,23 +2262,30 @@ e_book_client_remove_contacts (EBookClient *client,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
 {
-       gchar **strv;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (uids != NULL);
 
-       strv = e_client_util_slist_to_strv (uids);
-       g_return_if_fail (strv != NULL);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->string_list = g_slist_copy_deep (
+               (GSList *) uids, (GCopyFunc) g_strdup, NULL);
 
-       e_client_proxy_call_strv (
-               E_CLIENT (client),
-               (const gchar * const *) strv,
-               cancellable, callback, user_data,
-               e_book_client_remove_contacts,
-               e_gdbus_book_call_remove_contacts,
-               e_gdbus_book_call_remove_contacts_finish,
-               NULL, NULL, NULL, NULL);
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_remove_contacts);
 
-       g_strfreev (strv);
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
+
+       g_simple_async_result_run_in_thread (
+               simple, book_client_remove_contacts_thread,
+               G_PRIORITY_DEFAULT, cancellable);
+
+       g_object_unref (simple);
 }
 
 /**
@@ -1899,9 +2305,17 @@ e_book_client_remove_contacts_finish (EBookClient *client,
                                       GAsyncResult *result,
                                       GError **error)
 {
-       return e_client_proxy_call_finish_void (
-               E_CLIENT (client), result, error,
-               e_book_client_remove_contacts);
+       GSimpleAsyncResult *simple;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_remove_contacts), FALSE);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+
+       /* Assume success unless a GError is set. */
+       return !g_simple_async_result_propagate_error (simple, error);
 }
 
 /**
@@ -1926,8 +2340,9 @@ e_book_client_remove_contacts_sync (EBookClient *client,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       gboolean res;
        gchar **strv;
+       gboolean success;
+       gint ii = 0;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (uids != NULL, FALSE);
@@ -1937,17 +2352,41 @@ e_book_client_remove_contacts_sync (EBookClient *client,
                return FALSE;
        }
 
-       strv = e_client_util_slist_to_strv (uids);
-       g_return_val_if_fail (strv != NULL, FALSE);
+       strv = g_new0 (gchar *, g_slist_length ((GSList *) uids) + 1);
+       while (uids != NULL) {
+               strv[ii++] = e_util_utf8_make_valid (uids->data);
+               uids = g_slist_next (uids);
+       }
 
-       res = e_client_proxy_call_sync_strv__void (
-               E_CLIENT (client), (const gchar * const *) strv,
-               cancellable, error,
-               e_gdbus_book_call_remove_contacts_sync);
+       success = e_dbus_address_book_call_remove_contacts_sync (
+               client->priv->dbus_proxy,
+               (const gchar * const *) strv,
+               cancellable, error);
 
        g_strfreev (strv);
 
-       return res;
+       return success;
+}
+
+/* Helper for e_book_client_get_contact() */
+static void
+book_client_get_contact_thread (GSimpleAsyncResult *simple,
+                                GObject *source_object,
+                                GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
+
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       e_book_client_get_contact_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->uid,
+               &async_context->contact,
+               cancellable, &error);
+
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -1971,35 +2410,40 @@ e_book_client_get_contact (EBookClient *client,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
 {
-       const gchar *safe_uid;
-       gchar *gdbus_uid = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (uid != NULL);
 
-       safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
-       g_return_if_fail (safe_uid != NULL);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->uid  = g_strdup (uid);
 
-       e_client_proxy_call_string (
-               E_CLIENT (client),
-               safe_uid, cancellable, callback, user_data,
-               e_book_client_get_contact,
-               e_gdbus_book_call_get_contact,
-               NULL, NULL,
-               e_gdbus_book_call_get_contact_finish,
-               NULL, NULL);
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_get_contact);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
+
+       g_simple_async_result_run_in_thread (
+               simple, book_client_get_contact_thread,
+               G_PRIORITY_DEFAULT, cancellable);
 
-       g_free (gdbus_uid);
+       g_object_unref (simple);
 }
 
 /**
  * e_book_client_get_contact_finish:
  * @client: an #EBookClient
  * @result: a #GAsyncResult
- * @contact: (out): an #EContact for previously given uid
+ * @out_contact: (out): an #EContact for previously given uid
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_book_client_get_contact().
- * If successful, then the @contact is set to newly allocated
+ * If successful, then the @out_contact is set to newly allocated
  * #EContact, which should be freed with g_object_unref().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
@@ -2009,39 +2453,41 @@ e_book_client_get_contact (EBookClient *client,
 gboolean
 e_book_client_get_contact_finish (EBookClient *client,
                                   GAsyncResult *result,
-                                  EContact **contact,
+                                  EContact **out_contact,
                                   GError **error)
 {
-       gboolean res;
-       gchar *vcard = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       g_return_val_if_fail (contact != NULL, FALSE);
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_get_contact), FALSE);
 
-       res = e_client_proxy_call_finish_string (
-               E_CLIENT (client),
-               result, &vcard, error,
-               e_book_client_get_contact);
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       if (g_simple_async_result_propagate_error (simple, error))
+               return FALSE;
 
-       if (vcard && res)
-               *contact = e_contact_new_from_vcard (vcard);
-       else
-               *contact = NULL;
+       g_return_val_if_fail (async_context->contact != NULL, FALSE);
 
-       g_free (vcard);
+       if (out_contact != NULL)
+               *out_contact = g_object_ref (async_context->contact);
 
-       return res;
+       return TRUE;
 }
 
 /**
  * e_book_client_get_contact_sync:
  * @client: an #EBookClient
  * @uid: a unique string ID specifying the contact
- * @contact: (out): an #EContact for given @uid
+ * @out_contact: (out): an #EContact for given @uid
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Receive #EContact from the @client for the gived @uid.
- * If successful, then the @contact is set to newly allocated
+ * If successful, then the @out_contact is set to newly allocated
  * #EContact, which should be freed with g_object_unref().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
@@ -2051,40 +2497,64 @@ e_book_client_get_contact_finish (EBookClient *client,
 gboolean
 e_book_client_get_contact_sync (EBookClient *client,
                                 const gchar *uid,
-                                EContact **contact,
+                                EContact **out_contact,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       gboolean res;
-       const gchar *safe_uid;
-       gchar *vcard = NULL, *gdbus_uid = NULL;
+       gchar *utf8_uid;
+       gchar *vcard = NULL;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (uid != NULL, FALSE);
-       g_return_val_if_fail (contact != NULL, FALSE);
+       g_return_val_if_fail (out_contact != NULL, FALSE);
 
        if (client->priv->dbus_proxy == NULL) {
                set_proxy_gone_error (error);
                return FALSE;
        }
 
-       safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
-       g_return_val_if_fail (safe_uid != NULL, FALSE);
+       utf8_uid = e_util_utf8_make_valid (uid);
+
+       success = e_dbus_address_book_call_get_contact_sync (
+               client->priv->dbus_proxy,
+               utf8_uid, &vcard, cancellable, error);
+
+       /* Sanity check. */
+       g_return_val_if_fail (
+               (success && (vcard != NULL)) ||
+               (!success && (vcard == NULL)), FALSE);
+
+       if (vcard != NULL) {
+               *out_contact =
+                       e_contact_new_from_vcard_with_uid (vcard, utf8_uid);
+               g_free (vcard);
+       }
+
+       g_free (utf8_uid);
+
+       return success;
+}
 
-       res = e_client_proxy_call_sync_string__string (
-               E_CLIENT (client),
-               safe_uid, &vcard, cancellable, error,
-               e_gdbus_book_call_get_contact_sync);
+/* Helper for e_book_client_get_contacts() */
+static void
+book_client_get_contacts_thread (GSimpleAsyncResult *simple,
+                                 GObject *source_object,
+                                 GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
 
-       if (vcard && res)
-               *contact = e_contact_new_from_vcard_with_uid (vcard, safe_uid);
-       else
-               *contact = NULL;
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-       g_free (gdbus_uid);
-       g_free (vcard);
+       e_book_client_get_contacts_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->sexp,
+               &async_context->object_list,
+               cancellable, &error);
 
-       return res;
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -2111,33 +2581,42 @@ e_book_client_get_contacts (EBookClient *client,
                             GAsyncReadyCallback callback,
                             gpointer user_data)
 {
-       gchar *gdbus_sexp = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (sexp != NULL);
 
-       e_client_proxy_call_string (
-               E_CLIENT (client),
-               e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
-               cancellable, callback, user_data,
-               e_book_client_get_contacts,
-               e_gdbus_book_call_get_contact_list,
-               NULL, NULL, NULL,
-               e_gdbus_book_call_get_contact_list_finish,
-               NULL);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->sexp = g_strdup (sexp);
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_get_contacts);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       g_free (gdbus_sexp);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_get_contacts_thread,
+               G_PRIORITY_DEFAULT, cancellable);
+
+       g_object_unref (simple);
 }
 
 /**
  * e_book_client_get_contacts_finish:
  * @client: an #EBookClient
  * @result: a #GAsyncResult
- * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
+ * @out_contacts: (element-type EContact) (out): a #GSList of matched
+ *                #EContact-s
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_book_client_get_contacts().
- * If successful, then the @contacts is set to newly allocated list of #EContact-s,
- * which should be freed with e_client_util_free_object_slist().
+ * If successful, then the @out_contacts is set to newly allocated list of
+ * #EContact-s, which should be freed with e_client_util_free_object_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -2146,47 +2625,42 @@ e_book_client_get_contacts (EBookClient *client,
 gboolean
 e_book_client_get_contacts_finish (EBookClient *client,
                                    GAsyncResult *result,
-                                   GSList **contacts,
+                                   GSList **out_contacts,
                                    GError **error)
 {
-       gboolean res;
-       gchar **vcards = NULL;
-
-       g_return_val_if_fail (contacts != NULL, FALSE);
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       res = e_client_proxy_call_finish_strv (
-               E_CLIENT (client),
-               result, &vcards, error,
-               e_book_client_get_contacts);
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_get_contacts), FALSE);
 
-       if (vcards && res) {
-               gint ii;
-               GSList *slist = NULL;
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-               for (ii = 0; vcards[ii]; ii++) {
-                       slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
-               }
+       if (g_simple_async_result_propagate_error (simple, error))
+               return FALSE;
 
-               *contacts = g_slist_reverse (slist);
-       } else {
-               *contacts = NULL;
+       if (out_contacts != NULL) {
+               *out_contacts = async_context->object_list;
+               async_context->object_list = NULL;
        }
 
-       g_strfreev (vcards);
-
-       return res;
+       return TRUE;
 }
 
 /**
  * e_book_client_get_contacts_sync:
  * @client: an #EBookClient
  * @sexp: an S-expression representing the query
- * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
+ * @out_contacts: (element-type EContact) (out): a #GSList of matched
+ *                #EContact-s
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Query @client with @sexp, receiving a list of contacts which matched.
- * If successful, then the @contacts is set to newly allocated #GSList of
+ * If successful, then the @out_contacts is set to newly allocated #GSList of
  * #EContact-s, which should be freed with e_client_util_free_object_slist().
  *
  * Note: @sexp can be obtained through #EBookQuery, by converting it
@@ -2199,46 +2673,73 @@ e_book_client_get_contacts_finish (EBookClient *client,
 gboolean
 e_book_client_get_contacts_sync (EBookClient *client,
                                  const gchar *sexp,
-                                 GSList **contacts,
+                                 GSList **out_contacts,
                                  GCancellable *cancellable,
                                  GError **error)
 {
-       gboolean res;
-       gchar *gdbus_sexp = NULL;
+       gchar *utf8_sexp;
        gchar **vcards = NULL;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (sexp != NULL, FALSE);
-       g_return_val_if_fail (contacts != NULL, FALSE);
+       g_return_val_if_fail (out_contacts != NULL, FALSE);
 
        if (client->priv->dbus_proxy == NULL) {
                set_proxy_gone_error (error);
                return FALSE;
        }
 
-       res = e_client_proxy_call_sync_string__strv (
-               E_CLIENT (client),
-               e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
-               &vcards, cancellable, error,
-               e_gdbus_book_call_get_contact_list_sync);
+       utf8_sexp = e_util_utf8_make_valid (sexp);
+
+       success = e_dbus_address_book_call_get_contact_list_sync (
+               client->priv->dbus_proxy,
+               utf8_sexp, &vcards, cancellable, error);
+
+       g_free (utf8_sexp);
 
-       if (vcards && res) {
+       /* Sanity check. */
+       g_return_val_if_fail (
+               (success && (vcards != NULL)) ||
+               (!success && (vcards == NULL)), FALSE);
+
+       if (vcards != NULL) {
+               EContact *contact;
+               GSList *tmp = NULL;
                gint ii;
-               GSList *slist = NULL;
 
-               for (ii = 0; vcards[ii]; ii++) {
-                       slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
+               for (ii = 0; vcards[ii] != NULL; ii++) {
+                       contact = e_contact_new_from_vcard (vcards[ii]);
+                       tmp = g_slist_prepend (tmp, contact);
                }
 
-               *contacts = g_slist_reverse (slist);
-       } else {
-               *contacts = NULL;
+               *out_contacts = g_slist_reverse (tmp);
+
+               g_strfreev (vcards);
        }
 
-       g_free (gdbus_sexp);
-       g_strfreev (vcards);
+       return success;
+}
+
+/* Helper for e_book_client_get_contacts_uids() */
+static void
+book_client_get_contacts_uids_thread (GSimpleAsyncResult *simple,
+                                      GObject *source_object,
+                                      GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
+
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       e_book_client_get_contacts_uids_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->sexp,
+               &async_context->string_list,
+               cancellable, &error);
 
-       return res;
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -2265,32 +2766,41 @@ e_book_client_get_contacts_uids (EBookClient *client,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
 {
-       gchar *gdbus_sexp = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (sexp != NULL);
 
-       e_client_proxy_call_string (
-               E_CLIENT (client),
-               e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
-               cancellable, callback, user_data,
-               e_book_client_get_contacts_uids,
-               e_gdbus_book_call_get_contact_list_uids,
-               NULL, NULL, NULL,
-               e_gdbus_book_call_get_contact_list_uids_finish,
-               NULL);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->sexp = g_strdup (sexp);
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_get_contacts_uids);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       g_free (gdbus_sexp);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_get_contacts_uids_thread,
+               G_PRIORITY_DEFAULT, cancellable);
+
+       g_object_unref (simple);
 }
 
 /**
  * e_book_client_get_contacts_uids_finish:
  * @client: an #EBookClient
  * @result: a #GAsyncResult
- * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
+ * @out_contact_uids: (element-type utf8) (out): a #GSList of matched
+ *                    contact UIDs stored as strings
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_book_client_get_contacts_uids().
- * If successful, then the @contacts_uids is set to newly allocated list
+ * If successful, then the @out_contact_uids is set to newly allocated list
  * of UID strings, which should be freed with e_client_util_free_string_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
@@ -2300,47 +2810,42 @@ e_book_client_get_contacts_uids (EBookClient *client,
 gboolean
 e_book_client_get_contacts_uids_finish (EBookClient *client,
                                         GAsyncResult *result,
-                                        GSList **contacts_uids,
+                                        GSList **out_contact_uids,
                                         GError **error)
 {
-       gboolean res;
-       gchar **uids = NULL;
-
-       g_return_val_if_fail (contacts_uids != NULL, FALSE);
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
-       res = e_client_proxy_call_finish_strv (
-               E_CLIENT (client),
-               result, &uids, error,
-               e_book_client_get_contacts_uids);
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_get_contacts_uids), FALSE);
 
-       if (uids && res) {
-               gint ii;
-               GSList *slist = NULL;
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-               for (ii = 0; uids[ii]; ii++) {
-                       slist = g_slist_prepend (slist, g_strdup (uids[ii]));
-               }
+       if (g_simple_async_result_propagate_error (simple, error))
+               return FALSE;
 
-               *contacts_uids = g_slist_reverse (slist);
-       } else {
-               *contacts_uids = NULL;
+       if (out_contact_uids != NULL) {
+               *out_contact_uids = async_context->string_list;
+               async_context->string_list = NULL;
        }
 
-       g_strfreev (uids);
-
-       return res;
+       return TRUE;
 }
 
 /**
  * e_book_client_get_contacts_uids_sync:
  * @client: an #EBookClient
  * @sexp: an S-expression representing the query
- * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
+ * @out_contact_uids: (element-type utf8) (out): a #GSList of matched
+ *                    contacts UIDs stored as strings
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Query @client with @sexp, receiving a list of contacts UIDs which matched.
- * If successful, then the @contacts_uids is set to newly allocated list
+ * If successful, then the @out_contact_uids is set to newly allocated list
  * of UID strings, which should be freed with e_client_util_free_string_slist().
  *
  * Note: @sexp can be obtained through #EBookQuery, by converting it
@@ -2353,46 +2858,76 @@ e_book_client_get_contacts_uids_finish (EBookClient *client,
 gboolean
 e_book_client_get_contacts_uids_sync (EBookClient *client,
                                       const gchar *sexp,
-                                      GSList **contacts_uids,
+                                      GSList **out_contact_uids,
                                       GCancellable *cancellable,
                                       GError **error)
 {
-       gboolean res;
-       gchar *gdbus_sexp = NULL;
+       gchar *utf8_sexp;
        gchar **uids = NULL;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (sexp != NULL, FALSE);
-       g_return_val_if_fail (contacts_uids != NULL, FALSE);
+       g_return_val_if_fail (out_contact_uids != NULL, FALSE);
 
        if (client->priv->dbus_proxy == NULL) {
                set_proxy_gone_error (error);
                return FALSE;
        }
 
-       res = e_client_proxy_call_sync_string__strv (
-               E_CLIENT (client),
-               e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
-               &uids, cancellable, error,
-               e_gdbus_book_call_get_contact_list_uids_sync);
+       utf8_sexp = e_util_utf8_make_valid (sexp);
 
-       if (uids && res) {
+       success = e_dbus_address_book_call_get_contact_list_uids_sync (
+               client->priv->dbus_proxy,
+               utf8_sexp, &uids, cancellable, error);
+
+       g_free (utf8_sexp);
+
+       /* Sanity check. */
+       g_return_val_if_fail (
+               (success && (uids != NULL)) ||
+               (!success && (uids == NULL)), FALSE);
+
+       /* XXX We should have passed the string array directly
+        *     back to the caller instead of building a linked
+        *     list.  This is unnecessary work. */
+       if (uids != NULL) {
+               GSList *tmp = NULL;
                gint ii;
-               GSList *slist = NULL;
 
-               for (ii = 0; uids[ii]; ii++) {
-                       slist = g_slist_prepend (slist, g_strdup (uids[ii]));
+               /* Take ownership of the string array elements. */
+               for (ii = 0; uids[ii] != NULL; ii++) {
+                       tmp = g_slist_prepend (tmp, uids[ii]);
+                       uids[ii] = NULL;
                }
 
-               *contacts_uids = g_slist_reverse (slist);
-       } else {
-               *contacts_uids = NULL;
+               *out_contact_uids = g_slist_reverse (tmp);
+
+               g_free (uids);
        }
 
-       g_free (gdbus_sexp);
-       g_strfreev (uids);
+       return success;
+}
+
+/* Helper for e_book_client_get_view() */
+static void
+book_client_get_view_thread (GSimpleAsyncResult *simple,
+                             GObject *source_object,
+                             GCancellable *cancellable)
+{
+       AsyncContext *async_context;
+       GError *error = NULL;
 
-       return res;
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       e_book_client_get_view_sync (
+               E_BOOK_CLIENT (source_object),
+               async_context->sexp,
+               &async_context->client_view,
+               cancellable, &error);
+
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
 }
 
 /**
@@ -2419,73 +2954,41 @@ e_book_client_get_view (EBookClient *client,
                         GAsyncReadyCallback callback,
                         gpointer user_data)
 {
-       gchar *gdbus_sexp = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
 
+       g_return_if_fail (E_IS_BOOK_CLIENT (client));
        g_return_if_fail (sexp != NULL);
 
-       e_client_proxy_call_string (
-               E_CLIENT (client),
-               e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
-               cancellable, callback, user_data,
-               e_book_client_get_view,
-               e_gdbus_book_call_get_view,
-               NULL, NULL,
-               e_gdbus_book_call_get_view_finish, NULL, NULL);
-
-       g_free (gdbus_sexp);
-}
-
-static gboolean
-complete_get_view (EBookClient *client,
-                   gboolean res,
-                   gchar *view_path,
-                   EBookClientView **view,
-                   GError **error)
-{
-       g_return_val_if_fail (view != NULL, FALSE);
-
-       if (view_path && res && book_factory) {
-               GDBusConnection *connection;
-               GError *local_error = NULL;
-
-               connection = g_dbus_proxy_get_connection (
-                       G_DBUS_PROXY (book_factory));
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->sexp = g_strdup (sexp);
 
-               *view = g_initable_new (
-                       E_TYPE_BOOK_CLIENT_VIEW,
-                       NULL, &local_error,
-                       "client", client,
-                       "connection", connection,
-                       "object-path", view_path,
-                       NULL);
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback, user_data,
+               e_book_client_get_view);
 
-               if (local_error != NULL) {
-                       unwrap_dbus_error (local_error, error);
-                       res = FALSE;
-               }
-       } else {
-               *view = NULL;
-               res = FALSE;
-       }
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       if (!*view && error && !*error)
-               g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Cannot get connection to view"));
+       g_simple_async_result_set_op_res_gpointer (
+               simple, async_context, (GDestroyNotify) async_context_free);
 
-       g_free (view_path);
+       g_simple_async_result_run_in_thread (
+               simple, book_client_get_view_thread,
+               G_PRIORITY_DEFAULT, cancellable);
 
-       return res;
+       g_object_unref (simple);
 }
 
 /**
  * e_book_client_get_view_finish:
  * @client: an #EBookClient
  * @result: a #GAsyncResult
- * @view: (out): an #EBookClientView
+ * @out_view: (out): an #EBookClientView
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_book_client_get_view().
- * If successful, then the @view is set to newly allocated #EBookClientView,
- * which should be freed with g_object_unref().
+ * If successful, then the @out_view is set to newly allocated
+ * #EBookClientView, which should be freed with g_object_unref().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -2494,33 +2997,42 @@ complete_get_view (EBookClient *client,
 gboolean
 e_book_client_get_view_finish (EBookClient *client,
                                GAsyncResult *result,
-                               EBookClientView **view,
+                               EBookClientView **out_view,
                                GError **error)
 {
-       gboolean res;
-       gchar *view_path = NULL;
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (client),
+               e_book_client_get_view), FALSE);
 
-       g_return_val_if_fail (view != NULL, FALSE);
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-       res = e_client_proxy_call_finish_string (
-               E_CLIENT (client),
-               result, &view_path, error,
-               e_book_client_get_view);
+       if (g_simple_async_result_propagate_error (simple, error))
+               return FALSE;
 
-       return complete_get_view (client, res, view_path, view, error);
+       g_return_val_if_fail (async_context->client_view != NULL, FALSE);
+
+       if (out_view != NULL)
+               *out_view = g_object_ref (async_context->client_view);
+
+       return TRUE;
 }
 
 /**
  * e_book_client_get_view_sync:
  * @client: an #EBookClient
  * @sexp: an S-expression representing the query
- * @view: (out) an #EBookClientView
+ * @out_view: (out) an #EBookClientView
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Query @client with @sexp, creating an #EBookClientView.
- * If successful, then the @view is set to newly allocated #EBookClientView,
- * which should be freed with g_object_unref().
+ * If successful, then the @out_view is set to newly allocated
+ * #EBookClientView, which should be freed with g_object_unref().
  *
  * Note: @sexp can be obtained through #EBookQuery, by converting it
  * to a string with e_book_query_to_string().
@@ -2532,31 +3044,62 @@ e_book_client_get_view_finish (EBookClient *client,
 gboolean
 e_book_client_get_view_sync (EBookClient *client,
                              const gchar *sexp,
-                             EBookClientView **view,
+                             EBookClientView **out_view,
                              GCancellable *cancellable,
                              GError **error)
 {
-       gboolean res;
-       gchar *gdbus_sexp = NULL;
-       gchar *view_path = NULL;
+       gchar *utf8_sexp;
+       gchar *object_path = NULL;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
        g_return_val_if_fail (sexp != NULL, FALSE);
-       g_return_val_if_fail (view != NULL, FALSE);
+       g_return_val_if_fail (out_view != NULL, FALSE);
 
        if (client->priv->dbus_proxy == NULL) {
                set_proxy_gone_error (error);
                return FALSE;
        }
 
-       res = e_client_proxy_call_sync_string__string (
-               E_CLIENT (client),
-               e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
-               &view_path, cancellable, error,
-               e_gdbus_book_call_get_view_sync);
+       utf8_sexp = e_util_utf8_make_valid (sexp);
 
-       g_free (gdbus_sexp);
+       success = e_dbus_address_book_call_get_view_sync (
+               client->priv->dbus_proxy, utf8_sexp,
+               &object_path, cancellable, error);
+
+       g_free (utf8_sexp);
+
+       /* Sanity check. */
+       g_return_val_if_fail (
+               (success && (object_path != NULL)) ||
+               (!success && (object_path == NULL)), FALSE);
+
+       if (object_path != NULL) {
+               GDBusConnection *connection;
+               EBookClientView *client_view;
+
+               connection = g_dbus_proxy_get_connection (
+                       G_DBUS_PROXY (client->priv->dbus_proxy));
+
+               client_view = g_initable_new (
+                       E_TYPE_BOOK_CLIENT_VIEW,
+                       cancellable, error,
+                       "client", client,
+                       "connection", connection,
+                       "object-path", object_path,
+                       NULL);
+
+               /* XXX Would have been easier to return the
+                *     EBookClientView directly rather than
+                *     through an "out" parameter. */
+               if (client_view != NULL)
+                       *out_view = client_view;
+               else
+                       success = FALSE;
+
+               g_free (object_path);
+       }
 
-       return complete_get_view (client, res, view_path, view, error);
+       return success;
 }
 
index 26da1d6..1e782ab 100644 (file)
@@ -124,8 +124,8 @@ GType               e_book_client_get_type          (void) G_GNUC_CONST;
 EBookClient *  e_book_client_new               (ESource *source,
                                                 GError **error);
 gboolean       e_book_client_get_self          (ESourceRegistry *registry,
-                                                EContact **contact,
-                                                EBookClient **client,
+                                                EContact **out_contact,
+                                                EBookClient **out_client,
                                                 GError **error);
 gboolean       e_book_client_set_self          (EBookClient *client,
                                                 EContact *contact,
@@ -139,11 +139,11 @@ void              e_book_client_add_contact       (EBookClient *client,
 gboolean       e_book_client_add_contact_finish
                                                (EBookClient *client,
                                                 GAsyncResult *result,
-                                                gchar **added_uid,
+                                                gchar **out_added_uid,
                                                 GError **error);
 gboolean       e_book_client_add_contact_sync  (EBookClient *client,
                                                 EContact *contact,
-                                                gchar **added_uid,
+                                                gchar **out_added_uid,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_book_client_add_contacts      (EBookClient *client,
@@ -154,11 +154,11 @@ void              e_book_client_add_contacts      (EBookClient *client,
 gboolean       e_book_client_add_contacts_finish
                                                (EBookClient *client,
                                                 GAsyncResult *result,
-                                                GSList **added_uids,
+                                                GSList **out_added_uids,
                                                 GError **error);
 gboolean       e_book_client_add_contacts_sync (EBookClient *client,
                                                 GSList *contacts,
-                                                GSList **added_uids,
+                                                GSList **out_added_uids,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_book_client_modify_contact    (EBookClient *client,
@@ -240,11 +240,11 @@ void              e_book_client_get_contact       (EBookClient *client,
 gboolean       e_book_client_get_contact_finish
                                                (EBookClient *client,
                                                 GAsyncResult *result,
-                                                EContact **contact,
+                                                EContact **out_contact,
                                                 GError **error);
 gboolean       e_book_client_get_contact_sync  (EBookClient *client,
                                                 const gchar *uid,
-                                                EContact **contact,
+                                                EContact **out_contact,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_book_client_get_contacts      (EBookClient *client,
@@ -259,7 +259,7 @@ gboolean    e_book_client_get_contacts_finish
                                                 GError **error);
 gboolean       e_book_client_get_contacts_sync (EBookClient *client,
                                                 const gchar *sexp,
-                                                GSList **contacts,
+                                                GSList **out_contacts,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_book_client_get_contacts_uids (EBookClient *client,
@@ -270,12 +270,12 @@ void              e_book_client_get_contacts_uids (EBookClient *client,
 gboolean       e_book_client_get_contacts_uids_finish
                                                (EBookClient *client,
                                                 GAsyncResult *result,
-                                                GSList **contacts_uids,
+                                                GSList **out_contact_uids,
                                                 GError **error);
 gboolean       e_book_client_get_contacts_uids_sync
                                                (EBookClient *client,
                                                 const gchar *sexp,
-                                                GSList **contacts_uids,
+                                                GSList **out_contact_uids,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_book_client_get_view          (EBookClient *client,
@@ -285,11 +285,11 @@ void              e_book_client_get_view          (EBookClient *client,
                                                 gpointer user_data);
 gboolean       e_book_client_get_view_finish   (EBookClient *client,
                                                 GAsyncResult *result,
-                                                EBookClientView **view,
+                                                EBookClientView **out_view,
                                                 GError **error);
 gboolean       e_book_client_get_view_sync     (EBookClient *client,
                                                 const gchar *sexp,
-                                                EBookClientView **view,
+                                                EBookClientView **out_view,
                                                 GCancellable *cancellable,
                                                 GError **error);
 
index 948dca1..200d8e2 100644 (file)
@@ -81,6 +81,8 @@ book_backend_get_backend_property (EBookBackend *backend,
                e_data_book_respond_get_backend_property (book, opid, NULL, "TRUE");
        } else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENING)) {
                e_data_book_respond_get_backend_property (book, opid, NULL, "FALSE");
+       } else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_REVISION)) {
+               e_data_book_respond_get_backend_property (book, opid, NULL, "0");
        } else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_ONLINE)) {
                e_data_book_respond_get_backend_property (book, opid, NULL, e_backend_get_online (E_BACKEND (backend)) ? "TRUE" : "FALSE");
        } else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_READONLY)) {
@@ -497,17 +499,8 @@ e_book_backend_open (EBookBackend *backend,
        g_mutex_lock (&backend->priv->clients_mutex);
 
        if (e_book_backend_is_opened (backend)) {
-               gboolean online;
-               gboolean writable;
-
                g_mutex_unlock (&backend->priv->clients_mutex);
 
-               online = e_backend_get_online (E_BACKEND (backend));
-               writable = e_book_backend_get_writable (backend);
-
-               e_data_book_report_online (book, online);
-               e_data_book_report_readonly (book, !writable);
-
                e_data_book_respond_open (book, opid, NULL);
        } else {
                g_mutex_unlock (&backend->priv->clients_mutex);
@@ -1246,23 +1239,16 @@ e_book_backend_notify_error (EBookBackend *backend,
  * Notifies all backend's clients about the current readonly state.
  *
  * Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_book_backend_set_writable() instead.
  **/
 void
 e_book_backend_notify_readonly (EBookBackend *backend,
                                 gboolean is_readonly)
 {
-       EBookBackendPrivate *priv;
-       GList *clients;
+       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
 
-       priv = backend->priv;
        e_book_backend_set_writable (backend, !is_readonly);
-       g_mutex_lock (&priv->clients_mutex);
-
-       for (clients = priv->clients; clients != NULL; clients = g_list_next (clients))
-               e_data_book_report_readonly (E_DATA_BOOK (clients->data), is_readonly);
-
-       g_mutex_unlock (&priv->clients_mutex);
-
 }
 
 /**
@@ -1274,25 +1260,16 @@ e_book_backend_notify_readonly (EBookBackend *backend,
  * Meant to be used by backend implementations.
  *
  * Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_backend_set_online() instead.
  **/
 void
 e_book_backend_notify_online (EBookBackend *backend,
                               gboolean is_online)
 {
-       EBookBackendPrivate *priv;
-       GList *clients;
-
-       /* XXX Disregard the argument.
-        *     EBackend determines this for itself. */
-       is_online = e_backend_get_online (E_BACKEND (backend));
-
-       priv = backend->priv;
-       g_mutex_lock (&priv->clients_mutex);
-
-       for (clients = priv->clients; clients != NULL; clients = g_list_next (clients))
-               e_data_book_report_online (E_DATA_BOOK (clients->data), is_online);
+       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
 
-       g_mutex_unlock (&priv->clients_mutex);
+       e_backend_set_online (E_BACKEND (backend), is_online);
 }
 
 /**
index 890e0a6..6358805 100644 (file)
@@ -285,10 +285,6 @@ void               e_book_backend_notify_complete  (EBookBackend *backend);
 
 void           e_book_backend_notify_error     (EBookBackend *backend,
                                                 const gchar *message);
-void           e_book_backend_notify_readonly  (EBookBackend *backend,
-                                                gboolean is_readonly);
-void           e_book_backend_notify_online    (EBookBackend *backend,
-                                                gboolean is_online);
 void           e_book_backend_notify_property_changed
                                                (EBookBackend *backend,
                                                 const gchar *prop_name,
@@ -348,6 +344,10 @@ void               e_book_backend_foreach_view     (EBookBackend *backend,
                                                                       gpointer user_data);
 void           e_book_backend_notify_opened    (EBookBackend *backend,
                                                 GError *error);
+void           e_book_backend_notify_readonly  (EBookBackend *backend,
+                                                gboolean is_readonly);
+void           e_book_backend_notify_online    (EBookBackend *backend,
+                                                gboolean is_online);
 void           e_book_backend_respond_opened   (EBookBackend *backend,
                                                 EDataBook *book,
                                                 guint32 opid,
index 372647f..6591716 100644 (file)
@@ -25,6 +25,9 @@
 #include <glib/gi18n.h>
 #include <gio/gio.h>
 
+/* Private D-Bus classes. */
+#include <e-dbus-address-book.h>
+
 #include <libebook/libebook.h>
 
 #include "e-data-book-factory.h"
 #include "e-book-backend.h"
 #include "e-book-backend-sexp.h"
 
-#include "e-gdbus-book.h"
-
 #define E_DATA_BOOK_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_DATA_BOOK, EDataBookPrivate))
 
 struct _EDataBookPrivate {
        GDBusConnection *connection;
-       EGdbusBook *dbus_interface;
+       EDBusAddressBook *dbus_interface;
        EBookBackend *backend;
        gchar *object_path;
 
@@ -89,8 +90,6 @@ typedef struct {
        guint watcher_id;
 
        union {
-               /* OP_OPEN */
-               gboolean only_if_exists;
                /* OP_GET_CONTACT */
                gchar *uid;
                /* OP_REMOVE_CONTACTS */
@@ -103,7 +102,7 @@ typedef struct {
                /* OP_GET_CONTACTS_UIDS */
                gchar *query;
                /* OP_GET_BACKEND_PROPERTY */
-               gchar *prop_name;
+               const gchar *prop_name;
 
                /* OP_REFRESH */
                /* OP_CLOSE */
@@ -166,6 +165,7 @@ op_new (OperationID op,
        data->book = g_object_ref (book);
        data->cancellable = g_cancellable_new ();
 
+       /* This is optional so we can fake client requests. */
        if (invocation != NULL) {
                GDBusConnection *connection;
                const gchar *sender;
@@ -222,9 +222,6 @@ op_unref (OperationData *data)
                        case OP_GET_CONTACTS_UIDS:
                                g_free (data->d.query);
                                break;
-                       case OP_GET_BACKEND_PROPERTY:
-                               g_free (data->d.prop_name);
-                               break;
                        default:
                                break;
                }
@@ -261,11 +258,36 @@ op_dispatch (EDataBook *book,
        g_mutex_unlock (&book->priv->open_lock);
 }
 
+static OperationData *
+op_claim (EDataBook *book,
+          guint32 opid)
+{
+       OperationData *data;
+
+       g_return_val_if_fail (E_IS_DATA_BOOK (book), NULL);
+
+       e_operation_pool_release_opid (ops_pool, opid);
+
+       g_rec_mutex_lock (&book->priv->pending_ops_lock);
+       data = g_hash_table_lookup (
+               book->priv->pending_ops,
+               GUINT_TO_POINTER (opid));
+       if (data != NULL) {
+               /* Steal the hash table's reference. */
+               g_hash_table_steal (
+                       book->priv->pending_ops,
+                       GUINT_TO_POINTER (opid));
+       }
+       g_rec_mutex_unlock (&book->priv->pending_ops_lock);
+
+       return data;
+}
+
 static void
 op_complete (EDataBook *book,
              guint32 opid)
 {
-       g_return_if_fail (book != NULL);
+       g_return_if_fail (E_IS_DATA_BOOK (book));
 
        e_operation_pool_release_opid (ops_pool, opid);
 
@@ -277,11 +299,126 @@ op_complete (EDataBook *book,
 }
 
 static void
+data_book_convert_to_client_error (GError *error)
+{
+       g_return_if_fail (error != NULL);
+
+       if (error->domain != E_DATA_BOOK_ERROR)
+               return;
+
+       switch (error->code) {
+               case E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_REPOSITORY_OFFLINE;
+                       break;
+
+               case E_DATA_BOOK_STATUS_PERMISSION_DENIED:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_PERMISSION_DENIED;
+                       break;
+
+               case E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND:
+                       error->domain = E_BOOK_CLIENT_ERROR;
+                       error->code = E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND;
+                       break;
+
+               case E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS:
+                       error->domain = E_BOOK_CLIENT_ERROR;
+                       error->code = E_BOOK_CLIENT_ERROR_CONTACT_ID_ALREADY_EXISTS;
+                       break;
+
+               case E_DATA_BOOK_STATUS_AUTHENTICATION_FAILED:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_AUTHENTICATION_FAILED;
+                       break;
+
+               case E_DATA_BOOK_STATUS_UNSUPPORTED_AUTHENTICATION_METHOD:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD;
+                       break;
+
+               case E_DATA_BOOK_STATUS_TLS_NOT_AVAILABLE:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_TLS_NOT_AVAILABLE;
+                       break;
+
+               case E_DATA_BOOK_STATUS_NO_SUCH_BOOK:
+                       error->domain = E_BOOK_CLIENT_ERROR;
+                       error->code = E_BOOK_CLIENT_ERROR_NO_SUCH_BOOK;
+                       break;
+
+               case E_DATA_BOOK_STATUS_BOOK_REMOVED:
+                       error->domain = E_BOOK_CLIENT_ERROR;
+                       error->code = E_BOOK_CLIENT_ERROR_NO_SUCH_SOURCE;
+                       break;
+
+               case E_DATA_BOOK_STATUS_OFFLINE_UNAVAILABLE:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_OFFLINE_UNAVAILABLE;
+                       break;
+
+               case E_DATA_BOOK_STATUS_SEARCH_SIZE_LIMIT_EXCEEDED:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED;
+                       break;
+
+               case E_DATA_BOOK_STATUS_SEARCH_TIME_LIMIT_EXCEEDED:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED;
+                       break;
+
+               case E_DATA_BOOK_STATUS_INVALID_QUERY:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_INVALID_QUERY;
+                       break;
+
+               case E_DATA_BOOK_STATUS_QUERY_REFUSED:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_QUERY_REFUSED;
+                       break;
+
+               case E_DATA_BOOK_STATUS_COULD_NOT_CANCEL:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_COULD_NOT_CANCEL;
+                       break;
+
+               case E_DATA_BOOK_STATUS_NO_SPACE:
+                       error->domain = E_BOOK_CLIENT_ERROR;
+                       error->code = E_BOOK_CLIENT_ERROR_NO_SPACE;
+                       break;
+
+               case E_DATA_BOOK_STATUS_INVALID_ARG:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_INVALID_ARG;
+                       break;
+
+               case E_DATA_BOOK_STATUS_NOT_SUPPORTED:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_NOT_SUPPORTED;
+                       break;
+
+               case E_DATA_BOOK_STATUS_NOT_OPENED:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_NOT_OPENED;
+                       break;
+
+               case E_DATA_BOOK_STATUS_UNSUPPORTED_FIELD:
+               case E_DATA_BOOK_STATUS_OTHER_ERROR:
+               case E_DATA_BOOK_STATUS_INVALID_SERVER_VERSION:
+                       error->domain = E_CLIENT_ERROR;
+                       error->code = E_CLIENT_ERROR_OTHER_ERROR;
+                       break;
+
+               default:
+                       g_warn_if_reached ();
+       }
+}
+
+static void
 operation_thread (gpointer data,
                   gpointer user_data)
 {
        OperationData *op = data;
-       OperationData *cancel_op;
        EBookBackend *backend;
        GHashTableIter iter;
        gpointer value;
@@ -292,7 +429,7 @@ operation_thread (gpointer data,
        case OP_OPEN:
                e_book_backend_open (
                        backend, op->book, op->id,
-                       op->cancellable, op->d.only_if_exists);
+                       op->cancellable, FALSE);
                break;
 
        case OP_ADD_CONTACTS:
@@ -352,11 +489,13 @@ operation_thread (gpointer data,
 
                        card_sexp = e_book_backend_sexp_new (op->d.query);
                        if (!card_sexp) {
-                               error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
-                               /* Translators: This is prefix to a detailed error message */
-                               g_prefix_error (&error, "%s", _("Invalid query: "));
-                               e_gdbus_book_emit_get_view_done (op->book->priv->dbus_interface, op->id, error, NULL);
-                               g_error_free (error);
+                               g_dbus_method_invocation_return_error_literal (
+                                       op->invocation,
+                                       E_CLIENT_ERROR,
+                                       E_CLIENT_ERROR_INVALID_QUERY,
+                                       _("Invalid query"));
+
+                               op_complete (op->book, op->id);
                                break;
                        }
 
@@ -377,16 +516,23 @@ operation_thread (gpointer data,
                        if (error != NULL) {
                                /* Translators: This is prefix to a detailed error message */
                                g_prefix_error (&error, "%s", _("Invalid query: "));
-                               e_gdbus_book_emit_get_view_done (op->book->priv->dbus_interface, op->id, error, NULL);
-                               g_error_free (error);
+                               data_book_convert_to_client_error (error);
+                               g_dbus_method_invocation_take_error (
+                                       op->invocation, error);
+
+                               op_complete (op->book, op->id);
                                g_free (object_path);
                                break;
                        }
 
                        e_book_backend_add_view (backend, view);
 
-                       e_gdbus_book_emit_get_view_done (op->book->priv->dbus_interface, op->id, NULL, object_path);
+                       e_dbus_address_book_complete_get_view (
+                               op->book->priv->dbus_interface,
+                               op->invocation,
+                               object_path);
 
+                       op_complete (op->book, op->id);
                        g_free (object_path);
                }
                break;
@@ -399,11 +545,17 @@ operation_thread (gpointer data,
 
                g_hash_table_iter_init (&iter, op->book->priv->pending_ops);
                while (g_hash_table_iter_next (&iter, NULL, &value)) {
-                       cancel_op = (OperationData *) value;
+                       OperationData *cancel_op = value;
                        g_cancellable_cancel (cancel_op->cancellable);
                }
 
                g_rec_mutex_unlock (&op->book->priv->pending_ops_lock);
+
+               e_dbus_address_book_complete_close (
+                       op->book->priv->dbus_interface,
+                       op->invocation);
+
+               op_complete (op->book, op->id);
                break;
        }
 
@@ -547,25 +699,6 @@ e_data_book_create_error_fmt (EDataBookStatus status,
        return error;
 }
 
-static void
-data_book_return_error (GDBusMethodInvocation *invocation,
-                        const GError *perror,
-                        const gchar *error_prefix)
-{
-       GError *error;
-
-       if (perror == NULL)
-               error = g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_OTHER_ERROR, "%s", _("Unknown error"));
-       else
-               error = g_error_new (E_DATA_BOOK_ERROR, perror->code, "%s", perror->message);
-
-       g_prefix_error (&error, "%s", error_prefix);
-
-       g_dbus_method_invocation_return_gerror (invocation, error);
-
-       g_error_free (error);
-}
-
 /**
  * e_data_book_string_slist_to_comma_string:
  *
@@ -606,17 +739,13 @@ e_data_book_string_slist_to_comma_string (const GSList *strings)
 }
 
 static gboolean
-data_book_handle_open_cb (EGdbusBook *interface,
+data_book_handle_open_cb (EDBusAddressBook *interface,
                           GDBusMethodInvocation *invocation,
-                          gboolean only_if_exists,
                           EDataBook *book)
 {
        OperationData *op;
 
        op = op_new (OP_OPEN, book, invocation);
-       op->d.only_if_exists = only_if_exists;
-
-       e_gdbus_book_complete_open (interface, invocation, op->id);
 
        op_dispatch (book, op);
 
@@ -624,7 +753,7 @@ data_book_handle_open_cb (EGdbusBook *interface,
 }
 
 static gboolean
-data_book_handle_refresh_cb (EGdbusBook *interface,
+data_book_handle_refresh_cb (EDBusAddressBook *interface,
                              GDBusMethodInvocation *invocation,
                              EDataBook *book)
 {
@@ -632,147 +761,93 @@ data_book_handle_refresh_cb (EGdbusBook *interface,
 
        op = op_new (OP_REFRESH, book, invocation);
 
-       e_gdbus_book_complete_refresh (interface, invocation, op->id);
-
        op_dispatch (book, op);
 
        return TRUE;
 }
 
 static gboolean
-data_book_handle_get_contact_cb (EGdbusBook *interface,
+data_book_handle_get_contact_cb (EDBusAddressBook *interface,
                                  GDBusMethodInvocation *invocation,
                                  const gchar *in_uid,
                                  EDataBook *book)
 {
        OperationData *op;
 
-       if (in_uid == NULL) {
-               GError *error;
-
-               error = e_data_book_create_error (E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND, NULL);
-               /* Translators: This is prefix to a detailed error message */
-               data_book_return_error (invocation, error, _("Cannot get contact: "));
-               g_error_free (error);
-               return TRUE;
-       }
-
        op = op_new (OP_GET_CONTACT, book, invocation);
        op->d.uid = g_strdup (in_uid);
 
-       e_gdbus_book_complete_get_contact (interface, invocation, op->id);
-
        op_dispatch (book, op);
 
        return TRUE;
 }
 
 static gboolean
-data_book_handle_get_contact_list_cb (EGdbusBook *interface,
+data_book_handle_get_contact_list_cb (EDBusAddressBook *interface,
                                       GDBusMethodInvocation *invocation,
                                       const gchar *in_query,
                                       EDataBook *book)
 {
        OperationData *op;
 
-       if (in_query == NULL || !*in_query) {
-               GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
-               /* Translators: This is prefix to a detailed error message */
-               data_book_return_error (invocation, error, _("Empty query: "));
-               g_error_free (error);
-               return TRUE;
-       }
-
        op = op_new (OP_GET_CONTACTS, book, invocation);
        op->d.query = g_strdup (in_query);
 
-       e_gdbus_book_complete_get_contact_list (interface, invocation, op->id);
-
        op_dispatch (book, op);
 
        return TRUE;
 }
 
 static gboolean
-data_book_handle_get_contact_list_uids_cb (EGdbusBook *interface,
+data_book_handle_get_contact_list_uids_cb (EDBusAddressBook *interface,
                                            GDBusMethodInvocation *invocation,
                                            const gchar *in_query,
                                            EDataBook *book)
 {
        OperationData *op;
 
-       if (in_query == NULL || !*in_query) {
-               GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
-               /* Translators: This is prefix to a detailed error message */
-               data_book_return_error (invocation, error, _("Empty query: "));
-               g_error_free (error);
-               return TRUE;
-       }
-
        op = op_new (OP_GET_CONTACTS_UIDS, book, invocation);
        op->d.query = g_strdup (in_query);
 
-       e_gdbus_book_complete_get_contact_list_uids (interface, invocation, op->id);
-
        op_dispatch (book, op);
 
        return TRUE;
 }
 
 static gboolean
-data_book_handle_add_contacts_cb (EGdbusBook *interface,
-                                  GDBusMethodInvocation *invocation,
-                                  const gchar * const *in_vcards,
-                                  EDataBook *book)
+data_book_handle_create_contacts_cb (EDBusAddressBook *interface,
+                                     GDBusMethodInvocation *invocation,
+                                     const gchar * const *in_vcards,
+                                     EDataBook *book)
 {
        OperationData *op;
 
-       if (in_vcards == NULL || !*in_vcards) {
-               GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
-               /* Translators: This is prefix to a detailed error message */
-               data_book_return_error (invocation, error, _("Cannot add contact: "));
-               g_error_free (error);
-               return TRUE;
-       }
-
        op = op_new (OP_ADD_CONTACTS, book, invocation);
        op->d.vcards = e_util_strv_to_slist (in_vcards);
 
-       e_gdbus_book_complete_add_contacts (interface, invocation, op->id);
-
        op_dispatch (book, op);
 
        return TRUE;
 }
 
 static gboolean
-data_book_handle_modify_contacts_cb (EGdbusBook *interface,
+data_book_handle_modify_contacts_cb (EDBusAddressBook *interface,
                                      GDBusMethodInvocation *invocation,
                                      const gchar * const *in_vcards,
                                      EDataBook *book)
 {
        OperationData *op;
 
-       if (in_vcards == NULL || !*in_vcards) {
-               GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
-               /* Translators: This is prefix to a detailed error message */
-               data_book_return_error (invocation, error, _("Cannot modify contacts: "));
-               g_error_free (error);
-               return TRUE;
-       }
-
        op = op_new (OP_MODIFY_CONTACTS, book, invocation);
        op->d.vcards = e_util_strv_to_slist (in_vcards);
 
-       e_gdbus_book_complete_modify_contacts (interface, invocation, op->id);
-
        op_dispatch (book, op);
 
        return TRUE;
 }
 
 static gboolean
-data_book_handle_remove_contacts_cb (EGdbusBook *interface,
+data_book_handle_remove_contacts_cb (EDBusAddressBook *interface,
                                      GDBusMethodInvocation *invocation,
                                      const gchar * const *in_uids,
                                      EDataBook *book)
@@ -786,56 +861,22 @@ data_book_handle_remove_contacts_cb (EGdbusBook *interface,
                op->d.ids = g_slist_prepend (op->d.ids, g_strdup (*in_uids));
        }
 
-       e_gdbus_book_complete_remove_contacts (interface, invocation, op->id);
-
        op_dispatch (book, op);
 
        return TRUE;
 }
 
 static gboolean
-data_book_handle_get_backend_property_cb (EGdbusBook *interface,
-                                          GDBusMethodInvocation *invocation,
-                                          const gchar *in_prop_name,
-                                          EDataBook *book)
-{
-       OperationData *op;
-
-       op = op_new (OP_GET_BACKEND_PROPERTY, book, invocation);
-       op->d.prop_name = g_strdup (in_prop_name);
-
-       e_gdbus_book_complete_get_backend_property (interface, invocation, op->id);
-
-       /* This operation is never queued. */
-       e_operation_pool_push (ops_pool, op);
-
-       return TRUE;
-}
-
-static gboolean
-data_book_handle_get_view_cb (EGdbusBook *interface,
+data_book_handle_get_view_cb (EDBusAddressBook *interface,
                               GDBusMethodInvocation *invocation,
                               const gchar *in_query,
                               EDataBook *book)
 {
        OperationData *op;
 
-       if (!in_query || !*in_query) {
-               GError *error;
-
-               error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
-               /* Translators: This is prefix to a detailed error message */
-               data_book_return_error (invocation, error, _("Invalid query: "));
-               g_error_free (error);
-
-               return TRUE;
-       }
-
        op = op_new (OP_GET_VIEW, book, invocation);
        op->d.query = g_strdup (in_query);
 
-       e_gdbus_book_complete_get_view (interface, invocation, op->id);
-
        /* This operation is never queued. */
        e_operation_pool_push (ops_pool, op);
 
@@ -843,7 +884,7 @@ data_book_handle_get_view_cb (EGdbusBook *interface,
 }
 
 static gboolean
-data_book_handle_close_cb (EGdbusBook *interface,
+data_book_handle_close_cb (EDBusAddressBook *interface,
                            GDBusMethodInvocation *invocation,
                            EDataBook *book)
 {
@@ -853,8 +894,6 @@ data_book_handle_close_cb (EGdbusBook *interface,
        /* unref here makes sure the book is freed in a separate thread */
        g_object_unref (book);
 
-       e_gdbus_book_complete_close (interface, invocation, NULL);
-
        /* This operation is never queued. */
        e_operation_pool_push (ops_pool, op);
 
@@ -866,11 +905,13 @@ e_data_book_respond_open (EDataBook *book,
                           guint opid,
                           GError *error)
 {
+       OperationData *data;
        GError *copy = NULL;
 
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       op_complete (book, opid);
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
 
        /* Translators: This is prefix to a detailed error message */
        g_prefix_error (&error, "%s", _("Cannot open book: "));
@@ -882,10 +923,17 @@ e_data_book_respond_open (EDataBook *book,
                copy = g_error_copy (error);
        e_book_backend_notify_opened (book->priv->backend, copy);
 
-       e_gdbus_book_emit_open_done (book->priv->dbus_interface, opid, error);
+       if (error == NULL) {
+               e_dbus_address_book_complete_open (
+                       book->priv->dbus_interface,
+                       data->invocation);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
+       }
 
-       if (error != NULL)
-               g_error_free (error);
+       op_unref (data);
 
        /* Dispatch any pending operations. */
 
@@ -919,17 +967,27 @@ e_data_book_respond_refresh (EDataBook *book,
                              guint32 opid,
                              GError *error)
 {
+       OperationData *data;
+
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       op_complete (book, opid);
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
 
        /* Translators: This is prefix to a detailed error message */
        g_prefix_error (&error, "%s", _("Cannot refresh address book: "));
 
-       e_gdbus_book_emit_refresh_done (book->priv->dbus_interface, opid, error);
+       if (error == NULL) {
+               e_dbus_address_book_complete_refresh (
+                       book->priv->dbus_interface,
+                       data->invocation);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
+       }
 
-       if (error)
-               g_error_free (error);
+       op_unref (data);
 }
 
 /**
@@ -945,21 +1003,24 @@ e_data_book_respond_get_backend_property (EDataBook *book,
                                           GError *error,
                                           const gchar *prop_value)
 {
-       gchar *gdbus_prop_value = NULL;
+       OperationData *data;
 
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       op_complete (book, opid);
-
-       /* Translators: This is prefix to a detailed error message */
-       g_prefix_error (&error, "%s", _("Cannot get backend property: "));
-
-       e_gdbus_book_emit_get_backend_property_done (book->priv->dbus_interface, opid, error, e_util_ensure_gdbus_string (prop_value, &gdbus_prop_value));
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
 
-       if (error)
+       if (error == NULL) {
+               e_data_book_report_backend_property_changed (
+                       book, data->d.prop_name, prop_value);
+       } else {
+               /* This should never happen, since all backend property
+                * requests now originate from our constructed() method. */
+               g_warning ("%s: %s", G_STRFUNC, error->message);
                g_error_free (error);
+       }
 
-       g_free (gdbus_prop_value);
+       op_unref (data);
 }
 
 /**
@@ -985,21 +1046,34 @@ e_data_book_respond_get_contact (EDataBook *book,
                                  GError *error,
                                  const gchar *vcard)
 {
-       gchar *gdbus_vcard = NULL;
+       OperationData *data;
 
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       op_complete (book, opid);
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
 
        /* Translators: This is prefix to a detailed error message */
        g_prefix_error (&error, "%s", _("Cannot get contact: "));
 
-       e_gdbus_book_emit_get_contact_done (book->priv->dbus_interface, opid, error, e_util_ensure_gdbus_string (vcard, &gdbus_vcard));
+       if (error == NULL) {
+               gchar *utf8_vcard;
 
-       if (error)
-               g_error_free (error);
+               utf8_vcard = e_util_utf8_make_valid (vcard);
 
-       g_free (gdbus_vcard);
+               e_dbus_address_book_complete_get_contact (
+                       book->priv->dbus_interface,
+                       data->invocation,
+                       utf8_vcard);
+
+               g_free (utf8_vcard);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
+       }
+
+       op_unref (data);
 }
 
 void
@@ -1008,27 +1082,42 @@ e_data_book_respond_get_contact_list (EDataBook *book,
                                       GError *error,
                                       const GSList *cards)
 {
+       OperationData *data;
+
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       if (error) {
-               /* Translators: This is prefix to a detailed error message */
-               g_prefix_error (&error, "%s", _("Cannot get contact list: "));
-               e_gdbus_book_emit_get_contact_list_done (book->priv->dbus_interface, opid, error, NULL);
-               g_error_free (error);
-       } else {
-               gchar **array;
-               const GSList *l;
-               gint i = 0;
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
+
+       /* Translators: This is prefix to a detailed error message */
+       g_prefix_error (&error, "%s", _("Cannot get contact list: "));
+
+       if (error == NULL) {
+               gchar **strv;
+               guint length;
+               gint ii = 0;
 
-               array = g_new0 (gchar *, g_slist_length ((GSList *) cards) + 1);
-               for (l = cards; l != NULL; l = l->next) {
-                       array[i++] = e_util_utf8_make_valid (l->data);
+               length = g_slist_length ((GSList *) cards);
+               strv = g_new0 (gchar *, length + 1);
+
+               while (cards != NULL) {
+                       strv[ii++] = e_util_utf8_make_valid (cards->data);
+                       cards = g_slist_next ((GSList *) cards);
                }
 
-               e_gdbus_book_emit_get_contact_list_done (book->priv->dbus_interface, opid, NULL, (const gchar * const *) array);
+               e_dbus_address_book_complete_get_contact_list (
+                       book->priv->dbus_interface,
+                       data->invocation,
+                       (const gchar * const *) strv);
 
-               g_strfreev (array);
+               g_strfreev (strv);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
        }
+
+       op_unref (data);
 }
 
 /**
@@ -1044,27 +1133,42 @@ e_data_book_respond_get_contact_list_uids (EDataBook *book,
                                            GError *error,
                                            const GSList *uids)
 {
+       OperationData *data;
+
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       if (error) {
-               /* Translators: This is prefix to a detailed error message */
-               g_prefix_error (&error, "%s", _("Cannot get contact list uids: "));
-               e_gdbus_book_emit_get_contact_list_uids_done (book->priv->dbus_interface, opid, error, NULL);
-               g_error_free (error);
-       } else {
-               gchar **array;
-               const GSList *l;
-               gint i = 0;
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
+
+       /* Translators: This is prefix to a detailed error message */
+       g_prefix_error (&error, "%s", _("Cannot get contact list uids: "));
+
+       if (error == NULL) {
+               gchar **strv;
+               guint length;
+               gint ii = 0;
+
+               length = g_slist_length ((GSList *) uids);
+               strv = g_new0 (gchar *, length + 1);
 
-               array = g_new0 (gchar *, g_slist_length ((GSList *) uids) + 1);
-               for (l = uids; l != NULL; l = l->next) {
-                       array[i++] = e_util_utf8_make_valid (l->data);
+               while (uids != NULL) {
+                       strv[ii++] = e_util_utf8_make_valid (uids->data);
+                       uids = g_slist_next ((GSList *) uids);
                }
 
-               e_gdbus_book_emit_get_contact_list_uids_done (book->priv->dbus_interface, opid, NULL, (const gchar * const *) array);
+               e_dbus_address_book_complete_get_contact_list_uids (
+                       book->priv->dbus_interface,
+                       data->invocation,
+                       (const gchar * const *) strv);
 
-               g_strfreev (array);
+               g_strfreev (strv);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
        }
+
+       op_unref (data);
 }
 
 /**
@@ -1080,38 +1184,54 @@ e_data_book_respond_create_contacts (EDataBook *book,
                                      GError *error,
                                      const GSList *contacts)
 {
-       gchar **array = NULL;
-       const GSList *l;
-       gint i = 0;
+       OperationData *data;
 
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       op_complete (book, opid);
-
-       array = g_new0 (gchar *, g_slist_length ((GSList *) contacts) + 1);
-       for (l = contacts; l != NULL; l = l->next) {
-               EContact *contact = E_CONTACT (l->data);
-
-               array[i++] = e_util_utf8_make_valid (e_contact_get_const (contact, E_CONTACT_UID));
-       }
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
 
        /* Translators: This is prefix to a detailed error message */
        g_prefix_error (&error, "%s", _("Cannot add contact: "));
 
-       e_gdbus_book_emit_add_contacts_done (book->priv->dbus_interface, opid, error, (const gchar * const *) array);
+       if (error == NULL) {
+               EBookBackend *backend;
+               gchar **strv;
+               guint length;
+               gint ii = 0;
 
-       g_strfreev (array);
-       if (error) {
-               g_error_free (error);
-       } else {
-               for (l = contacts; l != NULL; l = l->next) {
-                       EContact *contact = E_CONTACT (l->data);
+               backend = e_data_book_get_backend (book);
+
+               length = g_slist_length ((GSList *) contacts);
+               strv = g_new0 (gchar *, length + 1);
+
+               while (contacts != NULL) {
+                       EContact *contact = E_CONTACT (contacts->data);
+                       const gchar *uid;
 
-                       e_book_backend_notify_update (e_data_book_get_backend (book), contact);
+                       uid = e_contact_get_const (contact, E_CONTACT_UID);
+                       strv[ii++] = e_util_utf8_make_valid (uid);
+
+                       e_book_backend_notify_update (backend, contact);
+
+                       contacts = g_slist_next ((GSList *) contacts);
                }
 
-               e_book_backend_notify_complete (e_data_book_get_backend (book));
+               e_dbus_address_book_complete_create_contacts (
+                       book->priv->dbus_interface,
+                       data->invocation,
+                       (const gchar * const *) strv);
+
+               e_book_backend_notify_complete (backend);
+
+               g_strfreev (strv);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
        }
+
+       op_unref (data);
 }
 
 /**
@@ -1127,25 +1247,39 @@ e_data_book_respond_modify_contacts (EDataBook *book,
                                      GError *error,
                                      const GSList *contacts)
 {
+       OperationData *data;
+
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       op_complete (book, opid);
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
 
        /* Translators: This is prefix to a detailed error message */
        g_prefix_error (&error, "%s", _("Cannot modify contacts: "));
 
-       e_gdbus_book_emit_modify_contacts_done (book->priv->dbus_interface, opid, error);
+       if (error == NULL) {
+               EBookBackend *backend;
 
-       if (error) {
-               g_error_free (error);
-       } else {
-               const GSList *l;
+               backend = e_data_book_get_backend (book);
+
+               e_dbus_address_book_complete_modify_contacts (
+                       book->priv->dbus_interface,
+                       data->invocation);
 
-               for (l = contacts; l != NULL; l = l->next)
-                       e_book_backend_notify_update (e_data_book_get_backend (book), l->data);
+               while (contacts != NULL) {
+                       EContact *contact = E_CONTACT (contacts->data);
+                       e_book_backend_notify_update (backend, contact);
+                       contacts = g_slist_next ((GSList *) contacts);
+               }
 
-               e_book_backend_notify_complete (e_data_book_get_backend (book));
+               e_book_backend_notify_complete (backend);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
        }
+
+       op_unref (data);
 }
 
 void
@@ -1154,26 +1288,38 @@ e_data_book_respond_remove_contacts (EDataBook *book,
                                      GError *error,
                                      const GSList *ids)
 {
+       OperationData *data;
+
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       op_complete (book, opid);
+       data = op_claim (book, opid);
+       g_return_if_fail (data != NULL);
 
        /* Translators: This is prefix to a detailed error message */
        g_prefix_error (&error, "%s", _("Cannot remove contacts: "));
 
-       e_gdbus_book_emit_remove_contacts_done (book->priv->dbus_interface, opid, error);
+       if (error == NULL) {
+               EBookBackend *backend;
 
-       if (error) {
-               g_error_free (error);
-       } else {
-               const GSList *ii;
+               backend = e_data_book_get_backend (book);
+
+               e_dbus_address_book_complete_remove_contacts (
+                       book->priv->dbus_interface,
+                       data->invocation);
 
-               for (ii = ids; ii; ii = ii->next)
-                       e_book_backend_notify_remove (e_data_book_get_backend (book), ii->data);
+               while (ids != NULL) {
+                       e_book_backend_notify_remove (backend, ids->data);
+                       ids = g_slist_next ((GSList *) ids);
+               }
 
-               e_book_backend_notify_complete (e_data_book_get_backend (book));
+               e_book_backend_notify_complete (backend);
+       } else {
+               data_book_convert_to_client_error (error);
+               g_dbus_method_invocation_take_error (
+                       data->invocation, error);
        }
 
+       op_unref (data);
 }
 
 /**
@@ -1190,7 +1336,7 @@ e_data_book_report_error (EDataBook *book,
        g_return_if_fail (E_IS_DATA_BOOK (book));
        g_return_if_fail (message != NULL);
 
-       e_gdbus_book_emit_backend_error (book->priv->dbus_interface, message);
+       e_dbus_address_book_emit_error (book->priv->dbus_interface, message);
 }
 
 /**
@@ -1199,6 +1345,8 @@ e_data_book_report_error (EDataBook *book,
  * FIXME: Document me.
  *
  * Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_book_backend_set_writable() instead.
  **/
 void
 e_data_book_report_readonly (EDataBook *book,
@@ -1206,7 +1354,7 @@ e_data_book_report_readonly (EDataBook *book,
 {
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       e_gdbus_book_emit_readonly (book->priv->dbus_interface, readonly);
+       e_book_backend_set_writable (book->priv->backend, !readonly);
 }
 
 /**
@@ -1215,6 +1363,8 @@ e_data_book_report_readonly (EDataBook *book,
  * FIXME: Document me.
  *
  * Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_backend_set_online() instead.
  **/
 void
 e_data_book_report_online (EDataBook *book,
@@ -1222,7 +1372,7 @@ e_data_book_report_online (EDataBook *book,
 {
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       e_gdbus_book_emit_online (book->priv->dbus_interface, is_online);
+       e_backend_set_online (E_BACKEND (book->priv->backend), is_online);
 }
 
 /**
@@ -1256,21 +1406,42 @@ e_data_book_report_backend_property_changed (EDataBook *book,
                                              const gchar *prop_name,
                                              const gchar *prop_value)
 {
+       EDBusAddressBook *dbus_interface;
        gchar **strv;
 
-       /* Notifies client about certain property value change */
-
        g_return_if_fail (E_IS_DATA_BOOK (book));
        g_return_if_fail (prop_name != NULL);
-       g_return_if_fail (*prop_name != '\0');
-       g_return_if_fail (prop_value != NULL);
 
-       strv = e_gdbus_templates_encode_two_strings (prop_name, prop_value);
-       g_return_if_fail (strv != NULL);
+       if (prop_value == NULL)
+               prop_value = "";
+
+       dbus_interface = book->priv->dbus_interface;
+
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+               strv = g_strsplit (prop_value, ",", -1);
+               e_dbus_address_book_set_capabilities (
+                       dbus_interface, (const gchar * const *) strv);
+               g_strfreev (strv);
+       }
+
+       if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_REVISION))
+               e_dbus_address_book_set_revision (dbus_interface, prop_value);
 
-       e_gdbus_book_emit_backend_property_changed (book->priv->dbus_interface, (const gchar * const *) strv);
+       if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
+               strv = g_strsplit (prop_value, ",", -1);
+               e_dbus_address_book_set_required_fields (
+                       dbus_interface, (const gchar * const *) strv);
+               g_strfreev (strv);
+       }
+
+       if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
+               strv = g_strsplit (prop_value, ",", -1);
+               e_dbus_address_book_set_supported_fields (
+                       dbus_interface, (const gchar * const *) strv);
+               g_strfreev (strv);
+       }
 
-       g_strfreev (strv);
+       /* Disregard anything else. */
 }
 
 static void
@@ -1415,6 +1586,63 @@ data_book_finalize (GObject *object)
        G_OBJECT_CLASS (e_data_book_parent_class)->finalize (object);
 }
 
+static void
+data_book_constructed (GObject *object)
+{
+       EDataBook *book = E_DATA_BOOK (object);
+       OperationData *op;
+
+       /* Chain up to parent's constructed() method. */
+       G_OBJECT_CLASS (e_data_book_parent_class)->constructed (object);
+
+       g_object_bind_property (
+               book->priv->backend, "cache-dir",
+               book->priv->dbus_interface, "cache-dir",
+               G_BINDING_SYNC_CREATE);
+
+       g_object_bind_property (
+               book->priv->backend, "online",
+               book->priv->dbus_interface, "online",
+               G_BINDING_SYNC_CREATE);
+
+       g_object_bind_property (
+               book->priv->backend, "writable",
+               book->priv->dbus_interface, "writable",
+               G_BINDING_SYNC_CREATE);
+
+       /* XXX Initialize the rest of the properties by faking client
+        *     requests.  At present it's the only way to fish values
+        *     from EBookBackend's antiquated API. */
+
+       op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+       op->d.prop_name = CLIENT_BACKEND_PROPERTY_CAPABILITIES;
+       e_book_backend_get_backend_property (
+               book->priv->backend, book, op->id,
+               op->cancellable, op->d.prop_name);
+       op_unref (op);
+
+       op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+       op->d.prop_name = CLIENT_BACKEND_PROPERTY_REVISION;
+       e_book_backend_get_backend_property (
+               book->priv->backend, book, op->id,
+               op->cancellable, op->d.prop_name);
+       op_unref (op);
+
+       op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+       op->d.prop_name = BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS;
+       e_book_backend_get_backend_property (
+               book->priv->backend, book, op->id,
+               op->cancellable, op->d.prop_name);
+       op_unref (op);
+
+       op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+       op->d.prop_name = BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS;
+       e_book_backend_get_backend_property (
+               book->priv->backend, book, op->id,
+               op->cancellable, op->d.prop_name);
+       op_unref (op);
+}
+
 static gboolean
 data_book_initable_init (GInitable *initable,
                          GCancellable *cancellable,
@@ -1424,8 +1652,8 @@ data_book_initable_init (GInitable *initable,
 
        book = E_DATA_BOOK (initable);
 
-       return e_gdbus_book_register_object (
-               book->priv->dbus_interface,
+       return g_dbus_interface_skeleton_export (
+               G_DBUS_INTERFACE_SKELETON (book->priv->dbus_interface),
                book->priv->connection,
                book->priv->object_path,
                error);
@@ -1443,6 +1671,7 @@ e_data_book_class_init (EDataBookClass *class)
        object_class->get_property = data_book_get_property;
        object_class->dispose = data_book_dispose;
        object_class->finalize = data_book_finalize;
+       object_class->constructed = data_book_constructed;
 
        g_object_class_install_property (
                object_class,
@@ -1495,11 +1724,13 @@ e_data_book_initable_init (GInitableIface *interface)
 static void
 e_data_book_init (EDataBook *ebook)
 {
-       EGdbusBook *dbus_interface;
+       EDBusAddressBook *dbus_interface;
 
        ebook->priv = E_DATA_BOOK_GET_PRIVATE (ebook);
 
-       ebook->priv->dbus_interface = e_gdbus_book_stub_new ();
+       dbus_interface = e_dbus_address_book_skeleton_new ();
+       ebook->priv->dbus_interface = dbus_interface;
+
        ebook->priv->pending_ops = g_hash_table_new_full (
                (GHashFunc) g_direct_hash,
                (GEqualFunc) g_direct_equal,
@@ -1509,7 +1740,6 @@ e_data_book_init (EDataBook *ebook)
 
        g_mutex_init (&ebook->priv->open_lock);
 
-       dbus_interface = ebook->priv->dbus_interface;
        g_signal_connect (
                dbus_interface, "handle-open",
                G_CALLBACK (data_book_handle_open_cb), ebook);
@@ -1526,8 +1756,8 @@ e_data_book_init (EDataBook *ebook)
                dbus_interface, "handle-get-contact-list-uids",
                G_CALLBACK (data_book_handle_get_contact_list_uids_cb), ebook);
        g_signal_connect (
-               dbus_interface, "handle-add-contacts",
-               G_CALLBACK (data_book_handle_add_contacts_cb), ebook);
+               dbus_interface, "handle-create-contacts",
+               G_CALLBACK (data_book_handle_create_contacts_cb), ebook);
        g_signal_connect (
                dbus_interface, "handle-modify-contacts",
                G_CALLBACK (data_book_handle_modify_contacts_cb), ebook);
@@ -1535,9 +1765,6 @@ e_data_book_init (EDataBook *ebook)
                dbus_interface, "handle-remove-contacts",
                G_CALLBACK (data_book_handle_remove_contacts_cb), ebook);
        g_signal_connect (
-               dbus_interface, "handle-get-backend-property",
-               G_CALLBACK (data_book_handle_get_backend_property_cb), ebook);
-       g_signal_connect (
                dbus_interface, "handle-get-view",
                G_CALLBACK (data_book_handle_get_view_cb), ebook);
        g_signal_connect (
index a1b7b7a..7417a9f 100644 (file)
@@ -195,10 +195,6 @@ void               e_data_book_respond_get_contact_list_uids
 
 void           e_data_book_report_error        (EDataBook *book,
                                                 const gchar *message);
-void           e_data_book_report_readonly     (EDataBook *book,
-                                                gboolean readonly);
-void           e_data_book_report_online       (EDataBook *book,
-                                                gboolean is_online);
 void           e_data_book_report_backend_property_changed
                                                (EDataBook *book,
                                                 const gchar *prop_name,
@@ -214,6 +210,10 @@ void               e_data_book_respond_set_backend_property
                                                 GError *error);
 void           e_data_book_report_opened       (EDataBook *book,
                                                 const GError *error);
+void           e_data_book_report_readonly     (EDataBook *book,
+                                                gboolean readonly);
+void           e_data_book_report_online       (EDataBook *book,
+                                                gboolean is_online);
 #endif /* EDS_DISABLE_DEPRECATED */
 
 G_END_DECLS
index 7584a27..6f75cfe 100644 (file)
@@ -11,8 +11,6 @@ libegdbus_book_la_CPPFLAGS =                  \
        $(NULL)
 
 libegdbus_book_la_SOURCES =                    \
-       e-gdbus-book.h                          \
-       e-gdbus-book.c                          \
        e-gdbus-book-view.h                     \
        e-gdbus-book-view.c
 
diff --git a/addressbook/libegdbus/e-gdbus-book.c b/addressbook/libegdbus/e-gdbus-book.c
deleted file mode 100644 (file)
index 2c66074..0000000
+++ /dev/null
@@ -1,1462 +0,0 @@
-/*
- * e-gdbus-book.c
- *
- * This program 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) version 3.
- *
- * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 2011 Red Hat, Inc. (www.redhat.com)
- *
- */
-
-#include <stdio.h>
-#include <gio/gio.h>
-
-#include "e-gdbus-book.h"
-
-#define E_GDBUS_BOOK_PROXY_GET_PRIVATE(obj) \
-       (G_TYPE_INSTANCE_GET_PRIVATE \
-       ((obj), E_TYPE_GDBUS_BOOK_PROXY, EGdbusBookProxyPrivate))
-
-#define GDBUS_BOOK_INTERFACE_NAME "org.gnome.evolution.dataserver.AddressBook"
-
-typedef EGdbusBookIface EGdbusBookInterface;
-G_DEFINE_INTERFACE (EGdbusBook, e_gdbus_book, G_TYPE_OBJECT);
-
-enum
-{
-       _0_SIGNAL,
-       __BACKEND_ERROR_SIGNAL,
-       __READONLY_SIGNAL,
-       __ONLINE_SIGNAL,
-       __OPENED_SIGNAL,
-       __BACKEND_PROPERTY_CHANGED_SIGNAL,
-       __OPEN_METHOD,
-       __OPEN_DONE_SIGNAL,
-       __REMOVE_DONE_SIGNAL,
-       __REFRESH_METHOD,
-       __REFRESH_DONE_SIGNAL,
-       __GET_CONTACT_METHOD,
-       __GET_CONTACT_DONE_SIGNAL,
-       __GET_CONTACT_LIST_METHOD,
-       __GET_CONTACT_LIST_DONE_SIGNAL,
-       __GET_CONTACT_LIST_UIDS_METHOD,
-       __GET_CONTACT_LIST_UIDS_DONE_SIGNAL,
-       __ADD_CONTACTS_METHOD,
-       __ADD_CONTACTS_DONE_SIGNAL,
-       __REMOVE_CONTACTS_METHOD,
-       __REMOVE_CONTACTS_DONE_SIGNAL,
-       __MODIFY_CONTACTS_METHOD,
-       __MODIFY_CONTACTS_DONE_SIGNAL,
-       __GET_BACKEND_PROPERTY_METHOD,
-       __GET_BACKEND_PROPERTY_DONE_SIGNAL,
-       __SET_BACKEND_PROPERTY_METHOD,
-       __SET_BACKEND_PROPERTY_DONE_SIGNAL,
-       __GET_VIEW_METHOD,
-       __GET_VIEW_DONE_SIGNAL,
-       __CANCEL_OPERATION_METHOD,
-       __CANCEL_ALL_METHOD,
-       __CLOSE_METHOD,
-       __LAST_SIGNAL
-};
-
-static guint signals[__LAST_SIGNAL] = {0};
-
-struct _EGdbusBookProxyPrivate
-{
-       GHashTable *pending_ops;
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Various lookup tables */
-
-static GHashTable *_method_name_to_id = NULL;
-static GHashTable *_method_name_to_type = NULL;
-static GHashTable *_signal_name_to_id = NULL;
-static GHashTable *_signal_name_to_type = NULL;
-
-static guint
-lookup_method_id_from_method_name (const gchar *method_name)
-{
-       return GPOINTER_TO_UINT (g_hash_table_lookup (_method_name_to_id, method_name));
-}
-
-static guint
-lookup_method_type_from_method_name (const gchar *method_name)
-{
-       return GPOINTER_TO_UINT (g_hash_table_lookup (_method_name_to_type, method_name));
-}
-
-static guint
-lookup_signal_id_from_signal_name (const gchar *signal_name)
-{
-       return GPOINTER_TO_UINT (g_hash_table_lookup (_signal_name_to_id, signal_name));
-}
-
-static guint
-lookup_signal_type_from_signal_name (const gchar *signal_name)
-{
-       return GPOINTER_TO_UINT (g_hash_table_lookup (_signal_name_to_type, signal_name));
-}
-
-/* ------------------------------------------------------------------------- */
-
-E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRING (GDBUS_BOOK_INTERFACE_NAME,
-                                             backend_error)
-E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_BOOK_INTERFACE_NAME,
-                                              readonly)
-E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_BOOK_INTERFACE_NAME,
-                                              online)
-E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV (GDBUS_BOOK_INTERFACE_NAME,
-                                           opened)
-E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV (GDBUS_BOOK_INTERFACE_NAME,
-                                           backend_property_changed)
-
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME,
-                                                      open)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME,
-                                                      refresh)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_BOOK_INTERFACE_NAME,
-                                                        get_contact)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_BOOK_INTERFACE_NAME,
-                                                      get_contact_list)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_BOOK_INTERFACE_NAME,
-                                                      get_contact_list_uids)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_BOOK_INTERFACE_NAME,
-                                                        add_contacts)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME,
-                                                      remove_contacts)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME,
-                                                      modify_contacts)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_BOOK_INTERFACE_NAME,
-                                                        get_backend_property)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME,
-                                                      set_backend_property)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_BOOK_INTERFACE_NAME,
-                                                        get_view)
-
-static void
-e_gdbus_book_default_init (EGdbusBookIface *iface)
-{
-       /* Build lookup structures */
-       _method_name_to_id = g_hash_table_new (g_str_hash, g_str_equal);
-       _method_name_to_type = g_hash_table_new (g_str_hash, g_str_equal);
-       _signal_name_to_id = g_hash_table_new (g_str_hash, g_str_equal);
-       _signal_name_to_type = g_hash_table_new (g_str_hash, g_str_equal);
-
-       /* GObject signals definitions for D-Bus signals: */
-       E_INIT_GDBUS_SIGNAL_STRING (
-               EGdbusBookIface,
-               "backend_error",
-               backend_error,
-               __BACKEND_ERROR_SIGNAL)
-       E_INIT_GDBUS_SIGNAL_BOOLEAN (
-               EGdbusBookIface,
-               "readonly",
-               readonly,
-               __READONLY_SIGNAL)
-       E_INIT_GDBUS_SIGNAL_BOOLEAN (
-               EGdbusBookIface,
-               "online",
-               online,
-               __ONLINE_SIGNAL)
-       E_INIT_GDBUS_SIGNAL_STRV (
-               EGdbusBookIface,
-               "opened",
-               opened,
-               __OPENED_SIGNAL)
-       E_INIT_GDBUS_SIGNAL_STRV (
-               EGdbusBookIface,
-               "backend_property_changed",
-               backend_property_changed,
-               __BACKEND_PROPERTY_CHANGED_SIGNAL)
-
-       /* GObject signals definitions for D-Bus methods: */
-       E_INIT_GDBUS_METHOD_ASYNC_BOOLEAN__VOID (
-               EGdbusBookIface,
-               "open",
-               open,
-               __OPEN_METHOD,
-               __OPEN_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_VOID__VOID (
-               EGdbusBookIface,
-               "refresh",
-               refresh,
-               __REFRESH_METHOD,
-               __REFRESH_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING (
-               EGdbusBookIface,
-               "get_contact",
-               get_contact,
-               __GET_CONTACT_METHOD,
-               __GET_CONTACT_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (
-               EGdbusBookIface,
-               "get_contact_list",
-               get_contact_list,
-               __GET_CONTACT_LIST_METHOD,
-               __GET_CONTACT_LIST_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (
-               EGdbusBookIface,
-               "get_contact_list_uids",
-               get_contact_list_uids,
-               __GET_CONTACT_LIST_UIDS_METHOD,
-               __GET_CONTACT_LIST_UIDS_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRV__STRV (
-               EGdbusBookIface,
-               "add_contacts",
-               add_contacts,
-               __ADD_CONTACTS_METHOD,
-               __ADD_CONTACTS_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (
-               EGdbusBookIface,
-               "remove_contacts",
-               remove_contacts,
-               __REMOVE_CONTACTS_METHOD,
-               __REMOVE_CONTACTS_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (
-               EGdbusBookIface,
-               "modify_contacts",
-               modify_contacts,
-               __MODIFY_CONTACTS_METHOD,
-               __MODIFY_CONTACTS_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING (
-               EGdbusBookIface,
-               "get_backend_property",
-               get_backend_property,
-               __GET_BACKEND_PROPERTY_METHOD,
-               __GET_BACKEND_PROPERTY_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (
-               EGdbusBookIface,
-               "set_backend_property",
-               set_backend_property,
-               __SET_BACKEND_PROPERTY_METHOD,
-               __SET_BACKEND_PROPERTY_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING (
-               EGdbusBookIface,
-               "get_view",
-               get_view,
-               __GET_VIEW_METHOD,
-               __GET_VIEW_DONE_SIGNAL)
-       E_INIT_GDBUS_METHOD_UINT (
-               EGdbusBookIface,
-               "cancel_operation",
-               cancel_operation,
-               __CANCEL_OPERATION_METHOD)
-       E_INIT_GDBUS_METHOD_VOID (
-               EGdbusBookIface,
-               "cancel_all",
-               cancel_all,
-               __CANCEL_ALL_METHOD)
-       E_INIT_GDBUS_METHOD_VOID (
-               EGdbusBookIface,
-               "close",
-               close,
-               __CLOSE_METHOD)
-}
-
-void
-e_gdbus_book_call_open (GDBusProxy *proxy,
-                        gboolean in_only_if_exists,
-                        GCancellable *cancellable,
-                        GAsyncReadyCallback callback,
-                        gpointer user_data)
-{
-       e_gdbus_proxy_call_boolean ("open", e_gdbus_book_call_open, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_only_if_exists, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_open_finish (GDBusProxy *proxy,
-                               GAsyncResult *result,
-                               GError **error)
-{
-       return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_book_call_open);
-}
-
-gboolean
-e_gdbus_book_call_open_sync (GDBusProxy *proxy,
-                             gboolean in_only_if_exists,
-                             GCancellable *cancellable,
-                             GError **error)
-{
-       return e_gdbus_proxy_call_sync_boolean__void (
-               proxy, in_only_if_exists, cancellable, error,
-               e_gdbus_book_call_open,
-               e_gdbus_book_call_open_finish);
-}
-
-void
-e_gdbus_book_call_refresh (GDBusProxy *proxy,
-                           GCancellable *cancellable,
-                           GAsyncReadyCallback callback,
-                           gpointer user_data)
-{
-       e_gdbus_proxy_call_void ("refresh", e_gdbus_book_call_refresh, E_GDBUS_ASYNC_OP_KEEPER (proxy), cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_refresh_finish (GDBusProxy *proxy,
-                                  GAsyncResult *result,
-                                  GError **error)
-{
-       return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_book_call_refresh);
-}
-
-gboolean
-e_gdbus_book_call_refresh_sync (GDBusProxy *proxy,
-                                GCancellable *cancellable,
-                                GError **error)
-{
-       return e_gdbus_proxy_call_sync_void__void (
-               proxy, cancellable, error,
-               e_gdbus_book_call_refresh,
-               e_gdbus_book_call_refresh_finish);
-}
-
-void
-e_gdbus_book_call_get_contact (GDBusProxy *proxy,
-                               const gchar *in_uid,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       e_gdbus_proxy_call_string ("get_contact", e_gdbus_book_call_get_contact, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_uid, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_get_contact_finish (GDBusProxy *proxy,
-                                      GAsyncResult *result,
-                                      gchar **out_vcard,
-                                      GError **error)
-{
-       return e_gdbus_proxy_finish_call_string (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_vcard, error, e_gdbus_book_call_get_contact);
-}
-
-gboolean
-e_gdbus_book_call_get_contact_sync (GDBusProxy *proxy,
-                                    const gchar *in_uid,
-                                    gchar **out_vcard,
-                                    GCancellable *cancellable,
-                                    GError **error)
-{
-       return e_gdbus_proxy_call_sync_string__string (
-               proxy, in_uid, out_vcard, cancellable, error,
-               e_gdbus_book_call_get_contact,
-               e_gdbus_book_call_get_contact_finish);
-}
-
-void
-e_gdbus_book_call_get_contact_list (GDBusProxy *proxy,
-                                    const gchar *in_query,
-                                    GCancellable *cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
-{
-       e_gdbus_proxy_call_string ("get_contact_list", e_gdbus_book_call_get_contact_list, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_query, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_get_contact_list_finish (GDBusProxy *proxy,
-                                           GAsyncResult *result,
-                                           gchar ***out_vcards,
-                                           GError **error)
-{
-       return e_gdbus_proxy_finish_call_strv (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_vcards, error, e_gdbus_book_call_get_contact_list);
-}
-
-gboolean
-e_gdbus_book_call_get_contact_list_sync (GDBusProxy *proxy,
-                                         const gchar *in_query,
-                                         gchar ***out_vcards,
-                                         GCancellable *cancellable,
-                                         GError **error)
-{
-       return e_gdbus_proxy_call_sync_string__strv (
-               proxy, in_query, out_vcards, cancellable, error,
-               e_gdbus_book_call_get_contact_list,
-               e_gdbus_book_call_get_contact_list_finish);
-}
-
-void
-e_gdbus_book_call_get_contact_list_uids (GDBusProxy *proxy,
-                                         const gchar *in_query,
-                                         GCancellable *cancellable,
-                                         GAsyncReadyCallback callback,
-                                         gpointer user_data)
-{
-       e_gdbus_proxy_call_string ("get_contact_list_uids", e_gdbus_book_call_get_contact_list_uids, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_query, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_get_contact_list_uids_finish (GDBusProxy *proxy,
-                                                GAsyncResult *result,
-                                                gchar ***out_uids,
-                                                GError **error)
-{
-       return e_gdbus_proxy_finish_call_strv (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_uids, error, e_gdbus_book_call_get_contact_list_uids);
-}
-
-gboolean
-e_gdbus_book_call_get_contact_list_uids_sync (GDBusProxy *proxy,
-                                              const gchar *in_query,
-                                              gchar ***out_uids,
-                                              GCancellable *cancellable,
-                                              GError **error)
-{
-       return e_gdbus_proxy_call_sync_string__strv (
-               proxy, in_query, out_uids, cancellable, error,
-               e_gdbus_book_call_get_contact_list_uids,
-               e_gdbus_book_call_get_contact_list_uids_finish);
-}
-
-void
-e_gdbus_book_call_add_contacts (GDBusProxy *proxy,
-                               const gchar * const *in_vcards,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       e_gdbus_proxy_call_strv ("add_contacts", e_gdbus_book_call_add_contacts, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_vcards, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_add_contacts_finish (GDBusProxy *proxy,
-                                      GAsyncResult *result,
-                                      gchar ***out_uids,
-                                      GError **error)
-{
-       return e_gdbus_proxy_finish_call_strv (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_uids, error, e_gdbus_book_call_add_contacts);
-}
-
-gboolean
-e_gdbus_book_call_add_contacts_sync (GDBusProxy *proxy,
-                                    const gchar * const *in_vcards,
-                                    gchar ***out_uids,
-                                    GCancellable *cancellable,
-                                    GError **error)
-{
-       return e_gdbus_proxy_call_sync_strv__strv (
-               proxy, in_vcards, out_uids, cancellable, error,
-               e_gdbus_book_call_add_contacts,
-               e_gdbus_book_call_add_contacts_finish);
-}
-
-void
-e_gdbus_book_call_remove_contacts (GDBusProxy *proxy,
-                                   const gchar * const *in_list,
-                                   GCancellable *cancellable,
-                                   GAsyncReadyCallback callback,
-                                   gpointer user_data)
-{
-       e_gdbus_proxy_call_strv ("remove_contacts", e_gdbus_book_call_remove_contacts, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_list, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_remove_contacts_finish (GDBusProxy *proxy,
-                                          GAsyncResult *result,
-                                          GError **error)
-{
-       return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_book_call_remove_contacts);
-}
-
-gboolean
-e_gdbus_book_call_remove_contacts_sync (GDBusProxy *proxy,
-                                        const gchar * const *in_list,
-                                        GCancellable *cancellable,
-                                        GError **error)
-{
-       return e_gdbus_proxy_call_sync_strv__void (
-               proxy, in_list, cancellable, error,
-               e_gdbus_book_call_remove_contacts,
-               e_gdbus_book_call_remove_contacts_finish);
-}
-
-void
-e_gdbus_book_call_modify_contacts (GDBusProxy *proxy,
-                                   const gchar * const *in_vcards,
-                                   GCancellable *cancellable,
-                                   GAsyncReadyCallback callback,
-                                   gpointer user_data)
-{
-       e_gdbus_proxy_call_strv ("modify_contacts", e_gdbus_book_call_modify_contacts, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_vcards, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_modify_contacts_finish (GDBusProxy *proxy,
-                                         GAsyncResult *result,
-                                         GError **error)
-{
-       return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_book_call_modify_contacts);
-}
-
-gboolean
-e_gdbus_book_call_modify_contacts_sync (GDBusProxy *proxy,
-                                        const gchar * const *in_vcards,
-                                        GCancellable *cancellable,
-                                        GError **error)
-{
-       return e_gdbus_proxy_call_sync_strv__void (
-               proxy, in_vcards, cancellable, error,
-               e_gdbus_book_call_modify_contacts,
-               e_gdbus_book_call_modify_contacts_finish);
-}
-
-void
-e_gdbus_book_call_get_backend_property (GDBusProxy *proxy,
-                                        const gchar *in_prop_name,
-                                        GCancellable *cancellable,
-                                        GAsyncReadyCallback callback,
-                                        gpointer user_data)
-{
-       e_gdbus_proxy_call_string ("get_backend_property", e_gdbus_book_call_get_backend_property, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_prop_name, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_get_backend_property_finish (GDBusProxy *proxy,
-                                               GAsyncResult *result,
-                                               gchar **out_prop_value,
-                                               GError **error)
-{
-       return e_gdbus_proxy_finish_call_string (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_prop_value, error, e_gdbus_book_call_get_backend_property);
-}
-
-gboolean
-e_gdbus_book_call_get_backend_property_sync (GDBusProxy *proxy,
-                                             const gchar *in_prop_name,
-                                             gchar **out_prop_value,
-                                             GCancellable *cancellable,
-                                             GError **error)
-{
-       return e_gdbus_proxy_call_sync_string__string (
-               proxy, in_prop_name, out_prop_value, cancellable, error,
-               e_gdbus_book_call_get_backend_property,
-               e_gdbus_book_call_get_backend_property_finish);
-}
-
-/* free returned pointer with g_strfreev() */
-gchar **
-e_gdbus_book_encode_set_backend_property (const gchar *in_prop_name,
-                                          const gchar *in_prop_value)
-{
-       return e_gdbus_templates_encode_two_strings (in_prop_name, in_prop_value);
-}
-
-/* free out_prop_name and out_prop_value with g_free() */
-gboolean
-e_gdbus_book_decode_set_backend_property (const gchar * const *in_strv,
-                                          gchar **out_prop_name,
-                                          gchar **out_prop_value)
-{
-       return e_gdbus_templates_decode_two_strings (in_strv, out_prop_name, out_prop_value);
-}
-
-void
-e_gdbus_book_call_set_backend_property (GDBusProxy *proxy,
-                                        const gchar * const *in_prop_name_value,
-                                        GCancellable *cancellable,
-                                        GAsyncReadyCallback callback,
-                                        gpointer user_data)
-{
-       e_gdbus_proxy_call_strv ("set_backend_property", e_gdbus_book_call_set_backend_property, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_prop_name_value, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_set_backend_property_finish (GDBusProxy *proxy,
-                                               GAsyncResult *result,
-                                               GError **error)
-{
-       return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_book_call_set_backend_property);
-}
-
-gboolean
-e_gdbus_book_call_set_backend_property_sync (GDBusProxy *proxy,
-                                             const gchar * const *in_prop_name_value,
-                                             GCancellable *cancellable,
-                                             GError **error)
-{
-       return e_gdbus_proxy_call_sync_strv__void (
-               proxy, in_prop_name_value, cancellable, error,
-               e_gdbus_book_call_set_backend_property,
-               e_gdbus_book_call_set_backend_property_finish);
-}
-
-void
-e_gdbus_book_call_get_view (GDBusProxy *proxy,
-                            const gchar *in_query,
-                            GCancellable *cancellable,
-                            GAsyncReadyCallback callback,
-                            gpointer user_data)
-{
-       e_gdbus_proxy_call_string ("get_view", e_gdbus_book_call_get_view, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_query, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_get_view_finish (GDBusProxy *proxy,
-                                   GAsyncResult *result,
-                                   gchar **out_view_path,
-                                   GError **error)
-{
-       return e_gdbus_proxy_finish_call_string (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_view_path, error, e_gdbus_book_call_get_view);
-}
-
-gboolean
-e_gdbus_book_call_get_view_sync (GDBusProxy *proxy,
-                                 const gchar *in_query,
-                                 gchar **out_view_path,
-                                 GCancellable *cancellable,
-                                 GError **error)
-{
-       return e_gdbus_proxy_call_sync_string__string (
-               proxy, in_query, out_view_path, cancellable, error,
-               e_gdbus_book_call_get_view,
-               e_gdbus_book_call_get_view_finish);
-}
-
-void
-e_gdbus_book_call_cancel_operation (GDBusProxy *proxy,
-                                    guint in_opid,
-                                    GCancellable *cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
-{
-       e_gdbus_proxy_method_call_uint ("cancel_operation", proxy, in_opid, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_cancel_operation_finish (GDBusProxy *proxy,
-                                           GAsyncResult *result,
-                                           GError **error)
-{
-       return e_gdbus_proxy_method_call_finish_void (proxy, result, error);
-}
-
-gboolean
-e_gdbus_book_call_cancel_operation_sync (GDBusProxy *proxy,
-                                         guint in_opid,
-                                         GCancellable *cancellable,
-                                         GError **error)
-{
-       return e_gdbus_proxy_method_call_sync_uint__void ("cancel_operation", proxy, in_opid, cancellable, error);
-}
-
-void
-e_gdbus_book_call_cancel_all (GDBusProxy *proxy,
-                              GCancellable *cancellable,
-                              GAsyncReadyCallback callback,
-                              gpointer user_data)
-{
-       e_gdbus_proxy_method_call_void ("cancel_all", proxy, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_cancel_all_finish (GDBusProxy *proxy,
-                                     GAsyncResult *result,
-                                     GError **error)
-{
-       return e_gdbus_proxy_method_call_finish_void (proxy, result, error);
-}
-
-gboolean
-e_gdbus_book_call_cancel_all_sync (GDBusProxy *proxy,
-                                   GCancellable *cancellable,
-                                   GError **error)
-{
-       return e_gdbus_proxy_method_call_sync_void__void ("cancel_all", proxy, cancellable, error);
-}
-
-void
-e_gdbus_book_call_close (GDBusProxy *proxy,
-                         GCancellable *cancellable,
-                         GAsyncReadyCallback callback,
-                         gpointer user_data)
-{
-       e_gdbus_proxy_method_call_void ("close", proxy, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_close_finish (GDBusProxy *proxy,
-                                GAsyncResult *result,
-                                GError **error)
-{
-       return e_gdbus_proxy_method_call_finish_void (proxy, result, error);
-}
-
-gboolean
-e_gdbus_book_call_close_sync (GDBusProxy *proxy,
-                              GCancellable *cancellable,
-                              GError **error)
-{
-       return e_gdbus_proxy_method_call_sync_void__void ("close", proxy, cancellable, error);
-}
-
-#define DECLARE_EMIT_DONE_SIGNAL_0(_mname, _sig_id)                                                                    \
-void                                                                                                                   \
-e_gdbus_book_emit_ ## _mname ## _done (EGdbusBook *object, guint arg_opid, const GError *arg_error)                    \
-{                                                                                                                      \
-       g_signal_emit (object, signals[_sig_id], 0, arg_opid, arg_error);                                               \
-}
-
-#define DECLARE_EMIT_DONE_SIGNAL_1(_mname, _sig_id, _par_type)                                                         \
-void                                                                                                                   \
-e_gdbus_book_emit_ ## _mname ## _done (EGdbusBook *object, guint arg_opid, const GError *arg_error, _par_type out_par) \
-{                                                                                                                      \
-       g_signal_emit (object, signals[_sig_id], 0, arg_opid, arg_error, out_par);                                      \
-}
-
-DECLARE_EMIT_DONE_SIGNAL_0 (open,
-                            __OPEN_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_0 (refresh,
-                            __REFRESH_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_1 (get_contact,
-                            __GET_CONTACT_DONE_SIGNAL,
-                            const gchar *)
-DECLARE_EMIT_DONE_SIGNAL_1 (get_contact_list,
-                            __GET_CONTACT_LIST_DONE_SIGNAL,
-                            const gchar * const *)
-DECLARE_EMIT_DONE_SIGNAL_1 (get_contact_list_uids,
-                            __GET_CONTACT_LIST_UIDS_DONE_SIGNAL,
-                            const gchar * const *)
-DECLARE_EMIT_DONE_SIGNAL_1 (add_contacts,
-                            __ADD_CONTACTS_DONE_SIGNAL,
-                            const gchar * const *)
-DECLARE_EMIT_DONE_SIGNAL_0 (remove_contacts,
-                            __REMOVE_CONTACTS_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_0 (modify_contacts,
-                            __MODIFY_CONTACTS_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_1 (get_backend_property,
-                            __GET_BACKEND_PROPERTY_DONE_SIGNAL,
-                            const gchar *)
-DECLARE_EMIT_DONE_SIGNAL_0 (set_backend_property,
-                            __SET_BACKEND_PROPERTY_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_1 (get_view,
-                            __GET_VIEW_DONE_SIGNAL,
-                            const gchar *)
-
-void
-e_gdbus_book_emit_backend_error (EGdbusBook *object,
-                                 const gchar *arg_message)
-{
-       g_return_if_fail (object != NULL);
-       g_return_if_fail (arg_message != NULL);
-
-       g_signal_emit (object, signals[__BACKEND_ERROR_SIGNAL], 0, arg_message);
-}
-
-void
-e_gdbus_book_emit_readonly (EGdbusBook *object,
-                            gboolean arg_is_readonly)
-{
-       g_signal_emit (object, signals[__READONLY_SIGNAL], 0, arg_is_readonly);
-}
-
-void
-e_gdbus_book_emit_online (EGdbusBook *object,
-                          gboolean arg_is_online)
-{
-       g_signal_emit (object, signals[__ONLINE_SIGNAL], 0, arg_is_online);
-}
-
-void
-e_gdbus_book_emit_opened (EGdbusBook *object,
-                          const gchar * const *arg_error)
-{
-       g_signal_emit (object, signals[__OPENED_SIGNAL], 0, arg_error);
-}
-
-void
-e_gdbus_book_emit_backend_property_changed (EGdbusBook *object,
-                                            const gchar * const *arg_name_value)
-{
-       g_signal_emit (object, signals[__BACKEND_PROPERTY_CHANGED_SIGNAL], 0, arg_name_value);
-}
-
-E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book,
-                                 backend_error,
-                                 message,
-                                 "s")
-E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book,
-                                 readonly,
-                                 is_readonly,
-                                 "b")
-E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book,
-                                 online,
-                                 is_online,
-                                 "b")
-E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book,
-                                 opened,
-                                 error,
-                                 "as")
-E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book,
-                                 backend_property_changed,
-                                 name_value,
-                                 "as")
-
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (book,
-                                  open,
-                                  only_if_exists,
-                                  "b")
-E_DECLARE_GDBUS_ASYNC_METHOD_0 (book,
-                                refresh)
-E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book,
-                                            get_contact,
-                                            uid,
-                                            "s",
-                                            vcard,
-                                            "s")
-E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book,
-                                            get_contact_list,
-                                            query,
-                                            "s",
-                                            vcards,
-                                            "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book,
-                                            get_contact_list_uids,
-                                            query,
-                                            "s",
-                                            uids,
-                                            "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book,
-                                            add_contacts,
-                                            vcards,
-                                            "as",
-                                            uids,
-                                            "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (book,
-                                  remove_contacts,
-                                  list,
-                                  "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (book,
-                                  modify_contacts,
-                                  vcard,
-                                  "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book,
-                                            get_backend_property,
-                                            prop_name,
-                                            "s",
-                                            prop_value,
-                                            "s")
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (book,
-                                  set_backend_property,
-                                  prop_name_value,
-                                  "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book,
-                                            get_view,
-                                            query,
-                                            "s",
-                                            view,
-                                            "s")
-
-E_DECLARE_GDBUS_SYNC_METHOD_1 (book,
-                                 cancel_operation,
-                                 opid,
-                                 "u")
-E_DECLARE_GDBUS_SYNC_METHOD_0 (book,
-                               cancel_all)
-E_DECLARE_GDBUS_SYNC_METHOD_0 (book,
-                               close)
-
-static const GDBusMethodInfo * const e_gdbus_book_method_info_pointers[] =
-{
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, open),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, refresh),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_contact),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_contact_list),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_contact_list_uids),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, add_contacts),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, remove_contacts),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, modify_contacts),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_backend_property),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, set_backend_property),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_view),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, cancel_operation),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, cancel_all),
-       &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, close),
-       NULL
-};
-
-static const GDBusSignalInfo * const e_gdbus_book_signal_info_pointers[] =
-{
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, backend_error),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, readonly),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, online),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, opened),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, backend_property_changed),
-
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, open_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, refresh_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_contact_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_contact_list_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_contact_list_uids_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, add_contacts_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, remove_contacts_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, modify_contacts_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_backend_property_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, set_backend_property_done),
-       &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_view_done),
-       NULL
-};
-
-static const GDBusInterfaceInfo _e_gdbus_book_interface_info =
-{
-       -1,
-       (gchar *) GDBUS_BOOK_INTERFACE_NAME,
-       (GDBusMethodInfo **) &e_gdbus_book_method_info_pointers,
-       (GDBusSignalInfo **) &e_gdbus_book_signal_info_pointers,
-       (GDBusPropertyInfo **) NULL
-};
-
-static void
-handle_method_call (GDBusConnection *connection,
-                    const gchar *sender,
-                    const gchar *object_path,
-                    const gchar *interface_name,
-                    const gchar *method_name,
-                    GVariant *parameters,
-                    GDBusMethodInvocation *invocation,
-                    gpointer user_data)
-{
-       guint method_id, method_type;
-
-       method_id = lookup_method_id_from_method_name (method_name);
-       method_type = lookup_method_type_from_method_name (method_name);
-
-       g_return_if_fail (method_id != 0);
-       g_return_if_fail (method_type != 0);
-
-       e_gdbus_stub_handle_method_call (user_data, invocation, parameters, method_name, signals[method_id], method_type);
-}
-
-static GVariant *
-get_property (GDBusConnection *connection,
-              const gchar *sender,
-              const gchar *object_path,
-              const gchar *interface_name,
-              const gchar *property_name,
-              GError **error,
-              gpointer user_data)
-{
-       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "This implementation does not support property `%s'", property_name);
-       return NULL;
-}
-
-static gboolean
-set_property (GDBusConnection *connection,
-              const gchar *sender,
-              const gchar *object_path,
-              const gchar *interface_name,
-              const gchar *property_name,
-              GVariant *value,
-              GError **error,
-              gpointer user_data)
-{
-       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "This implementation does not support property `%s'", property_name);
-       return FALSE;
-}
-
-static const GDBusInterfaceVTable e_gdbus_book_interface_vtable =
-{
-       handle_method_call,
-       get_property,
-       set_property
-};
-
-static gboolean
-emit_notifications_in_idle (gpointer user_data)
-{
-       GObject *object = G_OBJECT (user_data);
-       GDBusConnection *connection;
-       const gchar *path;
-       GHashTable *notification_queue;
-       GHashTableIter iter;
-       const gchar *property_name;
-       GVariant *value;
-       GVariantBuilder *builder;
-       GVariantBuilder *invalidated_builder;
-       GHashTable *pvc;
-       gboolean has_changes;
-
-       notification_queue = g_object_get_data (object, "gdbus-codegen-notification-queue");
-       path = g_object_get_data (object, "gdbus-codegen-path");
-       connection = g_object_get_data (object, "gdbus-codegen-connection");
-       pvc = g_object_get_data (object, "gdbus-codegen-pvc");
-       g_assert (notification_queue != NULL && path != NULL && connection != NULL && pvc != NULL);
-
-       builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
-       invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
-       g_hash_table_iter_init (&iter, notification_queue);
-       has_changes = FALSE;
-       while (g_hash_table_iter_next (&iter, (gpointer) &property_name, (gpointer) &value)) {
-               GVariant *cached_value;
-               cached_value = g_hash_table_lookup (pvc, property_name);
-               if (cached_value == NULL || !g_variant_equal (cached_value, value)) {
-                       g_hash_table_insert (pvc, (gpointer) property_name, (gpointer) g_variant_ref (value));
-                       g_variant_builder_add (builder, "{sv}", property_name, value);
-                       has_changes = TRUE;
-               }
-       }
-
-       if (has_changes) {
-               g_dbus_connection_emit_signal (
-                       connection, NULL, path, "org.freedesktop.DBus.Properties", "PropertiesChanged",
-                       g_variant_new ("(sa{sv}as)", GDBUS_BOOK_INTERFACE_NAME, builder, invalidated_builder),
-                       NULL);
-       } else {
-               g_variant_builder_unref (builder);
-               g_variant_builder_unref (invalidated_builder);
-       }
-
-       g_hash_table_remove_all (notification_queue);
-       g_object_set_data (object, "gdbus-codegen-notification-idle-id", GUINT_TO_POINTER (0));
-
-       return FALSE;
-}
-
-/**
- * e_gdbus_book_drain_notify:
- * @object: A #EGdbusBook that is exported.
- *
- * If @object has queued notifications, empty the queue forcing
- * the <literal>PropertiesChanged</literal> signal to be emitted.
- * See <xref linkend="EGdbusBook.description"/> for more background information.
- */
-void
-e_gdbus_book_drain_notify (EGdbusBook *object)
-{
-       gint idle_id;
-       idle_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (object), "gdbus-codegen-notification-idle-id"));
-       if (idle_id > 0) {
-               emit_notifications_in_idle (object);
-               g_source_remove (idle_id);
-       }
-}
-
-static void
-on_object_unregistered (GObject *object)
-{
-       gint idle_id;
-       idle_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (object), "gdbus-codegen-notification-idle-id"));
-       if (idle_id > 0) {
-               g_source_remove (idle_id);
-       }
-       g_object_set_data (G_OBJECT (object), "gdbus-codegen-path", NULL);
-       g_object_set_data (G_OBJECT (object), "gdbus-codegen-connection", NULL);
-}
-
-/**
- * e_gdbus_book_register_object:
- * @object: An instance of a #GObject<!-- -->-derived type implementing the #EGdbusBook interface.
- * @connection: A #GDBusConnection.
- * @object_path: The object to register the object at.
- * @error: Return location for error or %NULL.
- *
- * Registers @object at @object_path on @connection.
- *
- * See <xref linkend="EGdbusBook.description"/>
- * for how properties, methods and signals are handled.
- *
- * Returns: 0 if @error is set, otherwise a registration id (never 0) that can be used with g_dbus_connection_unregister_object().
- */
-guint
-e_gdbus_book_register_object (EGdbusBook *object,
-                              GDBusConnection *connection,
-                              const gchar *object_path,
-                              GError **error)
-{
-       GHashTable *pvc;
-
-       pvc = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_variant_unref);
-
-       g_object_set_data_full (G_OBJECT (object), "gdbus-codegen-path", (gpointer) g_strdup (object_path), g_free);
-       g_object_set_data (G_OBJECT (object), "gdbus-codegen-connection", (gpointer) connection);
-       g_object_set_data_full (G_OBJECT (object), "gdbus-codegen-pvc", (gpointer) pvc, (GDestroyNotify) g_hash_table_unref);
-
-       return g_dbus_connection_register_object (
-               connection, object_path, (GDBusInterfaceInfo *) &_e_gdbus_book_interface_info,
-                       &e_gdbus_book_interface_vtable, object, (GDestroyNotify) on_object_unregistered, error);
-}
-
-/**
- * e_gdbus_book_interface_info:
- *
- * Gets interface description for the <literal>org.gnome.evolution.dataserver.AddressBook</literal> D-Bus interface.
- *
- * Returns: A #GDBusInterfaceInfo. Do not free, the object is statically allocated.
- */
-const GDBusInterfaceInfo *
-e_gdbus_book_interface_info (void)
-{
-       return &_e_gdbus_book_interface_info;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void proxy_iface_init (EGdbusBookIface *iface);
-static void async_op_keeper_iface_init (EGdbusAsyncOpKeeperInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (EGdbusBookProxy, e_gdbus_book_proxy, G_TYPE_DBUS_PROXY,
-                         G_IMPLEMENT_INTERFACE (E_TYPE_GDBUS_BOOK, proxy_iface_init)
-                        G_IMPLEMENT_INTERFACE (E_TYPE_GDBUS_ASYNC_OP_KEEPER, async_op_keeper_iface_init));
-
-static void
-e_gdbus_book_proxy_init (EGdbusBookProxy *proxy)
-{
-       g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), (GDBusInterfaceInfo *) &_e_gdbus_book_interface_info);
-
-       proxy->priv = E_GDBUS_BOOK_PROXY_GET_PRIVATE (proxy);
-       proxy->priv->pending_ops = e_gdbus_async_op_keeper_create_pending_ops (E_GDBUS_ASYNC_OP_KEEPER (proxy));
-
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID   (open);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID   (refresh);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_contact);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV   (get_contact_list);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV   (get_contact_list_uids);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV   (add_contacts);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID   (remove_contacts);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID   (modify_contacts);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_backend_property);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID   (set_backend_property);
-       E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_view);
-}
-
-static void
-g_signal (GDBusProxy *proxy,
-          const gchar *sender_name,
-          const gchar *signal_name,
-          GVariant *parameters)
-{
-       guint signal_id, signal_type;
-
-       signal_id = lookup_signal_id_from_signal_name (signal_name);
-       signal_type = lookup_signal_type_from_signal_name (signal_name);
-
-       g_return_if_fail (signal_id != 0);
-       g_return_if_fail (signal_type != 0);
-
-       e_gdbus_proxy_emit_signal (proxy, parameters, signals[signal_id], signal_type);
-}
-
-static void
-gdbus_book_proxy_finalize (GObject *object)
-{
-       EGdbusBookProxy *proxy = E_GDBUS_BOOK_PROXY (object);
-
-       if (g_hash_table_size (proxy->priv->pending_ops))
-               g_debug ("%s: Kept %d items in pending_ops", G_STRFUNC, g_hash_table_size (proxy->priv->pending_ops));
-
-       g_hash_table_destroy (proxy->priv->pending_ops);
-
-       G_OBJECT_CLASS (e_gdbus_book_proxy_parent_class)->finalize (object);
-}
-
-static void
-e_gdbus_book_proxy_class_init (EGdbusBookProxyClass *class)
-{
-       GObjectClass *object_class;
-       GDBusProxyClass *proxy_class;
-
-       g_type_class_add_private (class, sizeof (EGdbusBookProxyPrivate));
-
-       object_class = G_OBJECT_CLASS (class);
-       object_class->finalize = gdbus_book_proxy_finalize;
-
-       proxy_class = G_DBUS_PROXY_CLASS (class);
-       proxy_class->g_signal = g_signal;
-}
-
-static void
-proxy_iface_init (EGdbusBookIface *iface)
-{
-}
-
-static GHashTable *
-gdbus_book_get_pending_ops (EGdbusAsyncOpKeeper *object)
-{
-       EGdbusBookProxy *proxy;
-
-       g_return_val_if_fail (E_IS_GDBUS_BOOK_PROXY (object), NULL);
-
-       proxy = E_GDBUS_BOOK_PROXY (object);
-
-       return proxy->priv->pending_ops;
-}
-
-static gboolean
-gdbus_book_call_cancel_operation_sync (EGdbusAsyncOpKeeper *object,
-                                       guint in_opid,
-                                       GCancellable *cancellable,
-                                       GError **error)
-{
-       return e_gdbus_book_call_cancel_operation_sync (G_DBUS_PROXY (object), in_opid, cancellable, error);
-}
-
-static void
-async_op_keeper_iface_init (EGdbusAsyncOpKeeperInterface *iface)
-{
-       g_return_if_fail (iface != NULL);
-
-       iface->get_pending_ops = gdbus_book_get_pending_ops;
-       iface->cancel_op_sync = gdbus_book_call_cancel_operation_sync;
-}
-
-/**
- * e_gdbus_book_proxy_new:
- * @connection: A #GDBusConnection.
- * @flags: Flags used when constructing the proxy.
- * @name: A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
- * @object_path: An object path.
- * @cancellable: A #GCancellable or %NULL.
- * @callback: Callback function to invoke when the proxy is ready.
- * @user_data: User data to pass to @callback.
- *
- * Like g_dbus_proxy_new() but returns a #EGdbusBookProxy.
- *
- * This is a failable asynchronous constructor - when the proxy is ready, callback will be invoked and you can use e_gdbus_book_proxy_new_finish() to get the result.
- */
-void
-e_gdbus_book_proxy_new (GDBusConnection *connection,
-                        GDBusProxyFlags flags,
-                        const gchar *name,
-                        const gchar *object_path,
-                        GCancellable *cancellable,
-                        GAsyncReadyCallback callback,
-                        gpointer user_data)
-{
-       g_async_initable_new_async (
-               E_TYPE_GDBUS_BOOK_PROXY,
-               G_PRIORITY_DEFAULT,
-               cancellable,
-               callback,
-               user_data,
-               "g-flags", flags,
-               "g-name", name,
-               "g-connection", connection,
-               "g-object-path", object_path,
-               "g-interface-name", GDBUS_BOOK_INTERFACE_NAME,
-               NULL);
-}
-
-/**
- * e_gdbus_book_proxy_new_finish:
- * @result: A #GAsyncResult obtained from the #GAsyncReadyCallback function passed to e_gdbus_book_proxy_new().
- * @error: Return location for error or %NULL.
- *
- * Finishes creating a #EGdbusBookProxy.
- *
- * Returns: A #EGdbusBookProxy or %NULL if @error is set. Free with g_object_unref().
- */
-EGdbusBook *
-e_gdbus_book_proxy_new_finish (GAsyncResult *result,
-                               GError **error)
-{
-       GObject *object;
-       GObject *source_object;
-       source_object = g_async_result_get_source_object (result);
-       g_assert (source_object != NULL);
-       object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
-       g_object_unref (source_object);
-
-       if (object != NULL)
-               return E_GDBUS_BOOK (object);
-       else
-               return NULL;
-}
-
-/**
- * e_gdbus_book_proxy_new_sync:
- * @connection: A #GDBusConnection.
- * @flags: Flags used when constructing the proxy.
- * @name: A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
- * @object_path: An object path.
- * @cancellable: A #GCancellable or %NULL.
- * @error: Return location for error or %NULL.
- *
- * Like g_dbus_proxy_new_sync() but returns a #EGdbusBookProxy.
- *
- * This is a synchronous failable constructor. See e_gdbus_book_proxy_new() and e_gdbus_book_proxy_new_finish() for the asynchronous version.
- *
- * Returns: A #EGdbusBookProxy or %NULL if error is set. Free with g_object_unref().
- */
-EGdbusBook *
-e_gdbus_book_proxy_new_sync (GDBusConnection *connection,
-                             GDBusProxyFlags flags,
-                             const gchar *name,
-                             const gchar *object_path,
-                             GCancellable *cancellable,
-                             GError **error)
-{
-       GInitable *initable;
-       initable = g_initable_new (
-               E_TYPE_GDBUS_BOOK_PROXY,
-               cancellable,
-               error,
-               "g-flags", flags,
-               "g-name", name,
-               "g-connection", connection,
-               "g-object-path", object_path,
-               "g-interface-name", GDBUS_BOOK_INTERFACE_NAME,
-               NULL);
-       if (initable != NULL)
-               return E_GDBUS_BOOK (initable);
-       else
-               return NULL;
-}
-
-/**
- * e_gdbus_book_proxy_new_for_bus:
- * @bus_type: A #GBusType.
- * @flags: Flags used when constructing the proxy.
- * @name: A bus name (well-known or unique).
- * @object_path: An object path.
- * @cancellable: A #GCancellable or %NULL.
- * @callback: Callback function to invoke when the proxy is ready.
- * @user_data: User data to pass to @callback.
- *
- * Like g_dbus_proxy_new_for_bus() but returns a #EGdbusBookProxy.
- *
- * This is a failable asynchronous constructor - when the proxy is ready, callback will be invoked and you can use e_gdbus_book_proxy_new_for_bus_finish() to get the result.
- */
-void
-e_gdbus_book_proxy_new_for_bus (GBusType bus_type,
-                                GDBusProxyFlags flags,
-                                const gchar *name,
-                                const gchar *object_path,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
-{
-       g_async_initable_new_async (
-               E_TYPE_GDBUS_BOOK_PROXY,
-               G_PRIORITY_DEFAULT,
-               cancellable,
-               callback,
-               user_data,
-               "g-flags", flags,
-               "g-name", name,
-               "g-bus-type", bus_type,
-               "g-object-path", object_path,
-               "g-interface-name", GDBUS_BOOK_INTERFACE_NAME,
-               NULL);
-}
-
-/**
- * e_gdbus_book_proxy_new_for_bus_finish:
- * @result: A #GAsyncResult obtained from the #GAsyncReadyCallback function passed to e_gdbus_book_proxy_new_for_bus().
- * @error: Return location for error or %NULL.
- *
- * Finishes creating a #EGdbusBookProxy.
- *
- * Returns: A #EGdbusBookProxy or %NULL if @error is set. Free with g_object_unref().
- */
-EGdbusBook *
-e_gdbus_book_proxy_new_for_bus_finish (GAsyncResult *result,
-                                       GError **error)
-{
-       GObject *object;
-       GObject *source_object;
-       source_object = g_async_result_get_source_object (result);
-       g_assert (source_object != NULL);
-       object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
-       g_object_unref (source_object);
-
-       if (object != NULL)
-               return E_GDBUS_BOOK (object);
-       else
-               return NULL;
-}
-
-/**
- * e_gdbus_book_proxy_new_for_bus_sync:
- * @bus_type: A #GBusType.
- * @flags: Flags used when constructing the proxy.
- * @name: A bus name (well-known or unique).
- * @object_path: An object path.
- * @cancellable: A #GCancellable or %NULL.
- * @error: Return location for error or %NULL.
- *
- * Like g_dbus_proxy_new_for_bus_sync() but returns a #EGdbusBookProxy.
- *
- * This is a synchronous failable constructor. See e_gdbus_book_proxy_new_for_bus() and e_gdbus_book_proxy_new_for_bus_finish() for the asynchronous version.
- *
- * Returns: A #EGdbusBookProxy or %NULL if error is set. Free with g_object_unref().
- */
-EGdbusBook *
-e_gdbus_book_proxy_new_for_bus_sync (GBusType bus_type,
-                                     GDBusProxyFlags flags,
-                                     const gchar *name,
-                                     const gchar *object_path,
-                                     GCancellable *cancellable,
-                                     GError **error)
-{
-       GInitable *initable;
-
-       initable = g_initable_new (
-               E_TYPE_GDBUS_BOOK_PROXY,
-               cancellable,
-               error,
-               "g-flags", flags,
-               "g-name", name,
-               "g-bus-type", bus_type,
-               "g-object-path", object_path,
-               "g-interface-name", GDBUS_BOOK_INTERFACE_NAME,
-               NULL);
-       if (initable != NULL)
-               return E_GDBUS_BOOK (initable);
-       else
-               return NULL;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void stub_iface_init (EGdbusBookIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (EGdbusBookStub, e_gdbus_book_stub, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (E_TYPE_GDBUS_BOOK, stub_iface_init));
-
-static void
-e_gdbus_book_stub_init (EGdbusBookStub *stub)
-{
-}
-
-static void
-e_gdbus_book_stub_class_init (EGdbusBookStubClass *class)
-{
-}
-
-static void
-stub_iface_init (EGdbusBookIface *iface)
-{
-}
-
-/**
- * e_gdbus_book_stub_new:
- *
- * Creates a new stub object that can be exported via e_gdbus_book_register_object().
- *
- * Returns: A #EGdbusBookStub instance. Free with g_object_unref().
- */
-EGdbusBook *
-e_gdbus_book_stub_new (void)
-{
-       return E_GDBUS_BOOK (g_object_new (E_TYPE_GDBUS_BOOK_STUB, NULL));
-}
-
-/* Returns GDBus connection associated with the stub object */
-GDBusConnection *
-e_gdbus_book_stub_get_connection (EGdbusBook *stub)
-{
-       g_return_val_if_fail (stub != NULL, NULL);
-       g_return_val_if_fail (E_IS_GDBUS_BOOK_STUB (stub), NULL);
-
-       return g_object_get_data (G_OBJECT (stub), "gdbus-codegen-connection");
-}
diff --git a/addressbook/libegdbus/e-gdbus-book.h b/addressbook/libegdbus/e-gdbus-book.h
deleted file mode 100644 (file)
index 2ee76f5..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * e-gdbus-book.h
- *
- * This program 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) version 3.
- *
- * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 2011 Red Hat, Inc. (www.redhat.com)
- *
- */
-
-#ifndef E_GDBUS_BOOK_H
-#define E_GDBUS_BOOK_H
-
-#include <gio/gio.h>
-
-#include <libedataserver/libedataserver.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_GDBUS_BOOK         (e_gdbus_book_get_type ())
-#define E_GDBUS_BOOK(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_GDBUS_BOOK, EGdbusBook))
-#define E_IS_GDBUS_BOOK(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_GDBUS_BOOK))
-#define E_GDBUS_BOOK_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), E_TYPE_GDBUS_BOOK, EGdbusBookIface))
-
-/**
- * EGdbusBook:
- *
- * Opaque type representing a proxy or an exported object.
- */
-typedef struct _EGdbusBook EGdbusBook; /* Dummy typedef */
-
-typedef struct _EGdbusBookIface EGdbusBookIface;
-
-GType e_gdbus_book_get_type (void) G_GNUC_CONST;
-
-/* ---------------------------------------------------------------------- */
-
-#define E_TYPE_GDBUS_BOOK_PROXY         (e_gdbus_book_proxy_get_type ())
-#define E_GDBUS_BOOK_PROXY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_GDBUS_BOOK_PROXY, EGdbusBookProxy))
-#define E_IS_GDBUS_BOOK_PROXY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_GDBUS_BOOK_PROXY))
-
-typedef struct _EGdbusBookProxy EGdbusBookProxy;
-typedef struct _EGdbusBookProxyClass EGdbusBookProxyClass;
-typedef struct _EGdbusBookProxyPrivate EGdbusBookProxyPrivate;
-
-struct _EGdbusBookProxy
-{
-       GDBusProxy parent_instance;
-       EGdbusBookProxyPrivate *priv;
-};
-
-struct _EGdbusBookProxyClass
-{
-       GDBusProxyClass parent_class;
-};
-
-GType e_gdbus_book_proxy_get_type (void) G_GNUC_CONST;
-
-void e_gdbus_book_proxy_new (GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-EGdbusBook *e_gdbus_book_proxy_new_finish (GAsyncResult *result, GError **error);
-EGdbusBook *e_gdbus_book_proxy_new_sync (GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error);
-
-void e_gdbus_book_proxy_new_for_bus (GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-EGdbusBook *e_gdbus_book_proxy_new_for_bus_finish (GAsyncResult *result, GError **error);
-EGdbusBook *e_gdbus_book_proxy_new_for_bus_sync (GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error);
-
-/* ---------------------------------------------------------------------- */
-
-typedef struct _EGdbusBookStub EGdbusBookStub;
-typedef struct _EGdbusBookStubClass EGdbusBookStubClass;
-typedef struct _EGdbusBookStubPrivate EGdbusBookStubPrivate;
-
-struct _EGdbusBookStub
-{
-       GObject parent_instance;
-       EGdbusBookStubPrivate *priv;
-};
-
-struct _EGdbusBookStubClass
-{
-       GObjectClass parent_class;
-};
-
-#define E_TYPE_GDBUS_BOOK_STUB (e_gdbus_book_stub_get_type ())
-#define E_GDBUS_BOOK_STUB(o)   (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_GDBUS_BOOK_STUB, EGdbusBookStub))
-#define E_IS_GDBUS_BOOK_STUB(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_GDBUS_BOOK_STUB))
-
-GType e_gdbus_book_stub_get_type (void) G_GNUC_CONST;
-
-EGdbusBook *e_gdbus_book_stub_new (void);
-GDBusConnection *e_gdbus_book_stub_get_connection (EGdbusBook *stub);
-
-guint e_gdbus_book_register_object (EGdbusBook *object, GDBusConnection *connection, const gchar *object_path, GError **error);
-
-void e_gdbus_book_drain_notify (EGdbusBook *object);
-
-const GDBusInterfaceInfo *e_gdbus_book_interface_info (void) G_GNUC_CONST;
-
-struct _EGdbusBookIface
-{
-       GTypeInterface parent_iface;
-
-       /* Signal handlers for receiving D-Bus signals: */
-       void    (*backend_error)                (EGdbusBook *object, const gchar *arg_message);
-       void    (*readonly)                     (EGdbusBook *object, gboolean arg_is_readonly);
-       void    (*online)                       (EGdbusBook *object, gboolean arg_is_online);
-       void    (*opened)                       (EGdbusBook *object, const gchar * const *arg_error);
-       void    (*backend_property_changed)     (EGdbusBook *object, const gchar * const *arg_name_value);
-
-       /* Signal handlers for handling D-Bus method calls: */
-       gboolean (*handle_open)                 (EGdbusBook *object, GDBusMethodInvocation *invocation, gboolean in_only_if_exists);
-       void     (*open_done)                   (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-
-       gboolean (*handle_refresh)              (EGdbusBook *object, GDBusMethodInvocation *invocation);
-       void     (*refresh_done)                (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-
-       gboolean (*handle_get_contact)          (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_uid);
-       void     (*get_contact_done)            (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar **out_vcard);
-
-       gboolean (*handle_get_contact_list)     (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_query);
-       void     (*get_contact_list_done)       (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar ***out_vcards);
-
-       gboolean (*handle_get_contact_list_uids)(EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_query);
-       void     (*get_contact_list_uids_done)  (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar ***out_uids);
-
-       gboolean (*handle_add_contacts)         (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_vcards);
-       void     (*add_contacts_done)           (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar ***out_uids);
-
-       gboolean (*handle_remove_contacts)      (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_list);
-       void     (*remove_contacts_done)        (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-
-       gboolean (*handle_modify_contacts)      (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_vcards);
-       void     (*modify_contacts_done)        (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-
-       gboolean (*handle_get_backend_property) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_prop_name);
-       void     (*get_backend_property_done)   (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar **out_prop_value);
-
-       gboolean (*handle_set_backend_property) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_prop_name_value);
-       void     (*set_backend_property_done)   (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-
-       gboolean (*handle_get_view)             (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_query);
-       void     (*get_view_done)               (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar **out_view);
-
-       gboolean (*handle_cancel_operation)     (EGdbusBook *object, GDBusMethodInvocation *invocation, guint in_opid);
-       gboolean (*handle_cancel_all)           (EGdbusBook *object, GDBusMethodInvocation *invocation);
-       gboolean (*handle_close)                (EGdbusBook *object, GDBusMethodInvocation *invocation);
-
-};
-
-/* C Bindings for properties */
-
-/* D-Bus Methods */
-void           e_gdbus_book_call_open (GDBusProxy *proxy, gboolean in_only_if_exists, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_open_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_open_sync (GDBusProxy *proxy, gboolean in_only_if_exists, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_refresh (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_refresh_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_refresh_sync (GDBusProxy *proxy, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_get_contact (GDBusProxy *proxy, const gchar *in_uid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_get_contact_finish (GDBusProxy *proxy, GAsyncResult *result, gchar **out_vcard, GError **error);
-gboolean       e_gdbus_book_call_get_contact_sync (GDBusProxy *proxy, const gchar *in_uid, gchar **out_vcard, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_get_contact_list (GDBusProxy *proxy, const gchar *in_query, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_get_contact_list_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_vcards, GError **error);
-gboolean       e_gdbus_book_call_get_contact_list_sync (GDBusProxy *proxy, const gchar *in_query, gchar ***out_vcards, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_get_contact_list_uids (GDBusProxy *proxy, const gchar *in_query, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_get_contact_list_uids_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_uids, GError **error);
-gboolean       e_gdbus_book_call_get_contact_list_uids_sync (GDBusProxy *proxy, const gchar *in_query, gchar ***out_uids, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_add_contacts (GDBusProxy *proxy, const gchar * const *in_vcards, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_add_contacts_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_uids, GError **error);
-gboolean       e_gdbus_book_call_add_contacts_sync (GDBusProxy *proxy, const gchar * const *in_vcards, gchar ***out_uids, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_remove_contacts (GDBusProxy *proxy, const gchar * const *in_list, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_remove_contacts_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_remove_contacts_sync (GDBusProxy *proxy, const gchar * const *in_list, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_modify_contacts (GDBusProxy *proxy, const gchar * const *in_vcards, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_modify_contacts_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_modify_contacts_sync (GDBusProxy *proxy, const gchar * const *in_vcards, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_get_backend_property (GDBusProxy *proxy, const gchar *in_prop_name, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_get_backend_property_finish (GDBusProxy *proxy, GAsyncResult *result, gchar **out_prop_value, GError **error);
-gboolean       e_gdbus_book_call_get_backend_property_sync (GDBusProxy *proxy, const gchar *prop_name, gchar **out_prop_value, GCancellable *cancellable, GError **error);
-
-gchar **       e_gdbus_book_encode_set_backend_property (const gchar *in_prop_name, const gchar *in_prop_value);
-gboolean       e_gdbus_book_decode_set_backend_property (const gchar * const *in_strv, gchar **out_prop_name, gchar **out_prop_value);
-void           e_gdbus_book_call_set_backend_property (GDBusProxy *proxy, const gchar * const *in_prop_name_value, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_set_backend_property_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_set_backend_property_sync (GDBusProxy *proxy, const gchar * const *prop_name_value, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_get_view (GDBusProxy *proxy, const gchar *in_query, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_get_view_finish (GDBusProxy *proxy, GAsyncResult *result, gchar **out_view_path, GError **error);
-gboolean       e_gdbus_book_call_get_view_sync (GDBusProxy *proxy, const gchar *in_query, gchar **out_view_path, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_cancel_operation (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_cancel_operation_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_cancel_operation_sync (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_cancel_all (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_cancel_all_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_cancel_all_sync (GDBusProxy *proxy, GCancellable *cancellable, GError **error);
-
-void           e_gdbus_book_call_close (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean       e_gdbus_book_call_close_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean       e_gdbus_book_call_close_sync (GDBusProxy *proxy, GCancellable *cancellable, GError **error);
-
-/* D-Bus Methods Completion Helpers */
-#define e_gdbus_book_complete_open                             e_gdbus_complete_async_method
-#define e_gdbus_book_complete_refresh                          e_gdbus_complete_async_method
-#define e_gdbus_book_complete_get_contact                      e_gdbus_complete_async_method
-#define e_gdbus_book_complete_get_contact_list                 e_gdbus_complete_async_method
-#define e_gdbus_book_complete_get_contact_list_uids            e_gdbus_complete_async_method
-#define e_gdbus_book_complete_add_contacts                     e_gdbus_complete_async_method
-#define e_gdbus_book_complete_remove_contacts                  e_gdbus_complete_async_method
-#define e_gdbus_book_complete_modify_contacts                  e_gdbus_complete_async_method
-#define e_gdbus_book_complete_get_backend_property             e_gdbus_complete_async_method
-#define e_gdbus_book_complete_set_backend_property             e_gdbus_complete_async_method
-#define e_gdbus_book_complete_get_view                         e_gdbus_complete_async_method
-#define e_gdbus_book_complete_cancel_operation                 e_gdbus_complete_sync_method_void
-#define e_gdbus_book_complete_cancel_all                       e_gdbus_complete_sync_method_void
-#define e_gdbus_book_complete_close                            e_gdbus_complete_sync_method_void
-
-void e_gdbus_book_emit_open_done                       (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_book_emit_refresh_done                    (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_book_emit_get_contact_done                        (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *out_vcard);
-void e_gdbus_book_emit_get_contact_list_done           (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar * const *out_vcards);
-void e_gdbus_book_emit_get_contact_list_uids_done      (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar * const *out_uids);
-void e_gdbus_book_emit_add_contacts_done               (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *const *out_uids);
-void e_gdbus_book_emit_remove_contacts_done            (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_book_emit_modify_contacts_done            (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_book_emit_get_backend_property_done       (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *out_prop_value);
-void e_gdbus_book_emit_set_backend_property_done       (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_book_emit_get_view_done                   (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *out_view);
-
-/* D-Bus Signal Emission Helpers */
-void e_gdbus_book_emit_backend_error   (EGdbusBook *object, const gchar *arg_message);
-void e_gdbus_book_emit_readonly                (EGdbusBook *object, gboolean arg_is_readonly);
-void e_gdbus_book_emit_online          (EGdbusBook *object, gboolean arg_is_online);
-void e_gdbus_book_emit_opened          (EGdbusBook *object, const gchar * const *arg_error);
-void e_gdbus_book_emit_backend_property_changed        (EGdbusBook *object, const gchar * const *arg_name_value);
-
-G_END_DECLS
-
-#endif /* E_GDBUS_BOOK_H */
index 387d5b7..854a7a9 100644 (file)
@@ -37,8 +37,6 @@ e_book_backend_notify_update
 e_book_backend_notify_remove
 e_book_backend_notify_complete
 e_book_backend_notify_error
-e_book_backend_notify_readonly
-e_book_backend_notify_online
 e_book_backend_notify_property_changed
 e_book_backend_sync
 e_book_backend_set_is_removed
@@ -50,6 +48,8 @@ e_book_backend_is_opening
 e_book_backend_set_backend_property
 e_book_backend_foreach_view
 e_book_backend_notify_opened
+e_book_backend_notify_readonly
+e_book_backend_notify_online
 e_book_backend_respond_opened
 <SUBSECTION Standard>
 E_BOOK_BACKEND
@@ -281,13 +281,13 @@ e_data_book_respond_get_contact
 e_data_book_respond_get_contact_list
 e_data_book_respond_get_contact_list_uids
 e_data_book_report_error
-e_data_book_report_readonly
-e_data_book_report_online
 e_data_book_report_backend_property_changed
 e_data_book_string_slist_to_comma_string
 <SUBSECTION Deprecated>
 e_data_book_respond_set_backend_property
 e_data_book_report_opened
+e_data_book_report_readonly
+e_data_book_report_online
 <SUBSECTION Standard>
 E_DATA_BOOK
 E_IS_DATA_BOOK