From bb5133759bc92716c24770e46fc95ad7d8073980 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Fri, 27 Sep 2013 12:25:34 +0200 Subject: Prepare TpAccount if needed Make sure that the TpAccount we receive from public API is prepared as more and more API are relying on it. https://bugs.freedesktop.org/show_bug.cgi?id=69814 --- telepathy-logger/log-manager.c | 60 +++++++++++++++++++++++++++++++++++++++++- tests/dbus/test-log-manager.c | 45 +++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/telepathy-logger/log-manager.c b/telepathy-logger/log-manager.c index 944b741..64ffca7 100644 --- a/telepathy-logger/log-manager.c +++ b/telepathy-logger/log-manager.c @@ -870,13 +870,71 @@ _get_dates_async_thread (GSimpleAsyncResult *simple, _list_of_date_free); } +typedef struct +{ + GSimpleAsyncResult *result; + GSimpleAsyncThreadFunc func; +} AsyncOpData; + +static AsyncOpData * +async_op_data_new (GSimpleAsyncResult *result, + GSimpleAsyncThreadFunc func) +{ + AsyncOpData *data = g_slice_new (AsyncOpData); + + data->result = g_object_ref (result); + data->func = func; + return data; +} + +static void +async_op_data_free (AsyncOpData *data) +{ + g_object_unref (data->result); + g_slice_free (AsyncOpData, data); +} + +static void +account_prepared_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + AsyncOpData *data = user_data; + GError *error = NULL; + + if (!tp_proxy_prepare_finish (source, result, &error)) + { + g_simple_async_result_take_error (data->result, error); + g_simple_async_result_complete (data->result); + } + else + { + g_simple_async_result_run_in_thread (data->result, data->func, 0, NULL); + } + + async_op_data_free (data); +} static void start_async_op_in_thread (TpAccount *account, GSimpleAsyncResult *result, GSimpleAsyncThreadFunc func) { - g_simple_async_result_run_in_thread (result, func, 0, NULL); + if (account != NULL) + { + GQuark features[] = { TP_ACCOUNT_FEATURE_CORE, 0 }; + + /* Most APIs rely on TpAccount being prepared, so make sure + * it is. telepathy-glib is not thread-safe, so we must do + * this in the main thread, before starting the actual + * operation in the other thread. */ + tp_proxy_prepare_async (account, features, account_prepared_cb, + async_op_data_new (result, func)); + } + else + { + g_simple_async_result_run_in_thread (result, func, 0, NULL); + } } /** diff --git a/tests/dbus/test-log-manager.c b/tests/dbus/test-log-manager.c index a6e9f5f..5441b87 100644 --- a/tests/dbus/test-log-manager.c +++ b/tests/dbus/test-log-manager.c @@ -387,6 +387,47 @@ test_get_events_for_date (TestCaseFixture *fixture, g_list_free (fixture->ret); } +static void +test_get_events_for_date_account_unprepared (TestCaseFixture *fixture, + gconstpointer user_data) +{ + GHashTable *params = (GHashTable *) user_data; + TplEntity *entity; + GDate *date; + TpAccount *account; + const gchar *account_path; + + g_clear_object (&fixture->account); + + account_path = g_value_get_string ( + (const GValue *) g_hash_table_lookup (params, "account-path")); + + account = tp_simple_client_factory_ensure_account (fixture->factory, + account_path, NULL, NULL); + g_assert (!tp_proxy_is_prepared (account, TP_ACCOUNT_FEATURE_CORE)); + + entity = tpl_entity_new (ID, TPL_ENTITY_CONTACT, NULL, NULL); + date = g_date_new_dmy (13, 1, 2010); + + tpl_log_manager_get_events_for_date_async (fixture->manager, + account, + entity, + TPL_EVENT_MASK_TEXT, + date, + get_events_for_date_cb, + fixture); + g_main_loop_run (fixture->main_loop); + + g_object_unref (entity); + g_date_free (date); + + /* We got 6 events in old Empathy and 6 in new TpLogger storage */ + g_assert_cmpint (g_list_length (fixture->ret), ==, 12); + + g_list_foreach (fixture->ret, (GFunc) g_object_unref, NULL); + g_list_free (fixture->ret); + g_object_unref (account); +} static void get_filtered_events_cb (GObject *object, @@ -738,6 +779,10 @@ main (int argc, char **argv) TestCaseFixture, params, setup, test_get_events_for_date, teardown); + g_test_add ("/log-manager/get-events-for-date-account-unprepared", + TestCaseFixture, params, + setup, test_get_events_for_date_account_unprepared, teardown); + g_test_add ("/log-manager/get-filtered-events", TestCaseFixture, params, setup, test_get_filtered_events, teardown); -- cgit v1.2.1