diff options
Diffstat (limited to 'src/daemon/gsignond-signonui-proxy.c')
-rw-r--r-- | src/daemon/gsignond-signonui-proxy.c | 121 |
1 files changed, 91 insertions, 30 deletions
diff --git a/src/daemon/gsignond-signonui-proxy.c b/src/daemon/gsignond-signonui-proxy.c index ec79fca..6002049 100644 --- a/src/daemon/gsignond-signonui-proxy.c +++ b/src/daemon/gsignond-signonui-proxy.c @@ -25,7 +25,6 @@ #include "gsignond-signonui-proxy.h" #include <gsignond/gsignond-log.h> -#include <gsignond/gsignond-signonui.h> #include "dbus/gsignond-dbus-signonui-adapter.h" static void _process_next_request (GSignondSignonuiProxy *proxy); @@ -53,6 +52,7 @@ typedef struct { struct _GSignondSignonuiProxyPrivate { GSignondDbusSignonuiAdapter *signonui; + guint signonui_timer_id; _UIQueryRequest *active_request; /* Active dialog */ GQueue *request_queue; /* request queue */ gboolean is_idle; @@ -71,7 +71,7 @@ _ui_query_request_new (GObject *caller, _UIQueryRequest *req = g_new0(_UIQueryRequest, 1); req->caller = caller; - req->ui_data = gsignond_signonui_data_ref (ui_data); + req->ui_data = gsignond_dictionary_ref (ui_data); req->cb = cb; req->refresh_cb = refresh_cb; req->userdata = userdata; @@ -105,7 +105,7 @@ static void _ui_query_request_free (_UIQueryRequest *req) { if (!req) return; - if (req->ui_data) gsignond_signonui_data_unref (req->ui_data); + if (req->ui_data) gsignond_dictionary_unref (req->ui_data); g_free (req); } @@ -114,6 +114,10 @@ _dispose (GObject *object) { GSignondSignonuiProxy *self = GSIGNOND_SIGNONUI_PROXY (object); + if (self->priv->signonui_timer_id) { + g_source_remove (self->priv->signonui_timer_id); + self->priv->signonui_timer_id = 0; + } if (self->priv->signonui) { g_object_unref (self->priv->signonui); self->priv->signonui = NULL; @@ -151,10 +155,7 @@ gsignond_signonui_proxy_init (GSignondSignonuiProxy *proxy) { proxy->priv = GSIGNOND_SIGNONUI_PROXY_GET_PRIV (proxy); - proxy->priv->signonui = gsignond_dbus_signonui_adapter_new (); - - if (proxy->priv->signonui) - g_signal_connect_swapped (proxy->priv->signonui, "refresh", G_CALLBACK(_on_refresh_request), proxy); + proxy->priv->signonui = NULL; proxy->priv->active_request = NULL; proxy->priv->request_queue = g_queue_new (); proxy->priv->is_idle = TRUE; @@ -174,43 +175,92 @@ _on_refresh_request (GSignondSignonuiProxy *proxy, gchar *request_id, gpointer u } static void -_query_dialog_cb (GVariant *reply, GError *error, gpointer user_data) +_query_dialog_cb_internal (GSignondSignonuiProxy *proxy, GSignondSignonuiData *ui_data, GError *error) { - GSignondSignonuiProxy *proxy = GSIGNOND_SIGNONUI_PROXY (user_data); - _UIQueryRequest *req = proxy->priv->active_request; - if (req && req->cb) - req->cb (gsignond_signonui_data_new_from_variant (reply), error, req->userdata); + proxy->priv->active_request = NULL; + if (req && req->cb && G_OBJECT(req->caller)) { + req->cb (ui_data, error, req->userdata); + } else if (error) { WARN ("UI-Error: %s", error->message); g_error_free (error); } - _ui_query_request_free (req); - - proxy->priv->active_request = NULL; + if (req) _ui_query_request_free (req); + if (ui_data) gsignond_dictionary_unref (ui_data); _process_next_request (proxy); } static void +_query_dialog_cb (GVariant *reply, GError *error, gpointer user_data) +{ + GSignondSignonuiProxy *proxy = GSIGNOND_SIGNONUI_PROXY (user_data); + GSignondSignonuiData *ui_data = reply ? gsignond_dictionary_new_from_variant (reply) : NULL; + + _query_dialog_cb_internal (proxy, ui_data, error); +} + +static gboolean +_close_ui_connection (gpointer data) +{ + GSignondSignonuiProxy *proxy = GSIGNOND_SIGNONUI_PROXY(data); + g_return_val_if_fail (proxy, FALSE); + + proxy->priv->signonui_timer_id = 0; + + g_clear_object (&proxy->priv->signonui); + + return FALSE; +} + +static void _process_next_request (GSignondSignonuiProxy *proxy) { _UIQueryRequest *req = g_queue_pop_head (proxy->priv->request_queue); + GVariant *params = NULL; if (!req) { proxy->priv->is_idle = TRUE; proxy->priv->active_request = NULL; + proxy->priv->signonui_timer_id = + g_timeout_add_seconds (10, (GSourceFunc)_close_ui_connection, proxy); return; } + else { + proxy->priv->active_request = req; + + if (proxy->priv->signonui_timer_id) { + g_source_remove (proxy->priv->signonui_timer_id); + proxy->priv->signonui_timer_id = 0; + } + if (!proxy->priv->signonui) + proxy->priv->signonui = gsignond_dbus_signonui_adapter_new (); + if (proxy->priv->signonui) + g_signal_connect_swapped (proxy->priv->signonui, "refresh", + G_CALLBACK(_on_refresh_request), proxy); + else { + GSignondSignonuiData *reply = gsignond_dictionary_new (); + gsignond_signonui_data_set_query_error(reply, SIGNONUI_ERROR_NO_SIGNONUI); + _query_dialog_cb_internal (proxy, reply, NULL); + return; + } + } - proxy->priv->active_request = req; /* update request id */ gsignond_signonui_data_set_request_id (req->ui_data, G_OBJECT_TYPE_NAME(req->caller)); - gsignond_dbus_signonui_adapter_query_dialog (proxy->priv->signonui, - gsignond_signonui_data_to_variant(req->ui_data), _query_dialog_cb, proxy); + params = gsignond_dictionary_to_variant(req->ui_data) ; + if (!gsignond_dbus_signonui_adapter_query_dialog (proxy->priv->signonui, + params, _query_dialog_cb, proxy)) { + GSignondSignonuiData *reply = gsignond_dictionary_new (); + gsignond_signonui_data_set_query_error(reply, SIGNONUI_ERROR_GENERAL); + _query_dialog_cb_internal (proxy, reply, NULL); + g_variant_unref (params); + return; + } proxy->priv->is_idle = FALSE; } @@ -257,13 +307,15 @@ gsignond_signonui_proxy_refresh_dialog (GSignondSignonuiProxy *proxy, if (proxy->priv->active_request && proxy->priv->active_request->caller == caller) { _UIRefreshRequest *req = _ui_refresh_request_new (cb, userdata); + GVariant *var_uidata = gsignond_dictionary_to_variant (ui_data); - /* FIXME: Is it required to set refresh id for refresh data */ gsignond_signonui_data_set_request_id (ui_data, G_OBJECT_TYPE_NAME(caller)); - gsignond_dbus_signonui_adapter_refresh_dialog (proxy->priv->signonui, - gsignond_signonui_data_to_variant (ui_data), _refresh_dialog_cb, req); - - return TRUE; + if (gsignond_dbus_signonui_adapter_refresh_dialog (proxy->priv->signonui, + var_uidata, _refresh_dialog_cb, req)) { + return TRUE; + } + g_variant_unref (var_uidata); + g_free (req); } return FALSE; @@ -306,23 +358,32 @@ gsignond_signonui_proxy_cancel_request (GSignondSignonuiProxy *proxy, /* cancel active request */ if (proxy->priv->active_request->caller == caller) { _UICancelRequest *req = _ui_cancel_request_new (cb, userdata); - gsignond_dbus_signonui_adapter_cancel_request (proxy->priv->signonui, - G_OBJECT_TYPE_NAME (caller), _cancel_request_cb, req); + if (!gsignond_dbus_signonui_adapter_cancel_request (proxy->priv->signonui, + G_OBJECT_TYPE_NAME (caller), _cancel_request_cb, req)) { + g_free (req); + return FALSE; + } + _ui_query_request_free (proxy->priv->active_request); + proxy->priv->active_request = NULL; return TRUE; } /* cancel pending request */ element = g_queue_find_custom (proxy->priv->request_queue, caller, _find_request_by_caller); - if (!element) return FALSE; + req = element->data; - if (req->cb) { - gsignond_signonui_data_ref (req->ui_data); - gsignond_signonui_data_set_query_error(req->ui_data, SIGNONUI_ERROR_CANCELED); + g_queue_delete_link (proxy->priv->request_queue, element); - req->cb (req->ui_data, NULL, req->userdata); + if (req && req->cb) { + GSignondSignonuiData *reply = gsignond_dictionary_new (); + gsignond_signonui_data_set_query_error(reply, SIGNONUI_ERROR_CANCELED); + + req->cb (reply, NULL, req->userdata); + gsignond_dictionary_unref (reply); } + _ui_query_request_free (req); if (cb) cb(NULL, userdata); |