From bee2939e886835e90108f72c25bd38435d4128b5 Mon Sep 17 00:00:00 2001 From: Cosimo Alfarano Date: Thu, 25 Feb 2010 14:48:43 +0000 Subject: Preparing TpAccount and TpChannel before channel retrieval. --- telepathy-logger/observer.c | 148 +++++++++++++++++++++++++++++++++++++------- 1 file 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); } -- cgit v1.2.1