[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