[libsecret/wip/dueno/backend] secret-backend: Add instantiation logic [ci skip]



commit 15b00a8d79c96a1c15dd1c50ff782c6f9e4835e5
Author: Daiki Ueno <dueno src gnome org>
Date:   Mon Jul 1 07:46:53 2019 +0200

    secret-backend: Add instantiation logic [ci skip]

 libsecret/secret-backend.c | 177 ++++++++++++++++++++++++++++++++++++++++-----
 libsecret/secret-backend.h | 115 ++++++++++++++++++-----------
 2 files changed, 231 insertions(+), 61 deletions(-)
---
diff --git a/libsecret/secret-backend.c b/libsecret/secret-backend.c
index 1cd3f1f..ac1227c 100644
--- a/libsecret/secret-backend.c
+++ b/libsecret/secret-backend.c
@@ -17,6 +17,8 @@
 #include "secret-backend.h"
 #include "secret-private.h"
 
+#include "libsecret/secret-enum-types.h"
+
 /**
  * SECTION:secret-backend
  * @title: SecretBackend
@@ -61,35 +63,174 @@
  */
 
 G_DEFINE_INTERFACE_WITH_CODE (SecretBackend, secret_backend, G_TYPE_OBJECT,
-                             g_type_interface_add_prerequisite(g_define_type_id, G_TYPE_ASYNC_INITABLE);
+                              g_type_interface_add_prerequisite(g_define_type_id, G_TYPE_ASYNC_INITABLE);
 );
 
 static void
 secret_backend_default_init (SecretBackendInterface *iface)
 {
-       /**
-        * SecretBackend:flags:
-        *
-        * A set of flags describing which parts of the secret backend have
-        * been initialized.
-        */
-       g_object_interface_install_property (iface,
-                    g_param_spec_flags ("flags", "Flags", "Service flags",
-                                        secret_service_flags_get_type (), SECRET_SERVICE_NONE,
-                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
G_PARAM_STATIC_STRINGS));
+        /**
+         * SecretBackend:flags:
+         *
+         * A set of flags describing which parts of the secret backend have
+         * been initialized.
+         */
+        g_object_interface_install_property (iface,
+                     g_param_spec_flags ("flags", "Flags", "Service flags",
+                                         secret_service_flags_get_type (), SECRET_SERVICE_NONE,
+                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
G_PARAM_STATIC_STRINGS));
 }
 
 void
 _secret_backend_ensure_extension_point (void)
 {
-       GIOExtensionPoint *ep;
-       static gboolean registered = FALSE;
+        GIOExtensionPoint *ep;
+        static gboolean registered = FALSE;
+
+        if (registered)
+                return;
+
+        ep = g_io_extension_point_register (SECRET_BACKEND_EXTENSION_POINT_NAME);
+        g_io_extension_point_set_required_type (ep, SECRET_TYPE_BACKEND);
+
+        registered = TRUE;
+}
+
+G_LOCK_DEFINE (backend_instance);
+static gpointer backend_instance = NULL;
+
+static SecretBackend *
+backend_get_instance (void)
+{
+        SecretBackend *instance = NULL;
+
+        G_LOCK (backend_instance);
+        if (backend_instance != NULL)
+                instance = g_object_ref (backend_instance);
+        G_UNLOCK (backend_instance);
+
+        return instance;
+}
+
+static GType
+backend_get_impl_type (void)
+{
+        const gchar *envvar = g_getenv ("SECRET_BACKEND");
+        const gchar *extension_name;
+        GIOExtension *e;
+        GIOExtensionPoint *ep;
+
+        if (envvar == NULL || *envvar == '\0')
+                extension_name = "service";
+
+        ep = g_io_extension_point_lookup (SECRET_BACKEND_EXTENSION_POINT_NAME);
+        e = g_io_extension_point_get_extension_by_name (ep, extension_name);
+        if (e == NULL) {
+                g_warning ("Backend extension \"%s\" from SECRET_BACKEND_EXTENSION_POINT_NAME environment 
variable not found.", extension_name);
+                return G_TYPE_NONE;
+        }
+
+        return g_io_extension_get_type (e);
+}
+
+static void
+on_ensure_for_flags (GObject *source_object,
+                     GAsyncResult *res,
+                     gpointer user_data)
+{
+        SecretBackendInterface *iface;
+        SecretBackend *backend = SECRET_BACKEND (source_object);
+        GTask *task = G_TASK (user_data);
+        GError *error = NULL;
+
+        iface = SECRET_BACKEND_GET_IFACE (self);
+        g_return_if_fail (iface->ensure_for_flags_finish != NULL);
+
+        if (!iface->ensure_for_flags_finish (backend, result, &error)) {
+                g_task_return_error (task, error);
+                g_object_unref (task);
+                return;
+        }
+
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+}
+
+void
+secret_backend_get (SecretBackendFlags flags,
+                    GCancellable *cancellable,
+                    GAsyncReadyCallback callback,
+                    gpointer user_data)
+{
+        SecretBackend *backend = NULL;
+        SecretBackendInterface *iface;
+        GTask *task;
+        InitClosure *closure;
+
+        backend = backend_get_instance ();
+
+        /* Create a whole new backend */
+        if (backend == NULL) {
+                GType impl_type = backend_get_impl_type ();
+                g_return_if_fail (g_type_is_a (impl_type, G_TYPE_ASYNC_INITABLE));
+                g_async_initable_new_async (impl_type,
+                                            G_PRIORITY_DEFAULT,
+                                            cancellable, callback, user_data,
+                                            "flags", flags,
+                                            NULL);
+
+        /* Just have to ensure that the backend matches flags */
+        } else {
+                iface = SECRET_BACKEND_GET_IFACE (self);
+                g_return_if_fail (iface->ensure_for_flags != NULL);
+
+                task = g_task_new (backend, cancellable, callback, usear_data);
+                g_task_set_source_tag (task, secret_backend_get);
+                iface->ensure_for_flags (backend, flags, cancellable,
+                                         on_ensure_for_flags, task);
+
+                g_object_unref (backend);
+                g_object_unref (task);
+        }
+}
+
+SecretBackend *
+secret_backend_get_finish (GAsyncResult *result,
+                           GError **error)
+{
+        GTask *task;
+        GObject *backend = NULL;
+        GObject *source_object;
+
+        g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+        g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+        task = G_TASK (result);
+        source_object = g_task_get_source_object (task);
+
+        g_return_val_if_fail (g_task_is_valid (result, source_object), NULL);
+
+        /* Just ensuring that the backend matches flags */
+        if (g_task_get_source_tag (task) == secret_backend_get) {
+                if (g_task_had_error (task)) {
+                        g_task_propagate_pointer (task, error);
+                } else {
+                        backend = g_object_ref (source_object);
+                }
 
-       if (registered)
-               return;
+        /* Creating a whole new backend */
+        } else {
+                backend = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
+                if (backend) {
+                        G_LOCK (backend_instance);
+                        if (backend_instance == NULL)
+                                backend_instance = instance;
+                        G_UNLOCK (backend_instance);
+                }
+        }
 
-       ep = g_io_extension_point_register (SECRET_BACKEND_EXTENSION_POINT_NAME);
-       g_io_extension_point_set_required_type (ep, SECRET_TYPE_BACKEND);
+        if (backend == NULL)
+                return NULL;
 
-       registered = TRUE;
+        return SECRET_BACKEND (backend);
 }
diff --git a/libsecret/secret-backend.h b/libsecret/secret-backend.h
index eb7f0ab..72eacd8 100644
--- a/libsecret/secret-backend.h
+++ b/libsecret/secret-backend.h
@@ -20,61 +20,90 @@
 #define __SECRET_BACKEND_H__
 
 #include <glib-object.h>
+#include "secret-schema.h"
+#include "secret-value.h"
 
 G_BEGIN_DECLS
 
+typedef enum {
+        SECRET_BACKEND_NONE = SECRET_SERVICE_NONE,
+        SECRET_BACKEND_OPEN_SESSION = SECRET_SERVICE_OPEN_SESSION,
+        SECRET_BACKEND_LOAD_COLLECTIONS = SECRET_SERVICE_LOAD_COLLECTIONS,
+} SecretBackendFlags;
+
 #define SECRET_TYPE_BACKEND secret_backend_get_type ()
 G_DECLARE_INTERFACE (SecretBackend, secret_backend, SECRET, BACKEND, GObject)
 
 struct _SecretBackendInterface
 {
-       GTypeInterface parent_iface;
-
-       void         (*store)         (SecretBackend *self,
-                                      const SecretSchema *schema,
-                                      GHashTable *attributes,
-                                      const gchar *collection,
-                                      const gchar *label,
-                                      SecretValue *value,
-                                      GCancellable *cancellable,
-                                      GAsyncReadyCallback callback,
-                                      gpointer user_data);
-       gboolean     (*store_finish)  (SecretBackend *self,
-                                      GAsyncResult *result,
-                                      GError **error);
-       void         (*lookup)        (SecretBackend *self,
-                                      const SecretSchema *schema,
-                                      GHashTable *attributes,
-                                      GCancellable *cancellable,
-                                      GAsyncReadyCallback callback,
-                                      gpointer user_data);
-       SecretValue *(*lookup_finish) (SecretBackend *self,
-                                      GAsyncResult *result,
-                                      GError **error);
-       void         (*clear)         (SecretBackend *self,
-                                      const SecretSchema *schema,
-                                      GHashTable *attributes,
-                                      GCancellable *cancellable,
-                                      GAsyncReadyCallback callback,
-                                      gpointer user_data);
-       gboolean     (*clear_finish)  (SecretBackend *self,
-                                      GAsyncResult *result,
-                                      GError **error);
-       void         (*search)        (SecretBackend *self,
-                                      const SecretSchema *schema,
-                                      GHashTable *attributes,
-                                      SecretSearchFlags flags,
-                                      GCancellable *cancellable,
-                                      GAsyncReadyCallback callback,
-                                      gpointer user_data);
-       GList *      (*search_finish) (SecretBackend *self,
-                                      GAsyncResult *result,
-                                      GError **error);
+        GTypeInterface parent_iface;
+
+        void         (*ensure_for_flags)        (SecretBackend *self,
+                                                 SecretBackendFlags flags,
+                                                GCancellable *cancellable,
+                                                GAsyncReadyCallback callback,
+                                                 gpointer user_data);
+        gboolean     (*ensure_for_flags_finish) (SecretBackend *self,
+                                                 GAsyncResult *result,
+                                                 GError **error);
+
+        void         (*store)                   (SecretBackend *self,
+                                                 const SecretSchema *schema,
+                                                 GHashTable *attributes,
+                                                 const gchar *collection,
+                                                 const gchar *label,
+                                                 SecretValue *value,
+                                                 GCancellable *cancellable,
+                                                 GAsyncReadyCallback callback,
+                                                 gpointer user_data);
+        gboolean     (*store_finish)            (SecretBackend *self,
+                                                 GAsyncResult *result,
+                                                 GError **error);
+
+        void         (*lookup)                  (SecretBackend *self,
+                                                 const SecretSchema *schema,
+                                                 GHashTable *attributes,
+                                                 GCancellable *cancellable,
+                                                 GAsyncReadyCallback callback,
+                                                 gpointer user_data);
+        SecretValue *(*lookup_finish)           (SecretBackend *self,
+                                                 GAsyncResult *result,
+                                                 GError **error);
+
+        void         (*clear)                   (SecretBackend *self,
+                                                 const SecretSchema *schema,
+                                                 GHashTable *attributes,
+                                                 GCancellable *cancellable,
+                                                 GAsyncReadyCallback callback,
+                                                 gpointer user_data);
+        gboolean     (*clear_finish)            (SecretBackend *self,
+                                                 GAsyncResult *result,
+                                                 GError **error);
+
+        void         (*search)                  (SecretBackend *self,
+                                                 const SecretSchema *schema,
+                                                 GHashTable *attributes,
+                                                 SecretSearchFlags flags,
+                                                 GCancellable *cancellable,
+                                                 GAsyncReadyCallback callback,
+                                                 gpointer user_data);
+        GList *      (*search_finish)           (SecretBackend *self,
+                                                 GAsyncResult *result,
+                                                 GError **error);
 };
 
 #define SECRET_BACKEND_EXTENSION_POINT_NAME "secret-backend"
 
-void _secret_backend_ensure_extension_point (void);
+void           _secret_backend_ensure_extension_point
+                                         (void);
+
+void           secret_backend_get        (SecretBackendFlags flags,
+                                          GCancellable *cancellable,
+                                          GAsyncReadyCallback callback,
+                                          gpointer user_data);
+
+SecretBackend *secret_backend_get_finish (GAsyncResult *result,
+                                          GError **error);
 
 G_END_DECLS
 


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