diff options
Diffstat (limited to 'telepathy-logger')
-rw-r--r-- | telepathy-logger/debug.h | 4 | ||||
-rw-r--r-- | telepathy-logger/log-manager.c | 8 | ||||
-rw-r--r-- | telepathy-logger/log-store-empathy.c | 2 | ||||
-rw-r--r-- | telepathy-logger/observer.c | 185 |
4 files changed, 187 insertions, 12 deletions
diff --git a/telepathy-logger/debug.h b/telepathy-logger/debug.h index 1766b2c..db9b35a 100644 --- a/telepathy-logger/debug.h +++ b/telepathy-logger/debug.h @@ -61,8 +61,8 @@ G_END_DECLS #define DEBUGGING gabble_debug_flag_is_set (DEBUG_FLAG) -/* The same of DEBUG, printing also the object-path property for the TpProxy - * passed as first arg. prepending '_' not not shadow any local variable */ +/* The same of DEBUG, printing also the object-path property for the TpProxy, + * passed as first arg. prepending '_' to avoid shadowing local variables */ #define PATH_DEBUG(_proxy, _format, ...) \ G_STMT_START { \ const gchar *_path; \ diff --git a/telepathy-logger/log-manager.c b/telepathy-logger/log-manager.c index 98ebe37..01c83b1 100644 --- a/telepathy-logger/log-manager.c +++ b/telepathy-logger/log-manager.c @@ -151,6 +151,8 @@ tpl_log_manager_init (TplLogManager *self) self->priv = priv; + DEBUG ("Initialising the Log Manager"); + /* The TPL's default read-write logstore */ tplogger = g_object_new (TPL_TYPE_LOG_STORE_EMPATHY, "name", TPL_LOG_MANAGER_LOG_STORE_DEFAULT, @@ -158,7 +160,8 @@ tpl_log_manager_init (TplLogManager *self) "readable", TRUE, NULL); if (tplogger == NULL) - g_critical ("Error during TplLogStoreEmpathy (name=TpLogger) initialisation."); + g_critical ("Error during TplLogStoreEmpathy (name=TpLogger) " + "initialisation."); else { /* manual registration, to set up priv->stores for @@ -187,6 +190,9 @@ tpl_log_manager_init (TplLogManager *self) /* internally referenced within register_logstore */ if (empathy != NULL) g_object_unref (empathy); + + + DEBUG ("Log Manager initialised"); } diff --git a/telepathy-logger/log-store-empathy.c b/telepathy-logger/log-store-empathy.c index 14ce05f..e3893b3 100644 --- a/telepathy-logger/log-store-empathy.c +++ b/telepathy-logger/log-store-empathy.c @@ -437,8 +437,8 @@ _log_store_empathy_write_to_store (TplLogStore *self, if (file != NULL) fseek (file, -strlen (LOG_FOOTER), SEEK_END); } - g_fprintf (file, "%s", entry); + DEBUG ("%s: written: %s", filename, entry); fclose (file); g_free (filename); diff --git a/telepathy-logger/observer.c b/telepathy-logger/observer.c index 27f0e8b..aa7fa0f 100644 --- a/telepathy-logger/observer.c +++ b/telepathy-logger/observer.c @@ -29,6 +29,7 @@ #include <telepathy-glib/dbus.h> #include <telepathy-glib/svc-generic.h> #include <telepathy-glib/svc-client.h> +#include <telepathy-glib/account-manager.h> #include <telepathy-logger/conf.h> #include <telepathy-logger/channel.h> @@ -87,6 +88,7 @@ static void got_tpl_channel_text_ready_cb (GObject *obj, GAsyncResult *result, gpointer user_data); static TplChannelFactory tpl_observer_get_channel_factory (TplObserver *self); static GHashTable *tpl_observer_get_channel_map (TplObserver *self); +static void tpl_observer_get_open_channels (void); #define GET_PRIV(obj) TPL_GET_PRIV (obj, TplObserver) @@ -151,6 +153,10 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, g_return_if_fail (!TPL_STR_EMPTY (account)); g_return_if_fail (!TPL_STR_EMPTY (connection)); + if (dbus_context == NULL) + DEBUG ("called during open channel inspection, not by the Channel " + "Dispatcher. OK."); + chan_factory = tpl_observer_get_channel_factory (TPL_OBSERVER (self)); /* Check if logging if enabled globally and for the given account_path, @@ -225,8 +231,7 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, if (tpl_chan == NULL) { DEBUG ("%s", error->message); - g_error_free (error); - error = NULL; + g_clear_error (&error); continue; } PATH_DEBUG (tpl_chan, "Starting preparation fo TplChannel instance"); @@ -249,9 +254,13 @@ error: g_object_unref (tp_bus_daemon); g_clear_error (&error); - DEBUG ("Returning from observe channels on error condition. " + /* observer_channels has been called by the Channel Dispatcher */ + if (dbus_context != NULL) + { + DEBUG ("Returning from observe channels on error condition. " "Unable to log the channel"); - tp_svc_client_observer_return_from_observe_channels (dbus_context); + tp_svc_client_observer_return_from_observe_channels (dbus_context); + } } @@ -266,8 +275,12 @@ got_tpl_channel_text_ready_cb (GObject *obj, observing_ctx->chan_n -= 1; if (observing_ctx->chan_n == 0) { - DEBUG ("Returning from observe channels"); - tp_svc_client_observer_return_from_observe_channels (dbus_ctx); + if (dbus_ctx != NULL) + { + /* observer_channels has been called by the Channel Dispatcher */ + DEBUG ("Returning from observe channels"); + tp_svc_client_observer_return_from_observe_channels (dbus_ctx); + } g_slice_free (ObservingContext, observing_ctx); } } @@ -427,6 +440,8 @@ tpl_observer_init (TplObserver *self) priv->channel_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); priv->logmanager = tpl_log_manager_dup_singleton (); + + tpl_observer_get_open_channels (); } @@ -622,11 +637,165 @@ tpl_observer_set_channel_factory (TplObserver *self, { TplObserverPriv *priv = GET_PRIV (self); - g_return_if_fail (TPL_IS_OBSERVER (self)); - g_return_if_fail (factory != NULL); g_return_if_fail (factory != NULL); g_return_if_fail (priv->channel_factory == NULL); + g_return_if_fail (TPL_IS_OBSERVER (self)); priv->channel_factory = factory; +} + + +static void +tpl_observer_got_channel_list_cb (TpProxy *proxy, + const GValue *value, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + TpAccount *account = TP_ACCOUNT (user_data); + TpConnection *conn = TP_CONNECTION (proxy); + TplObserver *observer = tpl_observer_new (); + GPtrArray *channels; + + g_return_if_fail (TP_IS_CONNECTION (conn)); + g_return_if_fail (TP_IS_ACCOUNT (account)); + + if (error != NULL) + { + DEBUG ("unable to retrieve channels for connection %s: %s", + tp_proxy_get_object_path (TP_PROXY (conn)), + error->message); + return; + } + + if (!G_VALUE_HOLDS (value, TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST)) + { + g_critical ("channel list GValue does not hold " + "TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST"); + return; + } + + channels = g_value_get_boxed (value); + + /* call observe_channels with + * Dispatch_Operation = NULL, Requests_Satisfied = NULL, + * Observer_Info = NULL and DBusGMethodInvocation = NULL + * so that it will undertand that it's not been called by a Channel + * Dispatcher */ + tpl_observer_observe_channels (TP_SVC_CLIENT_OBSERVER (observer), + tp_proxy_get_object_path (TP_PROXY (account)), + tp_proxy_get_object_path (TP_PROXY (conn)), + channels, NULL, NULL, NULL, NULL); +} + + +static void +tpl_observer_get_open_channels_prepared_connection (TpConnection *conn, + const GError *error, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (user_data); + + g_return_if_fail (TP_IS_CONNECTION (conn)); + g_return_if_fail (TP_IS_ACCOUNT (account)); + + if (error != NULL) + { + DEBUG ("unable to prepare connection for open channel retrieval: %s", + error->message); + goto out; + } + + /* I do not pass the observer as a weak_object or I will leak some + * references to account and connection in the callback in case is destroyed + * and the call canceled */ + tp_cli_dbus_properties_call_get (conn, -1, + TP_IFACE_CONNECTION_INTERFACE_REQUESTS, "Channels", + tpl_observer_got_channel_list_cb, + g_object_ref (account), g_object_unref, NULL); + +out: + g_object_unref (account); +} + + +static void +tpl_observer_get_open_channels_prepare_account_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (proxy); + TpConnection *conn; + GError *error = NULL; + + g_return_if_fail (TP_IS_ACCOUNT (account)); + + if (!tp_account_prepare_finish (account, result, &error)) + { + DEBUG ("unable to prapare account: %s", error->message); + g_error_free (error); + } + + if (!tp_account_is_enabled (account)) + return; + + conn = tp_account_get_connection (account); + + /* check if account's connection is offline */ + if (conn == NULL) + return; + + /* ref here, unref in callbacks on error or at the end of the chain */ + tp_connection_call_when_ready (conn, + tpl_observer_get_open_channels_prepared_connection, + g_object_ref (account)); +} + + +static void +tpl_observer_prepared_account_manager_cb (GObject *obj, + GAsyncResult *result, + gpointer user_data) +{ + TpAccountManager *am = TP_ACCOUNT_MANAGER (obj); + GList *list, *l; + GError *error = NULL; + + if (!tp_account_manager_prepare_finish (TP_ACCOUNT_MANAGER (obj), result, + &error)) + { + DEBUG ("Unable to prepare connection manager: %s", error->message); + return; + } + + /* accountspointed by the list are not referenced */ + list = tp_account_manager_get_valid_accounts (am); + + for (l = list; l != NULL; l = g_list_next (l)) + { + TpAccount *account = l->data; + + g_assert (TP_IS_ACCOUNT (account)); + + tp_account_prepare_async (account, NULL, + tpl_observer_get_open_channels_prepare_account_cb, NULL); + } + + g_list_free (list); +} + + +/* Retrieving open channel */ +/* This part can be removed when the Channel Dispatcher will implement a + * proper API for + * org.freedesktop.Telepathy.Connection.Interface.Requests.Channels */ +static void +tpl_observer_get_open_channels (void) +{ + TpAccountManager *am = tp_account_manager_dup (); + + tp_account_manager_prepare_async (am, NULL, + tpl_observer_prepared_account_manager_cb, NULL); + g_object_unref (am); } |