summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--telepathy-logger/action-chain-internal.h5
-rw-r--r--telepathy-logger/action-chain.c39
-rw-r--r--telepathy-logger/channel-internal.h51
-rw-r--r--telepathy-logger/channel.c262
-rw-r--r--telepathy-logger/dbus-service.c24
-rw-r--r--telepathy-logger/observer.c18
-rw-r--r--telepathy-logger/text-channel-internal.h31
-rw-r--r--telepathy-logger/text-channel.c154
8 files changed, 222 insertions, 362 deletions
diff --git a/telepathy-logger/action-chain-internal.h b/telepathy-logger/action-chain-internal.h
index f0a75f4..c2c072f 100644
--- a/telepathy-logger/action-chain-internal.h
+++ b/telepathy-logger/action-chain-internal.h
@@ -40,8 +40,9 @@ void _tpl_action_chain_append (TplActionChain *self, TplPendingAction func,
void _tpl_action_chain_prepend (TplActionChain *self, TplPendingAction func,
gpointer user_data);
void _tpl_action_chain_continue (TplActionChain *self);
-void _tpl_action_chain_terminate (TplActionChain *self);
+void _tpl_action_chain_terminate (TplActionChain *self, const GError *error);
gpointer _tpl_action_chain_get_object (TplActionChain *self);
-gboolean _tpl_action_chain_new_finish (GAsyncResult *result);
+gboolean _tpl_action_chain_new_finish (GObject *source,
+ GAsyncResult *result, GError **error);
#endif // __TPL_ACTION_CHAIN_H__
diff --git a/telepathy-logger/action-chain.c b/telepathy-logger/action-chain.c
index f68a770..0999885 100644
--- a/telepathy-logger/action-chain.c
+++ b/telepathy-logger/action-chain.c
@@ -110,12 +110,7 @@ void
_tpl_action_chain_continue (TplActionChain *self)
{
if (g_queue_is_empty (self->chain))
- {
- GSimpleAsyncResult *simple = self->simple;
-
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
- g_simple_async_result_complete (simple);
- }
+ g_simple_async_result_complete (self->simple);
else
{
TplActionLink *l = g_queue_pop_head (self->chain);
@@ -127,35 +122,49 @@ _tpl_action_chain_continue (TplActionChain *self)
void
-_tpl_action_chain_terminate (TplActionChain *self)
+_tpl_action_chain_terminate (TplActionChain *self,
+ const GError *error)
{
GSimpleAsyncResult *simple = self->simple;
- g_simple_async_result_set_op_res_gboolean (simple, FALSE);
+ g_assert (error != NULL);
+
+ g_simple_async_result_set_from_error (simple, error);
g_simple_async_result_complete (simple);
}
/**
* _tpl_action_chain_new_finish:
+ * @source: the #GObject pass to _tpl_action_chain_new_async()
+ * @result: the #GAsyncResult pass in callback
+ * @error: a pointer to a #GError that will be set on error, or NULL to ignore
*
* Get the result from running the action chain (%TRUE if the chain completed
- * successfully, %FALSE if it was terminated).
+ * successfully, %FALSE with @error set if it was terminated).
*
* This function also frees the chain.
+ *
+ * Returns: %TRUE on success, %FALSE with @error set on error.
*/
gboolean
-_tpl_action_chain_new_finish (GAsyncResult *result)
+_tpl_action_chain_new_finish (GObject *source,
+ GAsyncResult *result,
+ GError **error)
{
TplActionChain *chain;
- gboolean retval;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, source,
+ _tpl_action_chain_new_async), FALSE);
chain = g_object_get_data (G_OBJECT (result), "chain");
- retval = g_simple_async_result_get_op_res_gboolean (
- G_SIMPLE_ASYNC_RESULT (result));
+ g_return_val_if_fail (chain != NULL, FALSE);
- _tpl_action_chain_free (chain);
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+ error))
+ return FALSE;
- return retval;
+ _tpl_action_chain_free (chain);
+ return TRUE;
}
diff --git a/telepathy-logger/channel-internal.h b/telepathy-logger/channel-internal.h
index 7c5ec5e..9da0f61 100644
--- a/telepathy-logger/channel-internal.h
+++ b/telepathy-logger/channel-internal.h
@@ -30,40 +30,35 @@
#include <telepathy-glib/channel.h>
G_BEGIN_DECLS
-#define TPL_TYPE_CHANNEL (_tpl_channel_get_type ())
-#define TPL_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TPL_TYPE_CHANNEL, TplChannel))
-#define TPL_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TPL_TYPE_CHANNEL, TplChannelClass))
-#define TPL_IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_CHANNEL))
-#define TPL_IS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TPL_TYPE_CHANNEL))
-#define TPL_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TPL_TYPE_CHANNEL, TplChannelClass))
-typedef struct _TplChannelPriv TplChannelPriv;
+#define TPL_TYPE_CHANNEL (_tpl_channel_get_type ())
+#define TPL_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TPL_TYPE_CHANNEL, TplChannel))
+#define TPL_IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_CHANNEL))
+#define TPL_CHANNEL_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TPL_TYPE_CHANNEL, TplChannelInterface))
-typedef struct
-{
- TpChannel parent;
-
- /* private */
- TplChannelPriv *priv;
-} TplChannel;
+typedef struct _TplChannel TplChannel;
+typedef struct _TplChannelInterface TplChannelInterface;
-typedef struct
+struct _TplChannelInterface
{
- TpChannelClass parent_class;
- /* Virtual method, to be implemented by subclasses */
- void (*call_when_ready) (TplChannel *self, GAsyncReadyCallback cb,
- gpointer user_data);
- /* Protected method, should be called only by subclasses to prepare
- * TplChannel */
- void (*call_when_ready_protected) (TplChannel *self, GAsyncReadyCallback cb,
- gpointer user_data);
-} TplChannelClass;
+ GTypeInterface g_iface;
+
+ void (*prepare_async) (TplChannel *self,
+ GAsyncReadyCallback cb,
+ gpointer user_data);
+ gboolean (*prepare_finish) (TplChannel *self,
+ GAsyncResult *result,
+ GError **error);
+};
-GType _tpl_channel_get_type (void);
+GType _tpl_channel_get_type (void) G_GNUC_CONST;
-TpAccount *_tpl_channel_get_account (TplChannel *self);
-void _tpl_channel_call_when_ready (TplChannel *self, GAsyncReadyCallback cb,
- gpointer user_data);
+void _tpl_channel_prepare_async (TplChannel *self,
+ GAsyncReadyCallback cb,
+ gpointer user_data);
+gboolean _tpl_channel_prepare_finish (TplChannel *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
#endif // __TPL_CHANNEL_H__
diff --git a/telepathy-logger/channel.c b/telepathy-logger/channel.c
index a098e46..fe5309c 100644
--- a/telepathy-logger/channel.c
+++ b/telepathy-logger/channel.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Copyright (C) 2009 Collabora Ltd.
+ * Copyright (C) 2009-2011 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,168 +17,25 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk>
+ * Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
*/
#include "config.h"
#include "channel-internal.h"
-#include <string.h>
-
#include <glib.h>
-#include <telepathy-glib/util.h>
-
-#include <telepathy-logger/text-channel-internal.h>
-#include <telepathy-logger/observer-internal.h>
-
-#define DEBUG_FLAG TPL_DEBUG_CHANNEL
-#include <telepathy-logger/action-chain-internal.h>
-#include <telepathy-logger/debug-internal.h>
-#include <telepathy-logger/util-internal.h>
-
-#define TPCHAN_PROP_PREFIX "org.freedesktop.Telepathy.Channel."
-#define TPCHAN_PROP_PREFIX_LEN strlen(TPCHAN_PROP_PREFIX)
-
-static void tpl_channel_set_account (TplChannel *self, TpAccount *data);
-static void call_when_ready_protected (TplChannel *self,
- GAsyncReadyCallback cb, gpointer user_data);
-static void pendingproc_get_ready_tp_connection (TplActionChain *ctx,
- gpointer user_data);
-static void pendingproc_get_ready_tp_channel (TplActionChain *ctx,
- gpointer user_data);
-
-G_DEFINE_ABSTRACT_TYPE (TplChannel, _tpl_channel, TP_TYPE_CHANNEL)
-
-struct _TplChannelPriv
-{
- TpAccount *account;
-};
-
-enum
-{
- PROP0,
- PROP_ACCOUNT
-};
-
-static void
-tpl_channel_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TplChannelPriv *priv = TPL_CHANNEL (object)->priv;
-
- switch (param_id)
- {
- case PROP_ACCOUNT:
- g_value_set_object (value, priv->account);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- };
-}
-
-static void
-tpl_channel_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- TplChannel *self = TPL_CHANNEL (object);
-
- switch (param_id) {
- case PROP_ACCOUNT:
- tpl_channel_set_account (self, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- };
-}
-
-
-static void
-tpl_channel_dispose (GObject *obj)
-{
- TplChannelPriv *priv = TPL_CHANNEL (obj)->priv;
-
- if (priv->account != NULL)
- {
- g_object_unref (priv->account);
- priv->account = NULL;
- }
-
- G_OBJECT_CLASS (_tpl_channel_parent_class)->dispose (obj);
-}
-
-
-static void
-_tpl_channel_class_init (TplChannelClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- object_class->dispose = tpl_channel_dispose;
- object_class->get_property = tpl_channel_get_property;
- object_class->set_property = tpl_channel_set_property;
-
- klass->call_when_ready_protected = call_when_ready_protected;
-
- /**
- * TplChannel:account:
- *
- * the TpAccount instance associated with TplChannel
- */
- param_spec = g_param_spec_object ("account",
- "Account", "TpAccount instance associated with TplChannel",
- TP_TYPE_ACCOUNT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
-
- g_type_class_add_private (object_class, sizeof (TplChannelPriv));
-}
-
-
-static void
-_tpl_channel_init (TplChannel *self)
-{
- TplChannelPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TPL_TYPE_CHANNEL,
- TplChannelPriv);
- self->priv = priv;
-}
-
-
-TpAccount *
-_tpl_channel_get_account (TplChannel *self)
-{
- TplChannelPriv *priv;
-
- g_return_val_if_fail (TPL_IS_CHANNEL (self), NULL);
-
- priv = self->priv;
- return priv->account;
-}
+G_DEFINE_INTERFACE (TplChannel, _tpl_channel, TP_TYPE_CHANNEL)
static void
-tpl_channel_set_account (TplChannel *self,
- TpAccount *data)
+_tpl_channel_default_init (TplChannelInterface *iface)
{
- TplChannelPriv *priv;
-
- g_return_if_fail (TPL_IS_CHANNEL (self));
- g_return_if_fail (TP_IS_ACCOUNT (data));
-
- priv = self->priv;
- g_return_if_fail (priv->account == NULL);
-
- priv->account = g_object_ref (data);
}
/**
- * tpl_channel_call_when_ready
+ * tpl_channel_prepare_async
* @self: a TplChannel instance
* @cb: a callback
* @user_data: user's data passed to the callback
@@ -186,116 +43,29 @@ tpl_channel_set_account (TplChannel *self,
* The TplObserver has no idea of what TplChannel subclass instance it's
* dealing with.
* In order to prepare the subclass instance this method has to
- * be called, which will call #TplChannelClass.call_when_ready
+ * be called, which will call #TplChannelClass.prepare_async
* virtual method, implemented (mandatory) by #TplChannel subclasses.
- * Such method has to call, internally,
- * #TplChannelClass.call_when_ready_protected in order to prepare also the
- * #TplChannel instance.
*/
void
-_tpl_channel_call_when_ready (TplChannel *self,
+_tpl_channel_prepare_async (TplChannel *self,
GAsyncReadyCallback cb,
gpointer user_data)
{
g_return_if_fail (TPL_IS_CHANNEL (self));
- /* Subclasses have to implement it */
- g_return_if_fail (TPL_CHANNEL_GET_CLASS (self)->call_when_ready != NULL);
-
- TPL_CHANNEL_GET_CLASS (self)->call_when_ready (self, cb, user_data);
-}
-
-
-/**
- * call_when_ready_protected
- * @self: a TplChannel instance
- * @cb: a callback
- * @user_data: user's data passed to the callback
- *
- * This static method is called from #TplChannelClass.call_when_ready, implemented by
- * #TplChannel subclasses.
- *
- * See also: %tpl_channel_call_when_ready
- */
-static void
-call_when_ready_protected (TplChannel *self,
- GAsyncReadyCallback cb,
- gpointer user_data)
-{
- TplActionChain *actions;
-
- actions = _tpl_action_chain_new_async (G_OBJECT (self), cb, user_data);
- _tpl_action_chain_append (actions, pendingproc_get_ready_tp_connection, NULL);
- _tpl_action_chain_append (actions, pendingproc_get_ready_tp_channel, NULL);
- _tpl_action_chain_continue (actions);
-}
-
-static void
-conn_prepared_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- TplActionChain *ctx = user_data;
- GError *error = NULL;
-
- if (!tp_proxy_prepare_finish (source, result, &error))
- {
- TplChannel *tpl_chan;
-
- tpl_chan = _tpl_action_chain_get_object (ctx);
- PATH_DEBUG (tpl_chan, "Giving up channel observation: %s",
- error->message);
+ g_return_if_fail (TPL_CHANNEL_GET_IFACE (self)->prepare_async != NULL);
- _tpl_action_chain_terminate (ctx);
- g_error_free (error);
- return;
- }
-
- _tpl_action_chain_continue (ctx);
+ TPL_CHANNEL_GET_IFACE (self)->prepare_async (self, cb, user_data);
}
-static void
-pendingproc_get_ready_tp_connection (TplActionChain *ctx,
- gpointer user_data)
-{
- TplChannel *tpl_chan = _tpl_action_chain_get_object (ctx);
- TpConnection *tp_conn = tp_channel_borrow_connection (TP_CHANNEL (
- tpl_chan));
- GQuark features[] = { TP_CONNECTION_FEATURE_CORE, 0 };
-
- tp_proxy_prepare_async (tp_conn, features, conn_prepared_cb, ctx);
-}
-static void
-channel_prepared_cb (GObject *source,
+gboolean
+_tpl_channel_prepare_finish (TplChannel *self,
GAsyncResult *result,
- gpointer user_data)
-{
- TplActionChain *ctx = user_data;
- TplChannel *tpl_chan = _tpl_action_chain_get_object (ctx);
- GError *error = NULL;
-
- if (!tp_proxy_prepare_finish (source, result, &error))
- {
- PATH_DEBUG (tpl_chan, "Giving up channel observation: %s",
- error->message);
-
- _tpl_action_chain_terminate (ctx);
- g_error_free (error);
- return;
-
- }
-
- _tpl_action_chain_continue (ctx);
-}
-
-static void
-pendingproc_get_ready_tp_channel (TplActionChain *ctx,
- gpointer user_data)
+ GError **error)
{
- TplChannel *tpl_chan = _tpl_action_chain_get_object (ctx);
- GQuark features[] = { TP_CHANNEL_FEATURE_CORE, TP_CHANNEL_FEATURE_GROUP, 0 };
+ g_return_val_if_fail (TPL_IS_CHANNEL (self), FALSE);
+ g_return_val_if_fail (TPL_CHANNEL_GET_IFACE (self)->prepare_finish != NULL,
+ FALSE);
- /* user_data is a TplChannel instance */
- tp_proxy_prepare_async (TP_CHANNEL (tpl_chan), features, channel_prepared_cb,
- ctx);
+ return TPL_CHANNEL_GET_IFACE (self)->prepare_finish (self, result, error);
}
diff --git a/telepathy-logger/dbus-service.c b/telepathy-logger/dbus-service.c
index 536733d..22561ad 100644
--- a/telepathy-logger/dbus-service.c
+++ b/telepathy-logger/dbus-service.c
@@ -214,9 +214,9 @@ favourite_contacts_file_read_line_cb (GObject *object,
if (error != NULL)
{
- DEBUG ("failed to open favourite contacts file: %s", error->message);
+ g_prefix_error (&error, "failed to open favourite contacts file: ");
+ _tpl_action_chain_terminate (action_chain, error);
g_clear_error (&error);
- _tpl_action_chain_terminate (action_chain);
}
else if (line != NULL)
{
@@ -260,9 +260,9 @@ favourite_contacts_file_open_cb (GObject *object,
}
else
{
- DEBUG ("Failed to open the favourite contacts file: %s", error->message);
+ g_prefix_error (&error, "Failed to open the favourite contacts file: ");
+ _tpl_action_chain_terminate (action_chain, error);
g_clear_error (&error);
- _tpl_action_chain_terminate (action_chain);
}
}
@@ -309,11 +309,13 @@ favourite_contacts_file_parsed_cb (GObject *object,
{
TplDBusService *self = TPL_DBUS_SERVICE (object);
TplDBusServicePriv *priv = self->priv;
+ GError *error = NULL;
- if (!_tpl_action_chain_new_finish (result))
+ if (!_tpl_action_chain_new_finish (object, result, &error))
{
DEBUG ("Failed to parse the favourite contacts file and/or execute "
- "subsequent queued method calls");
+ "subsequent queued method calls: %s", error->message);
+ g_error_free (error);
}
priv->favourite_contacts_actions = NULL;
@@ -602,9 +604,10 @@ pendingproc_add_favourite_contact (TplActionChain *action_chain,
return;
pendingproc_add_favourite_contact_ERROR:
- g_clear_error (&error);
if (action_chain != NULL)
- _tpl_action_chain_terminate (action_chain);
+ _tpl_action_chain_terminate (action_chain, error);
+
+ g_clear_error (&error);
}
@@ -702,9 +705,10 @@ pendingproc_remove_favourite_contact (TplActionChain *action_chain,
return;
pendingproc_remove_favourite_contact_ERROR:
- g_clear_error (&error);
if (action_chain != NULL)
- _tpl_action_chain_terminate (action_chain);
+ _tpl_action_chain_terminate (action_chain, error);
+
+ g_clear_error (&error);
}
static void
diff --git a/telepathy-logger/observer.c b/telepathy-logger/observer.c
index a2bd40b..2645e08 100644
--- a/telepathy-logger/observer.c
+++ b/telepathy-logger/observer.c
@@ -82,7 +82,8 @@
*/
static void tpl_observer_dispose (GObject * obj);
-static void got_tpl_text_channel_ready_cb (GObject *obj, GAsyncResult *result,
+static void channel_prepared_cb (GObject *obj,
+ GAsyncResult *result,
gpointer user_data);
static TplChannelFactory tpl_observer_get_channel_factory (TplObserver *self);
@@ -181,7 +182,7 @@ tpl_observer_observe_channels (TpBaseClient *client,
g_hash_table_insert (self->priv->preparing_channels,
(gchar *) tp_proxy_get_object_path (tpl_chan), tpl_chan);
- _tpl_channel_call_when_ready (tpl_chan, got_tpl_text_channel_ready_cb,
+ _tpl_channel_prepare_async (tpl_chan, channel_prepared_cb,
observing_ctx);
}
@@ -227,23 +228,24 @@ _tpl_observer_register_channel (TplObserver *self,
return TRUE;
}
+
static void
-got_tpl_text_channel_ready_cb (GObject *obj,
+channel_prepared_cb (GObject *obj,
GAsyncResult *result,
gpointer user_data)
{
ObservingContext *observing_ctx = user_data;
- gboolean success = _tpl_action_chain_new_finish (result);
+ GError *error = NULL;
- if (success)
+ if (_tpl_action_chain_new_finish (obj, result, &error))
{
- PATH_DEBUG (obj, "prepared channel");
-
+ PATH_DEBUG (obj, "channel prepared");
_tpl_observer_register_channel (observing_ctx->self, TPL_CHANNEL (obj));
}
else
{
- PATH_DEBUG (obj, "failed to prepare");
+ PATH_DEBUG (obj, "failed to prepare channel: %s", error->message);
+ g_error_free (error);
}
g_hash_table_remove (observing_ctx->self->priv->preparing_channels,
diff --git a/telepathy-logger/text-channel-internal.h b/telepathy-logger/text-channel-internal.h
index 2b71a01..00f4d87 100644
--- a/telepathy-logger/text-channel-internal.h
+++ b/telepathy-logger/text-channel-internal.h
@@ -31,21 +31,34 @@
#include <telepathy-glib/channel.h>
#include <telepathy-glib/connection.h>
#include <telepathy-glib/contact.h>
+#include <telepathy-glib/text-channel.h>
-#include <telepathy-logger/channel-internal.h>
+#include "channel-internal.h"
G_BEGIN_DECLS
-#define TPL_TYPE_TEXT_CHANNEL (_tpl_text_channel_get_type ())
-#define TPL_TEXT_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TPL_TYPE_TEXT_CHANNEL, TplTextChannel))
-#define TPL_TEXT_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TPL_TYPE_TEXT_CHANNEL, TplTextChannelClass))
-#define TPL_IS_TEXT_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_TEXT_CHANNEL))
-#define TPL_IS_TEXT_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TPL_TYPE_TEXT_CHANNEL))
-#define TPL_TEXT_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TPL_TYPE_TEXT_CHANNEL, TplTextChannelClass))
+
+#define TPL_TYPE_TEXT_CHANNEL (_tpl_text_channel_get_type ())
+#define TPL_TEXT_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TPL_TYPE_TEXT_CHANNEL, TplTextChannel))
+#define TPL_TEXT_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TPL_TYPE_TEXT_CHANNEL, TplTextChannelClass))
+#define TPL_IS_TEXT_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_TEXT_CHANNEL))
+#define TPL_IS_TEXT_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TPL_TYPE_TEXT_CHANNEL))
+#define TPL_TEXT_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TPL_TYPE_TEXT_CHANNEL, TplTextChannelClass))
+
+
+#define TPL_TEXT_CHANNEL_ERROR \
+ g_quark_from_static_string ("tpl-text-channel-error-quark")
+
+typedef enum
+{
+ /* generic error */
+ TPL_TEXT_CHANNEL_ERROR_FAILED,
+ TPL_TEXT_CHANNEL_ERROR_NEED_MESSAGE_INTERFACE,
+} TplTextChannelError;
typedef struct _TplTextChannelPriv TplTextChannelPriv;
typedef struct
{
- TplChannel parent;
+ TpTextChannel parent;
/* private */
TplTextChannelPriv *priv;
@@ -53,7 +66,7 @@ typedef struct
typedef struct
{
- TplChannelClass parent_class;
+ TpTextChannelClass parent_class;
} TplTextChannelClass;
GType _tpl_text_channel_get_type (void);
diff --git a/telepathy-logger/text-channel.c b/telepathy-logger/text-channel.c
index 6b2f054..58114bd 100644
--- a/telepathy-logger/text-channel.c
+++ b/telepathy-logger/text-channel.c
@@ -43,6 +43,7 @@
struct _TplTextChannelPriv
{
+ TpAccount *account;
TplEntity *self;
gboolean is_chatroom;
TplEntity *chatroom; /* only set if is_chatroom==TRUE */
@@ -62,36 +63,86 @@ static TpContactFeature features[3] = {
TP_CONTACT_FEATURE_AVATAR_TOKEN
};
-G_DEFINE_TYPE (TplTextChannel, _tpl_text_channel, TPL_TYPE_CHANNEL)
+static void tpl_text_channel_iface_init (TplChannelInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (TplTextChannel, _tpl_text_channel,
+ TP_TYPE_TEXT_CHANNEL,
+ G_IMPLEMENT_INTERFACE (TPL_TYPE_CHANNEL, tpl_text_channel_iface_init))
static void
-got_tpl_chan_ready_cb (GObject *obj,
+connection_prepared_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- TpProxy *proxy = TP_PROXY (obj);
TplActionChain *ctx = user_data;
+ GError *error = NULL;
- /* if TplChannel preparation is OK (and support Message interface,
- * keep on with the TplTextChannel */
- if (_tpl_action_chain_new_finish (result)
- && tp_proxy_has_interface_by_id (proxy,
- TP_IFACE_QUARK_CHANNEL_INTERFACE_MESSAGES))
- _tpl_action_chain_continue (ctx);
- else
- _tpl_action_chain_terminate (ctx);
+ if (!tp_proxy_prepare_finish (source, result, &error))
+ {
+ _tpl_action_chain_terminate (ctx, error);
+ g_error_free (error);
+ return;
+ }
+
+ _tpl_action_chain_continue (ctx);
}
static void
-pendingproc_prepare_tpl_channel (TplActionChain *ctx,
+pendingproc_prepare_tp_connection (TplActionChain *ctx,
gpointer user_data)
{
- TplChannel *tpl_chan = TPL_CHANNEL (_tpl_action_chain_get_object (ctx));
+ TplChannel *chan = _tpl_action_chain_get_object (ctx);
+ TpConnection *conn = tp_channel_borrow_connection (TP_CHANNEL (chan));
+ GQuark conn_features[] = { TP_CONNECTION_FEATURE_CORE, 0 };
- TPL_CHANNEL_GET_CLASS (tpl_chan)->call_when_ready_protected (tpl_chan,
- got_tpl_chan_ready_cb, ctx);
+ tp_proxy_prepare_async (conn, conn_features, connection_prepared_cb, ctx);
+}
+
+
+static void
+channel_prepared_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer ctx)
+{
+ TplChannel *chan = _tpl_action_chain_get_object (ctx);
+ GError *error = NULL;
+
+ if (!tp_proxy_prepare_finish (source, result, &error))
+ {
+ _tpl_action_chain_terminate (ctx, error);
+ g_error_free (error);
+ return;
+ }
+ else if (!tp_proxy_has_interface_by_id (TP_PROXY (chan),
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_MESSAGES))
+ {
+ error = g_error_new (TPL_TEXT_CHANNEL_ERROR,
+ TPL_TEXT_CHANNEL_ERROR_NEED_MESSAGE_INTERFACE,
+ "The text channel does not implement Message interface.");
+ _tpl_action_chain_terminate (ctx, error);
+ g_error_free (error);
+ }
+
+ _tpl_action_chain_continue (ctx);
+}
+
+
+static void
+pendingproc_prepare_tp_text_channel (TplActionChain *ctx,
+ gpointer user_data)
+{
+ TplChannel *chan = _tpl_action_chain_get_object (ctx);
+ GQuark chan_features[] = {
+ TP_CHANNEL_FEATURE_CORE,
+ TP_CHANNEL_FEATURE_GROUP,
+ TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES,
+ 0
+ };
+
+ /* user_data is a TplChannel instance */
+ tp_proxy_prepare_async (chan, chan_features, channel_prepared_cb, ctx);
}
@@ -116,13 +167,16 @@ get_self_contact_cb (TpConnection *connection,
{
TpConnection *tp_conn = tp_channel_borrow_connection (tp_chan);
const gchar *conn_path;
+ GError *new_error = NULL;
conn_path = tp_proxy_get_object_path (TP_PROXY (tp_conn));
- PATH_DEBUG (tpl_text, "Error resolving self handle for connection %s."
- " Aborting channel observation", conn_path);
+ new_error = g_error_new (error->domain, error->code,
+ "Error resolving self handle for connection %s: %s)",
+ conn_path, error->message);
- _tpl_action_chain_terminate (ctx);
+ _tpl_action_chain_terminate (ctx, new_error);
+ g_error_free (new_error);
return;
}
@@ -168,10 +222,13 @@ get_remote_contacts_cb (TpConnection *connection,
if (error != NULL)
{
- DEBUG ("Failed to get remote contacts: %s", error->message);
-
if (ctx != NULL)
- _tpl_action_chain_terminate (ctx);
+ {
+ GError *new_error = NULL;
+ new_error = g_error_new (error->domain, error->code,
+ "Failed to get remote contacts: %s", error->message);
+ _tpl_action_chain_terminate (ctx, error);
+ }
return;
}
@@ -444,7 +501,7 @@ tpl_text_channel_store_message (TplTextChannel *self,
/* Initialise TplTextEvent */
event = g_object_new (TPL_TYPE_TEXT_EVENT,
/* TplEvent */
- "account", _tpl_channel_get_account (TPL_CHANNEL (self)),
+ "account", priv->account,
"channel-path", tp_proxy_get_object_path (TP_PROXY (self)),
"receiver", receiver,
"sender", sender,
@@ -538,33 +595,34 @@ pendingproc_connect_message_signals (TplActionChain *ctx,
return;
disaster:
- DEBUG ("couldn't connect to signals: %s", error->message);
- g_clear_error (&error);
- _tpl_action_chain_terminate (ctx);
+ g_prefix_error (&error, "Couldn't connect to signals: ");
+ _tpl_action_chain_terminate (ctx, error);
+ g_error_free (error);
+}
+
+static gboolean
+tpl_text_channel_prepare_finish (TplChannel *chan,
+ GAsyncResult *result,
+ GError **error)
+{
+ return _tpl_action_chain_new_finish (G_OBJECT (chan), result, error);
}
static void
-tpl_text_channel_call_when_ready (TplChannel *chan,
- GAsyncReadyCallback cb, gpointer user_data)
+tpl_text_channel_prepare_async (TplChannel *chan,
+ GAsyncReadyCallback cb,
+ gpointer user_data)
{
TplActionChain *actions;
- /* first: connect signals, so none are lost
- * second: prepare all TplChannel
- * third: cache my contact and the remote one.
- * last: connect to Message signals
- *
- * If for any reason, the order is changed, it's needed to check what objects
- * are unreferenced by g_object_unref but used by a next action AND what
- * object are actually not prepared but used anyway */
actions = _tpl_action_chain_new_async (G_OBJECT (chan), cb, user_data);
- _tpl_action_chain_append (actions, pendingproc_prepare_tpl_channel, NULL);
+ _tpl_action_chain_append (actions, pendingproc_prepare_tp_connection, NULL);
+ _tpl_action_chain_append (actions, pendingproc_prepare_tp_text_channel, NULL);
_tpl_action_chain_append (actions, pendingproc_get_my_contact, NULL);
_tpl_action_chain_append (actions, pendingproc_get_remote_contacts, NULL);
_tpl_action_chain_append (actions, pendingproc_connect_message_signals, NULL);
- /* start the chain consuming */
_tpl_action_chain_continue (actions);
}
@@ -595,18 +653,23 @@ static void
_tpl_text_channel_class_init (TplTextChannelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- TplChannelClass *tpl_chan_class = TPL_CHANNEL_CLASS (klass);
object_class->dispose = tpl_text_channel_dispose;
object_class->finalize = tpl_text_channel_finalize;
- tpl_chan_class->call_when_ready = tpl_text_channel_call_when_ready;
-
g_type_class_add_private (object_class, sizeof (TplTextChannelPriv));
}
static void
+tpl_text_channel_iface_init (TplChannelInterface *iface)
+{
+ iface->prepare_async = tpl_text_channel_prepare_async;
+ iface->prepare_finish = tpl_text_channel_prepare_finish;
+}
+
+
+static void
_tpl_text_channel_init (TplTextChannel *self)
{
TplTextChannelPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
@@ -652,8 +715,9 @@ _tpl_text_channel_new (TpConnection *conn,
GError **error)
{
TpProxy *conn_proxy = TP_PROXY (conn);
+ TplTextChannel *self;
- /* Do what tpl_channel_new does + set TplTextChannel specific properties */
+ /* Do what tpl_channel_new does + set TplTextChannel specific */
g_return_val_if_fail (TP_IS_CONNECTION (conn), NULL);
g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL);
@@ -663,9 +727,7 @@ _tpl_text_channel_new (TpConnection *conn,
if (!tp_dbus_check_valid_object_path (object_path, error))
return NULL;
- return g_object_new (TPL_TYPE_TEXT_CHANNEL,
- /* TplChannel properties */
- "account", account,
+ self = g_object_new (TPL_TYPE_TEXT_CHANNEL,
/* TpChannel properties */
"connection", conn,
"dbus-daemon", conn_proxy->dbus_daemon,
@@ -674,4 +736,8 @@ _tpl_text_channel_new (TpConnection *conn,
"handle-type", (guint) TP_UNKNOWN_HANDLE_TYPE,
"channel-properties", tp_chan_props,
NULL);
+
+ self->priv->account = g_object_ref (account);
+
+ return self;
}