diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2009-10-12 14:11:57 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2009-10-12 14:34:51 +0100 |
commit | 9b10119cc01e9e6cffe7e4cb6dd98dab9c32280a (patch) | |
tree | ff7a6ac580801a991e37f8a6f776785389576fcc | |
parent | f8a2f47b410454f77c68cbf9b59ec04ac89d7f1e (diff) | |
download | telepathy-mission-control-9b10119cc01e9e6cffe7e4cb6dd98dab9c32280a.tar.gz |
fd.o#24474: if NewChannels signals Requested channels that we didn't request, observe them but do nothing else
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.
-rw-r--r-- | src/mcd-connection.c | 26 | ||||
-rw-r--r-- | src/mcd-dispatcher-priv.h | 3 | ||||
-rw-r--r-- | 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 442c7683..bb7acec5 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 9b1fc7df..7509d0f5 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 f67a0545..65af2fc9 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); } } |