[empathy/mc5: 47/483] Implement a first minimal version of a Client.Handler



commit db59070855af10bc2ac8ac7355f80a27f6f91d3d
Author: Sjoerd Simons <sjoerd simons collabora co uk>
Date:   Fri Jul 10 11:51:39 2009 +0100

    Implement a first minimal version of a Client.Handler

 libempathy/empathy-dispatcher.c |  290 +++++++++++++++++++++++----------------
 libempathy/empathy-dispatcher.h |    2 +
 2 files changed, 176 insertions(+), 116 deletions(-)
---
diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c
index 8618be6..721d398 100644
--- a/libempathy/empathy-dispatcher.c
+++ b/libempathy/empathy-dispatcher.c
@@ -19,6 +19,9 @@
  *          Cosimo Cecchi <cosimo cecchi collabora co uk>
  */
 
+#define DISPATCHER_BUS_NAME TP_CLIENT_BUS_NAME_BASE "Empathy"
+#define DISPATCHER_OBJECT_PATH TP_CLIENT_OBJECT_PATH_BASE "Empathy"
+
 #include <config.h>
 
 #include <string.h>
@@ -31,6 +34,9 @@
 #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 <extensions/extensions.h>
 
@@ -62,7 +68,29 @@ typedef struct
   GHashTable *request_channel_class_async_ids;
 } EmpathyDispatcherPriv;
 
-G_DEFINE_TYPE (EmpathyDispatcher, empathy_dispatcher, G_TYPE_OBJECT);
+static void empathy_dispatcher_client_handler_iface_init (gpointer g_iface,
+  gpointer g_iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (EmpathyDispatcher,
+    empathy_dispatcher,
+    G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+      tp_dbus_properties_mixin_iface_init);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT, NULL);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT_HANDLER,
+      empathy_dispatcher_client_handler_iface_init);
+  );
+
+static const gchar *empathy_displatcher_interfaces[] = {
+  TP_IFACE_CLIENT_HANDLER,
+  NULL
+};
+
+enum
+{
+  PROP_INTERFACES = 1,
+  PROP_CHANNEL_FILTER,
+};
 
 enum
 {
@@ -636,30 +664,11 @@ dispatcher_connection_new_channel (EmpathyDispatcher *dispatcher,
 }
 
 static void
-dispatcher_connection_new_channel_cb (TpConnection *connection,
-                                      const gchar *object_path,
-                                      const gchar  *channel_type,
-                                      guint handle_type,
-                                      guint handle,
-                                      gboolean suppress_handler,
-                                      gpointer user_data,
-                                      GObject *object)
-{
-  EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (object);
-
-  /* Empathy heavily abuses surpress handler (don't try this at home), if
-   * surpress handler is true then it is an outgoing channel, which is
-   * requested either by us or some other party (like the megaphone applet).
-   * Otherwise it's an incoming channel */
-  dispatcher_connection_new_channel (dispatcher, connection,
-    object_path, channel_type, handle_type, handle, NULL, !suppress_handler);
-}
-
-static void
-dispatcher_connection_new_channel_with_properties (EmpathyDispatcher *dispatcher,
-                                                   TpConnection *connection,
-                                                   const gchar *object_path,
-                                                   GHashTable *properties)
+dispatcher_connection_new_channel_with_properties (
+    EmpathyDispatcher *dispatcher,
+    TpConnection *connection,
+    const gchar *object_path,
+    GHashTable *properties)
 {
   const gchar *channel_type;
   guint handle_type;
@@ -707,29 +716,6 @@ dispatcher_connection_new_channel_with_properties (EmpathyDispatcher *dispatcher
 }
 
 static void
-dispatcher_connection_new_channels_cb (TpConnection *connection,
-                                       const GPtrArray *channels,
-                                       gpointer user_data,
-                                       GObject *object)
-{
-  EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (object);
-  int i;
-
-  for (i = 0; i < channels->len ; i++)
-    {
-      GValueArray *arr = g_ptr_array_index (channels, i);
-      const gchar *object_path;
-      GHashTable *properties;
-
-      object_path = g_value_get_boxed (g_value_array_get_nth (arr, 0));
-      properties = g_value_get_boxed (g_value_array_get_nth (arr, 1));
-
-      dispatcher_connection_new_channel_with_properties (dispatcher,
-        connection, object_path, properties);
-    }
-}
-
-static void
 dispatcher_connection_got_all (TpProxy *proxy,
                                GHashTable *properties,
                                const GError *error,
@@ -738,7 +724,6 @@ dispatcher_connection_got_all (TpProxy *proxy,
 {
   EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (object);
   EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher);
-  GPtrArray *channels;
   GPtrArray *requestable_channels;
 
   if (error) {
@@ -746,15 +731,6 @@ dispatcher_connection_got_all (TpProxy *proxy,
     return;
   }
 
-  channels = tp_asv_get_boxed (properties, "Channels",
-    TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST);
-
-  if (channels == NULL)
-    DEBUG ("No Channels property !?! on connection");
-  else
-    dispatcher_connection_new_channels_cb (TP_CONNECTION (proxy),
-      channels, NULL, object);
-
   requestable_channels = tp_asv_get_boxed (properties,
     "RequestableChannelClasses", TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST);
 
@@ -796,38 +772,6 @@ dispatcher_connection_got_all (TpProxy *proxy,
 }
 
 static void
-dispatcher_connection_list_channels_cb (TpConnection    *connection,
-                                        const GPtrArray *channels,
-                                        const GError    *error,
-                                        gpointer         user_data,
-                                        GObject         *dispatcher)
-{
-  int i;
-
-  if (error)
-    {
-      DEBUG ("Error: %s", error->message);
-      return;
-    }
-
-  for (i = 0; i < channels->len; i++)
-    {
-      GValueArray *values;
-
-      values = g_ptr_array_index (channels, i);
-      /* We don't have any extra info, so assume already existing channels are
-       * incoming... */
-      dispatcher_connection_new_channel (EMPATHY_DISPATCHER (dispatcher),
-        connection,
-        g_value_get_boxed (g_value_array_get_nth (values, 0)),
-        g_value_get_string (g_value_array_get_nth (values, 1)),
-        g_value_get_uint (g_value_array_get_nth (values, 2)),
-        g_value_get_uint (g_value_array_get_nth (values, 3)),
-        NULL, TRUE);
-    }
-}
-
-static void
 dispatcher_connection_advertise_capabilities_cb (TpConnection    *connection,
                                                  const GPtrArray *capabilities,
                                                  const GError    *error,
@@ -861,26 +805,11 @@ dispatcher_new_connection_cb (EmpathyAccountManager *manager,
   if (tp_proxy_has_interface_by_id (TP_PROXY (connection),
       TP_IFACE_QUARK_CONNECTION_INTERFACE_REQUESTS))
     {
-      tp_cli_connection_interface_requests_connect_to_new_channels (connection,
-        dispatcher_connection_new_channels_cb,
-        NULL, NULL, G_OBJECT (dispatcher), NULL);
-
       tp_cli_dbus_properties_call_get_all (connection, -1,
         TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
         dispatcher_connection_got_all,
         NULL, NULL, G_OBJECT (dispatcher));
     }
-  else
-    {
-      tp_cli_connection_connect_to_new_channel (connection,
-        dispatcher_connection_new_channel_cb,
-        NULL, NULL, G_OBJECT (dispatcher), NULL);
-
-      tp_cli_connection_call_list_channels (connection, -1,
-        dispatcher_connection_list_channels_cb, NULL, NULL,
-        G_OBJECT (dispatcher));
-
-    }
 
   /* Advertise VoIP capabilities */
   capabilities = g_ptr_array_sized_new (1);
@@ -922,19 +851,25 @@ dispatcher_constructor (GType type,
                         GObjectConstructParam *construct_params)
 {
   GObject *retval;
+  TpDBusDaemon *dbus;
 
-  if (dispatcher == NULL)
-    {
-      retval = G_OBJECT_CLASS (empathy_dispatcher_parent_class)->constructor
-          (type, n_construct_params, construct_params);
+  if (dispatcher != NULL)
+    return g_object_ref (dispatcher);
 
-      dispatcher = EMPATHY_DISPATCHER (retval);
-      g_object_add_weak_pointer (retval, (gpointer) &dispatcher);
-    }
-  else
-    {
-      retval = g_object_ref (dispatcher);
-    }
+  retval = G_OBJECT_CLASS (empathy_dispatcher_parent_class)->constructor
+    (type, n_construct_params, construct_params);
+
+  dispatcher = EMPATHY_DISPATCHER (retval);
+  g_object_add_weak_pointer (retval, (gpointer) &dispatcher);
+
+  dbus = tp_dbus_daemon_dup (NULL);
+
+  g_assert (tp_dbus_daemon_request_name (dbus,
+    DISPATCHER_BUS_NAME, TRUE, NULL));
+  dbus_g_connection_register_g_object (tp_get_bus (),
+    DISPATCHER_OBJECT_PATH, retval);
+
+  DEBUG ("Registering at '%s'", DISPATCHER_OBJECT_PATH);
 
   return retval;
 }
@@ -988,13 +923,78 @@ dispatcher_finalize (GObject *object)
 }
 
 static void
+dispatcher_get_property (GObject *object,
+  guint property_id,
+  GValue *value,
+  GParamSpec *pspec)
+{
+  switch (property_id)
+    {
+      case PROP_INTERFACES:
+        g_value_set_boxed (value, empathy_displatcher_interfaces);
+        break;
+      case PROP_CHANNEL_FILTER:
+        {
+          GPtrArray *filters = g_ptr_array_new ();
+          GHashTable *filter = g_hash_table_new (NULL, NULL);
+
+          g_ptr_array_add (filters, filter);
+
+          g_value_set_boxed (value, filters);
+          break;
+        }
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+    }
+}
+
+static void
 empathy_dispatcher_class_init (EmpathyDispatcherClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GParamSpec *param_spec;
+
+  static TpDBusPropertiesMixinPropImpl client_props[] = {
+    { "Interfaces", "interfaces", NULL },
+    { NULL }
+  };
+  static TpDBusPropertiesMixinPropImpl client_handler_props[] = {
+    { "HandlerChannelFilter", "channel-filter", NULL },
+    { NULL }
+  };
+  static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+    { TP_IFACE_CLIENT,
+      tp_dbus_properties_mixin_getter_gobject_properties,
+      NULL,
+      client_props
+    },
+    { TP_IFACE_CLIENT_HANDLER,
+      tp_dbus_properties_mixin_getter_gobject_properties,
+      NULL,
+      client_handler_props
+    },
+    { NULL }
+  };
 
   object_class->finalize = dispatcher_finalize;
   object_class->constructor = dispatcher_constructor;
 
+  object_class->get_property = dispatcher_get_property;
+
+  param_spec = g_param_spec_boxed ("interfaces", "interfaces",
+    "Available D-Bus interfaces",
+    G_TYPE_STRV,
+    G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
+
+  param_spec = g_param_spec_boxed ("channel-filter", "channel-filter",
+    "Filter for channels this handles",
+    TP_ARRAY_TYPE_CHANNEL_CLASS_LIST,
+    G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class,
+    PROP_CHANNEL_FILTER, param_spec);
+
   signals[OBSERVE] =
     g_signal_new ("observe",
       G_TYPE_FROM_CLASS (klass),
@@ -1025,8 +1025,13 @@ empathy_dispatcher_class_init (EmpathyDispatcherClass *klass)
       G_TYPE_NONE,
       1, EMPATHY_TYPE_DISPATCH_OPERATION);
 
+
   g_type_class_add_private (object_class, sizeof (EmpathyDispatcherPriv));
 
+
+  klass->dbus_props_class.interfaces = prop_interfaces;
+  tp_dbus_properties_mixin_class_init (object_class,
+    G_STRUCT_OFFSET (EmpathyDispatcherClass, dbus_props_class));
 }
 
 static void
@@ -1751,3 +1756,56 @@ empathy_dispatcher_find_requestable_channel_classes_async
   g_hash_table_insert (priv->request_channel_class_async_ids,
     request, GUINT_TO_POINTER (source_id));
 }
+
+static void
+empathy_dispatcher_handle_channels (TpSvcClientHandler *self,
+    const gchar *account_path,
+    const gchar *connection_path,
+    const GPtrArray *channels,
+    const GPtrArray *requests_satisfied,
+    guint64 timestamp,
+    GHashTable *handler_info,
+    DBusGMethodInvocation *context)
+{
+  EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (self);
+  EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher);
+  int i;
+  EmpathyAccount *account;
+  TpConnection *connection;
+
+  account = empathy_account_manager_lookup (priv->account_manager,
+    account_path);
+  /* FIXME */
+  g_assert (account != NULL);
+
+  connection = empathy_account_get_connection (account);
+  /* FIXME */
+  g_assert (connection != NULL);
+
+  for (i = 0; i < channels->len ; i++)
+    {
+      GValueArray *arr = g_ptr_array_index (channels, i);
+      const gchar *object_path;
+      GHashTable *properties;
+
+      object_path = g_value_get_boxed (g_value_array_get_nth (arr, 0));
+      properties = g_value_get_boxed (g_value_array_get_nth (arr, 1));
+
+      dispatcher_connection_new_channel_with_properties (dispatcher,
+        connection, object_path, properties);
+    }
+
+  tp_svc_client_handler_return_from_handle_channels (context);
+
+  g_object_unref (account);
+}
+
+static void
+empathy_dispatcher_client_handler_iface_init (gpointer g_iface,
+  gpointer g_iface_data)
+{
+  TpSvcClientHandlerClass *klass = (TpSvcClientHandlerClass *) g_iface;
+
+  tp_svc_client_handler_implement_handle_channels (klass,
+    empathy_dispatcher_handle_channels);
+}
diff --git a/libempathy/empathy-dispatcher.h b/libempathy/empathy-dispatcher.h
index d6c83f6..41a1430 100644
--- a/libempathy/empathy-dispatcher.h
+++ b/libempathy/empathy-dispatcher.h
@@ -26,6 +26,7 @@
 #include <gio/gio.h>
 
 #include <telepathy-glib/channel.h>
+#include <telepathy-glib/dbus-properties-mixin.h>
 
 #include "empathy-contact.h"
 #include "empathy-dispatch-operation.h"
@@ -51,6 +52,7 @@ struct _EmpathyDispatcher
 struct _EmpathyDispatcherClass
 {
  GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_props_class;
 };
 
 /* Will be called when the channel is ready for dispatching. The requestor



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]