summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2010-02-26 14:46:32 +1100
committerDanielle Madeley <danielle.madeley@collabora.co.uk>2010-02-26 14:46:32 +1100
commit974c774d4d45dc2935bc8a6eee43e987a97dc486 (patch)
tree3f388c1a941a2dd56b5d9326cddfe93f14a89d00
parent441651cc42ab642626315df1bbf8ade20fa5400f (diff)
parent6a769d860f6a7cf5d16bc5acb130afd63bd9535a (diff)
downloadtelepathy-logger-974c774d4d45dc2935bc8a6eee43e987a97dc486.tar.gz
Merge branch 'observe-existing-channels'
-rw-r--r--telepathy-logger/debug.h4
-rw-r--r--telepathy-logger/log-manager.c8
-rw-r--r--telepathy-logger/log-store-empathy.c2
-rw-r--r--telepathy-logger/observer.c185
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);
}