]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-dispatcher.c
Merge branch 'sasl'
[empathy.git] / libempathy / empathy-dispatcher.c
index 557d435ec271d34148eaeada33c02a9d9ba8a0c5..5587677510c573640a9931ba95535c5e30bb32a4 100644 (file)
 #include <telepathy-glib/account-manager.h>
 #include <telepathy-glib/enums.h>
 #include <telepathy-glib/connection.h>
-#include <telepathy-glib/channel-dispatcher.h>
-#include <telepathy-glib/channel-request.h>
 #include <telepathy-glib/util.h>
 #include <telepathy-glib/dbus.h>
 #include <telepathy-glib/proxy-subclass.h>
 #include <telepathy-glib/gtypes.h>
 #include <telepathy-glib/defs.h>
-#include <telepathy-glib/svc-client.h>
-#include <telepathy-glib/svc-generic.h>
 #include <telepathy-glib/interfaces.h>
 
 #include <extensions/extensions.h>
@@ -62,19 +58,10 @@ typedef struct
   /* connection to connection data mapping */
   GHashTable *connections;
   GHashTable *outstanding_classes_requests;
-  gpointer token;
 
-  /* channels which the dispatcher is listening "invalidated" */
-  GList *channels;
-  GPtrArray *array;
-
-  GHashTable *request_channel_class_async_ids;
   /* reffed (TpAccount *) => gulong
    * Signal handler ID of the "status-changed" signal */
   GHashTable *status_changed_handlers;
-
-  TpChannelDispatcher *channel_dispatcher;
-  TpDBusDaemon *dbus;
 } EmpathyDispatcherPriv;
 
 G_DEFINE_TYPE (EmpathyDispatcher, empathy_dispatcher, G_TYPE_OBJECT);
@@ -98,9 +85,6 @@ typedef struct
 
 typedef struct
 {
-  /* ObjectPath -> EmpathyDispatchOperations */
-  GHashTable *dispatching_channels;
-
   /* List of requestable channel classes */
   GPtrArray *requestable_channels;
 } ConnectionData;
@@ -119,12 +103,7 @@ typedef struct
 static ConnectionData *
 new_connection_data (void)
 {
-  ConnectionData *cd = g_slice_new0 (ConnectionData);
-
-  cd->dispatching_channels = g_hash_table_new_full (g_str_hash, g_str_equal,
-      g_free, g_object_unref);
-
-  return cd;
+  return g_slice_new0 (ConnectionData);
 }
 
 static void
@@ -132,8 +111,6 @@ free_connection_data (ConnectionData *cd)
 {
   guint i;
 
-  g_hash_table_destroy (cd->dispatching_channels);
-
   if (cd->requestable_channels  != NULL)
     {
       for (i = 0 ; i < cd->requestable_channels->len ; i++)
@@ -181,88 +158,45 @@ dispatcher_connection_invalidated_cb (TpConnection *connection,
 }
 
 static void
-dispatcher_channel_invalidated_cb (TpProxy *proxy,
-                                   guint domain,
-                                   gint code,
-                                   gchar *message,
-                                   EmpathyDispatcher *self)
+got_connection_rcc (EmpathyDispatcher *self,
+    TpConnection *connection)
 {
-  /* Channel went away... */
   EmpathyDispatcherPriv *priv = GET_PRIV (self);
-  TpConnection *connection;
+  TpCapabilities *caps;
   ConnectionData *cd;
-  const gchar *object_path;
-
-  connection = tp_channel_borrow_connection (TP_CHANNEL (proxy));
+  GList *requests, *l;
+  FindChannelRequest *request;
+  GList *retval;
 
-  priv->channels = g_list_remove (priv->channels, proxy);
+  caps = tp_connection_get_capabilities (connection);
+  g_assert (caps != NULL);
 
   cd = g_hash_table_lookup (priv->connections, connection);
-  /* Connection itself invalidated? */
-  if (cd == NULL)
-    return;
-
-  object_path = tp_proxy_get_object_path (proxy);
+  g_assert (cd != NULL);
 
-  DEBUG ("Channel %s invalidated", object_path);
+  cd->requestable_channels = g_boxed_copy (
+    TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST,
+    tp_capabilities_get_channel_classes (caps));
 
-  g_hash_table_remove (cd->dispatching_channels, object_path);
-}
-
-static void
-dispatcher_connection_got_all (TpProxy *proxy,
-                               GHashTable *properties,
-                               const GError *error,
-                               gpointer user_data,
-                               GObject *object)
-{
-  EmpathyDispatcher *self = EMPATHY_DISPATCHER (object);
-  EmpathyDispatcherPriv *priv = GET_PRIV (self);
-  GPtrArray *requestable_channels;
-
-  if (error) {
-    DEBUG ("Error: %s", error->message);
-    return;
-  }
-
-  requestable_channels = tp_asv_get_boxed (properties,
-    "RequestableChannelClasses", TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST);
+  requests = g_hash_table_lookup (priv->outstanding_classes_requests,
+      connection);
 
-  if (requestable_channels == NULL)
-    DEBUG ("No RequestableChannelClasses property !?! on connection");
-  else
+  for (l = requests; l != NULL; l = l->next)
     {
-      ConnectionData *cd;
-      GList *requests, *l;
-      FindChannelRequest *request;
-      GList *retval;
-
-      cd = g_hash_table_lookup (priv->connections, proxy);
-      g_assert (cd != NULL);
-
-      cd->requestable_channels = g_boxed_copy (
-        TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, requestable_channels);
+      request = l->data;
 
-      requests = g_hash_table_lookup (priv->outstanding_classes_requests,
-          proxy);
-
-      for (l = requests; l != NULL; l = l->next)
-        {
-          request = l->data;
-
-          retval = empathy_dispatcher_find_channel_classes (self,
-              TP_CONNECTION (proxy), request->channel_type,
-              request->handle_type, request->properties);
-          request->callback (retval, request->user_data);
+      retval = empathy_dispatcher_find_channel_classes (self,
+          connection, request->channel_type,
+          request->handle_type, request->properties);
+      request->callback (retval, request->user_data);
 
-          free_find_channel_request (request);
-          g_list_free (retval);
-        }
+      free_find_channel_request (request);
+      g_list_free (retval);
+    }
 
-      g_list_free (requests);
+  g_list_free (requests);
 
-      g_hash_table_remove (priv->outstanding_classes_requests, proxy);
-    }
+  g_hash_table_remove (priv->outstanding_classes_requests, connection);
 }
 
 static void
@@ -282,9 +216,7 @@ connection_prepare_cb (GObject *source,
       goto out;
     }
 
-  tp_cli_dbus_properties_call_get_all (connection, -1,
-      TP_IFACE_CONNECTION_INTERFACE_REQUESTS, dispatcher_connection_got_all,
-      NULL, NULL, G_OBJECT (self));
+  got_connection_rcc (self, connection);
 
 out:
   g_object_unref (self);
@@ -296,6 +228,7 @@ dispatcher_init_connection_if_needed (EmpathyDispatcher *self,
 {
   EmpathyDispatcherPriv *priv = GET_PRIV (self);
   GQuark features[] = { TP_CONNECTION_FEATURE_CORE,
+         TP_CONNECTION_FEATURE_CAPABILITIES,
          0 };
 
   if (g_hash_table_lookup (priv->connections, connection) != NULL)
@@ -328,17 +261,6 @@ dispatcher_status_changed_cb (TpAccount *account,
     dispatcher_init_connection_if_needed (self, conn);
 }
 
-static void
-remove_idle_handlers (gpointer key,
-                      gpointer value,
-                      gpointer user_data)
-{
-  guint source_id;
-
-  source_id = GPOINTER_TO_UINT (value);
-  g_source_remove (source_id);
-}
-
 static GObject *
 dispatcher_constructor (GType type,
                         guint n_construct_params,
@@ -383,14 +305,6 @@ dispatcher_dispose (GObject *object)
   g_hash_table_destroy (priv->connections);
   priv->connections = NULL;
 
-  if (priv->channel_dispatcher != NULL)
-    g_object_unref (priv->channel_dispatcher);
-  priv->channel_dispatcher = NULL;
-
-  if (priv->dbus != NULL)
-    g_object_unref (priv->dbus);
-  priv->dbus = NULL;
-
   G_OBJECT_CLASS (empathy_dispatcher_parent_class)->dispose (object);
 }
 
@@ -398,27 +312,11 @@ static void
 dispatcher_finalize (GObject *object)
 {
   EmpathyDispatcherPriv *priv = GET_PRIV (object);
-  GList *l;
   GHashTableIter iter;
   gpointer connection;
   GList *list;
   gpointer account, id;
 
-  if (priv->request_channel_class_async_ids != NULL)
-    {
-      g_hash_table_foreach (priv->request_channel_class_async_ids,
-        remove_idle_handlers, NULL);
-      g_hash_table_destroy (priv->request_channel_class_async_ids);
-    }
-
-  for (l = priv->channels; l; l = l->next)
-    {
-      g_signal_handlers_disconnect_by_func (l->data,
-          dispatcher_channel_invalidated_cb, object);
-    }
-
-  g_list_free (priv->channels);
-
   g_hash_table_iter_init (&iter, priv->outstanding_classes_requests);
   while (g_hash_table_iter_next (&iter, &connection, (gpointer *) &list))
     {
@@ -549,8 +447,6 @@ empathy_dispatcher_init (EmpathyDispatcher *self)
   priv->outstanding_classes_requests = g_hash_table_new_full (g_direct_hash,
     g_direct_equal, g_object_unref, NULL);
 
-  priv->channels = NULL;
-
   tp_account_manager_prepare_async (priv->account_manager, NULL,
       account_manager_prepared_cb, self);
 
@@ -558,13 +454,8 @@ empathy_dispatcher_init (EmpathyDispatcher *self)
       "account-validity-changed", G_CALLBACK (account_validity_changed_cb),
       self, 0);
 
-  priv->request_channel_class_async_ids = g_hash_table_new (g_direct_hash,
-    g_direct_equal);
   priv->status_changed_handlers = g_hash_table_new_full (NULL, NULL,
       (GDestroyNotify) g_object_unref, NULL);
-
-  priv->dbus = tp_dbus_daemon_dup (NULL);
-  priv->channel_dispatcher = tp_channel_dispatcher_new (priv->dbus);
 }
 
 EmpathyDispatcher *
@@ -767,48 +658,6 @@ empathy_dispatcher_find_channel_classes (EmpathyDispatcher *self,
   return matching_classes;
 }
 
-static gboolean
-find_channel_class_idle_cb (gpointer user_data)
-{
-  GList *retval;
-  GList *requests;
-  FindChannelRequest *request = user_data;
-  ConnectionData *cd;
-  gboolean is_ready = TRUE;
-  EmpathyDispatcherPriv *priv = GET_PRIV (request->dispatcher);
-
-  g_hash_table_remove (priv->request_channel_class_async_ids, request);
-
-  cd = g_hash_table_lookup (priv->connections, request->connection);
-
-  if (cd == NULL)
-    is_ready = FALSE;
-  else if (cd->requestable_channels == NULL)
-    is_ready = FALSE;
-
-  if (is_ready)
-    {
-      retval = empathy_dispatcher_find_channel_classes (request->dispatcher,
-          request->connection, request->channel_type, request->handle_type,
-          request->properties);
-
-      request->callback (retval, request->user_data);
-      free_find_channel_request (request);
-      g_list_free (retval);
-
-      return FALSE;
-    }
-
-  requests = g_hash_table_lookup (priv->outstanding_classes_requests,
-      request->connection);
-  requests = g_list_prepend (requests, request);
-
-  g_hash_table_insert (priv->outstanding_classes_requests,
-      request->connection, requests);
-
-  return FALSE;
-}
-
 static GArray *
 setup_varargs (va_list var_args,
                const char *channel_namespace,
@@ -910,64 +759,3 @@ empathy_dispatcher_find_requestable_channel_classes
 
   return retval;
 }
-
-/**
- * empathy_dispatcher_find_requestable_channel_classes_async:
- * @dispatcher: an #EmpathyDispatcher
- * @connection: a #TpConnection
- * @channel_type: a string identifying the type of the channel to lookup
- * @handle_type: the handle type for the channel
- * @callback: the callback to call when @connection is ready
- * @user_data: the user data to pass to @callback
- * @first_property_name: %NULL, or the name of the first fixed property,
- * followed optionally by more names, followed by %NULL.
- *
- * Please see the documentation of
- * empathy_dispatcher_find_requestable_channel_classes() for a detailed
- * description of this function.
- */
-void
-empathy_dispatcher_find_requestable_channel_classes_async
-                                 (EmpathyDispatcher *self,
-                                  TpConnection *connection,
-                                  const gchar *channel_type,
-                                  guint handle_type,
-                                  EmpathyDispatcherFindChannelClassCb callback,
-                                  gpointer user_data,
-                                  const char *first_property_name,
-                                  ...)
-{
-  va_list var_args;
-  GArray *properties;
-  FindChannelRequest *request;
-  EmpathyDispatcherPriv *priv;
-  guint source_id;
-
-  g_return_if_fail (EMPATHY_IS_DISPATCHER (self));
-  g_return_if_fail (TP_IS_CONNECTION (connection));
-  g_return_if_fail (channel_type != NULL);
-  g_return_if_fail (handle_type != 0);
-
-  priv = GET_PRIV (self);
-
-  va_start (var_args, first_property_name);
-
-  properties = setup_varargs (var_args, channel_type, first_property_name);
-
-  va_end (var_args);
-
-  /* append another request for this connection */
-  request = g_slice_new0 (FindChannelRequest);
-  request->dispatcher = g_object_ref (self);
-  request->channel_type = g_strdup (channel_type);
-  request->handle_type = handle_type;
-  request->connection = connection;
-  request->callback = callback;
-  request->user_data = user_data;
-  request->properties = properties;
-
-  source_id = g_idle_add (find_channel_class_idle_cb, request);
-
-  g_hash_table_insert (priv->request_channel_class_async_ids,
-    request, GUINT_TO_POINTER (source_id));
-}