Commit f3f1e94f authored by Fabiano Fidêncio's avatar Fabiano Fidêncio

Bug #732948 - Add backend-per-process support

With this we can have all backends running on theirs own processes, in
this way, if a backend crashes we don't have the whole factory crashing
together. Also, each instance of the EBackendFactory can decide if they
want to have all instances of the same backend (like calendar, memo list,
and task list) running in only one process (useful for evolution-ews and
evolution-mapi where we can share the connections between calendar, memo
list and task list) or have each extension running on its own process.
Apart from that, a configure option was added and, in case the user wants
to keep the old behavior, it can be disabled by passing
"--disable-backend-per-process" to the configure.

As a side effect of these changes, we are enforcing that the hash-key
used to keep track of the backend-factories will be built internally and
that *always* will follow the "backend-name:extension-name" structure,
even for ECollectionBackends.
parent 3a4f47ec
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
typedef EBookBackendFactory EBookBackendFileFactory; typedef EBookBackendFactory EBookBackendFileFactory;
typedef EBookBackendFactoryClass EBookBackendFileFactoryClass; typedef EBookBackendFactoryClass EBookBackendFileFactoryClass;
static EModule *e_module;
/* Module Entry Points */ /* Module Entry Points */
void e_module_load (GTypeModule *type_module); void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module); void e_module_unload (GTypeModule *type_module);
...@@ -43,6 +45,12 @@ G_DEFINE_DYNAMIC_TYPE ( ...@@ -43,6 +45,12 @@ G_DEFINE_DYNAMIC_TYPE (
static void static void
e_book_backend_file_factory_class_init (EBookBackendFactoryClass *class) e_book_backend_file_factory_class_init (EBookBackendFactoryClass *class)
{ {
EBackendFactoryClass *backend_factory_class;
backend_factory_class = E_BACKEND_FACTORY_CLASS (class);
backend_factory_class->e_module = e_module;
backend_factory_class->share_subprocess = FALSE;
class->factory_name = FACTORY_NAME; class->factory_name = FACTORY_NAME;
class->backend_type = E_TYPE_BOOK_BACKEND_FILE; class->backend_type = E_TYPE_BOOK_BACKEND_FILE;
} }
...@@ -60,11 +68,13 @@ e_book_backend_file_factory_init (EBookBackendFactory *factory) ...@@ -60,11 +68,13 @@ e_book_backend_file_factory_init (EBookBackendFactory *factory)
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module) e_module_load (GTypeModule *type_module)
{ {
e_module = E_MODULE (type_module);
e_book_backend_file_factory_register_type (type_module); e_book_backend_file_factory_register_type (type_module);
} }
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_unload (GTypeModule *type_module) e_module_unload (GTypeModule *type_module)
{ {
e_module = NULL;
} }
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
typedef EBookBackendFactory EBookBackendGoogleFactory; typedef EBookBackendFactory EBookBackendGoogleFactory;
typedef EBookBackendFactoryClass EBookBackendGoogleFactoryClass; typedef EBookBackendFactoryClass EBookBackendGoogleFactoryClass;
static EModule *e_module;
/* Module Entry Points */ /* Module Entry Points */
void e_module_load (GTypeModule *type_module); void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module); void e_module_unload (GTypeModule *type_module);
...@@ -41,6 +43,12 @@ G_DEFINE_DYNAMIC_TYPE ( ...@@ -41,6 +43,12 @@ G_DEFINE_DYNAMIC_TYPE (
static void static void
e_book_backend_google_factory_class_init (EBookBackendFactoryClass *class) e_book_backend_google_factory_class_init (EBookBackendFactoryClass *class)
{ {
EBackendFactoryClass *backend_factory_class;
backend_factory_class = E_BACKEND_FACTORY_CLASS (class);
backend_factory_class->e_module = e_module;
backend_factory_class->share_subprocess = FALSE;
class->factory_name = FACTORY_NAME; class->factory_name = FACTORY_NAME;
class->backend_type = E_TYPE_BOOK_BACKEND_GOOGLE; class->backend_type = E_TYPE_BOOK_BACKEND_GOOGLE;
} }
...@@ -58,10 +66,13 @@ e_book_backend_google_factory_init (EBookBackendFactory *factory) ...@@ -58,10 +66,13 @@ e_book_backend_google_factory_init (EBookBackendFactory *factory)
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module) e_module_load (GTypeModule *type_module)
{ {
e_module = E_MODULE (type_module);
e_book_backend_google_factory_register_type (type_module); e_book_backend_google_factory_register_type (type_module);
} }
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_unload (GTypeModule *type_module) e_module_unload (GTypeModule *type_module)
{ {
e_module = NULL;
} }
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
typedef EBookBackendFactory EBookBackendLDAPFactory; typedef EBookBackendFactory EBookBackendLDAPFactory;
typedef EBookBackendFactoryClass EBookBackendLDAPFactoryClass; typedef EBookBackendFactoryClass EBookBackendLDAPFactoryClass;
static EModule *e_module;
/* Module Entry Points */ /* Module Entry Points */
void e_module_load (GTypeModule *type_module); void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module); void e_module_unload (GTypeModule *type_module);
...@@ -46,6 +48,12 @@ G_DEFINE_DYNAMIC_TYPE ( ...@@ -46,6 +48,12 @@ G_DEFINE_DYNAMIC_TYPE (
static void static void
e_book_backend_ldap_factory_class_init (EBookBackendFactoryClass *class) e_book_backend_ldap_factory_class_init (EBookBackendFactoryClass *class)
{ {
EBackendFactoryClass *backend_factory_class;
backend_factory_class = E_BACKEND_FACTORY_CLASS (class);
backend_factory_class->e_module = e_module;
backend_factory_class->share_subprocess = FALSE;
class->factory_name = FACTORY_NAME; class->factory_name = FACTORY_NAME;
class->backend_type = E_TYPE_BOOK_BACKEND_LDAP; class->backend_type = E_TYPE_BOOK_BACKEND_LDAP;
} }
...@@ -63,6 +71,8 @@ e_book_backend_ldap_factory_init (EBookBackendFactory *factory) ...@@ -63,6 +71,8 @@ e_book_backend_ldap_factory_init (EBookBackendFactory *factory)
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module) e_module_load (GTypeModule *type_module)
{ {
e_module = E_MODULE (type_module);
e_source_ldap_type_register (type_module); e_source_ldap_type_register (type_module);
e_book_backend_ldap_factory_register_type (type_module); e_book_backend_ldap_factory_register_type (type_module);
} }
...@@ -70,5 +80,5 @@ e_module_load (GTypeModule *type_module) ...@@ -70,5 +80,5 @@ e_module_load (GTypeModule *type_module)
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_unload (GTypeModule *type_module) e_module_unload (GTypeModule *type_module)
{ {
e_module = NULL;
} }
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
typedef EBookBackendFactory EBookBackendWebdavFactory; typedef EBookBackendFactory EBookBackendWebdavFactory;
typedef EBookBackendFactoryClass EBookBackendWebdavFactoryClass; typedef EBookBackendFactoryClass EBookBackendWebdavFactoryClass;
static EModule *e_module;
/* Module Entry Points */ /* Module Entry Points */
void e_module_load (GTypeModule *type_module); void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module); void e_module_unload (GTypeModule *type_module);
...@@ -41,6 +43,12 @@ G_DEFINE_DYNAMIC_TYPE ( ...@@ -41,6 +43,12 @@ G_DEFINE_DYNAMIC_TYPE (
static void static void
e_book_backend_webdav_factory_class_init (EBookBackendFactoryClass *class) e_book_backend_webdav_factory_class_init (EBookBackendFactoryClass *class)
{ {
EBackendFactoryClass *backend_factory_class;
backend_factory_class = E_BACKEND_FACTORY_CLASS (class);
backend_factory_class->e_module = e_module;
backend_factory_class->share_subprocess = FALSE;
class->factory_name = FACTORY_NAME; class->factory_name = FACTORY_NAME;
class->backend_type = E_TYPE_BOOK_BACKEND_WEBDAV; class->backend_type = E_TYPE_BOOK_BACKEND_WEBDAV;
} }
...@@ -58,11 +66,13 @@ e_book_backend_webdav_factory_init (EBookBackendFactory *factory) ...@@ -58,11 +66,13 @@ e_book_backend_webdav_factory_init (EBookBackendFactory *factory)
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module) e_module_load (GTypeModule *type_module)
{ {
e_module = E_MODULE (type_module);
e_book_backend_webdav_factory_register_type (type_module); e_book_backend_webdav_factory_register_type (type_module);
} }
G_MODULE_EXPORT void G_MODULE_EXPORT void
e_module_unload (GTypeModule *type_module) e_module_unload (GTypeModule *type_module)
{ {
e_module = NULL;
} }
...@@ -1103,18 +1103,23 @@ book_client_cursor_initable_init (GInitable *initable, ...@@ -1103,18 +1103,23 @@ book_client_cursor_initable_init (GInitable *initable,
EBookClientCursor *cursor = E_BOOK_CLIENT_CURSOR (initable); EBookClientCursor *cursor = E_BOOK_CLIENT_CURSOR (initable);
EBookClientCursorPrivate *priv = cursor->priv; EBookClientCursorPrivate *priv = cursor->priv;
EDBusAddressBookCursor *proxy; EDBusAddressBookCursor *proxy;
gchar *bus_name;
/* We only need a proxy for regular access, no need in DRA mode */ /* We only need a proxy for regular access, no need in DRA mode */
if (priv->direct_cursor) if (priv->direct_cursor)
return TRUE; return TRUE;
bus_name = e_client_dup_bus_name (E_CLIENT (priv->client));
proxy = e_dbus_address_book_cursor_proxy_new_sync ( proxy = e_dbus_address_book_cursor_proxy_new_sync (
priv->connection, priv->connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
ADDRESS_BOOK_DBUS_SERVICE_NAME, bus_name,
priv->object_path, priv->object_path,
cancellable, error); cancellable, error);
g_free (bus_name);
if (!proxy) if (!proxy)
return FALSE; return FALSE;
......
...@@ -876,19 +876,36 @@ book_client_view_initable_init (GInitable *initable, ...@@ -876,19 +876,36 @@ book_client_view_initable_init (GInitable *initable,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
EBookClient *book_client;
EBookClientViewPrivate *priv; EBookClientViewPrivate *priv;
EGdbusBookView *gdbus_bookview; EGdbusBookView *gdbus_bookview;
gulong handler_id; gulong handler_id;
gchar *bus_name;
priv = E_BOOK_CLIENT_VIEW_GET_PRIVATE (initable); priv = E_BOOK_CLIENT_VIEW_GET_PRIVATE (initable);
book_client = g_weak_ref_get (&priv->client);
if (book_client == NULL) {
g_set_error (
error, E_CLIENT_ERROR,
E_CLIENT_ERROR_OTHER_ERROR,
_("Client disappeared"));
return FALSE;
}
bus_name = e_client_dup_bus_name (E_CLIENT (book_client));
g_object_unref (book_client);
gdbus_bookview = e_gdbus_book_view_proxy_new_sync ( gdbus_bookview = e_gdbus_book_view_proxy_new_sync (
priv->connection, priv->connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
ADDRESS_BOOK_DBUS_SERVICE_NAME, bus_name,
priv->object_path, priv->object_path,
cancellable, error); cancellable, error);
g_free (bus_name);
if (gdbus_bookview == NULL) if (gdbus_bookview == NULL)
return FALSE; return FALSE;
......
...@@ -974,6 +974,7 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple, ...@@ -974,6 +974,7 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
ESource *source; ESource *source;
const gchar *uid; const gchar *uid;
gchar *object_path = NULL; gchar *object_path = NULL;
gchar *bus_name = NULL;
gulong handler_id; gulong handler_id;
GError *local_error = NULL; GError *local_error = NULL;
...@@ -1017,14 +1018,14 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple, ...@@ -1017,14 +1018,14 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
} }
e_dbus_address_book_factory_call_open_address_book_sync ( e_dbus_address_book_factory_call_open_address_book_sync (
factory_proxy, uid, &object_path, cancellable, &local_error); factory_proxy, uid, &object_path, &bus_name, cancellable, &local_error);
g_object_unref (factory_proxy); g_object_unref (factory_proxy);
/* Sanity check. */ /* Sanity check. */
g_return_if_fail ( g_return_if_fail (
((object_path != NULL) && (local_error == NULL)) || (((object_path != NULL) || (bus_name != NULL)) && (local_error == NULL)) ||
((object_path == NULL) && (local_error != NULL))); (((object_path == NULL) || (bus_name == NULL)) && (local_error != NULL)));
if (local_error != NULL) { if (local_error != NULL) {
g_dbus_error_strip_remote_error (local_error); g_dbus_error_strip_remote_error (local_error);
...@@ -1033,13 +1034,15 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple, ...@@ -1033,13 +1034,15 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
return; return;
} }
e_client_set_bus_name (client, bus_name);
priv->dbus_proxy = e_dbus_address_book_proxy_new_sync ( priv->dbus_proxy = e_dbus_address_book_proxy_new_sync (
connection, connection,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
ADDRESS_BOOK_DBUS_SERVICE_NAME, bus_name, object_path, cancellable, &local_error);
object_path, cancellable, &local_error);
g_free (object_path); g_free (object_path);
g_free (bus_name);
/* Sanity check. */ /* Sanity check. */
g_return_if_fail ( g_return_if_fail (
......
...@@ -12,6 +12,7 @@ libedata_book_1_2_la_CPPFLAGS = \ ...@@ -12,6 +12,7 @@ libedata_book_1_2_la_CPPFLAGS = \
-DLIBEDATA_BOOK_COMPILATION \ -DLIBEDATA_BOOK_COMPILATION \
-DG_LOG_DOMAIN=\"libedata-book\" \ -DG_LOG_DOMAIN=\"libedata-book\" \
-DBACKENDDIR=\"$(ebook_backenddir)\" \ -DBACKENDDIR=\"$(ebook_backenddir)\" \
-DSUBPROCESS_BOOK_BACKEND_PATH=\"$(libexecdir)/evolution-addressbook-factory-subprocess\" \
-I$(top_srcdir) \ -I$(top_srcdir) \
-I$(top_srcdir)/addressbook \ -I$(top_srcdir)/addressbook \
-I$(top_srcdir)/addressbook/libegdbus \ -I$(top_srcdir)/addressbook/libegdbus \
...@@ -40,6 +41,7 @@ libedata_book_1_2_la_SOURCES = \ ...@@ -40,6 +41,7 @@ libedata_book_1_2_la_SOURCES = \
e-data-book-direct.c \ e-data-book-direct.c \
e-data-book-factory.c \ e-data-book-factory.c \
e-data-book-view.c \ e-data-book-view.c \
e-subprocess-book-factory.c \
ximian-vcard.h \ ximian-vcard.h \
$(LIBDB_C_FILES) \ $(LIBDB_C_FILES) \
$(NULL) $(NULL)
...@@ -77,6 +79,7 @@ libedata_bookinclude_HEADERS = \ ...@@ -77,6 +79,7 @@ libedata_bookinclude_HEADERS = \
e-book-backend-cache.h \ e-book-backend-cache.h \
e-book-backend-sqlitedb.h \ e-book-backend-sqlitedb.h \
e-book-sqlite.h \ e-book-sqlite.h \
e-subprocess-book-factory.h \
$(LIBDB_H_FILES) \ $(LIBDB_H_FILES) \
$(NULL) $(NULL)
...@@ -97,6 +100,47 @@ e_book_backend_sqlitedb_test_LDADD = \ ...@@ -97,6 +100,47 @@ e_book_backend_sqlitedb_test_LDADD = \
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libedata-book-$(API_VERSION).pc pkgconfig_DATA = libedata-book-$(API_VERSION).pc
libexec_PROGRAMS = evolution-addressbook-factory-subprocess
evolution_addressbook_factory_subprocess_CPPFLAGS= \
$(AM_CPPFLAGS) \
-DLOCALEDIR=\"$(localedir)\" \
-I$(top_srcdir) \
-I$(top_srcdir)/private \
-I$(top_srcdir)/addressbook \
-I$(top_builddir) \
-I$(top_builddir)/private \
-I$(top_builddir)/addressbook \
$(EVOLUTION_ADDRESSBOOK_CFLAGS) \
$(LIBSECRET_CFLAGS) \
$(FACTORY_GTK_CFLAGS) \
$(CAMEL_CFLAGS) \
$(SOUP_CFLAGS) \
$(GOA_CFLAGS) \
$(CODE_COVERAGE_CFLAGS) \
$(NULL)
evolution_addressbook_factory_subprocess_SOURCES = \
evolution-addressbook-factory-subprocess.c \
$(NULL)
evolution_addressbook_factory_subprocess_LDADD = \
$(top_builddir)/libebackend/libebackend-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
libedata-book-1.2.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
$(LIBSECRET_LIBS) \
$(FACTORY_GTK_LIBS) \
$(CAMEL_LIBS) \
$(SOUP_LIBS) \
$(GOA_LIBS) \
$(NULL)
evolution_addressbook_factory_subprocess_LDFLAGS = \
$(AM_LDFLAGS) \
$(CODE_COVERAGE_LDFLAGS) \
$(NULL)
DISTCLEANFILES = $(pkgconfig_DATA) DISTCLEANFILES = $(pkgconfig_DATA)
EXTRA_DIST = \ EXTRA_DIST = \
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "e-book-backend-factory.h" #include "e-book-backend-factory.h"
#include "e-data-book.h" #include "e-data-book.h"
#include "e-data-book-factory.h" #include "e-data-book-factory.h"
#include "e-dbus-localed.h"
#define d(x) #define d(x)
...@@ -52,16 +51,8 @@ ...@@ -52,16 +51,8 @@
struct _EDataBookFactoryPrivate { struct _EDataBookFactoryPrivate {
EDBusAddressBookFactory *dbus_factory; EDBusAddressBookFactory *dbus_factory;
/* Watching "org.freedesktop.locale1" for locale changes */
guint localed_watch_id;
EDBusLocale1 *localed_proxy;
GCancellable *localed_cancel;
gchar *locale;
}; };
static GInitableIface *initable_parent_interface;
/* Forward Declarations */ /* Forward Declarations */
static void e_data_book_factory_initable_init static void e_data_book_factory_initable_init
(GInitableIface *iface); (GInitableIface *iface);
...@@ -84,82 +75,27 @@ data_book_factory_get_dbus_interface_skeleton (EDBusServer *server) ...@@ -84,82 +75,27 @@ data_book_factory_get_dbus_interface_skeleton (EDBusServer *server)
return G_DBUS_INTERFACE_SKELETON (factory->priv->dbus_factory); return G_DBUS_INTERFACE_SKELETON (factory->priv->dbus_factory);
} }
/* This is totally backwards, for some insane reason we holding static const gchar *
* references to the EBookBackends and then fetching the EDataBook data_book_get_factory_name (EBackendFactory *backend_factory)
* via e_book_backend_ref_data_book(), the whole scheme should
* be reversed and this function probably removed.
*/
static GList *
data_book_factory_list_books (EDataBookFactory *factory)
{ {
GList *books = NULL; EBookBackendFactoryClass *class;
GSList *backends, *l;
backends = e_data_factory_list_backends (E_DATA_FACTORY (factory));
for (l = backends; l != NULL; l = g_slist_next (l)) {
EBookBackend *backend = l->data;
EDataBook *book = e_book_backend_ref_data_book (backend);
if (g_list_find (books, book) == NULL) class = E_BOOK_BACKEND_FACTORY_GET_CLASS (E_BOOK_BACKEND_FACTORY (backend_factory));
books = g_list_prepend (books, book);
else
g_object_unref (book);
}
g_slist_free_full (backends, g_object_unref); return class->factory_name;
return books;
} }
static gchar * static void
data_book_factory_open (EDataFactory *data_factory, data_book_complete_open (EDataFactory *data_factory,
EBackend *backend, GDBusMethodInvocation *invocation,
GDBusConnection *connection, const gchar *object_path,
GError **error) const gchar *bus_name,
const gchar *extension_name)
{ {
EDataBookFactory *factory = E_DATA_BOOK_FACTORY (data_factory); EDataBookFactory *data_book_factory = E_DATA_BOOK_FACTORY (data_factory);
EDataBook *data_book;
gchar *object_path; e_dbus_address_book_factory_complete_open_address_book (
data_book_factory->priv->dbus_factory, invocation, object_path, bus_name);
/* If the backend already has an EDataBook installed, return its
* object path. Otherwise we need to install a new EDataBook. */
data_book = e_book_backend_ref_data_book (E_BOOK_BACKEND (backend));
if (data_book != NULL) {
object_path = g_strdup (
e_data_book_get_object_path (data_book));
} else {
object_path = e_data_factory_construct_path (data_factory);
/* The EDataBook will attach itself to EBookBackend,
* so no need to call e_book_backend_set_data_book(). */
data_book = e_data_book_new (
E_BOOK_BACKEND (backend),
connection, object_path, error);
if (data_book != NULL) {
e_data_factory_set_backend_callbacks (
data_factory, backend);
/* Don't set the locale on a new book if we have not
* yet received a notification of a locale change
*/
if (factory->priv->locale)
e_data_book_set_locale (
data_book,
factory->priv->locale,
NULL, NULL);
} else {
g_free (object_path);
object_path = NULL;
}
}
g_clear_object (&data_book);
return object_path;
} }
static gboolean static gboolean
...@@ -168,26 +104,10 @@ data_book_factory_handle_open_address_book_cb (EDBusAddressBookFactory *iface, ...@@ -168,26 +104,10 @@ data_book_factory_handle_open_address_book_cb (EDBusAddressBookFactory *iface,
const gchar *uid, const gchar *uid,
EDataBookFactory *factory) EDataBookFactory *factory)
{ {
GDBusConnection *connection; EDataFactory *data_factory = E_DATA_FACTORY (factory);
const gchar *sender;
gchar *object_path; e_data_factory_spawn_subprocess_backend (
GError *error = NULL; data_factory, invocation, uid, E_SOURCE_EXTENSION_ADDRESS_BOOK, SUBPROCESS_BOOK_BACKEND_PATH);
connection = g_dbus_method_invocation_get_connection (invocation);
sender = g_dbus_method_invocation_get_sender (invocation);
object_path = e_data_factory_open_backend (
E_DATA_FACTORY (factory), connection, sender,
uid, E_SOURCE_EXTENSION_ADDRESS_BOOK, &error);
if (object_path != NULL) {
e_dbus_address_book_factory_complete_open_address_book (
iface, invocation, object_path);
g_free (object_path);
} else {
g_return_val_if_fail (error != NULL, FALSE);
g_dbus_method_invocation_take_error (invocation, error);
}
return TRUE; return TRUE;
} }
...@@ -203,232 +123,10 @@ data_book_factory_dispose (GObject *object) ...@@ -203,232 +123,10 @@ data_book_factory_dispose (GObject *object)
g_clear_object (&priv->dbus_factory); g_clear_object (&priv->dbus_factory);
if (priv->localed_cancel)
g_cancellable_cancel (priv->localed_cancel);
g_clear_object (&priv->localed_cancel);
g_clear_object (&priv->localed_proxy);
if (priv->localed_watch_id > 0)
g_bus_unwatch_name (priv->localed_watch_id);
/* Chain up to parent's dispose() method. */ /* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_data_book_factory_parent_class)->dispose (object); G_OBJECT_CLASS (e_data_book_factory_parent_class)->dispose (object);
} }
static void
data_book_factory_finalize (GObject *object)
{
EDataBookFactory *factory;
factory = E_DATA_BOOK_FACTORY (object);
g_free (factory->priv->locale);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_data_book_factory_parent_class)->finalize (object);
}
static gchar *
data_book_factory_interpret_locale_value (const gchar *value)
{
gchar *interpreted_value = NULL;
gchar **split;
split = g_strsplit (value, "=", 2);
if (split && split[0] && split[1])
interpreted_value = g_strdup (split[1]);
g_strfreev (split);
if (!interpreted_value)
g_warning ("Failed to interpret locale value: %s", value);
return interpreted_value;
}
static gchar *
data_book_factory_interpret_locale (const gchar * const * locale)
{
gint i;
gchar *interpreted_locale = NULL;
/* Prioritize LC_COLLATE and then LANG values
* in the 'locale' specified by localed.
*
* If localed explicitly specifies no locale, then
* default to checking system locale.
*/
if (locale) {
for (i = 0; locale[i] != NULL && interpreted_locale == NULL; i++) {
if (strncmp (locale[i], "LC_COLLATE", 10) == 0)
interpreted_locale =
data_book_factory_interpret_locale_value (locale[i]);
}
for (i