[libsecret/wip/dueno/backend] secret-backend: Add instantiation logic [ci skip]
- From: Daiki Ueno <dueno src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsecret/wip/dueno/backend] secret-backend: Add instantiation logic [ci skip]
- Date: Mon, 1 Jul 2019 06:18:22 +0000 (UTC)
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]