summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2014-04-22 11:35:20 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2014-05-07 09:43:47 +0100
commitbdf5c7251f4fc907914d5fef5ab0fe50662a16fa (patch)
tree3ada9029be9f5e51c3a683ba587ea2d8976e205c
parent2941ce2adbc9cc3970328a751f0451f49f32e647 (diff)
downloadtelepathy-glib-bdf5c7251f4fc907914d5fef5ab0fe50662a16fa.tar.gz
TpBaseConnection: allow interfaces to be added in status-changed
This is necessary for Gabble's use of TpBaseContactList: it wants to add the Blocking interface on connections to Google servers (or in principle, servers implementing XEP-0016, XEP-0159, XEP-0161 or XEP-0191, if someone adds a client-side implementation of those). Also delay _tp_gdbus_connection_set_status() until just before we emit StatusChanged on D-Bus, so that we follow this good pattern: * update internal state, so that we will not give contradictory answers if a signal handler calls accessors * emit GLib signals, so that in-process stuff gets a chance to react before we signal changes to D-Bus (for instance, adding interfaces) * finally, update D-Bus properties and emit D-Bus signals Reviewed-by: Xavier Claessens <xavier.claessens@collabora.com> Bug: https://bugs.freedesktop.org/show_bug.cgi?id=77189
-rw-r--r--telepathy-glib/base-connection-internal.h3
-rw-r--r--telepathy-glib/base-connection.c17
2 files changed, 17 insertions, 3 deletions
diff --git a/telepathy-glib/base-connection-internal.h b/telepathy-glib/base-connection-internal.h
index 2062d2b27..aff75abf5 100644
--- a/telepathy-glib/base-connection-internal.h
+++ b/telepathy-glib/base-connection-internal.h
@@ -73,6 +73,9 @@ struct _TpBaseConnectionPrivate
gboolean been_constructed;
/* TRUE if on D-Bus */
gboolean been_registered;
+ /* TRUE if CONNECTED has been signalled to D-Bus, so it's too late to
+ * manipulate the list of interfaces */
+ gboolean been_connected;
/* g_strdup (unique name) => owned ClientData struct */
GHashTable *clients;
diff --git a/telepathy-glib/base-connection.c b/telepathy-glib/base-connection.c
index 76cd50f53..bde77e6a8 100644
--- a/telepathy-glib/base-connection.c
+++ b/telepathy-glib/base-connection.c
@@ -658,7 +658,7 @@ tp_base_connection_interface_changed_cb (TpBaseConnection *self,
g_assert (user_data == INTERFACE_ADDED || user_data == INTERFACE_REMOVED);
- if (self->priv->status == TP_CONNECTION_STATUS_CONNECTED)
+ if (self->priv->been_connected)
{
WARNING ("Adding or removing Connection interfaces after CONNECTED "
"status has been reached is not supported. "
@@ -1810,11 +1810,22 @@ tp_base_connection_change_status (TpBaseConnection *self,
}
DEBUG("emitting status-changed to %u, for reason %u", status, reason);
- _tp_gdbus_connection_set_status (self->priv->connection_skeleton, status);
+
/* Emit status-changed before sending the D-Bus signal, because in practice
* that's what happened in telepathy-glib 0.x, as demonstrated by Gabble's
- * regression tests failing otherwise. */
+ * regression tests failing otherwise. Also, connection manager modules
+ * (in particular the TpBaseContactList) need this opportunity to
+ * staple on additional interfaces when we go CONNECTED. */
g_signal_emit (self, signals[STATUS_CHANGED], 0, status, reason);
+
+ /* Handlers for the status-changed signal is the last possible point at
+ * which we are allowed to add interfaces. Once we've signalled CONNECTED
+ * to D-Bus, it's too late. */
+ if (status == TP_CONNECTION_STATUS_CONNECTED)
+ priv->been_connected = TRUE;
+
+ /* Tell D-Bus what we've done. */
+ _tp_gdbus_connection_set_status (self->priv->connection_skeleton, status);
_tp_gdbus_connection_emit_status_changed (self->priv->connection_skeleton,
status, reason);