summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-10-24 16:42:51 +0200
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-10-24 16:42:51 +0200
commit54ac9a23387546370652f5c81d2f735d1e294596 (patch)
treef0da3f27db3254dcf007350a16d66c1f8912c0e3
parentde32456d8d460b427ab26c489c142a41319d2023 (diff)
parent60615777a80c190a270e270b1b3972e367ad7dfd (diff)
Merge branch 'telepathy-glib-0.16'
-rw-r--r--telepathy-glib/account-manager.c5
-rw-r--r--telepathy-glib/connection-internal.h12
-rw-r--r--telepathy-glib/connection.c77
-rw-r--r--telepathy-glib/contact.c41
-rw-r--r--tests/lib/contacts-conn.c5
5 files changed, 108 insertions, 32 deletions
diff --git a/telepathy-glib/account-manager.c b/telepathy-glib/account-manager.c
index 107caf17..447f4185 100644
--- a/telepathy-glib/account-manager.c
+++ b/telepathy-glib/account-manager.c
@@ -371,6 +371,8 @@ _tp_account_manager_check_core_ready (TpAccountManager *manager)
{
TpAccountManagerPrivate *priv = manager->priv;
+ DEBUG ("manager has %d accounts left to prepare",
+ priv->n_preparing_accounts);
if (tp_proxy_is_prepared (manager, TP_ACCOUNT_MANAGER_FEATURE_CORE))
return;
@@ -416,6 +418,9 @@ account_prepared_cb (GObject *object,
insert_account (self, account);
}
+ DEBUG ("Account %s was prepared",
+ tp_proxy_get_object_path (object));
+
OUT:
self->priv->n_preparing_accounts--;
_tp_account_manager_check_core_ready (self);
diff --git a/telepathy-glib/connection-internal.h b/telepathy-glib/connection-internal.h
index 6e3c3b5b..cd9a53f9 100644
--- a/telepathy-glib/connection-internal.h
+++ b/telepathy-glib/connection-internal.h
@@ -59,6 +59,9 @@ struct _TpConnectionPrivate {
GHashTable *contacts;
TpCapabilities *capabilities;
+ /* Queue of owned GSimpleAsyncResult, each result being a pending call
+ * started using _tp_connection_do_get_capabilities_async */
+ GQueue capabilities_queue;
TpAvatarRequirements *avatar_requirements;
GArray *avatar_request_queue;
@@ -115,6 +118,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 faf86cdd..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
@@ -559,7 +611,8 @@ signal_connected (TpConnection *self)
{
/* we shouldn't have gone to status CONNECTED for any reason
* that isn't REQUESTED :-) */
- DEBUG ("%p: CORE and CONNECTED ready", self);
+ DEBUG ("%s (%p): CORE and CONNECTED ready",
+ tp_proxy_get_object_path (self), self);
self->priv->status = TP_CONNECTION_STATUS_CONNECTED;
self->priv->status_reason = TP_CONNECTION_STATUS_REASON_REQUESTED;
self->priv->ready = TRUE;
@@ -1360,6 +1413,8 @@ tp_connection_constructed (GObject *object)
if (object_class->constructed != NULL)
object_class->constructed (object);
+ DEBUG ("%s (%p) constructed", tp_proxy_get_object_path (object), object);
+
_tp_proxy_ensure_factory (self, NULL);
/* Connect to my own StatusChanged signal.
@@ -1383,8 +1438,6 @@ tp_connection_constructed (GObject *object)
static void
tp_connection_init (TpConnection *self)
{
- DEBUG ("%p", self);
-
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TYPE_CONNECTION,
TpConnectionPrivate);
@@ -1398,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
diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c
index 2be525b5..70c0100a 100644
--- a/telepathy-glib/contact.c
+++ b/telepathy-glib/contact.c
@@ -2487,38 +2487,38 @@ set_conn_capabilities_on_contacts (GPtrArray *contacts,
TpConnection *connection)
{
guint i;
+ TpCapabilities *conn_caps = tp_connection_get_capabilities (connection);
+ GPtrArray *rcc;
+
+ /* If the connection has no capabilities then don't bother setting them on
+ * the contact and pretend we just don't know.. In practise this will only
+ * happen if there was an error in getting the connections capabilities so
+ * claiming ignorance seems the most sensible thing to do */
+ if (conn_caps == NULL)
+ return;
+
+ rcc = tp_capabilities_get_channel_classes (conn_caps);
+ if (rcc == NULL || rcc->len == 0)
+ return;
for (i = 0; i < contacts->len; i++)
{
TpContact *contact = g_ptr_array_index (contacts, i);
- contact_set_capabilities (contact, tp_connection_get_capabilities (
- connection));
+ contact_set_capabilities (contact, conn_caps);
}
}
static void
-connection_capabilities_prepare_cb (GObject *object,
+connection_capabilities_fetched_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
- GError *error = NULL;
ContactsContext *c = user_data;
- if (!tp_proxy_prepare_finish (object, res, &error))
- {
- DEBUG ("Failed to prepare Connection capabilities feature: %s %u: %s",
- g_quark_to_string (error->domain), error->code, error->message);
- }
- else if (!tp_proxy_is_prepared (object, TP_CONNECTION_FEATURE_CAPABILITIES))
- {
- DEBUG ("Connection capabilities feature has not been actually prepared");
- }
- else
- {
- set_conn_capabilities_on_contacts (c->contacts, c->connection);
- }
+ DEBUG ("Connection capabilities prepared");
+ set_conn_capabilities_on_contacts (c->contacts, c->connection);
contacts_context_continue (c);
contacts_context_unref (c);
}
@@ -2526,12 +2526,13 @@ connection_capabilities_prepare_cb (GObject *object,
static void
contacts_get_conn_capabilities (ContactsContext *c)
{
- GQuark features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 };
g_assert (c->handles->len == c->contacts->len);
+ DEBUG ("Getting connection capabilities");
+
c->refcount++;
- tp_proxy_prepare_async (c->connection, features,
- connection_capabilities_prepare_cb, c);
+ _tp_connection_get_capabilities_async (c->connection,
+ connection_capabilities_fetched_cb, c);
}
static void
diff --git a/tests/lib/contacts-conn.c b/tests/lib/contacts-conn.c
index 82eb2321..1d1b5ee1 100644
--- a/tests/lib/contacts-conn.c
+++ b/tests/lib/contacts-conn.c
@@ -362,6 +362,7 @@ client_types_fill_contact_attributes (
static void
constructed (GObject *object)
{
+ TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
TpBaseConnection *base = TP_BASE_CONNECTION (object);
void (*parent_impl) (GObject *) =
G_OBJECT_CLASS (tp_tests_contacts_connection_parent_class)->constructed;
@@ -372,7 +373,8 @@ constructed (GObject *object)
tp_contacts_mixin_init (object,
G_STRUCT_OFFSET (TpTestsContactsConnection, contacts_mixin));
tp_base_connection_register_with_contacts_mixin (base);
- tp_base_contact_list_mixin_register_with_contacts_mixin (base);
+ if (self->priv->list_manager)
+ tp_base_contact_list_mixin_register_with_contacts_mixin (base);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
aliasing_fill_contact_attributes);
@@ -1346,4 +1348,5 @@ tp_tests_no_requests_connection_class_init (
(TpBaseConnectionClass *) klass;
base_class->interfaces_always_present = interfaces_always_present;
+ base_class->create_channel_managers = NULL;
}