89
66
e_data_book_factory_initable_init))
92
watched_names_value_free (gpointer value)
94
g_bus_unwatch_name (GPOINTER_TO_UINT (value));
98
data_book_factory_toggle_notify_cb (gpointer data,
100
gboolean is_last_ref)
103
/* Take a strong reference before removing the
104
* toggle reference, to keep the backend alive. */
105
g_object_ref (backend);
107
g_object_remove_toggle_ref (
108
backend, data_book_factory_toggle_notify_cb, data);
110
g_signal_emit_by_name (backend, "shutdown");
112
g_object_unref (backend);
117
data_book_factory_connections_add (EDataBookFactory *factory,
119
EBookBackend *backend)
121
GHashTable *connections;
124
g_return_if_fail (name != NULL);
125
g_return_if_fail (backend != NULL);
127
g_mutex_lock (&factory->priv->connections_lock);
129
connections = factory->priv->connections;
131
if (g_hash_table_size (connections) == 0)
132
e_dbus_server_hold (E_DBUS_SERVER (factory));
134
array = g_hash_table_lookup (connections, name);
137
array = g_ptr_array_new_with_free_func (
138
(GDestroyNotify) g_object_unref);
139
g_hash_table_insert (
140
connections, g_strdup (name), array);
143
g_ptr_array_add (array, g_object_ref (backend));
145
g_mutex_unlock (&factory->priv->connections_lock);
149
data_book_factory_connections_remove (EDataBookFactory *factory,
151
EBookBackend *backend)
153
GHashTable *connections;
155
gboolean removed = FALSE;
157
/* If backend is NULL, we remove all backends for name. */
158
g_return_val_if_fail (name != NULL, FALSE);
160
g_mutex_lock (&factory->priv->connections_lock);
162
connections = factory->priv->connections;
163
array = g_hash_table_lookup (connections, name);
166
if (backend != NULL) {
167
removed = g_ptr_array_remove_fast (array, backend);
168
} else if (array->len > 0) {
169
g_ptr_array_set_size (array, 0);
174
g_hash_table_remove (connections, name);
176
if (g_hash_table_size (connections) == 0)
177
e_dbus_server_release (E_DBUS_SERVER (factory));
180
g_mutex_unlock (&factory->priv->connections_lock);
186
data_book_factory_connections_remove_all (EDataBookFactory *factory)
188
GHashTable *connections;
190
g_mutex_lock (&factory->priv->connections_lock);
192
connections = factory->priv->connections;
194
if (g_hash_table_size (connections) > 0) {
195
g_hash_table_remove_all (connections);
196
e_dbus_server_release (E_DBUS_SERVER (factory));
199
g_mutex_unlock (&factory->priv->connections_lock);
203
data_book_factory_name_vanished_cb (GDBusConnection *connection,
207
GWeakRef *weak_ref = user_data;
68
static GDBusInterfaceSkeleton *
69
data_book_factory_get_dbus_interface_skeleton (EDBusServer *server)
208
71
EDataBookFactory *factory;
210
factory = g_weak_ref_get (weak_ref);
212
if (factory != NULL) {
213
data_book_factory_connections_remove (factory, name, NULL);
215
/* Unwatching the bus name from here will corrupt the
216
* 'name' argument, and possibly also the 'user_data'.
218
* This is a GDBus bug. Work around it by unwatching
221
* See: https://bugzilla.gnome.org/706088
223
g_mutex_lock (&factory->priv->watched_names_lock);
224
g_hash_table_remove (factory->priv->watched_names, name);
225
g_mutex_unlock (&factory->priv->watched_names_lock);
227
g_object_unref (factory);
232
data_book_factory_watched_names_add (EDataBookFactory *factory,
233
GDBusConnection *connection,
236
GHashTable *watched_names;
238
g_return_if_fail (name != NULL);
240
g_mutex_lock (&factory->priv->watched_names_lock);
242
watched_names = factory->priv->watched_names;
244
if (!g_hash_table_contains (watched_names, name)) {
247
/* The g_bus_watch_name() documentation says one of the two
248
* callbacks are guaranteed to be invoked after calling the
249
* function. But which one is determined asynchronously so
250
* there should be no chance of the name vanished callback
251
* deadlocking with us when it tries to acquire the lock. */
252
watcher_id = g_bus_watch_name_on_connection (
254
G_BUS_NAME_WATCHER_FLAGS_NONE,
255
(GBusNameAppearedCallback) NULL,
256
data_book_factory_name_vanished_cb,
257
e_weak_ref_new (factory),
258
(GDestroyNotify) e_weak_ref_free);
260
g_hash_table_insert (
261
watched_names, g_strdup (name),
262
GUINT_TO_POINTER (watcher_id));
265
g_mutex_unlock (&factory->priv->watched_names_lock);
269
data_book_factory_ref_backend (EDataFactory *factory,
274
ESourceBackend *extension;
275
const gchar *extension_name;
278
/* For address books the hash key is simply the backend name.
279
* (cf. calendar hash keys, which are slightly more complex) */
281
extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
282
extension = e_source_get_extension (source, extension_name);
283
backend_name = e_source_backend_dup_backend_name (extension);
285
if (backend_name == NULL || *backend_name == '\0') {
287
error, E_DATA_BOOK_ERROR,
288
E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
289
_("No backend name in source '%s'"),
290
e_source_get_display_name (source));
291
g_free (backend_name);
295
backend = e_data_factory_ref_initable_backend (
296
factory, backend_name, source, NULL, error);
298
g_free (backend_name);
304
construct_book_factory_path (void)
306
static volatile gint counter = 1;
308
g_atomic_int_inc (&counter);
310
return g_strdup_printf (
311
"/org/gnome/evolution/dataserver/AddressBook/%d/%u",
316
data_book_factory_closed_cb (EBookBackend *backend,
318
EDataBookFactory *factory)
320
data_book_factory_connections_remove (factory, sender, backend);
323
/* This is totally backwards, for some insane reason we holding
324
* references to the EBookBackends and then fetching the EDataBook
325
* via e_book_backend_ref_data_book(), the whole scheme should
326
* be reversed and this function probably removed.
329
data_book_factory_list_books (EDataBookFactory *factory)
332
GHashTable *connections;
336
g_mutex_lock (&factory->priv->connections_lock);
338
connections = factory->priv->connections;
340
g_hash_table_iter_init (&iter, connections);
341
while (g_hash_table_iter_next (&iter, &key, &value)) {
342
GPtrArray *array = (GPtrArray *) value;
345
for (i = 0; i < array->len; i++) {
346
EBookBackend *backend = g_ptr_array_index (array, i);
347
EDataBook *book = e_book_backend_ref_data_book (backend);
349
if (g_list_find (books, book) == NULL)
350
books = g_list_prepend (books, book);
352
g_object_unref (book);
355
g_mutex_unlock (&factory->priv->connections_lock);
361
data_book_factory_open (EDataBookFactory *factory,
362
GDBusConnection *connection,
367
EDataBook *data_book;
369
ESourceRegistry *registry;
373
if (uid == NULL || *uid == '\0') {
375
error, E_DATA_BOOK_ERROR,
376
E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
377
_("Missing source UID"));
381
registry = e_data_book_factory_get_registry (factory);
382
source = e_source_registry_ref_source (registry, uid);
384
if (source == NULL) {
386
error, E_DATA_BOOK_ERROR,
387
E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
388
_("No such source for UID '%s'"), uid);
392
backend = data_book_factory_ref_backend (
393
E_DATA_FACTORY (factory), source, error);
395
g_object_unref (source);
400
/* If the backend already has an EDataBook installed, return its
401
* object path. Otherwise we need to install a new EDataBook. */
403
data_book = e_book_backend_ref_data_book (E_BOOK_BACKEND (backend));
405
if (data_book != NULL) {
406
object_path = g_strdup (
407
e_data_book_get_object_path (data_book));
409
object_path = construct_book_factory_path ();
411
/* The EDataBook will attach itself to EBookBackend,
412
* so no need to call e_book_backend_set_data_book(). */
413
data_book = e_data_book_new (
414
E_BOOK_BACKEND (backend),
415
connection, object_path, error);
417
if (data_book != NULL) {
418
/* Install a toggle reference on the backend
419
* so we can signal it to shut down once all
420
* client connections are closed. */
421
g_object_add_toggle_ref (
423
data_book_factory_toggle_notify_cb,
426
g_signal_connect_object (
428
G_CALLBACK (data_book_factory_closed_cb),
431
/* Don't set the locale on a new book if we have not
432
* yet received a notification of a locale change
434
if (factory->priv->locale)
435
e_data_book_set_locale (
437
factory->priv->locale,
440
g_free (object_path);
445
if (data_book != NULL) {
446
/* Watch the sender's bus name so we can clean
447
* up its connections if the bus name vanishes. */
448
data_book_factory_watched_names_add (
449
factory, connection, sender);
451
/* A client may create multiple EClient instances for the
452
* same ESource, each of which calls close() individually.
453
* So we must track each and every connection made. */
454
data_book_factory_connections_add (
455
factory, sender, E_BOOK_BACKEND (backend));
458
g_clear_object (&data_book);
459
g_clear_object (&backend);
73
factory = E_DATA_BOOK_FACTORY (server);
75
return G_DBUS_INTERFACE_SKELETON (factory->priv->dbus_factory);
79
data_book_get_factory_name (EBackendFactory *backend_factory)
81
EBookBackendFactoryClass *class;
83
class = E_BOOK_BACKEND_FACTORY_GET_CLASS (E_BOOK_BACKEND_FACTORY (backend_factory));
85
return class->factory_name;
89
data_book_complete_open (EDataFactory *data_factory,
90
GDBusMethodInvocation *invocation,
91
const gchar *object_path,
92
const gchar *bus_name,
93
const gchar *extension_name)
95
EDataBookFactory *data_book_factory = E_DATA_BOOK_FACTORY (data_factory);
97
e_dbus_address_book_factory_complete_open_address_book (
98
data_book_factory->priv->dbus_factory, invocation, object_path, bus_name);
467
104
const gchar *uid,
468
105
EDataBookFactory *factory)
470
GDBusConnection *connection;
473
GError *error = NULL;
475
connection = g_dbus_method_invocation_get_connection (invocation);
476
sender = g_dbus_method_invocation_get_sender (invocation);
478
object_path = data_book_factory_open (
479
factory, connection, sender, uid, &error);
481
if (object_path != NULL) {
482
e_dbus_address_book_factory_complete_open_address_book (
483
iface, invocation, object_path);
484
g_free (object_path);
486
g_return_val_if_fail (error != NULL, FALSE);
487
g_dbus_method_invocation_take_error (invocation, error);
107
EDataFactory *data_factory = E_DATA_FACTORY (factory);
109
e_data_factory_spawn_subprocess_backend (
110
data_factory, invocation, uid, E_SOURCE_EXTENSION_ADDRESS_BOOK, SUBPROCESS_BOOK_BACKEND_PATH);
494
data_book_factory_get_property (GObject *object,
499
switch (property_id) {
503
e_data_book_factory_get_registry (
504
E_DATA_BOOK_FACTORY (object)));
508
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
512
116
data_book_factory_dispose (GObject *object)
118
EDataBookFactory *factory;
514
119
EDataBookFactoryPrivate *priv;
516
priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (object);
518
if (priv->registry != NULL) {
519
g_object_unref (priv->registry);
520
priv->registry = NULL;
523
if (priv->dbus_factory != NULL) {
524
g_object_unref (priv->dbus_factory);
525
priv->dbus_factory = NULL;
528
if (priv->localed_cancel) {
529
g_cancellable_cancel (priv->localed_cancel);
530
g_object_unref (priv->localed_cancel);
531
priv->localed_cancel = NULL;
534
if (priv->localed_proxy) {
535
g_object_unref (priv->localed_proxy);
536
priv->localed_proxy = NULL;
539
if (priv->localed_watch_id > 0)
540
g_bus_unwatch_name (priv->localed_watch_id);
542
g_hash_table_remove_all (priv->connections);
543
g_hash_table_remove_all (priv->watched_names);
121
factory = E_DATA_BOOK_FACTORY (object);
122
priv = factory->priv;
124
g_clear_object (&priv->dbus_factory);
545
126
/* Chain up to parent's dispose() method. */
546
127
G_OBJECT_CLASS (e_data_book_factory_parent_class)->dispose (object);
550
data_book_factory_finalize (GObject *object)
552
EDataBookFactoryPrivate *priv;
554
priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (object);
556
g_hash_table_destroy (priv->connections);
557
g_mutex_clear (&priv->connections_lock);
559
g_hash_table_destroy (priv->watched_names);
560
g_mutex_clear (&priv->watched_names_lock);
562
g_free (priv->locale);
564
/* Chain up to parent's finalize() method. */
565
G_OBJECT_CLASS (e_data_book_factory_parent_class)->finalize (object);
569
data_book_factory_bus_acquired (EDBusServer *server,
570
GDBusConnection *connection)
572
EDataBookFactoryPrivate *priv;
573
GError *error = NULL;
575
priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (server);
577
g_dbus_interface_skeleton_export (
578
G_DBUS_INTERFACE_SKELETON (priv->dbus_factory),
580
"/org/gnome/evolution/dataserver/AddressBookFactory",
585
"Failed to export AddressBookFactory interface: %s",
587
g_assert_not_reached ();
590
/* Chain up to parent's bus_acquired() method. */
591
E_DBUS_SERVER_CLASS (e_data_book_factory_parent_class)->
592
bus_acquired (server, connection);
596
data_book_factory_bus_name_lost (EDBusServer *server,
597
GDBusConnection *connection)
599
EDataBookFactory *factory;
601
factory = E_DATA_BOOK_FACTORY (server);
603
data_book_factory_connections_remove_all (factory);
605
/* Chain up to parent's bus_name_lost() method. */
606
E_DBUS_SERVER_CLASS (e_data_book_factory_parent_class)->
607
bus_name_lost (server, connection);
611
data_book_factory_quit_server (EDBusServer *server,
612
EDBusServerExitCode exit_code)
614
/* This factory does not support reloading, so stop the signal
615
* emission and return without chaining up to prevent quitting. */
616
if (exit_code == E_DBUS_SERVER_EXIT_RELOAD) {
617
g_signal_stop_emission_by_name (server, "quit-server");
621
/* Chain up to parent's quit_server() method. */
622
E_DBUS_SERVER_CLASS (e_data_book_factory_parent_class)->
623
quit_server (server, exit_code);
627
data_book_factory_interpret_locale_value (const gchar *value)
629
gchar *interpreted_value = NULL;
632
split = g_strsplit (value, "=", 2);
634
if (split && split[0] && split[1])
635
interpreted_value = g_strdup (split[1]);
639
if (!interpreted_value)
640
g_warning ("Failed to interpret locale value: %s", value);
642
return interpreted_value;
646
data_book_factory_interpret_locale (const gchar * const * locale)
649
gchar *interpreted_locale = NULL;
651
/* Prioritize LC_COLLATE and then LANG values
652
* in the 'locale' specified by localed.
654
* If localed explicitly specifies no locale, then
655
* default to checking system locale.
658
for (i = 0; locale[i] != NULL && interpreted_locale == NULL; i++) {
659
if (strncmp (locale[i], "LC_COLLATE", 10) == 0)
661
data_book_factory_interpret_locale_value (locale[i]);
664
for (i = 0; locale[i] != NULL && interpreted_locale == NULL; i++) {
665
if (strncmp (locale[i], "LANG", 4) == 0)
667
data_book_factory_interpret_locale_value (locale[i]);
671
if (!interpreted_locale) {
672
const gchar *system_locale = setlocale (LC_COLLATE, NULL);
674
interpreted_locale = g_strdup (system_locale);
677
return interpreted_locale;
681
data_book_factory_set_locale (EDataBookFactory *factory,
684
EDataBookFactoryPrivate *priv = factory->priv;
685
GError *error = NULL;
688
if (g_strcmp0 (priv->locale, locale) != 0) {
690
g_free (priv->locale);
691
priv->locale = g_strdup (locale);
693
books = data_book_factory_list_books (factory);
694
for (l = books; l; l = l->next) {
695
EDataBook *book = l->data;
697
if (!e_data_book_set_locale (book, locale, NULL, &error)) {
699
"Failed to set locale on addressbook: %s",
701
g_clear_error (&error);
704
g_list_free_full (books, g_object_unref);
709
data_book_factory_locale_changed (GObject *object,
713
EDBusLocale1 *locale_proxy = E_DBUS_LOCALE1 (object);
714
EDataBookFactory *factory = (EDataBookFactory *) user_data;
715
const gchar * const *locale;
716
gchar *interpreted_locale;
718
locale = e_dbus_locale1_get_locale (locale_proxy);
719
interpreted_locale = data_book_factory_interpret_locale (locale);
721
data_book_factory_set_locale (factory, interpreted_locale);
723
g_free (interpreted_locale);
727
data_book_factory_localed_ready (GObject *source_object,
731
EDataBookFactory *factory = (EDataBookFactory *) user_data;
732
GError *error = NULL;
734
factory->priv->localed_proxy = e_dbus_locale1_proxy_new_finish (res, &error);
736
if (factory->priv->localed_proxy == NULL) {
737
g_warning ("Error fetching localed proxy: %s", error->message);
738
g_error_free (error);
741
if (factory->priv->localed_cancel) {
742
g_object_unref (factory->priv->localed_cancel);
743
factory->priv->localed_cancel = NULL;
746
if (factory->priv->localed_proxy) {
748
factory->priv->localed_proxy, "notify::locale",
749
G_CALLBACK (data_book_factory_locale_changed), factory);
751
/* Initial refresh of the locale */
752
data_book_factory_locale_changed (G_OBJECT (factory->priv->localed_proxy), NULL, factory);
757
data_book_factory_localed_appeared (GDBusConnection *connection,
759
const gchar *name_owner,
762
EDataBookFactory *factory = (EDataBookFactory *) user_data;
764
factory->priv->localed_cancel = g_cancellable_new ();
766
e_dbus_locale1_proxy_new (
768
G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
769
"org.freedesktop.locale1",
770
"/org/freedesktop/locale1",
771
factory->priv->localed_cancel,
772
data_book_factory_localed_ready,
777
data_book_factory_localed_vanished (GDBusConnection *connection,
781
EDataBookFactory *factory = (EDataBookFactory *) user_data;
783
if (factory->priv->localed_cancel) {
784
g_cancellable_cancel (factory->priv->localed_cancel);
785
g_object_unref (factory->priv->localed_cancel);
786
factory->priv->localed_cancel = NULL;
789
if (factory->priv->localed_proxy) {
790
g_object_unref (factory->priv->localed_proxy);
791
factory->priv->localed_proxy = NULL;
796
data_book_factory_initable_init (GInitable *initable,
797
GCancellable *cancellable,
800
EDataBookFactoryPrivate *priv;
801
GBusType bus_type = G_BUS_TYPE_SYSTEM;
803
priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (initable);
805
priv->registry = e_source_registry_new_sync (cancellable, error);
807
/* When running tests, we pretend to be the "org.freedesktop.locale1" service
808
* on the session bus instead of the real location on the system bus.
810
if (g_getenv ("EDS_TESTING") != NULL)
811
bus_type = G_BUS_TYPE_SESSION;
813
/* Watch system bus for locale change notifications */
814
priv->localed_watch_id =
817
"org.freedesktop.locale1",
818
G_BUS_NAME_WATCHER_FLAGS_NONE,
819
data_book_factory_localed_appeared,
820
data_book_factory_localed_vanished,
824
return (priv->registry != NULL);
828
131
e_data_book_factory_class_init (EDataBookFactoryClass *class)
830
133
GObjectClass *object_class;