[telepathy-mission-control/master] McdDispatcher: implement a stub version of ChannelDispatcher

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Apr 1 12:11:32 PDT 2009


This takes the bus name and can list all channel dispatch operations, but
does not yet implement CreateChannel or EnsureChannel.
---
 src/mcd-dispatcher.c |  171 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/mcd-dispatcher.h |   11 +++-
 2 files changed, 180 insertions(+), 2 deletions(-)

diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 5ac0fbc..cd69eda 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -40,6 +40,8 @@
 #include <glib/gprintf.h>
 #include <glib/gi18n.h>
 
+#include <dbus/dbus-glib-lowlevel.h>
+
 #include "mcd-signals-marshal.h"
 #include "mcd-connection.h"
 #include "mcd-channel.h"
@@ -51,11 +53,13 @@
 #include <telepathy-glib/interfaces.h>
 #include <telepathy-glib/gtypes.h>
 #include <telepathy-glib/proxy-subclass.h>
+#include <telepathy-glib/svc-generic.h>
 #include <telepathy-glib/util.h>
 #include "_gen/interfaces.h"
 #include "_gen/gtypes.h"
 #include "_gen/cli-client.h"
 #include "_gen/cli-client-body.h"
+#include "_gen/svc-dispatcher.h"
 
 #include <libmcclient/mc-errors.h>
 
@@ -64,7 +68,16 @@
 
 #define MCD_DISPATCHER_PRIV(dispatcher) (MCD_DISPATCHER (dispatcher)->priv)
 
-G_DEFINE_TYPE (McdDispatcher, mcd_dispatcher, MCD_TYPE_MISSION);
+static void dispatcher_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (McdDispatcher, mcd_dispatcher, MCD_TYPE_MISSION,
+    G_IMPLEMENT_INTERFACE (MC_TYPE_SVC_CHANNEL_DISPATCHER,
+                           dispatcher_iface_init);
+    G_IMPLEMENT_INTERFACE (
+        MC_TYPE_SVC_CHANNEL_DISPATCHER_INTERFACE_OPERATION_LIST,
+        NULL);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+                           tp_dbus_properties_mixin_iface_init))
 
 struct _McdDispatcherContext
 {
@@ -232,6 +245,8 @@ enum
     PROP_0,
     PROP_DBUS_DAEMON,
     PROP_MCD_MASTER,
+    PROP_INTERFACES,
+    PROP_DISPATCH_OPERATIONS,
 };
 
 enum _McdDispatcherSignalType
@@ -1612,6 +1627,9 @@ on_operation_finished (McdDispatchOperation *operation,
      * CDO: according to which of these have happened, we run the choosen
      * handler or we don't. */
 
+    mc_svc_channel_dispatcher_interface_operation_list_emit_dispatch_operation_finished (
+        context->dispatcher, mcd_dispatch_operation_get_path (operation));
+
     if (mcd_dispatch_operation_is_claimed (operation))
     {
         GList *list;
@@ -1704,6 +1722,10 @@ _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher,
     {
         context->operation =
             _mcd_dispatch_operation_new (priv->dbus_daemon, channels);
+        mc_svc_channel_dispatcher_interface_operation_list_emit_new_dispatch_operation (
+            dispatcher,
+            mcd_dispatch_operation_get_path (context->operation),
+            mcd_dispatch_operation_get_properties (context->operation));
         g_signal_connect (context->operation, "finished",
                           G_CALLBACK (on_operation_finished), context);
     }
@@ -1764,6 +1786,11 @@ _mcd_dispatcher_set_property (GObject * obj, guint prop_id,
     }
 }
 
+static const char * const interfaces[] = {
+    MC_IFACE_CHANNEL_DISPATCHER_INTERFACE_OPERATION_LIST,
+    NULL
+};
+
 static void
 _mcd_dispatcher_get_property (GObject * obj, guint prop_id,
 			      GValue * val, GParamSpec * pspec)
@@ -1775,9 +1802,49 @@ _mcd_dispatcher_get_property (GObject * obj, guint prop_id,
     case PROP_DBUS_DAEMON:
 	g_value_set_object (val, priv->dbus_daemon);
 	break;
+
     case PROP_MCD_MASTER:
 	g_value_set_object (val, priv->master);
 	break;
+
+    case PROP_INTERFACES:
+        g_value_set_static_boxed (val, interfaces);
+        break;
+
+    case PROP_DISPATCH_OPERATIONS:
+        {
+            GList *iter;
+            GPtrArray *operations = g_ptr_array_new ();
+
+            for (iter = priv->contexts; iter != NULL; iter = iter->next)
+            {
+                McdDispatcherContext *context = iter->data;
+
+                if (context->operation != NULL)
+                {
+                    GValueArray *va = g_value_array_new (2);
+
+                    g_value_array_append (va, NULL);
+                    g_value_array_append (va, NULL);
+
+                    g_value_init (va->values + 0, DBUS_TYPE_G_OBJECT_PATH);
+                    g_value_init (va->values + 1,
+                                  TP_HASH_TYPE_STRING_VARIANT_MAP);
+
+                    g_value_set_boxed (va->values + 0,
+                        mcd_dispatch_operation_get_path (context->operation));
+                    g_value_set_boxed (va->values + 1,
+                        mcd_dispatch_operation_get_properties (
+                            context->operation));
+
+                    g_ptr_array_add (operations, va);
+                }
+            }
+
+            g_value_take_boxed (val, operations);
+        }
+        break;
+
     default:
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 	break;
@@ -2423,7 +2490,9 @@ name_owner_changed_cb (TpDBusDaemon *proxy,
 static void
 mcd_dispatcher_constructed (GObject *object)
 {
+    DBusGConnection *dgc;
     McdDispatcherPrivate *priv = MCD_DISPATCHER_PRIV (object);
+    DBusError error = { 0 };
 
     tp_cli_dbus_daemon_connect_to_name_owner_changed (priv->dbus_daemon,
         name_owner_changed_cb, NULL, NULL, object, NULL);
@@ -2433,11 +2502,51 @@ mcd_dispatcher_constructed (GObject *object)
 
     tp_cli_dbus_daemon_call_list_names (priv->dbus_daemon,
         -1, list_names_cb, NULL, NULL, object);
+
+    dgc = TP_PROXY (priv->dbus_daemon)->dbus_connection;
+
+    dbus_bus_request_name (dbus_g_connection_get_connection (dgc),
+                           MCD_CHANNEL_DISPATCHER_BUS_NAME, 0, &error);
+
+    if (dbus_error_is_set (&error))
+    {
+        /* FIXME: put in proper error handling when MC gains the ability to
+         * be the AM or the CD but not both */
+        g_error ("Unable to be the channel dispatcher: %s: %s", error.name,
+                 error.message);
+        dbus_error_free (&error);
+        return;
+    }
+
+    dbus_g_connection_register_g_object (dgc,
+                                         MCD_CHANNEL_DISPATCHER_OBJECT_PATH,
+                                         object);
 }
 
 static void
 mcd_dispatcher_class_init (McdDispatcherClass * klass)
 {
+    static TpDBusPropertiesMixinPropImpl cd_props[] = {
+        { "Interfaces", "interfaces", NULL },
+        { NULL }
+    };
+    static TpDBusPropertiesMixinPropImpl op_list_props[] = {
+        { "DispatchOperations", "dispatch-operations", NULL },
+        { NULL }
+    };
+    static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+        { MC_IFACE_CHANNEL_DISPATCHER,
+          tp_dbus_properties_mixin_getter_gobject_properties,
+          NULL,
+          cd_props,
+        },
+        { MC_IFACE_CHANNEL_DISPATCHER_INTERFACE_OPERATION_LIST,
+          tp_dbus_properties_mixin_getter_gobject_properties,
+          NULL,
+          op_list_props,
+        },
+        { NULL }
+    };
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
     g_type_class_add_private (object_class, sizeof (McdDispatcherPrivate));
@@ -2515,7 +2624,25 @@ mcd_dispatcher_class_init (McdDispatcherClass * klass)
                               MCD_TYPE_MASTER,
                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
+    g_object_class_install_property
+        (object_class, PROP_INTERFACES,
+         g_param_spec_boxed ("interfaces", "Interfaces", "Interfaces",
+                             G_TYPE_STRV,
+                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+    g_object_class_install_property
+        (object_class, PROP_DISPATCH_OPERATIONS,
+         g_param_spec_boxed ("dispatch-operations",
+                             "ChannelDispatchOperation details",
+                             "A dbus-glib a(oa{sv})",
+                             MC_ARRAY_TYPE_DISPATCH_OPERATION_DETAILS_LIST,
+                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
     client_ready_quark = g_quark_from_static_string ("mcd_client_ready");
+
+    klass->dbus_properties_class.real.interfaces = prop_interfaces,
+    tp_dbus_properties_mixin_class_init (object_class,
+        G_STRUCT_OFFSET (McdDispatcherClass, dbus_properties_class));
 }
 
 static void
@@ -3359,3 +3486,45 @@ _mcd_dispatcher_recover_channel (McdDispatcher *dispatcher,
     channel_recover_release_lock (cr);
 }
 
+static void
+dispatcher_create_channel (McSvcChannelDispatcher *iface,
+                           const gchar *account_path,
+                           GHashTable *requested_properties,
+                           gint64 user_action_time,
+                           const gchar *preferred_handler,
+                           DBusGMethodInvocation *context)
+{
+    McdDispatcher *self = MCD_DISPATCHER (iface);
+    GError ni = { TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
+        "CreateChannel not yet implemented" };
+
+    (void) self;
+    dbus_g_method_return_error (context, &ni);
+}
+
+static void
+dispatcher_ensure_channel (McSvcChannelDispatcher *iface,
+                           const gchar *account_path,
+                           GHashTable *requested_properties,
+                           gint64 user_action_time,
+                           const gchar *preferred_handler,
+                           DBusGMethodInvocation *context)
+{
+    McdDispatcher *self = MCD_DISPATCHER (iface);
+    GError ni = { TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
+        "EnsureChannel not yet implemented" };
+
+    (void) self;
+    dbus_g_method_return_error (context, &ni);
+}
+
+static void
+dispatcher_iface_init (gpointer g_iface,
+                       gpointer iface_data G_GNUC_UNUSED)
+{
+#define IMPLEMENT(x) mc_svc_channel_dispatcher_implement_##x (\
+    g_iface, dispatcher_##x)
+    IMPLEMENT (create_channel);
+    IMPLEMENT (ensure_channel);
+#undef IMPLEMENT
+}
diff --git a/src/mcd-dispatcher.h b/src/mcd-dispatcher.h
index 7d639c9..d39371a 100644
--- a/src/mcd-dispatcher.h
+++ b/src/mcd-dispatcher.h
@@ -29,6 +29,7 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <dbus/dbus-glib.h>
+#include <telepathy-glib/dbus-properties-mixin.h>
 
 G_BEGIN_DECLS
 
@@ -46,6 +47,11 @@ typedef struct _McdDispatcherPrivate McdDispatcherPrivate;
 #include "mcd-channel.h"
 #include "mcd-master.h"
 
+#define MCD_CHANNEL_DISPATCHER_BUS_NAME \
+    "org.freedesktop.Telepathy.ChannelDispatcher"
+#define MCD_CHANNEL_DISPATCHER_OBJECT_PATH \
+    "/org/freedesktop/Telepathy/ChannelDispatcher"
+
 struct _McdDispatcher
 {
     McdMission parent;
@@ -68,7 +74,10 @@ struct _McdDispatcherClass
 				    GError *error);
 
     /* virtual methods */
-    void (*_mc_reserved0) (void);
+    union {
+        TpDBusPropertiesMixinClass real;
+        GCallback _pad;
+    } dbus_properties_class;
     void (*_mc_reserved1) (void);
     void (*_mc_reserved2) (void);
     void (*_mc_reserved3) (void);
-- 
1.5.6.5




More information about the telepathy-commits mailing list