[telepathy-mission-control/telepathy-mission-control-5.2] fd.o#24474: if NewChannels signals Requested channels that we didn't request, observe them but do nothing else
Simon McVittie
simon.mcvittie at collabora.co.uk
Mon Oct 12 06:11:57 PDT 2009
Requested channels that we don't know about must have been requested by
another process (like Empathy 2.28), by calling Connection methods
directly rather than going via MC. As a result, we should not call
AddDispatchOperation or HandleChannels.
However, we do want to call ObserveChannels, to preserve the invariant
that observers are called for *all* channels. This means that observers
can do things like present some simple UI for *every* channel, regardless
of who the handler is.
---
src/mcd-connection.c | 26 +++++++++++++-------------
src/mcd-dispatcher-priv.h | 3 ++-
src/mcd-dispatcher.c | 36 +++++++++++++++++++++++++++++-------
3 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/src/mcd-connection.c b/src/mcd-connection.c
index 442c768..bb7acec 100644
--- a/src/mcd-connection.c
+++ b/src/mcd-connection.c
@@ -535,12 +535,6 @@ on_new_channel (TpConnection *proxy, const gchar *chan_obj_path,
chan_obj_path, chan_type, handle_type, handle,
suppress_handler ? 'T' : 'F');
- /* ignore all our own requests (they have always suppress_handler = 1) as
- * well as other requests for which our intervention has not been requested
- * */
- if (suppress_handler) return;
-
- /* It's an incoming channel, so we create a new McdChannel for it */
if (priv->dispatched_initial_channels)
{
channel = mcd_channel_new_from_path (proxy,
@@ -549,10 +543,16 @@ on_new_channel (TpConnection *proxy, const gchar *chan_obj_path,
if (G_UNLIKELY (!channel)) return;
mcd_operation_take_mission (MCD_OPERATION (connection),
MCD_MISSION (channel));
- /* Dispatch the incoming channel */
+
+ /* MC no longer calls RequestChannel. As a result, if suppress_handler
+ * is TRUE, we know that this channel was requested "behind our back",
+ * therefore we should call ObserveChannels, but refrain from calling
+ * AddDispatchOperation or HandleChannels.
+ *
+ * We assume that channels without suppress_handler are incoming. */
_mcd_dispatcher_take_channels (priv->dispatcher,
g_list_prepend (NULL, channel),
- FALSE);
+ ! suppress_handler, suppress_handler);
}
}
@@ -1193,6 +1193,7 @@ on_new_channels (TpConnection *proxy, const GPtrArray *channels,
McdChannel *channel;
GList *channel_list = NULL;
gboolean requested = FALSE;
+ gboolean only_observe = FALSE;
guint i;
if (DEBUGGING)
@@ -1223,10 +1224,8 @@ on_new_channels (TpConnection *proxy, const GPtrArray *channels,
* FALSE: they'll also be in Channels in the GetAll(Requests) result */
if (!priv->dispatched_initial_channels) return;
- /* first, check if we have to dispatch the channels at all */
- if (!MCD_CONNECTION_GET_CLASS (connection)->need_dispatch (connection,
- channels))
- return;
+ only_observe = ! MCD_CONNECTION_GET_CLASS (connection)->need_dispatch (
+ connection, channels);
sp_timestamp ("NewChannels received");
for (i = 0; i < channels->len; i++)
@@ -1261,7 +1260,8 @@ on_new_channels (TpConnection *proxy, const GPtrArray *channels,
channel_list = g_list_prepend (channel_list, channel);
}
- _mcd_dispatcher_take_channels (priv->dispatcher, channel_list, requested);
+ _mcd_dispatcher_take_channels (priv->dispatcher, channel_list, requested,
+ only_observe);
}
static void
diff --git a/src/mcd-dispatcher-priv.h b/src/mcd-dispatcher-priv.h
index 9b1fc7d..7509d0f 100644
--- a/src/mcd-dispatcher-priv.h
+++ b/src/mcd-dispatcher-priv.h
@@ -46,7 +46,8 @@ G_GNUC_INTERNAL GPtrArray *_mcd_dispatcher_get_channel_enhanced_capabilities (
void _mcd_dispatcher_add_request (McdDispatcher *dispatcher,
McdAccount *account, McdChannel *channel);
G_GNUC_INTERNAL void _mcd_dispatcher_take_channels (
- McdDispatcher *dispatcher, GList *channels, gboolean requested);
+ McdDispatcher *dispatcher, GList *channels, gboolean requested,
+ gboolean only_observe);
G_GNUC_INTERNAL
void _mcd_dispatcher_add_channel_request (McdDispatcher *dispatcher,
McdChannel *channel,
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index f67a054..65af2fc 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -1525,7 +1525,8 @@ static void
_mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher,
GList *channels,
GStrv possible_handlers,
- gboolean requested)
+ gboolean requested,
+ gboolean only_observe)
{
McdDispatcherContext *context;
McdDispatcherPrivate *priv;
@@ -1563,7 +1564,7 @@ _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher,
mcd_channel_get_object_path (context->channels->data));
priv->contexts = g_list_prepend (priv->contexts, context);
- if (!requested)
+ if (!requested && !only_observe)
{
context->operation =
_mcd_dispatch_operation_new (priv->dbus_daemon, channels,
@@ -1591,7 +1592,16 @@ _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher,
context);
}
- if (priv->filters != NULL)
+ if (only_observe)
+ {
+ DEBUG ("Context %p has channels created behind our back, starting "
+ "observers only", context);
+ /* this lock is never released - we specifically don't want to run
+ * Approvers or Handlers */
+ context->client_locks = 1;
+ mcd_dispatcher_run_observers (context);
+ }
+ else if (priv->filters != NULL)
{
DEBUG ("entering state machine for context %p", context);
@@ -3448,7 +3458,7 @@ _mcd_dispatcher_add_request (McdDispatcher *dispatcher, McdAccount *account,
*/
void
_mcd_dispatcher_take_channels (McdDispatcher *dispatcher, GList *channels,
- gboolean requested)
+ gboolean requested, gboolean only_observe)
{
GList *list;
GStrv possible_handlers;
@@ -3465,6 +3475,15 @@ _mcd_dispatcher_take_channels (McdDispatcher *dispatcher, GList *channels,
channels->next == NULL ? "only" : "and more",
mcd_channel_get_object_path (channels->data));
+ if (only_observe)
+ {
+ /* these channels were requested "behind our back", so only call
+ * ObserveChannels on them */
+ _mcd_dispatcher_enter_state_machine (dispatcher, channels, NULL,
+ requested, TRUE);
+ return;
+ }
+
/* See if there are any handlers that can take all these channels */
possible_handlers = mcd_dispatcher_get_possible_handlers (dispatcher,
channels);
@@ -3486,7 +3505,8 @@ _mcd_dispatcher_take_channels (McdDispatcher *dispatcher, GList *channels,
{
list = channels;
channels = g_list_remove_link (channels, list);
- _mcd_dispatcher_take_channels (dispatcher, list, requested);
+ _mcd_dispatcher_take_channels (dispatcher, list, requested,
+ FALSE);
}
}
}
@@ -3499,7 +3519,8 @@ _mcd_dispatcher_take_channels (McdDispatcher *dispatcher, GList *channels,
MCD_CHANNEL_STATUS_DISPATCHING);
_mcd_dispatcher_enter_state_machine (dispatcher, channels,
- possible_handlers, requested);
+ possible_handlers, requested,
+ FALSE);
}
}
@@ -3696,7 +3717,8 @@ _mcd_dispatcher_recover_channel (McdDispatcher *dispatcher,
requested = mcd_channel_is_requested (channel);
_mcd_dispatcher_take_channels (dispatcher,
g_list_prepend (NULL, channel),
- requested);
+ requested,
+ FALSE);
}
}
--
1.5.6.5
More information about the telepathy-commits
mailing list