Rework how the initialization work for various proxy objects

* Fix bugs and tests
This commit is contained in:
Stef Walter 2012-01-25 14:26:52 +01:00
parent f44aae6efa
commit c6c6afa2cc
18 changed files with 1152 additions and 702 deletions

1
.gitignore vendored
View File

@ -40,6 +40,7 @@ stamp*
!/egg/tests/test-*.c
/library/gsecret-dbus-generated.[ch]
/library/gsecret-enum-types.[ch]
/library/tests/test-*
!/library/tests/test-*.c

View File

@ -41,6 +41,8 @@ PKG_CHECK_MODULES(GLIB,
LIBS="$LIBS $GLIB_LIBS"
CFLAGS="$CFLAGS $GLIB_CFLAGS"
AC_PATH_PROG(GLIB_MKENUMS, glib-mkenums)
# --------------------------------------------------------------------
# libgcrypt
#

View File

@ -9,10 +9,22 @@ module_flags = \
-no-undefined \
-export-symbols-regex '^gsecret_'
INCLUDES = \
-DGSECRET_COMPILATION
lib_LTLIBRARIES = libgsecret.la
HEADER_FILES = \
gsecret-collection.h \
gsecret-item.h \
gsecret-password.h \
gsecret-prompt.h \
gsecret-service.h \
gsecret-value.h
BUILT_SOURCES = \
gsecret-dbus-generated.c gsecret-dbus-generated.h
gsecret-dbus-generated.c gsecret-dbus-generated.h \
gsecret-enum-types.c gsecret-enum-types.h
libgsecret_la_SOURCES = \
gsecret-collection.h gsecret-collection.c \
@ -45,5 +57,15 @@ gsecret-dbus-generated.c: $(DBUS_XML_DEFINITIONS) Makefile.am
$(AM_V_GEN) sed -i -e '1i #define GLIB_DISABLE_DEPRECATION_WARNINGS' gsecret-dbus-generated.c
gsecret-dbus-generated.h: gsecret-dbus-generated.c
gsecret-enum-types.h: gsecret-enum-types.h.template $(HEADER_FILES)
$(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@
gsecret-enum-types.c: gsecret-enum-types.c.template $(HEADER_FILES)
$(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@
EXTRA_DIST = \
gsecret-enum-types.h.template \
gsecret-enum-types.c.template
check-memory:
make -C tests check-memory

View File

@ -42,7 +42,18 @@ struct _GSecretCollectionPrivate {
GHashTable *items;
};
G_DEFINE_TYPE (GSecretCollection, gsecret_collection, G_TYPE_DBUS_PROXY);
static GInitableIface *gsecret_collection_initable_parent_iface = NULL;
static GAsyncInitableIface *gsecret_collection_async_initable_parent_iface = NULL;
static void gsecret_collection_initable_iface (GInitableIface *iface);
static void gsecret_collection_async_initable_iface (GAsyncInitableIface *iface);
G_DEFINE_TYPE_WITH_CODE (GSecretCollection, gsecret_collection, G_TYPE_DBUS_PROXY,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gsecret_collection_initable_iface);
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, gsecret_collection_async_initable_iface);
);
static GHashTable *
items_table_new (void)
@ -166,69 +177,63 @@ gsecret_collection_finalize (GObject *obj)
G_OBJECT_CLASS (gsecret_collection_parent_class)->finalize (obj);
}
static GSecretItem *
collection_lookup_item (GSecretCollection *self,
const gchar *path)
{
GSecretItem *item = NULL;
g_mutex_lock (&self->pv->mutex);
item = g_hash_table_lookup (self->pv->items, path);
if (item != NULL)
g_object_ref (item);
g_mutex_unlock (&self->pv->mutex);
return item;
}
static void
collection_update_items (GSecretCollection *self,
GHashTable *items)
{
GHashTable *previous;
g_hash_table_ref (items);
g_mutex_lock (&self->pv->mutex);
previous = self->pv->items;
self->pv->items = items;
g_mutex_unlock (&self->pv->mutex);
g_hash_table_unref (previous);
}
typedef struct {
GSecretCollection *collection;
GCancellable *cancellable;
GHashTable *items;
gint items_loading;
} LoadClosure;
} ItemsClosure;
static void
load_closure_free (gpointer data)
items_closure_free (gpointer data)
{
LoadClosure *closure = data;
g_object_unref (closure->collection);
ItemsClosure *closure = data;
g_clear_object (&closure->cancellable);
g_hash_table_unref (closure->items);
g_slice_free (LoadClosure, closure);
}
static GSimpleAsyncResult *
load_result_new (GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
LoadClosure *closure;
res = g_simple_async_result_new (NULL, callback, user_data, load_result_new);
closure = g_slice_new0 (LoadClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->items = items_table_new ();
g_simple_async_result_set_op_res_gpointer (res, closure, load_closure_free);
return res;
g_slice_free (ItemsClosure, closure);
}
static void
load_items_complete (GSimpleAsyncResult *res)
{
LoadClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GSecretCollection *self = closure->collection;
GHashTable *items;
g_assert (closure->items_loading == 0);
g_hash_table_ref (closure->items);
g_mutex_lock (&self->pv->mutex);
items = self->pv->items;
self->pv->items = closure->items;
g_mutex_unlock (&self->pv->mutex);
g_hash_table_unref (items);
g_simple_async_result_complete (res);
}
static void
on_item_loading (GObject *source,
on_load_item (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
LoadClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
const gchar *item_path;
ItemsClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GSecretCollection *self = GSECRET_COLLECTION (g_async_result_get_source_object (user_data));
const gchar *path;
GError *error = NULL;
GSecretItem *item;
@ -240,57 +245,118 @@ on_item_loading (GObject *source,
g_simple_async_result_take_error (res, error);
if (item != NULL) {
item_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (item));
g_hash_table_insert (closure->items, g_strdup (item_path), item);
path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (item));
g_hash_table_insert (closure->items, g_strdup (path), item);
}
if (closure->items_loading == 0)
load_items_complete (res);
if (closure->items_loading == 0) {
collection_update_items (self, closure->items);
g_simple_async_result_complete_in_idle (res);
}
g_object_unref (self);
g_object_unref (res);
}
static void
load_items_perform (GSecretCollection *self,
GSimpleAsyncResult *res,
GVariant *item_paths)
collection_load_items_async (GSecretCollection *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
LoadClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
ItemsClosure *closure;
GSecretItem *item;
GSimpleAsyncResult *res;
const gchar *path;
GVariant *paths;
GVariantIter iter;
gchar *item_path;
g_assert (GSECRET_IS_COLLECTION (self));
g_assert (item_paths != NULL);
g_assert (closure->collection == NULL);
paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Items");
g_return_if_fail (paths != NULL);
closure->collection = g_object_ref (self);
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
collection_load_items_async);
closure = g_slice_new0 (ItemsClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->items = items_table_new ();
g_simple_async_result_set_op_res_gpointer (res, closure, items_closure_free);
g_variant_iter_init (&iter, item_paths);
while (g_variant_iter_loop (&iter, "o", &item_path)) {
g_mutex_lock (&self->pv->mutex);
item = g_hash_table_lookup (self->pv->items, item_path);
if (item != NULL)
g_object_ref (item);
g_mutex_unlock (&self->pv->mutex);
g_variant_iter_init (&iter, paths);
while (g_variant_iter_loop (&iter, "&o", &path)) {
item = collection_lookup_item (self, path);
/* No such collection yet create a new one */
if (item == NULL) {
// TODO: xxxxxxxxxxxx;
gsecret_item_new (self->pv->service, item_path,
closure->cancellable, on_item_loading,
g_object_ref (res));
gsecret_item_new (self->pv->service, path, cancellable,
on_load_item, g_object_ref (res));
closure->items_loading++;
} else {
g_hash_table_insert (closure->items,
g_strdup (item_path), item);
g_hash_table_insert (closure->items, g_strdup (path), item);
}
}
if (closure->items_loading == 0) {
collection_update_items (self, closure->items);
g_simple_async_result_complete_in_idle (res);
}
if (closure->items_loading == 0)
load_items_complete (res);
g_variant_unref (paths);
g_object_unref (res);
}
static gboolean
collection_load_items_finish (GSecretCollection *self,
GAsyncResult *result,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
return TRUE;
}
static gboolean
collection_load_items_sync (GSecretCollection *self,
GCancellable *cancellable,
GError **error)
{
GSecretItem *item;
GHashTable *items;
GVariant *paths;
GVariantIter iter;
const gchar *path;
gboolean ret = TRUE;
paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Items");
g_return_val_if_fail (paths != NULL, FALSE);
items = items_table_new ();
g_variant_iter_init (&iter, paths);
while (g_variant_iter_next (&iter, "&o", &path)) {
item = collection_lookup_item (self, path);
/* No such collection yet create a new one */
if (item == NULL) {
item = gsecret_item_new_sync (self->pv->service, path,
cancellable, error);
if (item == NULL) {
ret = FALSE;
break;
}
}
g_hash_table_insert (items, g_strdup (path), item);
}
if (ret)
collection_update_items (self, items);
g_hash_table_unref (items);
g_variant_unref (paths);
return ret;
}
static void
@ -298,8 +364,6 @@ handle_property_changed (GSecretCollection *self,
const gchar *property_name,
GVariant *value)
{
GSimpleAsyncResult *res;
if (g_str_equal (property_name, "Label"))
g_object_notify (G_OBJECT (self), "label");
@ -312,24 +376,8 @@ handle_property_changed (GSecretCollection *self,
else if (g_str_equal (property_name, "Modified"))
g_object_notify (G_OBJECT (self), "modified");
else if (g_str_equal (property_name, "Items") && !self->pv->constructing) {
res = load_result_new (self->pv->cancellable, NULL, NULL);
if (value == NULL)
value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Items");
else
g_variant_ref (value);
if (value == NULL) {
g_warning ("couldn't retrieve Collection Items property");
g_simple_async_result_complete (res);
} else {
// TODO: yyyy;
load_items_perform (self, res, value);
g_variant_unref (value);
}
g_object_unref (res);
}
else if (g_str_equal (property_name, "Items") && !self->pv->constructing)
collection_load_items_async (self, self->pv->cancellable, NULL, NULL);
}
static void
@ -392,49 +440,147 @@ gsecret_collection_class_init (GSecretCollectionClass *klass)
g_type_class_add_private (gobject_class, sizeof (GSecretCollectionPrivate));
}
static gboolean
gsecret_collection_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
GSecretCollection *self;
GDBusProxy *proxy;
if (!gsecret_collection_initable_parent_iface->init (initable, cancellable, error))
return FALSE;
proxy = G_DBUS_PROXY (initable);
if (!_gsecret_util_have_cached_properties (proxy)) {
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
"No such secret collection at path: %s",
g_dbus_proxy_get_object_path (proxy));
return FALSE;
}
self = GSECRET_COLLECTION (initable);
if (!collection_load_items_sync (self, cancellable, error))
return FALSE;
return TRUE;
}
static void
on_collection_new (GObject *source,
gsecret_collection_initable_iface (GInitableIface *iface)
{
gsecret_collection_initable_parent_iface = g_type_interface_peek_parent (iface);
iface->init = gsecret_collection_initable_init;
}
typedef struct {
GCancellable *cancellable;
} InitClosure;
static void
init_closure_free (gpointer data)
{
InitClosure *closure = data;
g_clear_object (&closure->cancellable);
g_slice_free (InitClosure, closure);
}
static void
on_init_items (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GSecretCollection *self;
GObject *source_object;
GSecretCollection *self = GSECRET_COLLECTION (source);
GError *error = NULL;
GVariant *item_paths;
GObject *object;
GDBusProxy *proxy;
source_object = g_async_result_get_source_object (result);
object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
result, &error);
g_object_unref (source_object);
if (!collection_load_items_finish (self, result, &error))
g_simple_async_result_take_error (res, error);
proxy = G_DBUS_PROXY (object);
if (error == NULL && !_gsecret_util_have_cached_properties (proxy)) {
g_set_error (&error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
"No such secret collection at path: %s", g_dbus_proxy_get_object_path (proxy));
g_simple_async_result_complete (res);
g_object_unref (res);
}
if (error == NULL) {
self = GSECRET_COLLECTION (object);
self->pv->constructing = FALSE;
static void
on_init_base (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GSecretCollection *self = GSECRET_COLLECTION (source);
InitClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GDBusProxy *proxy = G_DBUS_PROXY (self);
GError *error = NULL;
item_paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), "Items");
g_return_if_fail (item_paths != NULL);
// TODO: yyyy;
load_items_perform (self, res, item_paths);
g_variant_unref (item_paths);
} else {
if (!gsecret_collection_async_initable_parent_iface->init_finish (G_ASYNC_INITABLE (self),
result, &error)) {
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
} else if (!_gsecret_util_have_cached_properties (proxy)) {
g_simple_async_result_set_error (res, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
"No such secret collection at path: %s",
g_dbus_proxy_get_object_path (proxy));
g_simple_async_result_complete (res);
} else {
collection_load_items_async (self, closure->cancellable,
on_init_items, g_object_ref (res));
}
g_clear_object (&object);
g_object_unref (res);
}
static void
gsecret_collection_async_initable_init_async (GAsyncInitable *initable,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
InitClosure *closure;
res = g_simple_async_result_new (G_OBJECT (initable), callback, user_data,
gsecret_collection_async_initable_init_async);
closure = g_slice_new0 (InitClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
g_simple_async_result_set_op_res_gpointer (res, closure, init_closure_free);
gsecret_collection_async_initable_parent_iface->init_async (initable, io_priority,
cancellable,
on_init_base,
g_object_ref (res));
g_object_unref (res);
}
static gboolean
gsecret_collection_async_initable_init_finish (GAsyncInitable *initable,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (initable),
gsecret_collection_async_initable_init_async), FALSE);
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
return TRUE;
}
static void
gsecret_collection_async_initable_iface (GAsyncInitableIface *iface)
{
gsecret_collection_async_initable_parent_iface = g_type_interface_peek_parent (iface);
iface->init_async = gsecret_collection_async_initable_init_async;
iface->init_finish = gsecret_collection_async_initable_init_finish;
}
void
gsecret_collection_new (GSecretService *service,
const gchar *collection_path,
@ -442,22 +588,16 @@ gsecret_collection_new (GSecretService *service,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
GDBusProxy *proxy;
g_return_if_fail (GSECRET_IS_SERVICE (service));
g_return_if_fail (collection_path != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = load_result_new (cancellable, callback, user_data);
proxy = G_DBUS_PROXY (service);
g_async_initable_new_async (GSECRET_SERVICE_GET_CLASS (service)->collection_gtype,
G_PRIORITY_DEFAULT,
cancellable,
// TODO: zzzz;
on_collection_new,
g_object_ref (res),
G_PRIORITY_DEFAULT, cancellable, callback, user_data,
"g-flags", G_DBUS_CALL_FLAGS_NONE,
"g-interface-info", _gsecret_gen_collection_interface_info (),
"g-name", g_dbus_proxy_get_name (proxy),
@ -466,27 +606,27 @@ gsecret_collection_new (GSecretService *service,
"g-interface-name", GSECRET_COLLECTION_INTERFACE,
"service", service,
NULL);
g_object_unref (res);
}
GSecretCollection *
gsecret_collection_new_finish (GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *res;
LoadClosure *closure;
GObject *source_object;
GObject *object;
g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, load_result_new), NULL);
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
res = G_SIMPLE_ASYNC_RESULT (result);
source_object = g_async_result_get_source_object (result);
object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
result, error);
g_object_unref (source_object);
if (g_simple_async_result_propagate_error (res, error))
if (object == NULL)
return NULL;
closure = g_simple_async_result_get_op_res_gpointer (res);
return g_object_ref (closure->collection);
return GSECRET_COLLECTION (object);
}
GSecretCollection *
@ -495,29 +635,25 @@ gsecret_collection_new_sync (GSecretService *service,
GCancellable *cancellable,
GError **error)
{
GSecretSync *sync;
GSecretCollection *collection;
GDBusProxy *proxy;
g_return_val_if_fail (GSECRET_IS_SERVICE (service), NULL);
g_return_val_if_fail (collection_path != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
sync = _gsecret_sync_new ();
g_main_context_push_thread_default (sync->context);
proxy = G_DBUS_PROXY (service);
// TODO: xxxxx;
gsecret_collection_new (service, collection_path, cancellable,
_gsecret_sync_on_result, sync);
g_main_loop_run (sync->loop);
collection = gsecret_collection_new_finish (sync->result, error);
g_main_context_pop_thread_default (sync->context);
_gsecret_sync_free (sync);
return collection;
return g_initable_new (GSECRET_SERVICE_GET_CLASS (service)->collection_gtype,
cancellable, error,
"g-flags", G_DBUS_CALL_FLAGS_NONE,
"g-interface-info", _gsecret_gen_collection_interface_info (),
"g-name", g_dbus_proxy_get_name (proxy),
"g-connection", g_dbus_proxy_get_connection (proxy),
"g-object-path", collection_path,
"g-interface-name", GSECRET_COLLECTION_INTERFACE,
"service", service,
NULL);
}
void

View File

@ -0,0 +1,43 @@
/*** BEGIN file-header ***/
#include <glib-object.h>
#ifndef GSECRET_COMPILATION
#define GSECRET_COMPILATION
#endif
/*** END file-header ***/
/*** BEGIN file-production ***/
#include "@filename@"
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void) G_GNUC_CONST;
GType
@enum_name@_get_type (void)
{
static GType etype = 0;
if (G_UNLIKELY(etype == 0)) {
static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};
etype = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
}
return etype;
}
/*** END value-tail ***/
/*** BEGIN file-tail ***/
/**/
/*** END file-tail ***/

View File

@ -0,0 +1,28 @@
/*** BEGIN file-header ***/
#if !defined (__GSECRET_INSIDE_HEADER__) && !defined (GSECRET_COMPILATION)
#error "Only <gsecret/gsecret.h> can be included directly."
#endif
#ifndef __GSECRET_ENUM_TYPES_H__
#define __GSECRET_ENUM_TYPES_H__
#include <glib-object.h>
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void) G_GNUC_CONST;
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
/*** END value-header ***/
/*** BEGIN file-tail ***/
G_END_DECLS
#endif /* __GSECRET_ENUM_TYPES_H__ */
/*** END file-tail ***/

View File

@ -37,7 +37,18 @@ typedef struct _GSecretItemPrivate {
GCancellable *cancellable;
} GSecretItemPrivate;
G_DEFINE_TYPE (GSecretItem, gsecret_item, G_TYPE_DBUS_PROXY);
static GInitableIface *gsecret_item_initable_parent_iface = NULL;
static GAsyncInitableIface *gsecret_item_async_initable_parent_iface = NULL;
static void gsecret_item_initable_iface (GInitableIface *iface);
static void gsecret_item_async_initable_iface (GAsyncInitableIface *iface);
G_DEFINE_TYPE_WITH_CODE (GSecretItem, gsecret_item, G_TYPE_DBUS_PROXY,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gsecret_item_initable_iface);
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, gsecret_item_async_initable_iface);
);
static void
gsecret_item_init (GSecretItem *self)
@ -248,20 +259,102 @@ gsecret_item_class_init (GSecretItemClass *klass)
g_type_class_add_private (gobject_class, sizeof (GSecretItemPrivate));
}
#if 0
static void
all_properties_changed (GSecretItem *item)
static gboolean
gsecret_item_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
GObject *obj = G_OBJECT (item);
gchar **property_names;
guint i;
GDBusProxy *proxy;
property_names = g_dbus_proxy_get_cached_property_names (G_DBUS_PROXY (item));
for (i = 0; property_names != NULL && property_names[i] != NULL; i++)
handle_property_changed (obj, property_names[i]);
g_strfreev (property_names);
if (!gsecret_item_initable_parent_iface->init (initable, cancellable, error))
return FALSE;
proxy = G_DBUS_PROXY (initable);
if (!_gsecret_util_have_cached_properties (proxy)) {
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
"No such secret item at path: %s",
g_dbus_proxy_get_object_path (proxy));
return FALSE;
}
return TRUE;
}
static void
gsecret_item_initable_iface (GInitableIface *iface)
{
gsecret_item_initable_parent_iface = g_type_interface_peek_parent (iface);
iface->init = gsecret_item_initable_init;
}
static void
on_init_base (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GSecretItem *self = GSECRET_ITEM (source);
GDBusProxy *proxy = G_DBUS_PROXY (self);
GError *error = NULL;
if (!gsecret_item_async_initable_parent_iface->init_finish (G_ASYNC_INITABLE (self),
result, &error)) {
g_simple_async_result_take_error (res, error);
} else if (!_gsecret_util_have_cached_properties (proxy)) {
g_simple_async_result_set_error (res, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
"No such secret item at path: %s",
g_dbus_proxy_get_object_path (proxy));
}
g_simple_async_result_complete (res);
g_object_unref (res);
}
static void
gsecret_item_async_initable_init_async (GAsyncInitable *initable,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
res = g_simple_async_result_new (G_OBJECT (initable), callback, user_data,
gsecret_item_async_initable_init_async);
gsecret_item_async_initable_parent_iface->init_async (initable, io_priority,
cancellable,
on_init_base,
g_object_ref (res));
g_object_unref (res);
}
static gboolean
gsecret_item_async_initable_init_finish (GAsyncInitable *initable,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (initable),
gsecret_item_async_initable_init_async), FALSE);
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
return TRUE;
}
static void
gsecret_item_async_initable_iface (GAsyncInitableIface *iface)
{
gsecret_item_async_initable_parent_iface = g_type_interface_peek_parent (iface);
iface->init_async = gsecret_item_async_initable_init_async;
iface->init_finish = gsecret_item_async_initable_init_finish;
}
#endif
void
gsecret_item_new (GSecretService *service,
@ -279,10 +372,7 @@ gsecret_item_new (GSecretService *service,
proxy = G_DBUS_PROXY (service);
g_async_initable_new_async (GSECRET_SERVICE_GET_CLASS (service)->item_gtype,
G_PRIORITY_DEFAULT,
cancellable,
callback,
user_data,
G_PRIORITY_DEFAULT, cancellable, callback, user_data,
"g-flags", G_DBUS_CALL_FLAGS_NONE,
"g-interface-info", _gsecret_gen_item_interface_info (),
"g-name", g_dbus_proxy_get_name (proxy),
@ -299,7 +389,6 @@ gsecret_item_new_finish (GAsyncResult *result,
{
GObject *object;
GObject *source_object;
GDBusProxy *proxy;
source_object = g_async_result_get_source_object (result);
object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
@ -309,14 +398,6 @@ gsecret_item_new_finish (GAsyncResult *result,
if (object == NULL)
return NULL;
proxy = G_DBUS_PROXY (object);
if (!_gsecret_util_have_cached_properties (proxy)) {
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
"No such secret item at path: %s", g_dbus_proxy_get_object_path (proxy));
g_object_unref (object);
return NULL;
}
return GSECRET_ITEM (object);
}
@ -326,29 +407,25 @@ gsecret_item_new_sync (GSecretService *service,
GCancellable *cancellable,
GError **error)
{
GSecretSync *sync;
GSecretItem *item;
GDBusProxy *proxy;
g_return_val_if_fail (GSECRET_IS_SERVICE (service), NULL);
g_return_val_if_fail (item_path != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
sync = _gsecret_sync_new ();
g_main_context_push_thread_default (sync->context);
proxy = G_DBUS_PROXY (service);
// TODO: xxxxx;
gsecret_item_new (service, item_path, cancellable,
_gsecret_sync_on_result, sync);
g_main_loop_run (sync->loop);
item = gsecret_item_new_finish (sync->result, error);
g_main_context_pop_thread_default (sync->context);
_gsecret_sync_free (sync);
return item;
return g_initable_new (GSECRET_SERVICE_GET_CLASS (service)->item_gtype,
cancellable, error,
"g-flags", G_DBUS_CALL_FLAGS_NONE,
"g-interface-info", _gsecret_gen_item_interface_info (),
"g-name", g_dbus_proxy_get_name (proxy),
"g-connection", g_dbus_proxy_get_connection (proxy),
"g-object-path", item_path,
"g-interface-name", GSECRET_ITEM_INTERFACE,
"service", service,
NULL);
}
void

View File

@ -68,7 +68,7 @@ on_store_connected (GObject *source,
GSecretService *service;
GError *error = NULL;
service = _gsecret_service_bare_connect_finish (result, &error);
service = gsecret_service_get_finish (result, &error);
if (error == NULL) {
gsecret_service_storev (service, closure->schema,
closure->attributes,
@ -147,7 +147,7 @@ gsecret_password_storev (const GSecretSchema *schema,
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
g_simple_async_result_set_op_res_gpointer (res, closure, store_closure_free);
_gsecret_service_bare_connect (NULL, TRUE, cancellable,
gsecret_service_get (GSECRET_SERVICE_OPEN_SESSION, cancellable,
on_store_connected, g_object_ref (res));
g_object_unref (res);
@ -306,7 +306,7 @@ on_lookup_connected (GObject *source,
GSecretService *service;
GError *error = NULL;
service = _gsecret_service_bare_connect_finish (result, &error);
service = gsecret_service_get_finish (result, &error);
if (error != NULL) {
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
@ -338,7 +338,7 @@ gsecret_password_lookupv (GHashTable *attributes,
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
g_simple_async_result_set_op_res_gpointer (res, closure, lookup_closure_free);
_gsecret_service_bare_connect (NULL, TRUE, cancellable,
gsecret_service_get (GSECRET_SERVICE_OPEN_SESSION, cancellable,
on_lookup_connected, g_object_ref (res));
g_object_unref (res);
@ -490,7 +490,7 @@ on_delete_connect (GObject *source,
GSecretService *service;
GError *error = NULL;
service = _gsecret_service_bare_connect_finish (result, &error);
service = gsecret_service_get_finish (result, &error);
if (error == NULL) {
gsecret_service_removev (service, closure->attributes,
closure->cancellable, on_delete_complete,
@ -524,9 +524,8 @@ gsecret_password_removev (GHashTable *attributes,
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
_gsecret_service_bare_connect (NULL, FALSE, cancellable,
on_delete_connect,
g_object_ref (res));
gsecret_service_get (GSECRET_SERVICE_NONE, cancellable,
on_delete_connect, g_object_ref (res));
g_object_unref (res);
}

View File

@ -99,6 +99,7 @@ gboolean _gsecret_util_have_cached_properties (GDBusProxy *prox
void _gsecret_service_set_default_bus_name (const gchar *bus_name);
#if 0
GSecretService * _gsecret_service_bare_instance (GDBusConnection *connection,
const gchar *bus_name);
@ -110,6 +111,7 @@ void _gsecret_service_bare_connect (const gchar *bus
GSecretService * _gsecret_service_bare_connect_finish (GAsyncResult *result,
GError **error);
#endif
GSecretSession * _gsecret_service_get_session (GSecretService *self);
@ -135,7 +137,7 @@ void _gsecret_session_open (GSecretService *
GAsyncReadyCallback callback,
gpointer user_data);
GSecretSession * _gsecret_session_open_finish (GAsyncResult *result,
gboolean _gsecret_session_open_finish (GAsyncResult *result,
GError **error);
GVariant * _gsecret_session_encode_secret (GSecretSession *session,

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,12 @@
G_BEGIN_DECLS
typedef enum {
GSECRET_SERVICE_NONE,
GSECRET_SERVICE_OPEN_SESSION = 1 << 1,
GSECRET_SERVICE_LOAD_COLLECTIONS = 1 << 2,
} GSecretServiceFlags;
#define GSECRET_TYPE_SERVICE (gsecret_service_get_type ())
#define GSECRET_SERVICE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), GSECRET_TYPE_SERVICE, GSecretService))
#define GSECRET_SERVICE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), GSECRET_TYPE_SERVICE, GSecretServiceClass))
@ -63,16 +69,34 @@ struct _GSecretServiceClass {
GType gsecret_service_get_type (void) G_GNUC_CONST;
void gsecret_service_get (GCancellable *cancellable,
void gsecret_service_get (GSecretServiceFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSecretService * gsecret_service_get_finish (GAsyncResult *result,
GError **error);
GSecretService * gsecret_service_get_sync (GCancellable *cancellable,
GSecretService * gsecret_service_get_sync (GSecretServiceFlags flags,
GCancellable *cancellable,
GError **error);
void gsecret_service_new (const gchar *service_bus_name,
GSecretServiceFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSecretService * gsecret_service_new_finish (GAsyncResult *result,
GError **error);
GSecretService * gsecret_service_new_sync (const gchar *service_bus_name,
GSecretServiceFlags flags,
GCancellable *cancellable,
GError **error);
GSecretServiceFlags gsecret_service_get_flags (GSecretService *self);
const gchar * gsecret_service_get_session_algorithms (GSecretService *self);
const gchar * gsecret_service_get_session_path (GSecretService *self);

View File

@ -334,20 +334,14 @@ _gsecret_session_open (GSecretService *service,
g_object_unref (res);
}
GSecretSession *
gboolean
_gsecret_session_open_finish (GAsyncResult *result,
GError **error)
{
OpenSessionClosure *closure;
GSecretSession *session;
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return NULL;
return FALSE;
closure = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
session = closure->session;
closure->session = NULL;
return session;
return TRUE;
}
#ifdef WITH_GCRYPT

View File

@ -29,7 +29,6 @@
#include <stdlib.h>
typedef struct {
GDBusConnection *connection;
GSecretService *service;
} Test;
@ -43,26 +42,18 @@ setup (Test *test,
mock_service_start (mock_script, &error);
g_assert_no_error (error);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
test->service = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert_no_error (error);
test->service = _gsecret_service_bare_instance (test->connection, NULL);
}
static void
teardown (Test *test,
gconstpointer unused)
{
GError *error = NULL;
g_object_unref (test->service);
egg_assert_not_object (test->service);
mock_service_stop ();
g_dbus_connection_flush_sync (test->connection, NULL, &error);
g_assert_no_error (error);
g_object_unref (test->connection);
}
static void

View File

@ -29,7 +29,6 @@
#include <stdlib.h>
typedef struct {
GDBusConnection *connection;
GSecretService *service;
} Test;
@ -43,26 +42,18 @@ setup (Test *test,
mock_service_start (mock_script, &error);
g_assert_no_error (error);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
test->service = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert_no_error (error);
test->service = _gsecret_service_bare_instance (test->connection, NULL);
}
static void
teardown (Test *test,
gconstpointer unused)
{
GError *error = NULL;
g_object_unref (test->service);
egg_assert_not_object (test->service);
mock_service_stop ();
g_dbus_connection_flush_sync (test->connection, NULL, &error);
g_assert_no_error (error);
g_object_unref (test->connection);
}
static void
@ -87,7 +78,6 @@ on_notify_stop (GObject *obj,
g_assert (*sigs > 0);
if (--(*sigs) == 0)
egg_test_wait_stop ();
g_printerr ("sigs: %u\n", *sigs);
}
static void
@ -520,15 +510,14 @@ main (int argc, char **argv)
g_test_add ("/item/properties", Test, "mock-service-normal.py", setup, test_properties, teardown);
g_test_add ("/item/set-label-sync", Test, "mock-service-normal.py", setup, test_set_label_sync, teardown);
g_test_add ("/item/set-label-async", Test, "mock-service-normal.py", setup, test_set_label_async, teardown);
g_test_add ("/item/set-label-prop", Test, "mock-service-normal.py", setup, test_set_label_prop, teardown);
g_test_add ("/item/set-attributes-sync", Test, "mock-service-normal.py", setup, test_set_attributes_sync, teardown);
g_test_add ("/item/set-attributes-async", Test, "mock-service-normal.py", setup, test_set_attributes_async, teardown);
g_test_add ("/item/set-attributes-prop", Test, "mock-service-normal.py", setup, test_set_attributes_prop, teardown);
g_test_add ("/item/get-secret-sync", Test, "mock-service-normal.py", setup, test_get_secret_sync, teardown);
g_test_add ("/item/get-secret-async", Test, "mock-service-normal.py", setup, test_get_secret_async, teardown);
g_test_add ("/item/delete-sync", Test, "mock-service-normal.py", setup, test_delete_sync, teardown);
g_test_add ("/item/delete-async", Test, "mock-service-normal.py", setup, test_delete_async, teardown);
g_test_add ("/item/set-attributes-prop", Test, "mock-service-normal.py", setup, test_set_attributes_prop, teardown);
g_test_add ("/item/set-label-prop", Test, "mock-service-normal.py", setup, test_set_label_prop, teardown);
return egg_tests_run_with_loop ();
}

View File

@ -30,7 +30,6 @@
#include <stdlib.h>
typedef struct {
GDBusConnection *connection;
GSecretService *service;
} Test;
@ -44,26 +43,18 @@ setup (Test *test,
mock_service_start (mock_script, &error);
g_assert_no_error (error);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
test->service = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert_no_error (error);
test->service = _gsecret_service_bare_instance (test->connection, NULL);
}
static void
teardown (Test *test,
gconstpointer unused)
{
GError *error = NULL;
g_object_unref (test->service);
egg_assert_not_object (test->service);
mock_service_stop ();
g_dbus_connection_flush_sync (test->connection, NULL, &error);
g_assert_no_error (error);
g_object_unref (test->connection);
}

View File

@ -25,8 +25,6 @@
#include <errno.h>
#include <stdlib.h>
static gchar *MOCK_NAME = "org.mock.Service";
static const GSecretSchema DELETE_SCHEMA = {
"org.mock.schema.Delete",
{
@ -37,8 +35,6 @@ static const GSecretSchema DELETE_SCHEMA = {
};
typedef struct {
GPid pid;
GDBusConnection *connection;
GSecretService *service;
} Test;
@ -61,10 +57,8 @@ setup (Test *test,
setup_mock (test, data);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
test->service = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert_no_error (error);
test->service = _gsecret_service_bare_instance (test->connection, NULL);
}
static void
@ -83,8 +77,6 @@ teardown (Test *test,
g_object_unref (test->service);
egg_assert_not_object (test->service);
g_clear_object (&test->connection);
teardown_mock (test, unused);
}
@ -107,15 +99,14 @@ test_instance (void)
GSecretService *service2;
GSecretService *service3;
GError *error = NULL;
GDBusConnection *connection;
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error (error);
/* Both these sohuld point to the same thing */
service1 = _gsecret_service_bare_instance (connection, MOCK_NAME);
service2 = _gsecret_service_bare_instance (connection, MOCK_NAME);
service1 = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert_no_error (error);
service2 = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert_no_error (error);
g_assert (GSECRET_IS_SERVICE (service1));
g_assert (service1 == service2);
@ -127,17 +118,16 @@ test_instance (void)
egg_assert_not_object (service2);
/* Services were unreffed, so this should create a new one */
service3 = _gsecret_service_bare_instance (connection, MOCK_NAME);
service3 = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert (GSECRET_IS_SERVICE (service3));
g_assert_no_error (error);
g_object_unref (service3);
egg_assert_not_object (service3);
g_object_unref (connection);
}
static void
test_connect_sync (Test *test,
test_connect_async (Test *test,
gconstpointer used)
{
GError *error = NULL;
@ -146,12 +136,12 @@ test_connect_sync (Test *test,
const gchar *path;
/* Passing false, not session */
_gsecret_service_bare_connect (MOCK_NAME, FALSE, NULL, on_complete_get_result, &result);
gsecret_service_get (GSECRET_SERVICE_NONE, NULL, on_complete_get_result, &result);
g_assert (result == NULL);
egg_test_wait ();
service = _gsecret_service_bare_connect_finish (result, &error);
service = gsecret_service_get_finish (result, &error);
g_assert (GSECRET_IS_SERVICE (service));
g_assert_no_error (error);
g_object_unref (result);
@ -164,7 +154,7 @@ test_connect_sync (Test *test,
}
static void
test_connect_ensure_sync (Test *test,
test_connect_ensure_async (Test *test,
gconstpointer used)
{
GError *error = NULL;
@ -173,12 +163,12 @@ test_connect_ensure_sync (Test *test,
const gchar *path;
/* Passing true, ensures session is established */
_gsecret_service_bare_connect (MOCK_NAME, TRUE, NULL, on_complete_get_result, &result);
gsecret_service_get (GSECRET_SERVICE_OPEN_SESSION, NULL, on_complete_get_result, &result);
g_assert (result == NULL);
egg_test_wait ();
service = _gsecret_service_bare_connect_finish (result, &error);
service = gsecret_service_get_finish (result, &error);
g_assert_no_error (error);
g_assert (GSECRET_IS_SERVICE (service));
g_object_unref (result);
@ -593,8 +583,8 @@ main (int argc, char **argv)
g_test_add_func ("/service/instance", test_instance);
g_test_add ("/service/connect-sync", Test, "mock-service-normal.py", setup_mock, test_connect_sync, teardown_mock);
g_test_add ("/service/connect-ensure-sync", Test, "mock-service-normal.py", setup_mock, test_connect_ensure_sync, teardown_mock);
g_test_add ("/service/connect-sync", Test, "mock-service-normal.py", setup_mock, test_connect_async, teardown_mock);
g_test_add ("/service/connect-ensure-sync", Test, "mock-service-normal.py", setup_mock, test_connect_ensure_async, teardown_mock);
g_test_add ("/service/search-for-paths", Test, "mock-service-normal.py", setup, test_search_paths, teardown);
g_test_add ("/service/search-for-paths-async", Test, "mock-service-normal.py", setup, test_search_paths_async, teardown);

View File

@ -27,8 +27,6 @@
#include <stdlib.h>
typedef struct {
GPid pid;
GDBusConnection *connection;
GSecretService *service;
} Test;
@ -42,26 +40,18 @@ setup (Test *test,
mock_service_start (mock_script, &error);
g_assert_no_error (error);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
test->service = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error);
g_assert_no_error (error);
test->service = _gsecret_service_bare_instance (test->connection, NULL);
}
static void
teardown (Test *test,
gconstpointer unused)
{
GError *error = NULL;
g_object_unref (test->service);
egg_assert_not_object (test->service);
mock_service_stop ();
g_dbus_connection_flush_sync (test->connection, NULL, &error);
g_assert_no_error (error);
g_object_unref (test->connection);
}
static void

View File

@ -1,2 +1,2 @@
library/gsecret-item.c
library/gsecret-service.c
library/gsecret-session.c