From fdb13f9bff8bdd54a76d732fb46ed10ad34c7125 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Mon, 23 Apr 2012 16:30:39 +0200 Subject: [PATCH] Add tp_capabilities_dup_channel_classes_variant() https://bugs.freedesktop.org/show_bug.cgi?id=30422 --- docs/reference/telepathy-glib-sections.txt | 1 + telepathy-glib/capabilities.c | 53 +++++++++++++++ telepathy-glib/capabilities.h | 1 + tests/capabilities.c | 96 ++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 0 deletions(-) diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index 0ac3c12..4aba8ca 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -4989,6 +4989,7 @@ TpContactPrivate capabilities TpCapabilities tp_capabilities_get_channel_classes +tp_capabilities_dup_channel_classes_variant tp_capabilities_is_specific_to_contact tp_capabilities_supports_text_chatrooms tp_capabilities_supports_text_chats diff --git a/telepathy-glib/capabilities.c b/telepathy-glib/capabilities.c index 34c7972..368edc0 100644 --- a/telepathy-glib/capabilities.c +++ b/telepathy-glib/capabilities.c @@ -23,6 +23,7 @@ #include "telepathy-glib/capabilities-internal.h" #include +#include #include #include #include @@ -66,12 +67,14 @@ G_DEFINE_TYPE (TpCapabilities, tp_capabilities, G_TYPE_OBJECT) enum { PROP_CHANNEL_CLASSES = 1, PROP_CONTACT_SPECIFIC, + PROP_CHANNEL_CLASSES_VARIANT, N_PROPS }; struct _TpCapabilitiesPrivate { GPtrArray *classes; gboolean contact_specific; + GVariant *classes_variant; }; /** @@ -157,6 +160,10 @@ tp_capabilities_get_property (GObject *object, g_value_set_boolean (value, self->priv->contact_specific); break; + case PROP_CHANNEL_CLASSES_VARIANT: + g_value_set_variant (value, self->priv->classes_variant); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -175,6 +182,9 @@ tp_capabilities_set_property (GObject *object, { case PROP_CHANNEL_CLASSES: self->priv->classes = g_value_dup_boxed (value); + self->priv->classes_variant = _tp_boxed_to_variant ( + TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, "a(a{sv}as)", + self->priv->classes); break; case PROP_CONTACT_SPECIFIC: @@ -236,6 +246,32 @@ tp_capabilities_class_init (TpCapabilitiesClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_CONTACT_SPECIFIC, param_spec); + + /** + * TpCapabilities:channel-classes-variant: + * + * The underlying data structure used by Telepathy to represent the + * requests that can succeed. + * + * This can be used by advanced clients to determine whether an unusually + * complex request would succeed. See the Telepathy D-Bus API Specification + * for details of how to interpret the returned #GVariant of type + * a(a{sv}as). + * + * The higher-level methods like + * tp_capabilities_supports_text_chats() are likely to be more useful to + * the majority of clients. + * + * Since: UNRELEASED + */ + param_spec = g_param_spec_variant ("channel-classes-variant", + "GVariant of type a(a{sv}as)", + "The channel classes supported", + G_VARIANT_TYPE ("a(a{sv}as)"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CHANNEL_CLASSES_VARIANT, + param_spec); } static void @@ -859,3 +895,20 @@ tp_capabilities_supports_room_list (TpCapabilities *self, return result; } + +/** + * tp_capabilities_dup_channel_classes_variant: + * @self: a #TpCapabilities + * + * Return the #TpCapabilities:channel-classes-variant property + * + * Returns: (transfer none): the value of + * #TpCapabilities:channel-classes-variant property + * + * Since: UNRELEASED + */ +GVariant * +tp_capabilities_dup_channel_classes_variant (TpCapabilities *self) +{ + return self->priv->classes_variant; +} diff --git a/telepathy-glib/capabilities.h b/telepathy-glib/capabilities.h index 1d55c1a..85d209f 100644 --- a/telepathy-glib/capabilities.h +++ b/telepathy-glib/capabilities.h @@ -49,6 +49,7 @@ GType tp_capabilities_get_type (void) G_GNUC_CONST; TpCapabilitiesClass)) GPtrArray * tp_capabilities_get_channel_classes (TpCapabilities *self); +GVariant * tp_capabilities_dup_channel_classes_variant (TpCapabilities *self); gboolean tp_capabilities_is_specific_to_contact (TpCapabilities *self); diff --git a/tests/capabilities.c b/tests/capabilities.c index 61c1ce6..75d1ee8 100644 --- a/tests/capabilities.c +++ b/tests/capabilities.c @@ -961,6 +961,100 @@ test_supports_call (Test *test, g_object_unref (caps); } +static void +test_classes_variant (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + TpCapabilities *caps; + GPtrArray *classes; + GVariant *v, *v2, *class, *fixed, *allowed; + const gchar *chan_type; + TpHandleType handle_type; + const gchar **strv; + + /* TpCapabilities containing the text chats and ft caps */ + classes = g_ptr_array_sized_new (2); + add_text_chat_class (classes, TP_HANDLE_TYPE_CONTACT); + add_ft_class (classes); + + caps = tp_tests_object_new_static_class (TP_TYPE_CAPABILITIES, + "channel-classes", classes, + "contact-specific", FALSE, + NULL); + + g_boxed_free (TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, + classes); + + v = tp_capabilities_dup_channel_classes_variant (caps); + + g_assert (v != NULL); + g_assert_cmpstr (g_variant_get_type_string (v), ==, "a(a{sv}as)"); + + g_assert_cmpuint (g_variant_n_children (v), ==, 2); + + /* Check text chats class */ + class = g_variant_get_child_value (v, 0); + g_assert_cmpstr (g_variant_get_type_string (class), ==, "(a{sv}as)"); + g_assert_cmpuint (g_variant_n_children (class), ==, 2); + + fixed = g_variant_get_child_value (class, 0); + allowed = g_variant_get_child_value (class, 1); + + g_assert_cmpuint (g_variant_n_children (fixed), ==, 2); + + g_assert (g_variant_lookup (fixed, + TP_PROP_CHANNEL_CHANNEL_TYPE, "&s", &chan_type)); + g_assert_cmpstr (chan_type, ==, TP_IFACE_CHANNEL_TYPE_TEXT); + + g_assert (g_variant_lookup (fixed, + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, "u", &handle_type)); + g_assert_cmpuint (handle_type, ==, TP_HANDLE_TYPE_CONTACT); + + g_assert_cmpuint (g_variant_n_children (allowed), ==, 0); + + g_variant_unref (class); + g_variant_unref (fixed); + g_variant_unref (allowed); + + /* Check ft class */ + class = g_variant_get_child_value (v, 1); + g_assert_cmpstr (g_variant_get_type_string (class), ==, "(a{sv}as)"); + g_assert_cmpuint (g_variant_n_children (class), ==, 2); + + fixed = g_variant_get_child_value (class, 0); + allowed = g_variant_get_child_value (class, 1); + + g_assert_cmpuint (g_variant_n_children (fixed), ==, 2); + + g_assert (g_variant_lookup (fixed, + TP_PROP_CHANNEL_CHANNEL_TYPE, "&s", &chan_type)); + g_assert_cmpstr (chan_type, ==, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER); + + g_assert (g_variant_lookup (fixed, + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, "u", &handle_type)); + g_assert_cmpuint (handle_type, ==, TP_HANDLE_TYPE_CONTACT); + + g_assert_cmpuint (g_variant_n_children (allowed), ==, 2); + strv = g_variant_get_strv (allowed, NULL); + g_assert (tp_strv_contains ((const gchar * const * ) strv, + TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME)); + g_assert (tp_strv_contains ((const gchar * const * ) strv, + TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE)); + g_free (strv); + + g_variant_unref (class); + g_variant_unref (fixed); + g_variant_unref (allowed); + + /* Test GObject getter */ + g_object_get (caps, "channel-classes-variant", &v2, NULL); + g_assert (g_variant_equal (v, v2)); + + g_variant_unref (v); + g_variant_unref (v2); + g_object_unref (caps); +} + int main (int argc, char **argv) @@ -982,6 +1076,8 @@ main (int argc, test_supports_sms, NULL); g_test_add (TEST_PREFIX "supports/call", Test, NULL, setup, test_supports_call, NULL); + g_test_add (TEST_PREFIX "classes-variant", Test, NULL, setup, + test_classes_variant, NULL); return g_test_run (); } -- 1.7.7.6