summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-10-31 17:43:54 +0100
committerStef Walter <stefw@collabora.co.uk>2011-12-13 21:45:09 +0100
commitcf51303c1b38857d3aa04cece982d6e8e58fea5a (patch)
tree260d2fc3ebba66e7dc533c68b777a5877c8833d9
parent4edd77e47f1f6ee6ed138a4d3f4f06cd5896cafa (diff)
gcr: Make prompter tests work properly, add debugging
* Run mock prompter in a separate thread to fix blocking and concurrency issues. * Run tests in in the main process thread * Add more debugging output
-rw-r--r--.gitignore2
-rw-r--r--egg/egg-error.h10
-rw-r--r--egg/egg-testing.c85
-rw-r--r--egg/egg-testing.h2
-rw-r--r--gcr/gcr-mock-prompter.c332
-rw-r--r--gcr/gcr-mock-prompter.h22
-rw-r--r--gcr/gcr-system-prompt.c195
-rw-r--r--gcr/gcr-system-prompt.h16
-rw-r--r--gcr/gcr-system-prompter.c72
-rw-r--r--gcr/gcr-system-prompter.h4
-rw-r--r--gcr/tests/frob-system-prompt.c106
-rw-r--r--gcr/tests/test-system-prompt.c409
12 files changed, 1161 insertions, 94 deletions
diff --git a/.gitignore b/.gitignore
index 4e4d3c7..3f5599f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,9 +83,11 @@ stamp-*
/gck/gck-marshal.*
/gcr/*.pc
+/gcr/gcr-dbus-generated.*
/gcr/gcr-enum-types*
/gcr/gcr-oids.*
/gcr/gcr-marshal.*
+/gcr/gcr-prompter
/gcr/gcr-viewer
/gcr/gcr-viewer.desktop
diff --git a/egg/egg-error.h b/egg/egg-error.h
index 50f459c..9e7b74e 100644
--- a/egg/egg-error.h
+++ b/egg/egg-error.h
@@ -24,11 +24,19 @@
#include <glib.h>
-static inline const gchar*
+static inline const gchar *
egg_error_message (GError *error)
{
g_return_val_if_fail (error, "(unknown)");
return error->message ? error->message : "(null)";
}
+static inline const gchar *
+egg_error_result_message (GError **error)
+{
+ if (error == NULL)
+ return "(unknown)";
+ return (*error) && (*error)->message ? (*error)->message : "(null)";
+}
+
#endif /* EGG_ERROR_H_ */
diff --git a/egg/egg-testing.c b/egg/egg-testing.c
index 88d647d..e220fbd 100644
--- a/egg/egg-testing.c
+++ b/egg/egg-testing.c
@@ -105,6 +105,9 @@ egg_assertion_message_cmpmem (const char *domain,
g_free (s);
}
+static void (*wait_stop_impl) (void);
+static gboolean (*wait_until_impl) (int timeout);
+
void
egg_assertion_not_object (const char *domain,
const char *file,
@@ -131,6 +134,20 @@ egg_assertion_not_object (const char *domain,
void
egg_test_wait_stop (void)
{
+ g_assert (wait_stop_impl != NULL);
+ (wait_stop_impl) ();
+}
+
+gboolean
+egg_test_wait_until (int timeout)
+{
+ g_assert (wait_until_impl != NULL);
+ return (wait_until_impl) (timeout);
+}
+
+static void
+thread_wait_stop (void)
+{
GTimeVal tv;
g_get_current_time (&tv);
@@ -146,8 +163,8 @@ egg_test_wait_stop (void)
g_mutex_unlock (wait_mutex);
}
-gboolean
-egg_test_wait_until (int timeout)
+static gboolean
+thread_wait_until (int timeout)
{
GTimeVal tv;
gboolean ret;
@@ -169,11 +186,70 @@ egg_test_wait_until (int timeout)
return ret;
}
+static GMainLoop *wait_loop = NULL;
+
+static void
+loop_wait_stop (void)
+{
+ g_assert (wait_loop != NULL);
+ g_main_loop_quit (wait_loop);
+}
+
+static gboolean
+on_loop_wait_timeout (gpointer data)
+{
+ gboolean *timed_out = data;
+ *timed_out = TRUE;
+
+ g_assert (wait_loop != NULL);
+ g_main_loop_quit (wait_loop);
+
+ return TRUE; /* we remove this source later */
+}
+
+static gboolean
+loop_wait_until (int timeout)
+{
+ gboolean ret = FALSE;
+ gboolean timed_out = FALSE;
+ guint source;
+
+ g_assert (wait_loop == NULL);
+ wait_loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
+
+ source = g_timeout_add (timeout, on_loop_wait_timeout, &timed_out);
+
+ g_main_loop_run (wait_loop);
+
+ if (timed_out) {
+ g_source_remove (source);
+ ret = FALSE;
+ } else {
+ ret = TRUE;
+ }
+
+ g_main_loop_unref (wait_loop);
+ wait_loop = NULL;
+ return ret;
+
+ g_assert (wait_loop != NULL);
+ g_main_loop_quit (wait_loop);
+}
+
static gpointer
testing_thread (gpointer loop)
{
- /* Must have been defined by the test including this file */
- gint ret = g_test_run ();
+ gint ret;
+
+ wait_stop_impl = thread_wait_stop;
+ wait_until_impl = thread_wait_until;
+
+ ret = g_test_run ();
+
+ wait_stop_impl = NULL;
+ wait_until_impl = NULL;
+
+ /* Quit the main loop now that tests are done */
g_main_loop_quit (loop);
return GINT_TO_POINTER (ret);
}
@@ -205,6 +281,7 @@ egg_tests_run_with_loop (void)
return GPOINTER_TO_INT (ret);
}
+<<<<<<< HEAD
#endif
diff --git a/egg/egg-testing.h b/egg/egg-testing.h
index a15925a..0995e4d 100644
--- a/egg/egg-testing.h
+++ b/egg/egg-testing.h
@@ -73,4 +73,6 @@ gboolean egg_test_wait_until (int timeout);
gint egg_tests_run_with_loop (void);
+gint egg_tests_run_with_loop (void);
+
#endif /* EGG_DH_H_ */
diff --git a/gcr/gcr-mock-prompter.c b/gcr/gcr-mock-prompter.c
index 412c101..836ef35 100644
--- a/gcr/gcr-mock-prompter.c
+++ b/gcr/gcr-mock-prompter.c
@@ -51,34 +51,62 @@
* The class for #GcrMockPrompter.
*/
+
+GType gcr_mock_prompter_get_type (void) G_GNUC_CONST;
+#define GCR_TYPE_MOCK_PROMPTER (gcr_mock_prompter_get_type ())
+#define GCR_MOCK_PROMPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_MOCK_PROMPTER, GcrMockPrompter))
+#define GCR_IS_MOCK_PROMPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_MOCK_PROMPTER))
#define GCR_IS_MOCK_PROMPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_MOCK_PROMPTER))
#define GCR_MOCK_PROMPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_MOCK_PROMPTER, GcrMockPromptClass))
#define GCR_MOCK_PROMPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_MOCK_PROMPTER, GcrMockPromptClass))
+typedef struct _GcrMockPrompter GcrMockPrompter;
typedef struct _GcrMockPrompterClass GcrMockPrompterClass;
typedef struct _GcrMockPrompterPrivate GcrMockPrompterPrivate;
enum {
PROP_0,
PROP_CONNECTION,
+ PROP_SHOWING,
+ PROP_DELAY_MSEC
};
-typedef struct {
- gboolean proceed;
- gchar *password;
- GList *properties;
-} MockResponse;
-
struct _GcrMockPrompter {
GcrSystemPrompter parent;
GDBusConnection *connection;
GQueue *responses;
+ gboolean showing;
+ guint delay_msec;
+ guint delay_source;
};
struct _GcrMockPrompterClass {
GcrSystemPrompterClass parent_class;
};
+typedef struct {
+ gboolean proceed;
+ gchar *password;
+ GList *properties;
+
+ /* Used while responding */
+ GcrMockPrompter *prompter;
+} MockResponse;
+
+typedef struct {
+ /* Owned by the calling thread */
+ GMutex *mutex;
+ GCond *start_cond;
+ GThread *thread;
+
+ /* Owned by the prompter thread*/
+ GcrMockPrompter *prompter;
+ const gchar *bus_name;
+ GMainLoop *loop;
+} ThreadData;
+
+static ThreadData *running = NULL;
+
G_DEFINE_TYPE (GcrMockPrompter, gcr_mock_prompter, GCR_TYPE_SYSTEM_PROMPTER);
static void
@@ -95,6 +123,8 @@ mock_response_free (gpointer data)
MockResponse *response = data;
g_free (response->password);
g_list_free_full (response->properties, mock_property_free);
+ g_clear_object (&response->prompter);
+ g_free (response);
}
static void
@@ -115,6 +145,9 @@ gcr_mock_prompter_set_property (GObject *obj,
case PROP_CONNECTION:
self->connection = g_value_get_object (value);
break;
+ case PROP_DELAY_MSEC:
+ self->delay_msec = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -133,6 +166,12 @@ gcr_mock_prompter_get_property (GObject *obj,
case PROP_CONNECTION:
g_value_set_object (value, self->connection);
break;
+ case PROP_SHOWING:
+ g_value_set_boolean (value, self->showing);
+ break;
+ case PROP_DELAY_MSEC:
+ g_value_set_uint (value, self->delay_msec);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -146,6 +185,11 @@ gcr_mock_prompter_dispose (GObject *obj)
GcrMockPrompter *self = GCR_MOCK_PROMPTER (obj);
MockResponse *response;
+ if (self->delay_source) {
+ g_source_remove (self->delay_source);
+ self->delay_source = 0;
+ }
+
if (self->connection) {
gcr_system_prompter_unregister (GCR_SYSTEM_PROMPTER (self), self->connection);
g_object_remove_weak_pointer (G_OBJECT (self->connection),
@@ -251,6 +295,42 @@ prompter_set_properties (GcrMockPrompter *self,
}
}
+static void
+gcr_mock_prompter_open (GcrSystemPrompter *prompter)
+{
+ GcrMockPrompter *self = GCR_MOCK_PROMPTER (prompter);
+ self->showing = TRUE;
+}
+
+static void
+gcr_mock_prompter_close (GcrSystemPrompter *prompter)
+{
+ GcrMockPrompter *self = GCR_MOCK_PROMPTER (prompter);
+
+ if (self->delay_source != 0) {
+ g_source_remove (self->delay_source);
+ self->delay_source = 0;
+ }
+
+ self->showing = FALSE;
+}
+
+static gboolean
+on_timeout_prompt_confirm (gpointer data)
+{
+ MockResponse *response = data;
+ GcrSystemPrompter *prompter = GCR_SYSTEM_PROMPTER (response->prompter);
+
+ response->prompter->delay_source = 0;
+
+ if (!response->proceed)
+ gcr_system_prompter_respond_cancelled (prompter);
+ else
+ gcr_system_prompter_respond_confirmed (prompter);
+
+ return FALSE;
+}
+
static gboolean
gcr_mock_prompter_prompt_confirm (GcrSystemPrompter *prompter)
{
@@ -268,14 +348,35 @@ gcr_mock_prompter_prompt_confirm (GcrSystemPrompter *prompter)
}
prompter_set_properties (self, response->properties);
+ response->prompter = g_object_ref (prompter);
+
+ if (self->delay_msec > 0) {
+ g_assert (!self->delay_source);
+ self->delay_source = g_timeout_add_full (G_PRIORITY_DEFAULT, self->delay_msec,
+ on_timeout_prompt_confirm,
+ response, mock_response_free);
+ } else {
+ on_timeout_prompt_confirm (response);
+ mock_response_free (response);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+on_timeout_prompt_password (gpointer data)
+{
+ MockResponse *response = data;
+ GcrSystemPrompter *prompter = GCR_SYSTEM_PROMPTER (response->prompter);
+
+ response->prompter->delay_source = 0;
if (!response->proceed)
- gcr_system_prompter_respond_cancelled (GCR_SYSTEM_PROMPTER (self));
+ gcr_system_prompter_respond_cancelled (prompter);
else
- gcr_system_prompter_respond_confirmed (GCR_SYSTEM_PROMPTER (self));
+ gcr_system_prompter_respond_with_password (prompter, response->password);
- mock_response_free (response);
- return TRUE;
+ return FALSE;
}
static gboolean
@@ -296,13 +397,18 @@ gcr_mock_prompter_prompt_password (GcrSystemPrompter *prompter)
}
prompter_set_properties (self, response->properties);
+ response->prompter = g_object_ref (prompter);
+
+ if (self->delay_msec > 0) {
+ g_assert (!self->delay_source);
+ self->delay_source = g_timeout_add_full (G_PRIORITY_DEFAULT, self->delay_msec,
+ on_timeout_prompt_password,
+ response, mock_response_free);
+ } else {
+ on_timeout_prompt_password (response);
+ mock_response_free (response);
+ }
- if (!response->proceed)
- gcr_system_prompter_respond_cancelled (GCR_SYSTEM_PROMPTER (self));
- else
- gcr_system_prompter_respond_with_password (GCR_SYSTEM_PROMPTER (self), response->password);
-
- mock_response_free (response);
return TRUE;
}
@@ -317,12 +423,22 @@ gcr_mock_prompter_class_init (GcrMockPrompterClass *klass)
gobject_class->dispose = gcr_mock_prompter_dispose;
gobject_class->finalize = gcr_mock_prompter_finalize;
+ prompter_class->open = gcr_mock_prompter_open;
+ prompter_class->close = gcr_mock_prompter_close;
prompter_class->prompt_password= gcr_mock_prompter_prompt_password;
prompter_class->prompt_confirm = gcr_mock_prompter_prompt_confirm;
g_object_class_install_property (gobject_class, PROP_CONNECTION,
g_param_spec_object ("connection", "Connection", "DBus connection",
G_TYPE_DBUS_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class, PROP_SHOWING,
+ g_param_spec_boolean ("showing", "Showing", "Whether showing a prompt",
+ FALSE, G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class, PROP_DELAY_MSEC,
+ g_param_spec_uint ("delay-msec", "Delay msec", "Prompt delay in milliseconds",
+ 0, G_MAXUINT, 0, G_PARAM_READWRITE));
}
static GList *
@@ -375,82 +491,224 @@ build_properties (GcrMockPrompter *self,
return result;
}
+gboolean
+gcr_mock_prompter_get_showing (void)
+{
+ gboolean showing = FALSE;
+
+ g_assert (running != NULL);
+ g_mutex_lock (running->mutex);
+ g_object_get (running->prompter, "showing", &showing, NULL);
+ g_mutex_unlock (running->mutex);
+
+ return showing;
+}
+
+guint
+gcr_mock_prompter_get_delay_msec (void)
+{
+ guint delay_msec;
+
+ g_assert (running != NULL);
+ g_mutex_lock (running->mutex);
+ g_object_get (running->prompter, "delay-msec", &delay_msec, NULL);
+ g_mutex_unlock (running->mutex);
+
+ return delay_msec;
+}
+
+void
+gcr_mock_prompter_set_delay_msec (guint delay_msec)
+{
+ g_assert (running != NULL);
+ g_mutex_lock (running->mutex);
+ g_object_set (running->prompter, "delay-msec", delay_msec, NULL);
+ g_mutex_unlock (running->mutex);
+}
+
void
-gcr_mock_prompter_expect_confirm_ok (GcrMockPrompter *self,
- const gchar *first_property_name,
+gcr_mock_prompter_expect_confirm_ok (const gchar *first_property_name,
...)
{
MockResponse *response;
va_list var_args;
- g_return_if_fail (GCR_IS_MOCK_PROMPTER (self));
+ g_assert (running != NULL);
+
+ g_mutex_lock (running->mutex);
response = g_new0 (MockResponse, 1);
response->password = NULL;
response->proceed = TRUE;
va_start (var_args, first_property_name);
- response->properties = build_properties (self, first_property_name, var_args);
+ response->properties = build_properties (running->prompter, first_property_name, var_args);
va_end (var_args);
- g_queue_push_tail (self->responses, response);
+ g_queue_push_tail (running->prompter->responses, response);
+ g_mutex_unlock (running->mutex);
}
void
-gcr_mock_prompter_expect_confirm_cancel (GcrMockPrompter *self)
+gcr_mock_prompter_expect_confirm_cancel (void)
{
MockResponse *response;
- g_return_if_fail (GCR_IS_MOCK_PROMPTER (self));
+ g_assert (running != NULL);
+
+ g_mutex_lock (running->mutex);
response = g_new0 (MockResponse, 1);
response->password = NULL;
response->proceed = FALSE;
- g_queue_push_tail (self->responses, response);
+ g_queue_push_tail (running->prompter->responses, response);
+ g_mutex_unlock (running->mutex);
}
void
-gcr_mock_prompter_expect_password_ok (GcrMockPrompter *self,
- const gchar *password,
+gcr_mock_prompter_expect_password_ok (const gchar *password,
const gchar *first_property_name,
...)
{
MockResponse *response;
va_list var_args;
- g_return_if_fail (GCR_IS_MOCK_PROMPTER (self));
- g_return_if_fail (password != NULL);
+ g_assert (running != NULL);
+ g_assert (password != NULL);
+
+ g_mutex_lock (running->mutex);
response = g_new0 (MockResponse, 1);
response->password = g_strdup (password);
response->proceed = TRUE;
va_start (var_args, first_property_name);
- response->properties = build_properties (self, first_property_name, var_args);
+ response->properties = build_properties (running->prompter, first_property_name, var_args);
va_end (var_args);
- g_queue_push_tail (self->responses, response);
+ g_queue_push_tail (running->prompter->responses, response);
+
+ g_mutex_unlock (running->mutex);
}
void
-gcr_mock_prompter_expect_password_cancel (GcrMockPrompter *self)
+gcr_mock_prompter_expect_password_cancel (void)
{
MockResponse *response;
- g_return_if_fail (GCR_IS_MOCK_PROMPTER (self));
+ g_assert (running != NULL);
+
+ g_mutex_lock (running->mutex);
response = g_new0 (MockResponse, 1);
response->password = g_strdup ("");
response->proceed = FALSE;
- g_queue_push_tail (self->responses, response);
+ g_queue_push_tail (running->prompter->responses, response);
+
+ g_mutex_unlock (running->mutex);
+}
+
+static gpointer
+mock_prompter_thread (gpointer data)
+{
+ ThreadData *thread_data = data;
+ GDBusConnection *connection;
+ GMainContext *context;
+ GError *error = NULL;
+ gchar *address;
+
+ g_mutex_lock (thread_data->mutex);
+ context = g_main_context_new ();
+ g_main_context_push_thread_default (context);
+
+ thread_data->prompter = g_object_new (GCR_TYPE_MOCK_PROMPTER, NULL);
+
+ address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, &error);
+ if (error == NULL) {
+ connection = g_dbus_connection_new_for_address_sync (address,
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
+ G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
+ NULL, NULL, &error);
+ if (error == NULL) {
+ gcr_system_prompter_register (GCR_SYSTEM_PROMPTER (thread_data->prompter),
+ connection);
+ thread_data->bus_name = g_dbus_connection_get_unique_name (connection);
+ }
+
+ g_free (address);
+ }
+
+ if (error != NULL) {
+ g_critical ("mock prompter couldn't get session bus address: %s",
+ egg_error_message (error));
+ g_clear_error (&error);
+ }
+
+ thread_data->loop = g_main_loop_new (context, FALSE);
+ g_cond_signal (thread_data->start_cond);
+ g_mutex_unlock (thread_data->mutex);
+
+ g_main_loop_run (thread_data->loop);
+
+ g_mutex_lock (thread_data->mutex);
+ g_main_context_pop_thread_default (context);
+ g_main_context_unref (context);
+
+ if (connection) {
+ gcr_system_prompter_unregister (GCR_SYSTEM_PROMPTER (thread_data->prompter),
+ connection);
+ g_object_unref (connection);
+ }
+
+ g_mutex_unlock (thread_data->mutex);
+ return thread_data;
}
-GcrMockPrompter *
-gcr_mock_prompter_new ()
+const gchar *
+gcr_mock_prompter_start (void)
{
- return g_object_new (GCR_TYPE_MOCK_PROMPTER,
- NULL);
+ GError *error = NULL;
+
+ g_assert (running == NULL);
+
+ running = g_new0 (ThreadData, 1);
+ running->mutex = g_mutex_new ();
+ running->start_cond = g_cond_new ();
+
+ g_mutex_lock (running->mutex);
+ running->thread = g_thread_create (mock_prompter_thread, running, TRUE, &error);
+
+ if (error != NULL)
+ g_error ("mock prompter couldn't start thread: %s", error->message);
+
+ g_cond_wait (running->start_cond, running->mutex);
+ g_assert (running->loop);
+ g_assert (running->prompter);
+ g_mutex_unlock (running->mutex);
+
+ return running->bus_name;
+}
+
+void
+gcr_mock_prompter_stop (void)
+{
+ ThreadData *check;
+
+ g_assert (running != NULL);
+
+ g_mutex_lock (running->mutex);
+ g_assert (running->loop != NULL);
+ g_main_loop_quit (running->loop);
+ g_mutex_unlock (running->mutex);
+
+ check = g_thread_join (running->thread);
+ g_assert (check == running);
+
+ g_cond_free (running->start_cond);
+ g_mutex_free (running->mutex);
+ g_free (running);
+ running = NULL;
}
diff --git a/gcr/gcr-mock-prompter.h b/gcr/gcr-mock-prompter.h
index 4b5f302..f2068ec 100644
--- a/gcr/gcr-mock-prompter.h
+++ b/gcr/gcr-mock-prompter.h
@@ -34,28 +34,26 @@
G_BEGIN_DECLS
-#define GCR_TYPE_MOCK_PROMPTER (gcr_mock_prompter_get_type ())
-#define GCR_MOCK_PROMPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_MOCK_PROMPTER, GcrMockPrompter))
-#define GCR_IS_MOCK_PROMPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_MOCK_PROMPTER))
+const gchar * gcr_mock_prompter_start (void);
-typedef struct _GcrMockPrompter GcrMockPrompter;
+void gcr_mock_prompter_stop (void);
-GType gcr_mock_prompter_get_type (void) G_GNUC_CONST;
+gboolean gcr_mock_prompter_get_showing (void);
-GcrMockPrompter * gcr_mock_prompter_new (void);
+guint gcr_mock_prompter_get_delay_msec (void);
-void gcr_mock_prompter_expect_confirm_ok (GcrMockPrompter *self,
- const gchar *property_name,
+void gcr_mock_prompter_set_delay_msec (guint delay_msec);
+
+void gcr_mock_prompter_expect_confirm_ok (const gchar *property_name,
...);
-void gcr_mock_prompter_expect_confirm_cancel (GcrMockPrompter *self);
+void gcr_mock_prompter_expect_confirm_cancel (void);
-void gcr_mock_prompter_expect_password_ok (GcrMockPrompter *self,
- const gchar *password,
+void gcr_mock_prompter_expect_password_ok (const gchar *password,
const gchar *property_name,
...);
-void gcr_mock_prompter_expect_password_cancel (GcrMockPrompter *self);
+void gcr_mock_prompter_expect_password_cancel (void);
G_END_DECLS
diff --git a/gcr/gcr-system-prompt.c b/gcr/gcr-system-prompt.c
index 5caac14..43868d7 100644
--- a/gcr/gcr-system-prompt.c
+++ b/gcr/gcr-system-prompt.c
@@ -25,11 +25,15 @@
#include "gcr-dbus-constants.h"
#include "gcr-dbus-generated.h"
+#define DEBUG_FLAG GCR_DEBUG_PROMPT
+#include "gcr-debug.h"
#include "gcr-internal.h"
#include "gcr-library.h"
#include "gcr-secret-exchange.h"
#include "gcr-system-prompt.h"
+#include "egg/egg-error.h"
+
/**
* SECTION:gcr-system-prompt
* @title: GcrSystemPrompt
@@ -205,12 +209,14 @@ gcr_system_prompt_dispose (GObject *obj)
g_clear_object (&self->pv->exchange);
if (self->pv->prompt_path) {
+ _gcr_debug ("closing prompt asynchronously: %s", self->pv->prompt_path);
+
g_dbus_connection_call (self->pv->connection,
self->pv->prompter_bus_name,
GCR_DBUS_PROMPTER_OBJECT_PATH,
GCR_DBUS_PROMPTER_INTERFACE,
GCR_DBUS_PROMPTER_METHOD_FINISH,
- g_variant_new ("()"),
+ g_variant_new ("(o)", self->pv->prompt_path),
NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START,
-1, NULL, NULL, NULL);
g_free (self->pv->prompt_path);
@@ -315,8 +321,10 @@ gcr_system_prompt_get_secret_exchange (GcrSystemPrompt *self)
{
g_return_val_if_fail (GCR_IS_SYSTEM_PROMPT (self), NULL);
- if (!self->pv->exchange)
+ if (!self->pv->exchange) {
+ _gcr_debug ("creating new secret exchange");
self->pv->exchange = gcr_secret_exchange_new (NULL);
+ }
return self->pv->exchange;
}
@@ -554,10 +562,16 @@ gcr_system_prompt_real_init (GInitable *initable,
/* 1. Connect to the session bus */
if (!self->pv->connection) {
+
self->pv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
cancellable, error);
- if (self->pv->connection == NULL)
+ if (self->pv->connection == NULL) {
+ _gcr_debug ("failed to connect to bus: %s",
+ egg_error_result_message (error));
return FALSE;
+ }
+
+ _gcr_debug ("connected to bus");
}
/* 2. Tell the prompter we want to begin prompting */
@@ -573,13 +587,18 @@ gcr_system_prompt_real_init (GInitable *initable,
G_VARIANT_TYPE ("(o)"),
G_DBUS_CALL_FLAGS_NONE,
-1, cancellable, error);
- if (ret == NULL)
+ if (ret == NULL) {
+ _gcr_debug ("failed to open prompt: %s",
+ egg_error_result_message (error));
return FALSE;
+ }
self->pv->begun_prompting = TRUE;
g_assert (self->pv->prompt_path == NULL);
g_variant_get (ret, "(o)", &self->pv->prompt_path);
g_variant_unref (ret);
+
+ _gcr_debug ("opened prompt: %s", self->pv->prompt_path);
}
/* 3. Create a dbus proxy */
@@ -591,10 +610,14 @@ gcr_system_prompt_real_init (GInitable *initable,
self->pv->prompt_path,
GCR_DBUS_PROMPT_INTERFACE,
cancellable, error);
- if (self->pv->prompt_proxy == NULL)
+ if (self->pv->prompt_proxy == NULL) {
+ _gcr_debug ("failed to create prompt proxy: %s",
+ egg_error_result_message (error));
return FALSE;
+ }
g_dbus_proxy_set_default_timeout (self->pv->prompt_proxy, G_MAXINT);
+ _gcr_debug ("created prompt proxy");
}
return TRUE;
@@ -633,9 +656,12 @@ on_bus_connected (GObject *source,
if (error == NULL) {
g_return_if_fail (self->pv->connection != NULL);
+
+ _gcr_debug ("connected to bus");
perform_init_async (self, res);
} else {
+ _gcr_debug ("failed to connect to bus: %s", egg_error_message (error));
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
}
@@ -662,10 +688,14 @@ on_prompter_begin_prompting (GObject *source,
g_variant_get (ret, "(o)", &self->pv->prompt_path);
g_variant_unref (ret);
+ _gcr_debug ("opened prompt: %s", self->pv->prompt_path);
+
g_return_if_fail (self->pv->prompt_path != NULL);
perform_init_async (self, res);
} else {
+ _gcr_debug ("failed to open prompt: %s", egg_error_message (error));
+
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
}
@@ -687,11 +717,16 @@ on_prompt_proxy_new (GObject *source,
self->pv->prompt_proxy = g_dbus_proxy_new_finish (result, &error);
if (error == NULL) {
+ _gcr_debug ("created prompt proxy");
+
g_return_if_fail (self->pv->prompt_proxy != NULL);
perform_init_async (self, res);
} else {
+ _gcr_debug ("failed to create prompt proxy: %s", egg_error_message (error));
+
g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
}
g_object_unref (self);
@@ -706,11 +741,13 @@ perform_init_async (GcrSystemPrompt *self,
/* 1. Connect to the session bus */
if (!self->pv->connection) {
+ _gcr_debug ("connecting to bus");
g_bus_get (G_BUS_TYPE_SESSION, closure->cancellable,
on_bus_connected, g_object_ref (res));
/* 2. Tell the prompter we want to begin prompting */
} else if (!self->pv->prompt_path) {
+ _gcr_debug ("opening prompt");
g_dbus_connection_call (self->pv->connection,
self->pv->prompter_bus_name,
GCR_DBUS_PROMPTER_OBJECT_PATH,
@@ -725,6 +762,7 @@ perform_init_async (GcrSystemPrompt *self,
/* 3. Create a dbus proxy */
} else if (!self->pv->prompt_proxy) {
+ _gcr_debug ("creating prompt proxy");
g_dbus_proxy_new (self->pv->connection,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
_gcr_prompter_prompt_interface_info (),
@@ -735,9 +773,11 @@ perform_init_async (GcrSystemPrompt *self,
on_prompt_proxy_new,
g_object_ref (res));
+ /* 4. All done */
+ } else {
+ _gcr_debug ("successfully initialized prompt");
+ g_simple_async_result_complete (res);
}
-
- g_simple_async_result_complete (res);
}
static void
@@ -799,6 +839,7 @@ parameter_properties (GcrSystemPrompt *self)
g_hash_table_iter_init (&iter, self->pv->properties_to_write);
while (g_hash_table_iter_next (&iter, (gpointer *)&property_name, NULL)) {
+ _gcr_debug ("sending prompt property: %s", property_name);
variant = g_hash_table_lookup (self->pv->property_cache, property_name);
if (variant == NULL)
g_warning ("couldn't find prompt property to write: %s", property_name);
@@ -823,6 +864,7 @@ return_properties (GcrSystemPrompt *self,
g_variant_get (properties, "a(ssv)", &iter);
while (g_variant_iter_loop (iter, "(ssv)", &interface, &property_name, &value)) {
+ _gcr_debug ("received prompt property: %s", property_name);
key = (gpointer)g_intern_string (property_name);
if (!g_hash_table_lookup (self->pv->properties_to_write, key)) {
g_hash_table_insert (self->pv->property_cache,
@@ -842,10 +884,13 @@ parameters_for_password (GcrSystemPrompt *self)
exchange = gcr_system_prompt_get_secret_exchange (self);
- if (self->pv->exchanged)
+ if (self->pv->exchanged) {
+ _gcr_debug ("sending secret exchange");
input = gcr_secret_exchange_send (exchange, NULL, 0);
- else
+ } else {
+ _gcr_debug ("beginning secret exchange");
input = gcr_secret_exchange_begin (exchange);
+ }
self->pv->exchanged = TRUE;
properties = parameter_properties (self);
@@ -872,11 +917,15 @@ return_for_password (GcrSystemPrompt *self,
if (output && output[0]) {
if (!gcr_secret_exchange_receive (exchange, output)) {
+ _gcr_debug ("received invalid secret exchange");
g_set_error (error, GCR_SYSTEM_PROMPT_ERROR,
GCR_SYSTEM_PROMPT_FAILED, "Invalid secret exchanged");
} else {
+ _gcr_debug ("received password in secret exchange");
ret = gcr_secret_exchange_get_secret (exchange, NULL);
}
+ } else {
+ _gcr_debug ("password prompt was cancelled");
}
g_variant_unref (properties);
@@ -904,8 +953,10 @@ on_prompt_requested_password (GObject *source,
g_variant_unref (retval);
}
- if (error != NULL)
+ if (error != NULL) {
+ _gcr_debug ("failed to prompt for password: %s", egg_error_message (error));
g_simple_async_result_take_error (res, error);
+ }
g_simple_async_result_complete (res);
g_object_unref (self);
@@ -926,6 +977,8 @@ gcr_system_prompt_password_async (GcrSystemPrompt *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gcr_system_prompt_password_async);
+ _gcr_debug ("prompting for password");
+
g_dbus_proxy_call (G_DBUS_PROXY (self->pv->prompt_proxy),
GCR_DBUS_PROMPT_METHOD_PASSWORD,
parameters_for_password (self),
@@ -970,6 +1023,8 @@ gcr_system_prompt_password (GcrSystemPrompt *self,
return NULL;
}
+ _gcr_debug ("prompting for password");
+
retval = g_dbus_proxy_call_sync (self->pv->prompt_proxy,
GCR_DBUS_PROMPT_METHOD_PASSWORD,
parameters_for_password (self),
@@ -1007,6 +1062,11 @@ return_for_confirm (GcrSystemPrompt *self,
g_variant_unref (properties);
+ if (confirm)
+ _gcr_debug ("prompt confirmed");
+ else
+ _gcr_debug ("prompt was cancelled");
+
return confirm;
}
@@ -1028,8 +1088,10 @@ on_prompt_requested_confirm (GObject *source,
g_simple_async_result_set_op_res_gboolean (res, ret);
}
- if (error != NULL)
+ if (error != NULL) {
+ _gcr_debug ("failed to prompt for confirm: %s", egg_error_message (error));
g_simple_async_result_take_error (res, error);
+ }
g_simple_async_result_complete (res);
g_object_unref (self);
@@ -1057,6 +1119,8 @@ gcr_system_prompt_confirm_async (GcrSystemPrompt *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gcr_system_prompt_confirm_async);
+ _gcr_debug ("prompting for confirm");
+
g_dbus_proxy_call (G_DBUS_PROXY (self->pv->prompt_proxy),
GCR_DBUS_PROMPT_METHOD_CONFIRM,
parameters_for_confirm (self),
@@ -1118,6 +1182,8 @@ gcr_system_prompt_confirm (GcrSystemPrompt *self,
return FALSE;
}
+ _gcr_debug ("prompting for confirm");
+
retval = g_dbus_proxy_call_sync (self->pv->prompt_proxy,
GCR_DBUS_PROMPT_METHOD_CONFIRM,
parameters_for_confirm (self),
@@ -1190,6 +1256,11 @@ gcr_system_prompt_open_for_prompter_async (const gchar *prompter_name,
g_return_if_fail (timeout_seconds >= -1);
g_return_if_fail (cancellable == NULL || G_CANCELLABLE (cancellable));
+ if (prompter_name == NULL)
+ _gcr_debug ("opening prompt");
+ else
+ _gcr_debug ("opening prompt for prompter: %s", prompter_name);
+
g_async_initable_new_async (GCR_TYPE_SYSTEM_PROMPT,
G_PRIORITY_DEFAULT,
cancellable,
@@ -1294,6 +1365,11 @@ gcr_system_prompt_open_for_prompter (const gchar *prompter_name,
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ if (prompter_name == NULL)
+ _gcr_debug ("opening prompt");
+ else
+ _gcr_debug ("opening prompt for prompter: %s", prompter_name);
+
return g_initable_new (GCR_TYPE_SYSTEM_PROMPT, cancellable, error,
"timeout-seconds", timeout_seconds,
"bus-name", prompter_name,
@@ -1308,12 +1384,103 @@ gcr_system_prompt_open_for_prompter (const gchar *prompter_name,
* called on this object. The prompt object is not unreferenced by this
* function, and you must unreference it once done.
*/
+gboolean
+gcr_system_prompt_close (GcrSystemPrompt *self,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GVariant *retval;
+
+ g_return_val_if_fail (GCR_IS_SYSTEM_PROMPT (self), FALSE);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (self->pv->prompt_path != NULL, FALSE);
+
+ _gcr_debug ("closing prompt");
+
+ retval = g_dbus_connection_call_sync (self->pv->connection,
+ self->pv->prompter_bus_name,
+ GCR_DBUS_PROMPTER_OBJECT_PATH,
+ GCR_DBUS_PROMPTER_INTERFACE,
+ GCR_DBUS_PROMPTER_METHOD_FINISH,
+ g_variant_new ("(o)", self->pv->prompt_path),
+ NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1, cancellable, error);
+ if (retval == NULL) {
+ _gcr_debug ("failed to close prompt: %s",
+ egg_error_result_message (error));
+ return FALSE;
+ }
+
+ g_variant_unref (retval);
+ g_free (self->pv->prompt_path);
+ self->pv->prompt_path = NULL;
+ return TRUE;
+}
+
+static void
+on_prompt_close_async (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ GcrSystemPrompt *self = GCR_SYSTEM_PROMPT (g_async_result_get_source_object (user_data));
+ GError *error = NULL;
+
+ if (!g_dbus_connection_call_finish (self->pv->connection, result, &error)) {
+ _gcr_debug ("failed to close prompt: %s", egg_error_message (error));
+ g_simple_async_result_take_error (res, error);
+ }
+
+ g_simple_async_result_complete (res);
+ g_object_unref (self);
+ g_object_unref (res);
+}
+
void
-gcr_system_prompt_close (GcrSystemPrompt *self)
+gcr_system_prompt_close_async (GcrSystemPrompt *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- g_return_if_fail (GCR_IS_SYSTEM_PROMPT (self));
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (GCR_SYSTEM_PROMPT (self));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (self->pv->prompt_path != NULL);
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ gcr_system_prompt_close_async);
+
+ _gcr_debug ("closing prompt");
+
+ g_dbus_connection_call (self->pv->connection,
+ self->pv->prompter_bus_name,
+ GCR_DBUS_PROMPTER_OBJECT_PATH,
+ GCR_DBUS_PROMPTER_INTERFACE,
+ GCR_DBUS_PROMPTER_METHOD_FINISH,
+ g_variant_new ("(o)", self->pv->prompt_path),
+ NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1, NULL, on_prompt_close_async, g_object_ref (res));
+
+ g_object_unref (res);
+}
- g_object_run_dispose (G_OBJECT (self));
+gboolean
+gcr_system_prompt_close_finish (GcrSystemPrompt *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GCR_IS_SYSTEM_PROMPT (self), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ gcr_system_prompt_close_async), FALSE);
+
+ if (!g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
}
static const GDBusErrorEntry SYSTEM_PROMPT_ERRORS[] = {
diff --git a/gcr/gcr-system-prompt.h b/gcr/gcr-system-prompt.h
index 19ffa1d..3fe2b33 100644
--- a/gcr/gcr-system-prompt.h
+++ b/gcr/gcr-system-prompt.h
@@ -39,7 +39,8 @@ G_BEGIN_DECLS
typedef enum {
GCR_SYSTEM_PROMPT_IN_PROGRESS = 1,
GCR_SYSTEM_PROMPT_NOT_HAPPENING,
- GCR_SYSTEM_PROMPT_FAILED
+ GCR_SYSTEM_PROMPT_FAILED,
+ GCR_SYSTEM_PROMPT_CLOSED
} GcrSystemPromptError;
#define GCR_SYSTEM_PROMPT_ERROR (gcr_system_prompt_error_get_domain ())
@@ -167,7 +168,18 @@ gboolean gcr_system_prompt_confirm (GcrSystemPromp
GCancellable *cancellable,
GError **error);
-void gcr_system_prompt_close (GcrSystemPrompt *self);
+gboolean gcr_system_prompt_close (GcrSystemPrompt *self,
+ GCancellable *cancellable,
+ GError **error);
+
+void gcr_system_prompt_close_async (GcrSystemPrompt *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean gcr_system_prompt_close_finish (GcrSystemPrompt *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/gcr/gcr-system-prompter.c b/gcr/gcr-system-prompter.c
index 7a60fc7..cf7eaa9 100644
--- a/gcr/gcr-system-prompter.c
+++ b/gcr/gcr-system-prompter.c
@@ -25,6 +25,8 @@
#include "gcr-dbus-constants.h"
#include "gcr-dbus-generated.h"
+#define DEBUG_FLAG GCR_DEBUG_PROMPT
+#include "gcr-debug.h"
#include "gcr-internal.h"
#include "gcr-library.h"
#include "gcr-secret-exchange.h"
@@ -69,11 +71,11 @@ enum {
};
enum {
- SHOW_PROMPT,
+ OPEN,
PROMPT_PASSWORD,
PROMPT_CONFIRM,
RESPONDED,
- HIDE_PROMPT,
+ CLOSE,
LAST_SIGNAL
};
@@ -88,7 +90,7 @@ struct _GcrSystemPrompterPrivate {
guint owner_watching_id;
GcrSecretExchange *exchange;
GDBusMethodInvocation *invocation;
- gboolean shown;
+ gboolean opened;
/* Properties */
GHashTable *properties;
@@ -297,9 +299,10 @@ prompt_method_request_password (GcrSystemPrompter *self,
prompt_update_properties (self, properties);
- if (!self->pv->shown) {
- self->pv->shown = TRUE;
- g_signal_emit (self, signals[SHOW_PROMPT], 0);
+ if (!self->pv->opened) {
+ self->pv->opened = TRUE;
+ _gcr_debug ("prompter opening prompt");
+ g_signal_emit (self, signals[OPEN], 0);
}
self->pv->invocation = invocation;
@@ -330,9 +333,10 @@ prompt_method_request_confirm (GcrSystemPrompter *self,
prompt_update_properties (self, properties);
- if (!self->pv->shown) {
- self->pv->shown = TRUE;
- g_signal_emit (self, signals[SHOW_PROMPT], 0);
+ if (!self->pv->opened) {
+ self->pv->opened = TRUE;
+ _gcr_debug ("prompter opening prompt");
+ g_signal_emit (self, signals[OPEN], 0);
}
self->pv->invocation = invocation;
@@ -400,6 +404,7 @@ begin_prompting (GcrSystemPrompter *self,
g_assert (self->pv->prompt_path == NULL);
self->pv->prompt_path = g_strdup (GCR_DBUS_PROMPTER_OBJECT_PATH "/prompt0");
+ _gcr_debug ("prompter registering prompt: %s", self->pv->prompt_path);
self->pv->prompt_registered = g_dbus_connection_register_object (connection, self->pv->prompt_path,
_gcr_prompter_prompt_interface_info (),
&prompt_dbus_vtable, self, NULL, &error);
@@ -424,12 +429,14 @@ finish_prompting (GcrSystemPrompter *self)
prompt_clear_properties (self);
/* Tell the implementation to hide the display */
- if (self->pv->shown) {
- self->pv->shown = FALSE;
- g_signal_emit (self, signals[HIDE_PROMPT], 0);
+ if (self->pv->opened) {
+ _gcr_debug ("prompter closing prompt");
+ self->pv->opened = FALSE;
+ g_signal_emit (self, signals[CLOSE], 0);
}
if (self->pv->owner_watching_id) {
+ _gcr_debug ("prompter stopping watch of client: %s", self->pv->owner_name);
g_bus_unwatch_name (self->pv->owner_watching_id);
self->pv->owner_watching_id = 0;
}
@@ -438,6 +445,7 @@ finish_prompting (GcrSystemPrompter *self)
self->pv->owner_name = NULL;
if (self->pv->prompt_registered) {
+ _gcr_debug ("prompter unregistering prompt: %s", self->pv->prompt_path);
if (!g_dbus_connection_unregister_object (self->pv->connection,
self->pv->prompt_registered))
g_return_if_reached ();
@@ -530,6 +538,8 @@ gcr_system_prompter_dispose (GObject *obj)
{
GcrSystemPrompter *self = GCR_SYSTEM_PROMPTER (obj);
+ _gcr_debug ("disposing prompter");
+
if (self->pv->invocation)
gcr_system_prompter_respond_cancelled (self);
@@ -546,6 +556,8 @@ gcr_system_prompter_finalize (GObject *obj)
{
GcrSystemPrompter *self = GCR_SYSTEM_PROMPTER (obj);
+ _gcr_debug ("finalizing prompter");
+
g_hash_table_destroy (self->pv->properties);
g_queue_free (self->pv->properties_changed);
@@ -586,10 +598,10 @@ gcr_system_prompter_class_init (GcrSystemPrompterClass *klass)
gobject_class->dispose = gcr_system_prompter_dispose;
gobject_class->finalize = gcr_system_prompter_finalize;
- klass->show_prompt = gcr_system_prompter_real_show_prompt;
+ klass->open = gcr_system_prompter_real_show_prompt;
klass->prompt_password= gcr_system_prompter_real_prompt_password;
klass->prompt_confirm = gcr_system_prompter_real_prompt_confirm;
- klass->hide_prompt = gcr_system_prompter_real_hide_prompt;
+ klass->close = gcr_system_prompter_real_hide_prompt;
g_type_class_add_private (gobject_class, sizeof (GcrSystemPrompterPrivate));
@@ -629,9 +641,9 @@ gcr_system_prompter_class_init (GcrSystemPrompterClass *klass)
g_param_spec_string ("caller-window", "Caller window", "Window id of caller",
"", G_PARAM_READABLE));
- signals[SHOW_PROMPT] = g_signal_new ("show-prompt", GCR_TYPE_SYSTEM_PROMPTER, G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GcrSystemPrompterClass, show_prompt),
- NULL, NULL, NULL, G_TYPE_NONE, 0);
+ signals[OPEN] = g_signal_new ("open", GCR_TYPE_SYSTEM_PROMPTER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcrSystemPrompterClass, open),
+ NULL, NULL, NULL, G_TYPE_NONE, 0);
signals[PROMPT_PASSWORD] = g_signal_new ("prompt-password", GCR_TYPE_SYSTEM_PROMPTER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GcrSystemPrompterClass, prompt_password),
@@ -647,9 +659,9 @@ gcr_system_prompter_class_init (GcrSystemPrompterClass *klass)
G_STRUCT_OFFSET (GcrSystemPrompterClass, responded),
NULL, NULL, NULL, G_TYPE_NONE, 0);
- signals[HIDE_PROMPT] = g_signal_new ("hide-prompt", GCR_TYPE_SYSTEM_PROMPTER, G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GcrSystemPrompterClass, hide_prompt),
- NULL, NULL, NULL, G_TYPE_NONE, 0);
+ signals[CLOSE] = g_signal_new ("close", GCR_TYPE_SYSTEM_PROMPTER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcrSystemPrompterClass, close),
+ NULL, NULL, NULL, G_TYPE_NONE, 0);
}
static void
@@ -713,6 +725,7 @@ prompter_method_begin_prompting (GcrSystemPrompter *self,
g_return_if_fail (self->pv->owner_name != NULL);
connection = g_dbus_method_invocation_get_connection (invocation);
+ _gcr_debug ("prompter starting watch of dbus client: %s", self->pv->owner_name);
self->pv->owner_watching_id = g_bus_watch_name_on_connection (connection,
self->pv->owner_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
@@ -730,6 +743,7 @@ prompter_method_finish_prompting (GcrSystemPrompter *self,
const gchar *prompt)
{
if (g_strcmp0 (prompt, self->pv->prompt_path) != 0) {
+ _gcr_debug ("caller passed invalid prompt: %s != %s", prompt, self->pv->prompt_path);
g_dbus_method_invocation_return_error_literal (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
@@ -738,6 +752,7 @@ prompter_method_finish_prompting (GcrSystemPrompter *self,
}
if (self->pv->owner_name == NULL) {
+ _gcr_debug ("prompting is not in progress");
g_dbus_method_invocation_return_error_literal (invocation,
GCR_SYSTEM_PROMPT_ERROR,
GCR_SYSTEM_PROMPT_NOT_HAPPENING,
@@ -745,6 +760,8 @@ prompter_method_finish_prompting (GcrSystemPrompter *self,
return;
}
+ _gcr_debug ("finishing prompting owned by caller %s", self->pv->owner_name);
+
/* Close a prompt that's prompting */
if (self->pv->invocation != NULL)
gcr_system_prompter_respond_cancelled (self);
@@ -800,6 +817,8 @@ gcr_system_prompter_register (GcrSystemPrompter *self,
g_return_if_fail (self->pv->prompter_registered == 0);
g_return_if_fail (self->pv->connection == NULL);
+ _gcr_debug ("registering prompter");
+
self->pv->connection = connection;
g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&self->pv->connection);
@@ -825,6 +844,8 @@ gcr_system_prompter_unregister (GcrSystemPrompter *self,
g_return_if_fail (self->pv->prompter_registered != 0);
g_return_if_fail (self->pv->connection == connection);
+ _gcr_debug ("unregistering prompter");
+
if (self->pv->invocation)
gcr_system_prompter_respond_cancelled (self);
@@ -1036,6 +1057,8 @@ gcr_system_prompter_respond_cancelled (GcrSystemPrompter *self)
/* Don't send back any changed properties on cancel */
properties = g_variant_new_array (G_VARIANT_TYPE ("(ssv)"), NULL, 0);
+ _gcr_debug ("responding to with cancelled");
+
method = g_dbus_method_invocation_get_method_name (invocation);
if (method && g_str_equal (method, GCR_DBUS_PROMPT_METHOD_PASSWORD))
g_dbus_method_invocation_return_value (invocation,
@@ -1076,11 +1099,13 @@ gcr_system_prompter_respond_with_password (GcrSystemPrompter *self,
invocation = self->pv->invocation;
self->pv->invocation = NULL;
+ method = g_dbus_method_invocation_get_method_name (invocation);
+ g_return_if_fail (method != NULL && g_str_equal (method, GCR_DBUS_PROMPT_METHOD_PASSWORD));
+
/* Send back all the properties before we respond */
properties = build_changed_properties (self);
- method = g_dbus_method_invocation_get_method_name (invocation);
- g_return_if_fail (method != NULL && g_str_equal (method, GCR_DBUS_PROMPT_METHOD_PASSWORD));
+ _gcr_debug ("responding to prompt with password");
exchange = gcr_secret_exchange_send (self->pv->exchange, password, -1);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@a(ssv)s)",
@@ -1115,6 +1140,9 @@ gcr_system_prompter_respond_confirmed (GcrSystemPrompter *self)
method = g_dbus_method_invocation_get_method_name (invocation);
g_return_if_fail (method != NULL && g_str_equal (method, GCR_DBUS_PROMPT_METHOD_CONFIRM));
+
+ _gcr_debug ("responding to prompt with confirm");
+
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@a(ssv)b)",
properties, TRUE));
diff --git a/gcr/gcr-system-prompter.h b/gcr/gcr-system-prompter.h
index ad84ecb..b697473 100644
--- a/gcr/gcr-system-prompter.h
+++ b/gcr/gcr-system-prompter.h
@@ -53,7 +53,7 @@ struct _GcrSystemPrompter {
struct _GcrSystemPrompterClass {
GObjectClass parent_class;
- void (*show_prompt) (GcrSystemPrompter *self);
+ void (*open) (GcrSystemPrompter *self);
gboolean (*prompt_password) (GcrSystemPrompter *self);
@@ -61,7 +61,7 @@ struct _GcrSystemPrompterClass {
void (*responded) (GcrSystemPrompter *self);
- void (*hide_prompt) (GcrSystemPrompter *self);
+ void (*close) (GcrSystemPrompter *self);
};
GType gcr_system_prompter_get_type (void) G_GNUC_CONST;
diff --git a/gcr/tests/frob-system-prompt.c b/gcr/tests/frob-system-prompt.c
new file mode 100644
index 0000000..ef01139
--- /dev/null
+++ b/gcr/tests/frob-system-prompt.c
@@ -0,0 +1,106 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gcr/gcr.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static void
+on_prompt_clicked (GtkToolButton *button,
+ gpointer user_data)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ const gchar *password;
+ GtkWidget *parent = user_data;
+ gchar *caller_id;
+
+ prompt = gcr_system_prompt_open (-1, NULL, &error);
+ if (error != NULL) {
+ g_warning ("couldn't open prompt: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ gcr_system_prompt_set_title (prompt, "This is the title");
+ gcr_system_prompt_set_message (prompt, "This is the message");
+ gcr_system_prompt_set_description (prompt, "This is the description");
+
+ caller_id = g_strdup_printf ("%lu", (gulong)GDK_WINDOW_XID (gtk_widget_get_window (parent)));
+ gcr_system_prompt_set_caller_window (prompt, caller_id);
+ g_free (caller_id);
+
+ password = gcr_system_prompt_password (prompt, NULL, &error);
+ if (error != NULL) {
+ g_warning ("couldn't prompt for password: %s", error->message);
+ g_error_free (error);
+ g_object_unref (prompt);
+ return;
+ }
+
+ g_print ("password: %s\n", password);
+ g_object_unref (prompt);
+}
+
+static gboolean
+on_window_delete (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ gtk_main_quit ();
+ return FALSE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *window;
+ GtkToolbar *toolbar;
+ GtkToolItem *item;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (window, "delete-event", G_CALLBACK (on_window_delete), NULL);
+
+ toolbar = GTK_TOOLBAR (gtk_toolbar_new ());
+ gtk_toolbar_set_style (toolbar, GTK_TOOLBAR_TEXT);
+ item = gtk_tool_button_new (NULL, "Prompt");
+ g_signal_connect (item, "clicked", G_CALLBACK (on_prompt_clicked), window);
+ gtk_toolbar_insert (toolbar, item, 0);
+ gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (toolbar));
+
+ gtk_window_set_default_size (GTK_WINDOW (window), 400, 80);
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/gcr/tests/test-system-prompt.c b/gcr/tests/test-system-prompt.c
new file mode 100644
index 0000000..aec1ce6
--- /dev/null
+++ b/gcr/tests/test-system-prompt.c
@@ -0,0 +1,409 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ Copyright (C) 2011 Collabora Ltd
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw@collabora.co.uk>
+*/
+
+#include "config.h"
+
+#include "gcr/gcr-base.h"
+#include "gcr/gcr-mock-prompter.h"
+
+#include "egg/egg-testing.h"
+
+#include <glib.h>
+
+typedef struct {
+ const gchar *prompter_name;
+} Test;
+
+static void
+setup (Test *test,
+ gconstpointer unused)
+{
+ test->prompter_name = gcr_mock_prompter_start ();
+}
+
+static void
+teardown (Test *test,
+ gconstpointer unused)
+{
+ gcr_mock_prompter_stop ();
+}
+
+static void
+test_prompt_password (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ const gchar *password;
+
+ gcr_mock_prompter_expect_password_ok ("booo", NULL);
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ password = gcr_system_prompt_password (prompt, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (password, ==, "booo");
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+static void
+test_password_in_exchange (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ GcrSecretExchange *exchange;
+
+ gcr_mock_prompter_expect_password_ok ("booo", NULL);
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ gcr_system_prompt_password (prompt, NULL, &error);
+ g_assert_no_error (error);
+
+ g_object_get (prompt, "secret-exchange", &exchange, NULL);
+ g_assert (GCR_IS_SECRET_EXCHANGE (exchange));
+ g_assert_cmpstr (gcr_secret_exchange_get_secret (exchange, NULL), ==, "booo");
+
+ g_object_unref (exchange);
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+static void
+on_async_result (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GAsyncResult **ret = user_data;
+ *ret = g_object_ref (result);
+ egg_test_wait_stop ();
+}
+
+static void
+test_async_password (Test *test,
+ gconstpointer unused)
+{
+ GAsyncResult *result = NULL;
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ const gchar *password;
+
+ gcr_mock_prompter_expect_password_ok ("booo", NULL);
+
+ gcr_system_prompt_open_for_prompter_async (test->prompter_name, 0, NULL,
+ on_async_result, &result);
+ g_assert (result == NULL);
+ egg_test_wait ();
+
+ g_assert (result != NULL);
+ prompt = gcr_system_prompt_open_finish (result, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+ g_clear_object (&result);
+
+ gcr_system_prompt_password_async (prompt, NULL,
+ on_async_result, &result);
+ g_assert (result == NULL);
+ egg_test_wait ();
+
+ password = gcr_system_prompt_password_finish (prompt, result, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (password, ==, "booo");
+ g_clear_object (&result);
+
+ g_object_unref (prompt);
+}
+
+static void
+test_prompt_confirm (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ gboolean ret;
+
+ gcr_mock_prompter_expect_confirm_ok (NULL);
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ ret = gcr_system_prompt_confirm (prompt, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+static void
+test_async_confirm (Test *test,
+ gconstpointer unused)
+{
+ GAsyncResult *result = NULL;
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ gboolean confirm;
+
+ gcr_mock_prompter_expect_confirm_ok (NULL);
+
+ gcr_system_prompt_open_for_prompter_async (test->prompter_name, 0, NULL,
+ on_async_result, &result);
+ g_assert (result == NULL);
+ egg_test_wait ();
+
+ g_assert (result != NULL);
+ prompt = gcr_system_prompt_open_finish (result, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+ g_clear_object (&result);
+
+ gcr_system_prompt_confirm_async (prompt, NULL,
+ on_async_result, &result);
+ g_assert (result == NULL);
+ egg_test_wait ();
+
+ confirm = gcr_system_prompt_confirm_finish (prompt, result, &error);
+ g_assert_no_error (error);
+ g_assert (confirm == TRUE);
+ g_clear_object (&result);
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+static void
+test_cancel_password (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ const gchar *password;
+
+ gcr_mock_prompter_expect_password_cancel ();
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ password = gcr_system_prompt_password (prompt, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (password, ==, NULL);
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+static void
+test_cancel_confirm (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ gboolean ret;
+
+ gcr_mock_prompter_expect_confirm_cancel ();
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ ret = gcr_system_prompt_confirm (prompt, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == FALSE);
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+static void
+test_prompt_properties (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ gboolean ret;
+
+ gcr_mock_prompter_expect_confirm_ok ("title", "My Title",
+ "description", "My Description",
+ "warning", "My Warning",
+ "message", "My Message",
+ "caller-window", "01010",
+ "choice-label", "My Choice",
+ "choice-chosen", TRUE,
+ "password-new", TRUE,
+ "password-strength", 2,
+ NULL);
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ g_object_set (prompt,
+ "title", "Other Title",
+ "choice-label", "Other Choice",
+ "description", "Other Description",
+ "message", "Other Message",
+ "caller-window", "01012",
+ "warning", "Other Warning",
+ "password-new", FALSE,
+ "choice-chosen", TRUE,
+ NULL);
+
+ g_assert_cmpstr (gcr_system_prompt_get_title (prompt), ==, "Other Title");
+ g_assert_cmpstr (gcr_system_prompt_get_choice_label (prompt), ==, "Other Choice");
+ g_assert_cmpstr (gcr_system_prompt_get_description (prompt), ==, "Other Description");
+ g_assert_cmpstr (gcr_system_prompt_get_message (prompt), ==, "Other Message");
+ g_assert_cmpstr (gcr_system_prompt_get_caller_window (prompt), ==, "01012");
+ g_assert_cmpstr (gcr_system_prompt_get_warning (prompt), ==, "Other Warning");
+ g_assert (gcr_system_prompt_get_password_new (prompt) == FALSE);
+ g_assert (gcr_system_prompt_get_choice_chosen (prompt) == TRUE);
+
+ gcr_system_prompt_set_title (prompt, "My Title");
+ gcr_system_prompt_set_choice_label (prompt, "My Choice");
+ gcr_system_prompt_set_description (prompt, "My Description");
+ gcr_system_prompt_set_message (prompt, "My Message");
+ gcr_system_prompt_set_caller_window (prompt, "01010");
+ gcr_system_prompt_set_warning (prompt, "My Warning");
+ gcr_system_prompt_set_password_new (prompt, TRUE);
+ gcr_system_prompt_set_choice_chosen (prompt, FALSE);
+
+ ret = gcr_system_prompt_confirm (prompt, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+
+ g_assert (gcr_system_prompt_get_choice_chosen (prompt) == TRUE);
+ g_assert_cmpint (gcr_system_prompt_get_password_strength (prompt), ==, 2);
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+static void
+test_prompt_close (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GcrSystemPrompt *prompt2;
+ GError *error = NULL;
+ gboolean showing;
+ gboolean ret;
+
+ gcr_mock_prompter_expect_confirm_ok (NULL);
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ prompt2 = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_error (error, GCR_SYSTEM_PROMPT_ERROR, GCR_SYSTEM_PROMPT_IN_PROGRESS);
+ g_clear_error (&error);
+ g_assert (prompt2 == NULL);
+
+ ret = gcr_system_prompt_confirm (prompt, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+
+ prompt2 = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_error (error, GCR_SYSTEM_PROMPT_ERROR, GCR_SYSTEM_PROMPT_IN_PROGRESS);
+ g_clear_error (&error);
+ g_assert (prompt2 == NULL);
+
+ showing = gcr_mock_prompter_get_showing ();
+ g_assert (showing == TRUE);
+
+ gcr_system_prompt_close (prompt, NULL, &error);
+ g_assert_no_error (error);
+
+ showing = gcr_mock_prompter_get_showing ();
+ g_assert (showing == FALSE);
+
+ prompt2 = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt2));
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+
+ g_object_unref (prompt2);
+ g_assert (!G_IS_OBJECT (prompt2));
+}
+
+static void
+test_finish_cancels (Test *test,
+ gconstpointer unused)
+{
+ GcrSystemPrompt *prompt;
+ GError *error = NULL;
+ const gchar *password = NULL;
+ GAsyncResult *result = NULL;
+
+ gcr_mock_prompter_set_delay_msec (3000);
+ gcr_mock_prompter_expect_password_ok ("booo", NULL);
+
+ prompt = gcr_system_prompt_open_for_prompter (test->prompter_name, 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GCR_IS_SYSTEM_PROMPT (prompt));
+
+ gcr_system_prompt_password_async (prompt, NULL, on_async_result, &result);
+
+ gcr_system_prompt_close (prompt, NULL, &error);
+ g_assert_no_error (error);
+
+ egg_test_wait ();
+
+ password = gcr_system_prompt_password_finish (prompt, result, &error);
+ g_assert_no_error (error);
+ g_assert (password == NULL);
+ g_clear_object (&result);
+
+ g_object_unref (prompt);
+ g_assert (!G_IS_OBJECT (prompt));
+}
+
+int
+main (int argc, char **argv)
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+ g_set_prgname ("test-system-prompt");
+
+ g_test_add ("/gcr/system-prompt/password", Test, NULL, setup, test_prompt_password, teardown);
+ g_test_add ("/gcr/system-prompt/password-async", Test, NULL, setup, test_async_password, teardown);
+ g_test_add ("/gcr/system-prompt/password-cancel", Test, NULL, setup, test_cancel_password, teardown);
+ g_test_add ("/gcr/system-prompt/password-in-exchange", Test, NULL, setup, test_password_in_exchange, teardown);
+ g_test_add ("/gcr/system-prompt/confirm", Test, NULL, setup, test_prompt_confirm, teardown);
+ g_test_add ("/gcr/system-prompt/confirm-async", Test, NULL, setup, test_async_confirm, teardown);
+ g_test_add ("/gcr/system-prompt/confirm-cancel", Test, NULL, setup, test_cancel_confirm, teardown);
+ g_test_add ("/gcr/system-prompt/properties", Test, NULL, setup, test_prompt_properties, teardown);
+ g_test_add ("/gcr/system-prompt/close", Test, NULL, setup, test_prompt_close, teardown);
+ g_test_add ("/gcr/system-prompt/finish-cancel", Test, NULL, setup, test_finish_cancels, teardown);
+
+ return egg_tests_run_with_loop ();
+}