[evolution-data-server] EBookBackend: Add a read-only "proxy-resolver" property.



commit bfc06ee84b81aca3cded549dcbff65f6af619879
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Oct 9 16:09:10 2013 -0400

    EBookBackend: Add a read-only "proxy-resolver" property.
    
    Tracks a GProxyResolver for the backend, which is actually another
    ESource with an ESourceProxy extension (if applicable to the backend).
    
    New functions:
    
      e_book_backend_ref_proxy_resolver()

 addressbook/libedata-book/e-book-backend.c         |  156 +++++++++++++++++++-
 addressbook/libedata-book/e-book-backend.h         |    3 +
 .../libedata-book/libedata-book-sections.txt       |    1 +
 3 files changed, 159 insertions(+), 1 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index f17615e..4033f99 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -47,9 +47,13 @@ struct _EBookBackendPrivate {
        GList *views;
 
        GMutex property_lock;
+       GProxyResolver *proxy_resolver;
        gchar *cache_dir;
        gboolean writable;
 
+       ESource *authentication_source;
+       gulong auth_source_changed_handler_id;
+
        GMutex operation_lock;
        GHashTable *operation_ids;
        GQueue pending_operations;
@@ -91,6 +95,7 @@ struct _DispatchNode {
 enum {
        PROP_0,
        PROP_CACHE_DIR,
+       PROP_PROXY_RESOLVER,
        PROP_REGISTRY,
        PROP_WRITABLE
 };
@@ -315,6 +320,72 @@ book_backend_set_default_cache_dir (EBookBackend *backend)
 }
 
 static void
+book_backend_update_proxy_resolver (EBookBackend *backend)
+{
+       GProxyResolver *proxy_resolver = NULL;
+       ESourceAuthentication *extension;
+       ESource *source = NULL;
+       gboolean notify = FALSE;
+       gchar *uid;
+
+       extension = e_source_get_extension (
+               backend->priv->authentication_source,
+               E_SOURCE_EXTENSION_AUTHENTICATION);
+
+       uid = e_source_authentication_dup_proxy_uid (extension);
+       if (uid != NULL) {
+               ESourceRegistry *registry;
+
+               registry = e_book_backend_get_registry (backend);
+               source = e_source_registry_ref_source (registry, uid);
+               g_free (uid);
+       }
+
+       if (source != NULL) {
+               proxy_resolver = G_PROXY_RESOLVER (source);
+               if (!g_proxy_resolver_is_supported (proxy_resolver))
+                       proxy_resolver = NULL;
+       }
+
+       g_mutex_lock (&backend->priv->property_lock);
+
+       /* Emitting a "notify" signal unnecessarily might have
+        * unwanted side effects like cancelling a SoupMessage.
+        * Only emit if we now have a different GProxyResolver. */
+
+       if (proxy_resolver != backend->priv->proxy_resolver) {
+               g_clear_object (&backend->priv->proxy_resolver);
+               backend->priv->proxy_resolver = proxy_resolver;
+
+               if (proxy_resolver != NULL)
+                       g_object_ref (proxy_resolver);
+
+               notify = TRUE;
+       }
+
+       g_mutex_unlock (&backend->priv->property_lock);
+
+       if (notify)
+               g_object_notify (G_OBJECT (backend), "proxy-resolver");
+
+       g_clear_object (&source);
+}
+
+static void
+book_backend_auth_source_changed_cb (ESource *authentication_source,
+                                     GWeakRef *backend_weak_ref)
+{
+       EBookBackend *backend;
+
+       backend = g_weak_ref_get (backend_weak_ref);
+
+       if (backend != NULL) {
+               book_backend_update_proxy_resolver (backend);
+               g_object_unref (backend);
+       }
+}
+
+static void
 book_backend_set_registry (EBookBackend *backend,
                            ESourceRegistry *registry)
 {
@@ -366,6 +437,12 @@ book_backend_get_property (GObject *object,
                                E_BOOK_BACKEND (object)));
                        return;
 
+               case PROP_PROXY_RESOLVER:
+                       g_value_take_object (
+                               value, e_book_backend_ref_proxy_resolver (
+                               E_BOOK_BACKEND (object)));
+                       return;
+
                case PROP_REGISTRY:
                        g_value_set_object (
                                value, e_book_backend_get_registry (
@@ -389,8 +466,17 @@ book_backend_dispose (GObject *object)
 
        priv = E_BOOK_BACKEND_GET_PRIVATE (object);
 
+       if (priv->auth_source_changed_handler_id > 0) {
+               g_signal_handler_disconnect (
+                       priv->authentication_source,
+                       priv->auth_source_changed_handler_id);
+               priv->auth_source_changed_handler_id = 0;
+       }
+
        g_clear_object (&priv->registry);
        g_clear_object (&priv->data_book);
+       g_clear_object (&priv->proxy_resolver);
+       g_clear_object (&priv->authentication_source);
 
        if (priv->views != NULL) {
                g_list_free (priv->views);
@@ -430,11 +516,36 @@ book_backend_finalize (GObject *object)
 static void
 book_backend_constructed (GObject *object)
 {
+       EBookBackend *backend;
+       ESourceRegistry *registry;
+       ESource *source;
+
        /* Chain up to parent's constructed() method. */
        G_OBJECT_CLASS (e_book_backend_parent_class)->constructed (object);
 
+       backend = E_BOOK_BACKEND (object);
+       registry = e_book_backend_get_registry (backend);
+       source = e_backend_get_source (E_BACKEND (backend));
+
        /* Initialize the "cache-dir" property. */
-       book_backend_set_default_cache_dir (E_BOOK_BACKEND (object));
+       book_backend_set_default_cache_dir (backend);
+
+       /* Track the proxy resolver for this backend. */
+       backend->priv->authentication_source =
+               e_source_registry_find_extension (
+               registry, source, E_SOURCE_EXTENSION_AUTHENTICATION);
+       if (backend->priv->authentication_source != NULL) {
+               gulong handler_id;
+
+               handler_id = g_signal_connect_data (
+                       backend->priv->authentication_source, "changed",
+                       G_CALLBACK (book_backend_auth_source_changed_cb),
+                       e_weak_ref_new (backend),
+                       (GClosureNotify) e_weak_ref_free, 0);
+               backend->priv->auth_source_changed_handler_id = handler_id;
+
+               book_backend_update_proxy_resolver (backend);
+       }
 }
 
 static gboolean
@@ -591,6 +702,17 @@ e_book_backend_class_init (EBookBackendClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_PROXY_RESOLVER,
+               g_param_spec_object (
+                       "proxy-resolver",
+                       "Proxy Resolver",
+                       "The proxy resolver for this backend",
+                       G_TYPE_PROXY_RESOLVER,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
                PROP_REGISTRY,
                g_param_spec_object (
                        "registry",
@@ -806,6 +928,38 @@ e_book_backend_set_data_book (EBookBackend *backend,
 }
 
 /**
+ * e_book_backend_ref_proxy_resolver:
+ * @backend: an #EBookBackend
+ *
+ * Returns the #GProxyResolver for @backend (if applicable), as indicated
+ * by the #ESourceAuthentication:proxy-uid of @backend's #EBackend:source
+ * or one of its ancestors.
+ *
+ * The returned #GProxyResolver is referenced for thread-safety and must
+ * be unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: a #GProxyResolver, or %NULL
+ *
+ * Since: 3.12
+ **/
+GProxyResolver *
+e_book_backend_ref_proxy_resolver (EBookBackend *backend)
+{
+       GProxyResolver *proxy_resolver = NULL;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), NULL);
+
+       g_mutex_lock (&backend->priv->property_lock);
+
+       if (backend->priv->proxy_resolver != NULL)
+               proxy_resolver = g_object_ref (backend->priv->proxy_resolver);
+
+       g_mutex_unlock (&backend->priv->property_lock);
+
+       return proxy_resolver;
+}
+
+/**
  * e_book_backend_get_registry:
  * @backend: an #EBookBackend
  *
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index e45ec6b..43594cb 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -246,6 +246,9 @@ void                e_book_backend_set_cache_dir    (EBookBackend *backend,
 EDataBook *    e_book_backend_ref_data_book    (EBookBackend *backend);
 void           e_book_backend_set_data_book    (EBookBackend *backend,
                                                 EDataBook *data_book);
+GProxyResolver *
+               e_book_backend_ref_proxy_resolver
+                                               (EBookBackend *backend);
 ESourceRegistry *
                e_book_backend_get_registry     (EBookBackend *backend);
 gboolean       e_book_backend_get_writable     (EBookBackend *backend);
diff --git a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt 
b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
index 584db3d..5d446cf 100644
--- a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
+++ b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
@@ -11,6 +11,7 @@ e_book_backend_dup_cache_dir
 e_book_backend_set_cache_dir
 e_book_backend_ref_data_book
 e_book_backend_set_data_book
+e_book_backend_ref_proxy_resolver
 e_book_backend_get_registry
 e_book_backend_get_writable
 e_book_backend_set_writable


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]