summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSjoerd Simons <sjoerd.simons@collabora.co.uk>2011-10-20 15:23:50 +0200
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-10-24 16:33:06 +0200
commitf1f4e8bc7f58bb8e4c551bbc0c98674cfa0dc1c7 (patch)
tree301ec193cdc8e58272cab12674a646c7e5fe4eac
parent6bf59dec6b50af267f56eeb7980476919a1dd92d (diff)
Add internal API to get connection capabilities without having core prepared
-rw-r--r--telepathy-glib/connection-internal.h10
-rw-r--r--telepathy-glib/connection.c70
2 files changed, 72 insertions, 8 deletions
diff --git a/telepathy-glib/connection-internal.h b/telepathy-glib/connection-internal.h
index 6e3c3b5b..8df5281b 100644
--- a/telepathy-glib/connection-internal.h
+++ b/telepathy-glib/connection-internal.h
@@ -59,6 +59,7 @@ struct _TpConnectionPrivate {
GHashTable *contacts;
TpCapabilities *capabilities;
+ GQueue capabilities_queue;
TpAvatarRequirements *avatar_requirements;
GArray *avatar_request_queue;
@@ -115,6 +116,15 @@ void _tp_connection_status_reason_to_gerror (TpConnectionStatusReason reason,
const gchar **ret_str,
GError **error);
+/* Internal hook to break potential dependency loop between Connection and
+ * Contacts */
+void _tp_connection_get_capabilities_async (TpConnection *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean _tp_connection_get_capabilities_finish (TpConnection *self,
+ GAsyncResult *result, GError **error);
+
void _tp_connection_add_contact (TpConnection *self, TpHandle handle,
TpContact *contact);
void _tp_connection_remove_contact (TpConnection *self, TpHandle handle,
diff --git a/telepathy-glib/connection.c b/telepathy-glib/connection.c
index 9b08fc3c..62f86a8a 100644
--- a/telepathy-glib/connection.c
+++ b/telepathy-glib/connection.c
@@ -500,7 +500,7 @@ tp_connection_get_rcc_cb (TpProxy *proxy,
GObject *weak_object)
{
TpConnection *self = (TpConnection *) proxy;
- GSimpleAsyncResult *result = user_data;
+ GSimpleAsyncResult *result;
if (error != NULL)
{
@@ -530,12 +530,66 @@ tp_connection_get_rcc_cb (TpProxy *proxy,
FALSE);
finally:
- g_simple_async_result_complete (result);
+ while ((result = g_queue_pop_head (&self->priv->capabilities_queue)) != NULL)
+ {
+ g_simple_async_result_complete (result);
+ g_object_unref (result);
+ }
g_object_notify ((GObject *) self, "capabilities");
}
static void
+_tp_connection_do_get_capabilities_async (TpConnection *self,
+ GSimpleAsyncResult *result)
+{
+ if (self->priv->capabilities != NULL)
+ {
+ /* been there, done that, bored now */
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+ }
+ else
+ {
+ g_queue_push_tail (&self->priv->capabilities_queue, result);
+ if (g_queue_get_length (&self->priv->capabilities_queue) == 1)
+ {
+ DEBUG ("%s: Retrieving capabilities",
+ tp_proxy_get_object_path (self));
+
+ /* We don't check whether we actually have this interface here. The
+ * quark is dbus properties quark is guaranteed to be on every
+ * TpProxy and only very very old CMs won't have Requests, in case
+ * someone still has such a relic we'll we'll just handle it when
+ * they reply to us with an error */
+ tp_cli_dbus_properties_call_get (self, -1,
+ TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
+ "RequestableChannelClasses",
+ tp_connection_get_rcc_cb, NULL, NULL, NULL);
+ }
+ }
+}
+
+void
+_tp_connection_get_capabilities_async (TpConnection *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new ((GObject *) self, callback, user_data,
+ _tp_connection_get_capabilities_async);
+ _tp_connection_do_get_capabilities_async (self, result);
+}
+
+gboolean
+_tp_connection_get_capabilities_finish (TpConnection *self,
+ GAsyncResult *result, GError **error)
+{
+ _tp_implement_finish_void (self, _tp_connection_get_capabilities_async);
+}
+
+static void
tp_connection_prepare_capabilities_async (TpProxy *proxy,
const TpProxyFeature *feature,
GAsyncReadyCallback callback,
@@ -544,14 +598,12 @@ tp_connection_prepare_capabilities_async (TpProxy *proxy,
TpConnection *self = (TpConnection *) proxy;
GSimpleAsyncResult *result;
- result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
- tp_connection_prepare_capabilities_async);
+ DEBUG ("%s: Preparing capabilities", tp_proxy_get_object_path (self));
- g_assert (self->priv->capabilities == NULL);
+ result = g_simple_async_result_new ((GObject *) self, callback, user_data,
+ tp_connection_prepare_capabilities_async);
- tp_cli_dbus_properties_call_get (self, -1,
- TP_IFACE_CONNECTION_INTERFACE_REQUESTS, "RequestableChannelClasses",
- tp_connection_get_rcc_cb, result, g_object_unref, NULL);
+ _tp_connection_do_get_capabilities_async (self, result);
}
static void
@@ -1399,6 +1451,8 @@ tp_connection_init (TpConnection *self)
self->priv->roster = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_object_unref);
self->priv->contacts_changed_queue = g_queue_new ();
+
+ g_queue_init (&self->priv->capabilities_queue);
}
static void