From d94685b66760fe5ec30fc54fbe4926d871915d14 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 12 Apr 2012 18:20:36 +0100 Subject: [PATCH 2/3] tp_base_connection_disconnect_with_dbus_error_vardict: add and test --- docs/reference/telepathy-glib-sections.txt | 1 + telepathy-glib/base-connection.c | 66 ++++++++++++++++++++ telepathy-glib/base-connection.h | 5 ++ tests/dbus/connection-error.c | 91 ++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+) diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index 1622f77..7a1aade 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -53,6 +53,7 @@ tp_base_connection_get_self_handle tp_base_connection_set_self_handle tp_base_connection_change_status tp_base_connection_disconnect_with_dbus_error +tp_base_connection_disconnect_with_dbus_error_vardict tp_base_connection_finish_shutdown tp_base_connection_add_interfaces tp_base_connection_dbus_request_handles diff --git a/telepathy-glib/base-connection.c b/telepathy-glib/base-connection.c index 0382717..23ebaec 100644 --- a/telepathy-glib/base-connection.c +++ b/telepathy-glib/base-connection.c @@ -2752,6 +2752,72 @@ tp_base_connection_disconnect_with_dbus_error (TpBaseConnection *self, } /** + * tp_base_connection_disconnect_with_dbus_error_vardict: (skip) + * @self: The connection + * @error_name: The D-Bus error with which the connection changed status to + * Disconnected + * @details: Further details of the error, as a variant of + * type %G_VARIANT_TYPE_VARDICT. The keys + * are strings as defined in the Telepathy specification, and the + * values are of type %G_VARIANT_TYPE_VARIANT. + * %NULL is allowed, and treated as an empty dictionary. + * @reason: The reason code to use in the StatusChanged signal + * (a less specific, non-extensible version of @error_name) + * + * Changes the #TpBaseConnection.status of @self to + * %TP_CONNECTION_STATUS_DISCONNECTED, as if by a call to + * tp_base_connection_change_status(), but additionally emits the + * ConnectionError D-Bus signal to provide more details about the + * error. + * + * Well-known keys for @details are documented in the Telepathy specification's + * definition + * of the ConnectionError signal, and include: + * + * + * "debug-message", whose value should have type + * #G_TYPE_STRING, for debugging information about the + * disconnection which should not be shown to the user + * "server-message", whose value should also have type + * #G_TYPE_STRING, for a human-readable error message from the server (in an + * unspecified language) explaining why the user was + * disconnected. + * + * + * Since: 0.7.24 + */ +void +tp_base_connection_disconnect_with_dbus_error_vardict (TpBaseConnection *self, + const gchar *error_name, + GVariant *details, + TpConnectionStatusReason reason) +{ + GValue value = G_VALUE_INIT; + + g_return_if_fail (TP_IS_BASE_CONNECTION (self)); + g_return_if_fail (tp_dbus_check_valid_interface_name (error_name, NULL)); + g_return_if_fail (g_variant_is_of_type (details, G_VARIANT_TYPE_VARDICT)); + + if (details == NULL) + { + g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP); + g_value_take_boxed (&value, g_hash_table_new (g_str_hash, g_str_equal)); + } + else + { + dbus_g_value_parse_g_variant (details, &value); + g_assert (G_VALUE_TYPE (&value) == TP_HASH_TYPE_STRING_VARIANT_MAP); + } + + tp_svc_connection_emit_connection_error (self, error_name, + g_value_get_boxed (&value)); + tp_base_connection_change_status (self, TP_CONNECTION_STATUS_DISCONNECTED, + reason); + + g_value_unset (&value); +} + +/** * tp_base_connection_change_status: * @self: The connection * @status: The new status diff --git a/telepathy-glib/base-connection.h b/telepathy-glib/base-connection.h index 9649014..913f08e 100644 --- a/telepathy-glib/base-connection.h +++ b/telepathy-glib/base-connection.h @@ -131,6 +131,11 @@ void tp_base_connection_disconnect_with_error (TpBaseConnection *self, void tp_base_connection_disconnect_with_dbus_error (TpBaseConnection *self, const gchar *error_name, GHashTable *details, TpConnectionStatusReason reason); +void tp_base_connection_disconnect_with_dbus_error_vardict ( + TpBaseConnection *self, + const gchar *error_name, + GVariant *details, + TpConnectionStatusReason reason); void tp_base_connection_change_status (TpBaseConnection *self, TpConnectionStatus status, TpConnectionStatusReason reason); diff --git a/tests/dbus/connection-error.c b/tests/dbus/connection-error.c index c6d507a..4e27b39 100644 --- a/tests/dbus/connection-error.c +++ b/tests/dbus/connection-error.c @@ -273,6 +273,93 @@ test_unregistered_error (Test *test, error = NULL; } +static void +on_detailed_connection_error (TpConnection *conn, + const gchar *error, + GHashTable *details, + gpointer user_data, + GObject *weak_object) +{ + connection_errors++; + g_assert_cmpstr (error, ==, "com.example.DomainSpecificError"); + g_assert_cmpuint (g_hash_table_size (details), ==, 2); +} + +static void +test_detailed_error (Test *test, + gconstpointer mode) +{ + GError *error = NULL; + const GHashTable *asv; + + asv = GUINT_TO_POINTER (0xDEADBEEF); + g_assert_cmpstr (tp_connection_get_detailed_error (test->conn, NULL), ==, + NULL); + g_assert_cmpstr (tp_connection_get_detailed_error (test->conn, &asv), ==, + NULL); + g_assert_cmpuint (GPOINTER_TO_UINT (asv), ==, 0xDEADBEEF); + + connection_errors = 0; + tp_cli_connection_connect_to_connection_error (test->conn, + on_detailed_connection_error, NULL, NULL, NULL, NULL); + tp_cli_connection_connect_to_status_changed (test->conn, on_status_changed, + test->mainloop, NULL, NULL, NULL); + + if (!tp_strdiff (mode, "variant")) + { + GVariant *details = g_variant_parse (G_VARIANT_TYPE_VARDICT, + "{ 'debug-message': <'not enough bees'>, " + " 'bees-required': <2342> }", NULL, NULL, &error); + + g_assert_no_error (error); + + tp_base_connection_disconnect_with_dbus_error_vardict ( + test->service_conn_as_base, + "com.example.DomainSpecificError", + details, + TP_CONNECTION_STATUS_REASON_NETWORK_ERROR); + g_variant_unref (details); + } + else + { + GHashTable *details = tp_asv_new ( + "debug-message", G_TYPE_STRING, "not enough bees", + "bees-required", G_TYPE_INT, 2342, + NULL); + + tp_base_connection_disconnect_with_dbus_error ( + test->service_conn_as_base, + "com.example.DomainSpecificError", + details, + TP_CONNECTION_STATUS_REASON_NETWORK_ERROR); + g_hash_table_unref (details); + } + + g_main_loop_run (test->mainloop); + + g_assert_cmpuint (connection_errors, ==, 1); + + MYASSERT (!tp_connection_run_until_ready (test->conn, FALSE, &error, NULL), + ""); + + g_assert_error (error, example_com_error_quark (), DOMAIN_SPECIFIC_ERROR); + + g_assert_cmpstr (tp_connection_get_detailed_error (test->conn, NULL), ==, + "com.example.DomainSpecificError"); + g_assert_cmpstr (tp_connection_get_detailed_error (test->conn, &asv), ==, + "com.example.DomainSpecificError"); + g_assert (asv != NULL); + g_assert_cmpstr (tp_asv_get_string (asv, "debug-message"), ==, + "not enough bees"); + g_assert_cmpint (tp_asv_get_int32 (asv, "bees-required", NULL), ==, 2342); + + g_assert_cmpstr (g_quark_to_string (error->domain), ==, + g_quark_to_string (example_com_error_quark ())); + g_assert_cmpuint (error->code, ==, DOMAIN_SPECIFIC_ERROR); + g_error_free (error); + error = NULL; +} + int main (int argc, char **argv) @@ -284,6 +371,10 @@ main (int argc, test_registered_error, teardown); g_test_add ("/connection/unregistered-error", Test, NULL, setup, test_unregistered_error, teardown); + g_test_add ("/connection/detailed-error", Test, NULL, setup, + test_detailed_error, teardown); + g_test_add ("/connection/detailed-error-vardict", Test, "variant", setup, + test_detailed_error, teardown); return g_test_run (); } -- 1.7.10