summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-11-03 11:48:10 (GMT)
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-11-04 14:08:39 (GMT)
commit45b8e51b72b95646ad855807d0b0f9d89737edf1 (patch)
treed1cb868bd2228a633e458253f595e24ed0eeeca4
parent252e1801e2f781a0ec8f3732a878fa87cef8402f (diff)
downloadtelepathy-glib-45b8e51b72b95646ad855807d0b0f9d89737edf1.tar.gz
telepathy-glib-45b8e51b72b95646ad855807d0b0f9d89737edf1.tar.xz
Add TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES
This feature is now a dependency on TP_CONNECTION_FEATURE_CONTACT_LIST so it will be automatically prepared when preparing TP_CONNECTION_FEATURE_CONTACT_LIST (so we don't break existing code) https://bugs.freedesktop.org/show_bug.cgi?id=42546
-rw-r--r--docs/reference/telepathy-glib-sections.txt2
-rw-r--r--telepathy-glib/connection-contact-list.c63
-rw-r--r--telepathy-glib/connection-contact-list.h4
-rw-r--r--telepathy-glib/connection-internal.h4
-rw-r--r--telepathy-glib/connection.c24
-rw-r--r--tests/dbus/contact-list-client.c34
6 files changed, 115 insertions, 16 deletions
diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index c1dd7f1..4b9345d 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -3605,6 +3605,7 @@ TP_CONNECTION_FEATURE_AVATAR_REQUIREMENTS
TP_CONNECTION_FEATURE_CONTACT_INFO
TP_CONNECTION_FEATURE_BALANCE
TP_CONNECTION_FEATURE_CONTACT_LIST
+TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES
TP_CONNECTION_FEATURE_CONTACT_GROUPS
TP_CONNECTION_FEATURE_CONTACT_BLOCKING
tp_connection_run_until_ready
@@ -3664,6 +3665,7 @@ tp_connection_get_feature_quark_avatar_requirements
tp_connection_get_feature_quark_contact_info
tp_connection_get_feature_quark_balance
tp_connection_get_feature_quark_contact_list
+tp_connection_get_feature_quark_contact_list_properties
tp_connection_get_feature_quark_contact_groups
tp_connection_get_feature_quark_contact_blocking
<SUBSECTION avatar-requirements>
diff --git a/telepathy-glib/connection-contact-list.c b/telepathy-glib/connection-contact-list.c
index 59b5b04..6e3a3e5 100644
--- a/telepathy-glib/connection-contact-list.c
+++ b/telepathy-glib/connection-contact-list.c
@@ -335,7 +335,8 @@ contact_list_state_changed_cb (TpConnection *self,
DEBUG ("contact list state changed: %d", state);
/* If state goes to success, delay notification until roster is ready */
- if (state == TP_CONTACT_LIST_STATE_SUCCESS)
+ if (state == TP_CONTACT_LIST_STATE_SUCCESS &&
+ tp_proxy_is_prepared (self, TP_CONNECTION_FEATURE_CONTACT_LIST))
{
prepare_roster (self, NULL);
return;
@@ -346,7 +347,7 @@ contact_list_state_changed_cb (TpConnection *self,
}
static void
-prepare_contact_list_cb (TpProxy *proxy,
+prepare_contact_list_props_cb (TpProxy *proxy,
GHashTable *properties,
const GError *error,
gpointer user_data,
@@ -400,6 +401,21 @@ prepare_contact_list_cb (TpProxy *proxy,
DEBUG ("Got contact list properties; state=%d",
self->priv->contact_list_state);
+OUT:
+ g_simple_async_result_complete (result);
+}
+
+void _tp_connection_prepare_contact_list_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TpConnection *self = (TpConnection *) proxy;
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new ((GObject *) self, callback, user_data,
+ _tp_connection_prepare_contact_list_async);
+
/* If the CM has the contact list, prepare it right away */
if (self->priv->contact_list_state == TP_CONTACT_LIST_STATE_SUCCESS)
{
@@ -407,11 +423,15 @@ prepare_contact_list_cb (TpProxy *proxy,
return;
}
-OUT:
- g_simple_async_result_complete (result);
+ /* Contacts will be prepared once the CM has fetched the contact list from
+ * the server.
+ * Complete the preparation as it's not supposed to wait for the contact
+ * list. */
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
}
-void _tp_connection_prepare_contact_list_async (TpProxy *proxy,
+void _tp_connection_prepare_contact_list_props_async (TpProxy *proxy,
const TpProxyFeature *feature,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -423,11 +443,11 @@ void _tp_connection_prepare_contact_list_async (TpProxy *proxy,
(self, contact_list_state_changed_cb, NULL, NULL, NULL, NULL);
result = g_simple_async_result_new ((GObject *) self, callback, user_data,
- _tp_connection_prepare_contact_list_async);
+ _tp_connection_prepare_contact_list_props_async);
tp_cli_dbus_properties_call_get_all (self, -1,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST,
- prepare_contact_list_cb, result, g_object_unref, NULL);
+ prepare_contact_list_props_cb, result, g_object_unref, NULL);
}
static void
@@ -625,8 +645,10 @@ _tp_connection_prepare_contact_groups_async (TpProxy *proxy,
* Expands to a call to a function that returns a #GQuark representing the
* "contact-list" feature.
*
- * When this feature is prepared, the contact list properties of the Connection
- * has been retrieved. If #TpConnection:contact-list-state is
+ * When this feature is prepared, the
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES has been prepared, so the
+ * contact list properties of the Connection has been retrieved.
+ * If #TpConnection:contact-list-state is
* %TP_CONTACT_LIST_STATE_SUCCESS, all #TpContact objects will also be created
* and prepared with the desired features. See tp_connection_dup_contact_list()
* to get the list of contacts, and
@@ -1917,3 +1939,26 @@ _tp_connection_blocked_changed_queue_free (GQueue *queue)
g_queue_foreach (queue, (GFunc) blocked_changed_item_free, NULL);
g_queue_free (queue);
}
+
+/**
+ * TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES:
+ *
+ * Expands to a call to a function that returns a #GQuark representing the
+ * "contact-list-properties" feature.
+ *
+ * When this feature is prepared, the contact list properties of the Connection
+ * has been retrieved.
+ * This feature will fail to prepare when using obsolete Telepathy connection
+ * managers which do not implement the ContactList interface.
+ *
+ * One can ask for a feature to be prepared using the
+ * tp_proxy_prepare_async() function, and waiting for it to callback.
+ *
+ * Since: 0.UNRELEASED
+ */
+GQuark
+tp_connection_get_feature_quark_contact_list_properties (void)
+{
+ return g_quark_from_static_string (
+ "tp-connection-feature-contact-list-properties");
+}
diff --git a/telepathy-glib/connection-contact-list.h b/telepathy-glib/connection-contact-list.h
index d04ba45..ec3ee5c 100644
--- a/telepathy-glib/connection-contact-list.h
+++ b/telepathy-glib/connection-contact-list.h
@@ -31,6 +31,10 @@ G_BEGIN_DECLS
(tp_connection_get_feature_quark_contact_list ())
GQuark tp_connection_get_feature_quark_contact_list (void) G_GNUC_CONST;
+#define TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES \
+ (tp_connection_get_feature_quark_contact_list_properties ())
+GQuark tp_connection_get_feature_quark_contact_list_properties (void) G_GNUC_CONST;
+
TpContactListState tp_connection_get_contact_list_state (TpConnection *self);
gboolean tp_connection_get_contact_list_persists (TpConnection *self);
gboolean tp_connection_get_can_change_contact_list (TpConnection *self);
diff --git a/telepathy-glib/connection-internal.h b/telepathy-glib/connection-internal.h
index e346c2b..5b48c8f 100644
--- a/telepathy-glib/connection-internal.h
+++ b/telepathy-glib/connection-internal.h
@@ -166,6 +166,10 @@ void _tp_connection_prepare_contact_list_async (TpProxy *proxy,
const TpProxyFeature *feature,
GAsyncReadyCallback callback,
gpointer user_data);
+void _tp_connection_prepare_contact_list_props_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
void _tp_connection_prepare_contact_groups_async (TpProxy *proxy,
const TpProxyFeature *feature,
GAsyncReadyCallback callback,
diff --git a/telepathy-glib/connection.c b/telepathy-glib/connection.c
index 82220e4..dbbe24a 100644
--- a/telepathy-glib/connection.c
+++ b/telepathy-glib/connection.c
@@ -1608,6 +1608,7 @@ enum {
FEAT_CONTACT_INFO,
FEAT_BALANCE,
FEAT_CONTACT_LIST,
+ FEAT_CONTACT_LIST_PROPS,
FEAT_CONTACT_GROUPS,
FEAT_CONTACT_BLOCKING,
N_FEAT
@@ -1624,6 +1625,7 @@ tp_connection_list_features (TpProxyClass *cls G_GNUC_UNUSED)
static GQuark need_contact_list[3] = {0, 0, 0};
static GQuark need_contact_groups[2] = {0, 0};
static GQuark need_contact_blocking[2] = {0, 0};
+ static GQuark depends_contact_list[2] = {0, 0};
if (G_LIKELY (features[0].name != 0))
return features;
@@ -1661,6 +1663,12 @@ tp_connection_list_features (TpProxyClass *cls G_GNUC_UNUSED)
need_contact_list[0] = TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_LIST;
need_contact_list[1] = TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACTS;
features[FEAT_CONTACT_LIST].interfaces_needed = need_contact_list;
+ depends_contact_list[0] = TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES;
+ features[FEAT_CONTACT_LIST].depends_on = depends_contact_list;
+
+ features[FEAT_CONTACT_LIST_PROPS].name = TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES;
+ features[FEAT_CONTACT_LIST_PROPS].prepare_async = _tp_connection_prepare_contact_list_props_async;
+ features[FEAT_CONTACT_LIST_PROPS].interfaces_needed = need_contact_list;
features[FEAT_CONTACT_GROUPS].name = TP_CONNECTION_FEATURE_CONTACT_GROUPS;
features[FEAT_CONTACT_GROUPS].prepare_async = _tp_connection_prepare_contact_groups_async;
@@ -1950,7 +1958,9 @@ tp_connection_class_init (TpConnectionClass *klass)
* The progress made in retrieving the contact list.
*
* For this property to be valid, you must first call
- * tp_proxy_prepare_async() with the feature %TP_CONNECTION_FEATURE_CONTACT_LIST.
+ * tp_proxy_prepare_async() with the feature
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES or
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST.
*
* Since: 0.15.5
*/
@@ -1970,7 +1980,9 @@ tp_connection_class_init (TpConnectionClass *klass)
* If false, presence subscriptions on this connection are not stored.
*
* For this property to be valid, you must first call
- * tp_proxy_prepare_async() with the feature %TP_CONNECTION_FEATURE_CONTACT_LIST.
+ * tp_proxy_prepare_async() with the feature
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES or
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST.
*
* Since: 0.15.5
*/
@@ -1991,7 +2003,9 @@ tp_connection_class_init (TpConnectionClass *klass)
* the local subnet, so the user cannot control their presence publication.
*
* For this property to be valid, you must first call
- * tp_proxy_prepare_async() with the feature %TP_CONNECTION_FEATURE_CONTACT_LIST.
+ * tp_proxy_prepare_async() with the feature
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES or
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST.
*
* Since: 0.15.5
*/
@@ -2012,7 +2026,9 @@ tp_connection_class_init (TpConnectionClass *klass)
* suitable default.
*
* For this property to be valid, you must first call
- * tp_proxy_prepare_async() with the feature %TP_CONNECTION_FEATURE_CONTACT_LIST.
+ * tp_proxy_prepare_async() with the feature
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES or
+ * %TP_CONNECTION_FEATURE_CONTACT_LIST.
*
* Since: 0.15.5
*/
diff --git a/tests/dbus/contact-list-client.c b/tests/dbus/contact-list-client.c
index 6f2d5ff..f9eeb6c 100644
--- a/tests/dbus/contact-list-client.c
+++ b/tests/dbus/contact-list-client.c
@@ -507,11 +507,20 @@ static void
test_contact_list_properties (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- GQuark conn_features[] = { TP_CONNECTION_FEATURE_CONTACT_LIST, 0 };
+ gboolean props_only = GPOINTER_TO_UINT (data);
+ GQuark conn_features[] = { 0, 0 };
+ GPtrArray *contacts;
+
+ if (props_only)
+ conn_features[0] = TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES;
+ else
+ conn_features[0] = TP_CONNECTION_FEATURE_CONTACT_LIST;
/* Feature isn't prepared yet */
g_assert (!tp_proxy_is_prepared (test->connection,
TP_CONNECTION_FEATURE_CONTACT_LIST));
+ g_assert (!tp_proxy_is_prepared (test->connection,
+ TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES));
g_assert_cmpuint (tp_connection_get_contact_list_state (test->connection), ==,
TP_CONTACT_LIST_STATE_NONE);
@@ -526,9 +535,26 @@ test_contact_list_properties (Test *test,
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
+ g_assert (tp_proxy_is_prepared (test->connection,
+ TP_CONNECTION_FEATURE_CONTACT_LIST) == !props_only);
+ g_assert (tp_proxy_is_prepared (test->connection,
+ TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES));
+
g_assert (tp_connection_get_contact_list_persists (test->connection));
g_assert (tp_connection_get_can_change_contact_list (test->connection));
g_assert (tp_connection_get_request_uses_message (test->connection));
+
+ contacts = tp_connection_dup_contact_list (test->connection);
+ if (props_only)
+ {
+ /* Contacts haven't be fetched */
+ g_assert_cmpuint (contacts->len, ==, 0);
+ }
+ else
+ {
+ g_assert_cmpuint (contacts->len, >, 0);
+ }
+ g_ptr_array_unref (contacts);
}
int
@@ -549,8 +575,10 @@ main (int argc,
g_test_add ("/contact-list-client/blocking/is-blocked", Test, NULL,
setup, test_is_blocked, teardown);
- g_test_add ("/contact-list-client/contact-list/properties", Test, NULL,
- setup, test_contact_list_properties, teardown);
+ g_test_add ("/contact-list-client/contact-list/properties", Test,
+ GUINT_TO_POINTER (FALSE), setup, test_contact_list_properties, teardown);
+ g_test_add ("/contact-list-client/contact-list/properties", Test,
+ GUINT_TO_POINTER (TRUE), setup, test_contact_list_properties, teardown);
return g_test_run ();
}