summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2009-10-12 14:11:57 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2009-10-12 14:34:51 +0100
commit9b10119cc01e9e6cffe7e4cb6dd98dab9c32280a (patch)
treeff7a6ac580801a991e37f8a6f776785389576fcc
parentf8a2f47b410454f77c68cbf9b59ec04ac89d7f1e (diff)
downloadtelepathy-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.c26
-rw-r--r--src/mcd-dispatcher-priv.h3
-rw-r--r--src/mcd-dispatcher.c36
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);
}
}