summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCosimo Alfarano <cosimo.alfarano@collabora.co.uk>2010-02-25 14:48:43 +0000
committerCosimo Alfarano <cosimo.alfarano@collabora.co.uk>2010-02-25 15:37:52 +0000
commitbee2939e886835e90108f72c25bd38435d4128b5 (patch)
tree6f428c27623495da0b34a9074c08475558e35d45
parent8d884a2f125a1f96256ec2511fd10a0590a77c85 (diff)
downloadtelepathy-logger-bee2939e886835e90108f72c25bd38435d4128b5.tar.gz
Preparing TpAccount and TpChannel before channel retrieval.
-rw-r--r--telepathy-logger/observer.c148
1 files changed, 127 insertions, 21 deletions
diff --git a/telepathy-logger/observer.c b/telepathy-logger/observer.c
index 22b9aac..6c5ff5d 100644
--- a/telepathy-logger/observer.c
+++ b/telepathy-logger/observer.c
@@ -96,6 +96,12 @@ static void tpl_observer_prepared_account_manager_cb (GObject *obj,
static void tpl_observer_got_channel_list_cb (TpProxy *proxy,
const GValue *out_Value, const GError *error, gpointer user_data,
GObject *weak_object);
+static void tpl_observer_get_open_channels_prepare_account_cb (GObject *proxy,
+ GAsyncResult *result, gpointer user_data);
+static void tpl_observer_get_open_channels_prepared_connection (TpConnection *conn,
+ const GError *error, gpointer user_data);
+
+
/* end of Get open channels API */
@@ -660,10 +666,8 @@ tpl_observer_set_channel_factory (TplObserver *self,
static void
tpl_observer_get_open_channels (void)
{
- const GQuark features[2] = { TP_ACCOUNT_MANAGER_FEATURE_CORE, 0 };
-
TpAccountManager *acc_man = tp_account_manager_dup ();
- tp_account_manager_prepare_async (acc_man, features,
+ tp_account_manager_prepare_async (acc_man, NULL,
tpl_observer_prepared_account_manager_cb, NULL);
}
@@ -681,31 +685,107 @@ tpl_observer_prepared_account_manager_cb (GObject *obj,
&error))
{
DEBUG ("Unable to prepare connection manager: %s", error->message);
+ g_object_unref (am);
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))
{
- TpConnection *conn = NULL;
TpAccount *acc = l->data;
+
g_assert (TP_IS_ACCOUNT (acc));
- if (!tp_account_is_enabled (acc))
- continue;
+ /* ref here, unref in callbacks on error or at the end of the
+ * chain */
+ tp_account_prepare_async (g_object_ref (acc), NULL,
+ tpl_observer_get_open_channels_prepare_account_cb, NULL);
+ }
+ g_list_free (list);
+}
+
+
+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));
- conn = tp_account_get_connection (acc);
- /* account's connection is offline */
- if (conn == NULL)
- continue;
+ if (!tp_account_is_enabled (account))
+ goto early_out;
- tp_cli_dbus_properties_call_get (conn, -1,
- TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
- "Channels",
- tpl_observer_got_channel_list_cb, acc, NULL, NULL);
+ if (!tp_account_prepare_finish (account, result, &error))
+ {
+ DEBUG ("unable to prapare account: %s", error->message);
+ goto early_out;
}
- g_list_free (list);
+
+ conn = tp_account_get_connection (account);
+ /* account's connection is offline */
+ if (conn == NULL)
+ goto early_out;
+
+ /* ref here, unref in callbacks on error or at the end of the chain */
+ tp_connection_call_when_ready (g_object_ref (conn),
+ tpl_observer_get_open_channels_prepared_connection, account);
+
+ return;
+
+early_out:
+ if (error != NULL)
+ g_error_free (error);
+ if (account != NULL)
+ g_object_unref (account);
+}
+
+
+static void
+tpl_observer_get_open_channels_prepared_connection (TpConnection *conn,
+ const GError *error,
+ gpointer user_data)
+{
+ TpAccount *account = TP_ACCOUNT (user_data);
+
+ /* not use g_return_* or it will leak refs */
+ if (!TP_IS_CONNECTION (conn))
+ {
+ DEBUG ("conn is not TP_CONNECTION");
+ goto err;
+ }
+ if (!TP_IS_ACCOUNT (account))
+ {
+ DEBUG ("account is not TP_ACCOUNT");
+ goto err;
+ }
+
+
+ if (error != NULL)
+ {
+ DEBUG ("unable to prepare connection for open channel retrieval: %s",
+ error->message);
+ goto err;
+ }
+
+ /* 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, account, NULL, NULL);
+ return;
+
+err:
+ if (conn != NULL)
+ g_object_unref (conn);
+ if (account != NULL)
+ g_object_unref (account);
}
@@ -715,18 +795,38 @@ void tpl_observer_got_channel_list_cb (TpProxy *proxy,
gpointer user_data,
GObject *weak_object)
{
- TpAccount *acc = TP_ACCOUNT (user_data);
+ TpAccount *account = TP_ACCOUNT (user_data);
TpConnection *conn = TP_CONNECTION (proxy);
TplObserver *observer = tpl_observer_new ();
GPtrArray *channels;
+ /* not use g_return_* or it will leak refs */
+ if (!TP_IS_CONNECTION (conn))
+ {
+ DEBUG ("conn is not TP_CONNECTION");
+ goto out;
+ }
+ if (!TP_IS_ACCOUNT (account))
+ {
+ DEBUG ("account is not TP_ACCOUNT");
+ goto out;
+ }
+
if (error != NULL)
{
- DEBUG ("%s", error->message);
- return;
+ DEBUG ("unable to retrieve channels for connection %s: %s",
+ tp_proxy_get_object_path (TP_PROXY (conn)),
+ error->message);
+ goto out;
}
- g_return_if_fail (G_VALUE_HOLDS (out_Value, TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST));
+ /* not use g_return_* or it will leak refs */
+ if (!G_VALUE_HOLDS (out_Value, TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST))
+ {
+ g_critical ("channel list GValue does not hold "
+ "TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST");
+ goto out;
+ }
channels = g_value_get_boxed (out_Value);
@@ -736,9 +836,15 @@ void tpl_observer_got_channel_list_cb (TpProxy *proxy,
* 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 (acc)),
+ tp_proxy_get_object_path (TP_PROXY (account)),
tp_proxy_get_object_path (TP_PROXY (conn)),
channels, NULL, NULL, NULL, NULL);
- g_object_unref (observer);
+out:
+ if (account != NULL)
+ g_object_unref (account);
+ if (conn != NULL)
+ g_object_unref (conn);
+ if (observer != NULL)
+ g_object_unref (observer);
}