From 211048c145e88b905019f66823748be21541c4b3 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Mon, 23 Apr 2012 16:30:39 +0200 Subject: [PATCH] Add tp_capabilities_get_channel_classes_variant() https://bugs.freedesktop.org/show_bug.cgi?id=30422 --- docs/reference/telepathy-glib-sections.txt | 1 + telepathy-glib/capabilities.c | 75 +++++++++++++++++++++++ telepathy-glib/capabilities.h | 1 + tests/capabilities.c | 88 ++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 0 deletions(-) diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index 0ac3c12..296eeb0 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_get_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..793c200 100644 --- a/telepathy-glib/capabilities.c +++ b/telepathy-glib/capabilities.c @@ -66,12 +66,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,12 +159,36 @@ 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; } } +static GVariant * +create_classes_variant (TpCapabilities *self, + GPtrArray *classes) +{ + GValue v = G_VALUE_INIT; + GVariant *ret; + + g_assert (classes != NULL); + + g_value_init (&v, TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST); + g_value_set_boxed (&v, classes); + + ret = dbus_g_value_build_g_variant (&v); + g_assert (!tp_strdiff (g_variant_get_type_string (ret), "a(a{sv}as)")); + + g_value_unset (&v); + + return g_variant_ref_sink (ret); +} + static void tp_capabilities_set_property (GObject *object, guint property_id, @@ -175,6 +201,8 @@ tp_capabilities_set_property (GObject *object, { case PROP_CHANNEL_CLASSES: self->priv->classes = g_value_dup_boxed (value); + self->priv->classes_variant = create_classes_variant (self, + self->priv->classes); break; case PROP_CONTACT_SPECIFIC: @@ -192,6 +220,7 @@ tp_capabilities_class_init (TpCapabilitiesClass *klass) { GObjectClass *object_class = (GObjectClass *) klass; GParamSpec *param_spec; + GVariantType *variant_type; g_type_class_add_private (klass, sizeof (TpCapabilitiesPrivate)); object_class->get_property = tp_capabilities_get_property; @@ -236,6 +265,35 @@ 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); + + variant_type = g_variant_type_new ("a(a{sv}as)"); + /** + * 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", + variant_type, + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CHANNEL_CLASSES_VARIANT, + param_spec); + + g_variant_type_free (variant_type); } static void @@ -859,3 +917,20 @@ tp_capabilities_supports_room_list (TpCapabilities *self, return result; } + +/** + * tp_capabilities_get_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_get_channel_classes_variant (TpCapabilities *self) +{ + return self->priv->classes_variant; +} diff --git a/telepathy-glib/capabilities.h b/telepathy-glib/capabilities.h index 1d55c1a..82b25af 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_get_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..f514468 100644 --- a/tests/capabilities.c +++ b/tests/capabilities.c @@ -961,6 +961,92 @@ 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, *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_get_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); + + /* 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); + + /* Test GObject getter */ + g_object_get (caps, "channel-classes-variant", &v, NULL); + g_assert (g_variant_equal (v, + tp_capabilities_get_channel_classes_variant (caps))); + g_variant_unref (v); + + g_object_unref (caps); +} + int main (int argc, char **argv) @@ -982,6 +1068,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