[telepathy-salut/master] tube-dbus: start to implement Channel interface and DBusTube type

Guillaume Desmottes guillaume.desmottes at collabora.co.uk
Fri Jun 26 07:28:08 PDT 2009


---
 src/tube-dbus.c |  267 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/tube-dbus.h |    5 +
 2 files changed, 266 insertions(+), 6 deletions(-)

diff --git a/src/tube-dbus.c b/src/tube-dbus.c
index 9ab79b5..637f936 100644
--- a/src/tube-dbus.c
+++ b/src/tube-dbus.c
@@ -33,7 +33,6 @@
 #include <telepathy-glib/channel-iface.h>
 #include <telepathy-glib/dbus.h>
 #include <telepathy-glib/exportable-channel.h>
-#include <telepathy-glib/group-mixin.h>
 #include <telepathy-glib/gtypes.h>
 #include <telepathy-glib/interfaces.h>
 #include <telepathy-glib/svc-channel.h>
@@ -58,11 +57,30 @@
  * arbitrary limit on the queue size set to 4MB. */
 #define MAX_QUEUE_SIZE (4096*1024)
 
-static void
-tube_iface_init (gpointer g_iface, gpointer iface_data);
+static void channel_iface_init (gpointer, gpointer);
+static void tube_iface_init (gpointer g_iface, gpointer iface_data);
+static void dbustube_iface_init (gpointer g_iface, gpointer iface_data);
 
 G_DEFINE_TYPE_WITH_CODE (SalutTubeDBus, salut_tube_dbus, G_TYPE_OBJECT,
-    G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init));
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+      tp_dbus_properties_mixin_iface_init);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
+    G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_DBUS_TUBE,
+      dbustube_iface_init);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE,
+      NULL);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));
+
+static const gchar *salut_tube_dbus_interfaces[] = {
+    TP_IFACE_CHANNEL_INTERFACE_GROUP,
+    /* If more interfaces are added, either keep Group as the first, or change
+     * the implementations of gabble_tube_dbus_get_interfaces () and
+     * gabble_tube_dbus_get_property () too */
+    TP_IFACE_CHANNEL_INTERFACE_TUBE,
+    NULL
+};
 
 static const gchar * const salut_tube_dbus_channel_allowed_properties[] = {
     TP_IFACE_CHANNEL ".TargetHandle",
@@ -85,7 +103,10 @@ static guint signals[LAST_SIGNAL] = {0};
 /* properties */
 enum
 {
-  PROP_CONNECTION = 1,
+  PROP_OBJECT_PATH = 1,
+  PROP_CHANNEL_TYPE,
+  PROP_CONNECTION,
+  PROP_INTERFACES,
   PROP_TUBES_CHANNEL,
   PROP_HANDLE,
   PROP_HANDLE_TYPE,
@@ -102,6 +123,11 @@ enum
   PROP_DBUS_ADDRESS,
   PROP_DBUS_NAME,
   PROP_DBUS_NAMES,
+  PROP_CHANNEL_DESTROYED,
+  PROP_CHANNEL_PROPERTIES,
+  PROP_REQUESTED,
+  PROP_TARGET_ID,
+  PROP_INITIATOR_ID,
   LAST_PROPERTY
 };
 
@@ -109,6 +135,7 @@ typedef struct _SalutTubeDBusPrivate SalutTubeDBusPrivate;
 struct _SalutTubeDBusPrivate
 {
   SalutConnection *conn;
+  gchar *object_path;
   SalutTubesChannel *tubes_channel;
   TpHandle handle;
   TpHandleType handle_type;
@@ -144,6 +171,8 @@ struct _SalutTubeDBusPrivate
   /* Number of bytes that will be in the next message, 0 if unknown */
   guint32 reassembly_bytes_needed;
 
+  gboolean closed;
+
   gboolean dispose_has_run;
 };
 
@@ -439,6 +468,7 @@ bytestream_state_changed_cb (GibberBytestreamIface *bytestream,
           priv->bytestream = NULL;
         }
 
+      priv->closed = TRUE;
       g_signal_emit (G_OBJECT (self), signals[CLOSED], 0);
     }
   else if (state == GIBBER_BYTESTREAM_STATE_OPEN)
@@ -531,6 +561,7 @@ salut_tube_dbus_finalize (GObject *object)
   SalutTubeDBus *self = SALUT_TUBE_DBUS (object);
   SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self);
 
+  g_free (priv->object_path);
   g_free (priv->stream_id);
   g_free (priv->service);
   g_hash_table_destroy (priv->parameters);
@@ -546,12 +577,32 @@ salut_tube_dbus_get_property (GObject *object,
 {
   SalutTubeDBus *self = SALUT_TUBE_DBUS (object);
   SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self);
+  TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn;
 
   switch (property_id)
     {
+      case PROP_OBJECT_PATH:
+        g_value_set_string (value, priv->object_path);
+        break;
+      case PROP_CHANNEL_TYPE:
+        g_value_set_static_string (value,
+            TP_IFACE_CHANNEL_TYPE_DBUS_TUBE);
+        break;
       case PROP_CONNECTION:
         g_value_set_object (value, priv->conn);
         break;
+     case PROP_INTERFACES:
+        if (priv->handle_type == TP_HANDLE_TYPE_CONTACT)
+          {
+            /* 1-1 tubes - omit the Group interface */
+            g_value_set_boxed (value, salut_tube_dbus_interfaces + 1);
+          }
+        else
+          {
+            /* MUC tubes */
+            g_value_set_boxed (value, salut_tube_dbus_interfaces);
+          }
+        break;
       case PROP_TUBES_CHANNEL:
         g_value_set_object (value, priv->tubes_channel);
         break;
@@ -600,6 +651,75 @@ salut_tube_dbus_get_property (GObject *object,
       case PROP_DBUS_NAMES:
         g_value_set_boxed (value, priv->dbus_names);
         break;
+      case PROP_CHANNEL_DESTROYED:
+        g_value_set_boolean (value, priv->closed);
+        break;
+      case PROP_CHANNEL_PROPERTIES:
+        {
+          GHashTable *properties;
+
+          properties = tp_dbus_properties_mixin_make_properties_hash (object,
+              TP_IFACE_CHANNEL, "TargetHandle",
+              TP_IFACE_CHANNEL, "TargetHandleType",
+              TP_IFACE_CHANNEL, "ChannelType",
+              TP_IFACE_CHANNEL, "TargetID",
+              TP_IFACE_CHANNEL, "InitiatorHandle",
+              TP_IFACE_CHANNEL, "InitiatorID",
+              TP_IFACE_CHANNEL, "Requested",
+              TP_IFACE_CHANNEL, "Interfaces",
+              /*
+               * FIXME
+              TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "ServiceName",
+              TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "SupportedAccessControls",
+              */
+              NULL);
+
+          if (priv->initiator != priv->self_handle)
+            {
+              /* channel has not been requested so Parameters is immutable */
+              GValue *prop_value = g_slice_new0 (GValue);
+
+              /* FIXME: use tp_dbus_properties_mixin_add_properties once it's
+               * added in tp-glib */
+              tp_dbus_properties_mixin_get (object,
+                  TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters",
+                  prop_value, NULL);
+              g_assert (G_IS_VALUE (prop_value));
+
+              g_hash_table_insert (properties,
+                  g_strdup_printf ("%s.%s", TP_IFACE_CHANNEL_INTERFACE_TUBE,
+                    "Parameters"), prop_value);
+            }
+
+          g_value_take_boxed (value, properties);
+        }
+        break;
+      case PROP_REQUESTED:
+        g_value_set_boolean (value,
+            (priv->initiator == priv->self_handle));
+        break;
+      case PROP_INITIATOR_ID:
+          {
+            TpHandleRepoIface *repo = tp_base_connection_get_handles (
+                base_conn, TP_HANDLE_TYPE_CONTACT);
+
+            /* some channel can have o.f.T.Channel.InitiatorHandle == 0 but
+             * tubes always have an initiator */
+            g_assert (priv->initiator != 0);
+
+            g_value_set_string (value,
+                tp_handle_inspect (repo, priv->initiator));
+          }
+        break;
+      case PROP_TARGET_ID:
+          {
+            TpHandleRepoIface *repo = tp_base_connection_get_handles (
+                base_conn, priv->handle_type);
+
+            g_value_set_string (value,
+                tp_handle_inspect (repo, priv->handle));
+          }
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
         break;
@@ -617,6 +737,14 @@ salut_tube_dbus_set_property (GObject *object,
 
   switch (property_id)
     {
+      case PROP_OBJECT_PATH:
+        g_free (priv->object_path);
+        priv->object_path = g_value_dup_string (value);
+        break;
+      case PROP_CHANNEL_TYPE:
+        /* this property is writable in the interface, but not actually
+         * meaningfully changeable on this channel, so we do nothing */
+        break;
       case PROP_CONNECTION:
         priv->conn = g_value_get_object (value);
         break;
@@ -683,6 +811,7 @@ salut_tube_dbus_constructor (GType type,
   GObject *obj;
   SalutTubeDBus *self;
   SalutTubeDBusPrivate *priv;
+  DBusGConnection *bus;
   TpHandleRepoIface *contact_repo;
   TpHandleRepoIface *handles_repo;
 
@@ -702,6 +831,11 @@ salut_tube_dbus_constructor (GType type,
       ((TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
   tp_handle_ref (contact_repo, priv->initiator);
 
+  bus = tp_get_bus ();
+  dbus_g_connection_register_g_object (bus, priv->object_path, obj);
+
+  DEBUG ("Registering at '%s'", priv->object_path);
+
   g_assert (priv->self_handle != 0);
   if (priv->handle_type == TP_HANDLE_TYPE_ROOM)
     {
@@ -769,6 +903,46 @@ salut_tube_dbus_constructor (GType type,
 static void
 salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class)
 {
+  static TpDBusPropertiesMixinPropImpl channel_props[] = {
+      { "TargetHandleType", "handle-type", NULL },
+      { "TargetHandle", "handle", NULL },
+      { "ChannelType", "channel-type", NULL },
+      { "TargetID", "target-id", NULL },
+      { "Interfaces", "interfaces", NULL },
+      { "Requested", "requested", NULL },
+      { "InitiatorHandle", "initiator-handle", NULL },
+      { "InitiatorID", "initiator-id", NULL },
+      { NULL }
+  };
+  static TpDBusPropertiesMixinPropImpl dbus_tube_props[] = {
+      { "ServiceName", "service", NULL },
+      { "DBusNames", "dbus-names", NULL },
+      { "SupportedAccessControls", "supported-access-controls", NULL },
+      { NULL }
+  };
+  static TpDBusPropertiesMixinPropImpl tube_iface_props[] = {
+      { "Parameters", "parameters", NULL },
+      { "State", "state", NULL },
+      { NULL }
+  };
+  static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+      { TP_IFACE_CHANNEL,
+        tp_dbus_properties_mixin_getter_gobject_properties,
+        NULL,
+        channel_props,
+      },
+      { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+        tp_dbus_properties_mixin_getter_gobject_properties,
+        NULL,
+        dbus_tube_props,
+      },
+      { TP_IFACE_CHANNEL_INTERFACE_TUBE,
+        tp_dbus_properties_mixin_getter_gobject_properties,
+        NULL,
+        tube_iface_props,
+      },
+      { NULL }
+  };
   GObjectClass *object_class = G_OBJECT_CLASS (salut_tube_dbus_class);
   GParamSpec *param_spec;
 
@@ -782,6 +956,10 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class)
   object_class->dispose = salut_tube_dbus_dispose;
   object_class->finalize = salut_tube_dbus_finalize;
 
+  g_object_class_override_property (object_class, PROP_OBJECT_PATH,
+      "object-path");
+  g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
+      "channel-type");
   g_object_class_override_property (object_class, PROP_CONNECTION,
     "connection");
   g_object_class_override_property (object_class, PROP_TUBES_CHANNEL,
@@ -805,6 +983,11 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class)
   g_object_class_override_property (object_class, PROP_STATE,
     "state");
 
+  g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED,
+      "channel-destroyed");
+  g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES,
+      "channel-properties");
+
   param_spec = g_param_spec_object (
       "muc-connection",
       "GibberMucConnection object",
@@ -857,6 +1040,31 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class)
       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class, PROP_DBUS_NAMES, param_spec);
 
+  param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+      "Additional Channel.Interface.* 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_string ("target-id", "Target JID",
+      "The string obtained by inspecting the target handle",
+      NULL,
+      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
+
+  param_spec = g_param_spec_string ("initiator-id", "Initiator's bare JID",
+      "The string obtained by inspecting the initiator-handle",
+      NULL,
+      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_INITIATOR_ID,
+      param_spec);
+
+  param_spec = g_param_spec_boolean ("requested", "Requested?",
+      "True if this channel was requested by the local user",
+      FALSE,
+      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
+
   signals[OPENED] =
     g_signal_new ("tube-opened",
                   G_OBJECT_CLASS_TYPE (salut_tube_dbus_class),
@@ -884,6 +1092,10 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class)
                   NULL, NULL,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
+
+  salut_tube_dbus_class->dbus_props_class.interfaces = prop_interfaces;
+  tp_dbus_properties_mixin_class_init (object_class,
+      G_STRUCT_OFFSET (SalutTubeDBusClass, dbus_props_class));
 }
 
 static void
@@ -1120,8 +1332,15 @@ salut_tube_dbus_new (SalutConnection *conn,
                      GHashTable *parameters,
                      guint id)
 {
-  SalutTubeDBus *tube = g_object_new (SALUT_TYPE_TUBE_DBUS,
+  SalutTubeDBus *tube;
+  gchar *object_path;
+
+  object_path = g_strdup_printf ("%s/DBusTubeChannel_%u_%u",
+      conn->parent.object_path, handle, id);
+
+  tube = g_object_new (SALUT_TYPE_TUBE_DBUS,
       "connection", conn,
+      "object-path", object_path,
       "tubes-channel", tubes_channel,
       "handle", handle,
       "handle-type", handle_type,
@@ -1191,6 +1410,7 @@ salut_tube_dbus_close (SalutTubeIface *tube, gboolean closed_remotely)
     }
   else
     {
+      priv->closed = TRUE;
       g_signal_emit (G_OBJECT (self), signals[CLOSED], 0);
     }
 }
@@ -1292,6 +1512,24 @@ salut_tube_dbus_channel_get_allowed_properties (void)
 }
 
 static void
+channel_iface_init (gpointer g_iface,
+                    gpointer iface_data)
+{
+  /* FIXME */
+#if 0
+  TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface;
+
+#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\
+    klass, salut_tube_dbus_##x##suffix)
+  IMPLEMENT(close,_async);
+  IMPLEMENT(get_channel_type,);
+  IMPLEMENT(get_handle,);
+  IMPLEMENT(get_interfaces,);
+#undef IMPLEMENT
+#endif
+}
+
+static void
 tube_iface_init (gpointer g_iface,
                  gpointer iface_data)
 {
@@ -1302,3 +1540,20 @@ tube_iface_init (gpointer g_iface,
   klass->close = salut_tube_dbus_close;
   klass->add_bytestream = salut_tube_dbus_add_bytestream;
 }
+
+static void
+dbustube_iface_init (gpointer g_iface,
+                     gpointer iface_data)
+{
+  /* FIXME */
+#if 0
+  TpSvcChannelTypeDBusTubeClass *klass =
+      (TpSvcChannelTypeDBusTubeClass *) g_iface;
+
+#define IMPLEMENT(x, suffix) tp_svc_channel_type_dbus_tube_implement_##x (\
+    klass, salut_tube_dbus_##x##suffix)
+  IMPLEMENT(offer,_async);
+  IMPLEMENT(accept,_async);
+#undef IMPLEMENT
+#endif
+}
diff --git a/src/tube-dbus.h b/src/tube-dbus.h
index 4d89609..20c41bc 100644
--- a/src/tube-dbus.h
+++ b/src/tube-dbus.h
@@ -22,6 +22,9 @@
 
 #include <glib-object.h>
 
+#include <telepathy-glib/enums.h>
+#include <telepathy-glib/interfaces.h>
+
 #include "salut-connection.h"
 #include "salut-tubes-channel.h"
 #include <gibber/gibber-muc-connection.h>
@@ -34,6 +37,8 @@ typedef struct _SalutTubeDBusClass SalutTubeDBusClass;
 
 struct _SalutTubeDBusClass {
   GObjectClass parent_class;
+
+  TpDBusPropertiesMixinClass dbus_props_class;
 };
 
 struct _SalutTubeDBus {
-- 
1.5.6.5




More information about the telepathy-commits mailing list