[Telepathy-commits] [telepathy-gabble/master] Tubes requestotron: Advertise the right RequestableChannelClasses for tubes, and strongly check properties in CreateChannel/RequestChannel.

Alban Crequy alban.crequy at collabora.co.uk
Thu Oct 23 12:38:00 PDT 2008


Conflicts:

	src/private-tubes-factory.c
---
 extensions/Makefile.am               |    2 +-
 src/private-tubes-factory.c          |   98 ++++++++++++++++++++++++++-------
 src/tube-stream.c                    |   23 ++------
 src/tubes-channel.c                  |   10 +++-
 src/tubes-channel.h                  |    4 +-
 tests/twisted/tubes/test-si-tubes.py |   25 ++++-----
 6 files changed, 103 insertions(+), 59 deletions(-)

diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index 327452c..c03db3c 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -9,7 +9,7 @@ EXTRA_DIST = \
     OLPC_Gadget.xml \
     OLPC_Channel_Interface_View.xml \
     OLPC_Channel_Type_BuddyView.xml \
-    OLPC_Channel_Type_ActivityView.xml
+    OLPC_Channel_Type_ActivityView.xml \
     Channel_Interface_Tube.xml \
     Channel_Type_DBus_Tube.xml \
     Channel_Type_Stream_Tube.xml
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index 24c0584..33f75b5 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -59,9 +59,7 @@ G_DEFINE_TYPE_WITH_CODE (GabblePrivateTubesFactory,
     gabble_private_tubes_factory,
     G_TYPE_OBJECT,
     G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
-      channel_manager_iface_init);
-    G_IMPLEMENT_INTERFACE (GABBLE_TYPE_CAPS_CHANNEL_MANAGER,
-      caps_channel_manager_iface_init));
+      channel_manager_iface_init));
 
 /* properties */
 enum
@@ -532,11 +530,25 @@ static const gchar * const tubes_channel_fixed_properties[] = {
     NULL
 };
 
-static const gchar * const tubes_channel_allowed_properties[] = {
+static const gchar * const old_tubes_channel_allowed_properties[] = {
     TP_IFACE_CHANNEL ".TargetHandle",
     TP_IFACE_CHANNEL ".TargetID",
     NULL
 };
+static const gchar * const stream_tube_channel_allowed_properties[] = {
+    TP_IFACE_CHANNEL ".TargetHandle",
+    TP_IFACE_CHANNEL ".TargetID",
+    GABBLE_IFACE_CHANNEL_INTERFACE_TUBE ".Parameters",
+    GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service",
+    NULL
+};
+static const gchar * const dbus_tube_channel_allowed_properties[] = {
+    TP_IFACE_CHANNEL ".TargetHandle",
+    TP_IFACE_CHANNEL ".TargetID",
+    GABBLE_IFACE_CHANNEL_INTERFACE_TUBE ".Parameters",
+    GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName",
+    NULL
+};
 
 
 static void
@@ -562,7 +574,7 @@ gabble_private_tubes_factory_foreach_channel_class (
   g_hash_table_insert (table, TP_IFACE_CHANNEL ".TargetHandleType",
       value);
 
-  func (manager, table, tubes_channel_allowed_properties, user_data);
+  func (manager, table, old_tubes_channel_allowed_properties, user_data);
 
   g_hash_table_destroy (table);
 
@@ -580,8 +592,7 @@ gabble_private_tubes_factory_foreach_channel_class (
   g_hash_table_insert (table, TP_IFACE_CHANNEL ".TargetHandleType",
       value);
 
-  func (manager, table, tubes_channel_required_properties,
-      tubes_channel_optional_properties, user_data);
+  func (manager, table, stream_tube_channel_allowed_properties, user_data);
 
   /* 1-1 Channel.Type.DBusTube */
   table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
@@ -597,8 +608,7 @@ gabble_private_tubes_factory_foreach_channel_class (
   g_hash_table_insert (table, TP_IFACE_CHANNEL ".TargetHandleType",
       value);
 
-  func (manager, table, tubes_channel_required_properties,
-      tubes_channel_optional_properties, user_data);
+  func (manager, table, dbus_tube_channel_allowed_properties, user_data);
 
   g_hash_table_destroy (table);
 }
@@ -618,6 +628,10 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self,
   GabbleTubesChannel *channel;
   const gchar *channel_type;
 
+  if (tp_asv_get_uint32 (request_properties,
+        TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_CONTACT)
+    return FALSE;
+
   channel_type = tp_asv_get_string (request_properties,
             TP_IFACE_CHANNEL ".ChannelType");
 
@@ -626,9 +640,56 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self,
       tp_strdiff (channel_type, GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE))
     return FALSE;
 
-  if (tp_asv_get_uint32 (request_properties,
-        TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_CONTACT)
-    return FALSE;
+  if (! tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES))
+    {
+      if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+              tubes_channel_fixed_properties,
+              old_tubes_channel_allowed_properties,
+              &error))
+        goto error;
+    }
+  else if (! tp_strdiff (channel_type, GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE))
+    {
+      const gchar *service;
+
+      if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+              tubes_channel_fixed_properties,
+              stream_tube_channel_allowed_properties,
+              &error))
+        goto error;
+
+      /* "Service" is a mandatory, not-fixed property */
+      service = tp_asv_get_string (request_properties,
+                GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
+      if (service == NULL)
+        {
+          g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
+              "Request missed a mandatory property '%s'",
+              GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
+          goto error;
+        }
+    }
+  else if (! tp_strdiff (channel_type, GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE))
+    {
+      const gchar *service;
+
+      if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+              tubes_channel_fixed_properties,
+              dbus_tube_channel_allowed_properties,
+              &error))
+        goto error;
+
+      /* "ServiceName" is a mandatory, not-fixed property */
+      service = tp_asv_get_string (request_properties,
+                GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName");
+      if (service == NULL)
+        {
+          g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
+              "Request missed a mandatory property '%s'",
+              GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName");
+          goto error;
+        }
+    }
 
   handle = tp_asv_get_uint32 (request_properties,
       TP_IFACE_CHANNEL ".TargetHandle", NULL);
@@ -636,11 +697,6 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self,
   if (!tp_handle_is_valid (contact_repo, handle, &error))
     goto error;
 
-  if (tp_channel_manager_asv_has_unknown_properties (request_properties,
-          tubes_channel_fixed_properties, tubes_channel_allowed_properties,
-          &error))
-    goto error;
-
   /* Don't support opening a channel to our self handle */
   if (handle == base_conn->self_handle)
     {
@@ -670,8 +726,8 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self,
           goto error;
         }
 
-      gabble_channel_manager_emit_request_already_satisfied (self,
-          request_token, GABBLE_EXPORTABLE_CHANNEL (channel));
+      tp_channel_manager_emit_request_already_satisfied (self,
+          request_token, TP_EXPORTABLE_CHANNEL (channel));
       return TRUE;
     }
   else
@@ -713,8 +769,8 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self,
         }
       else
         {
-          gabble_channel_manager_emit_request_already_satisfied (self,
-              request_token, GABBLE_EXPORTABLE_CHANNEL (channel));
+          tp_channel_manager_emit_request_already_satisfied (self,
+              request_token, TP_EXPORTABLE_CHANNEL (channel));
         }
 
       return TRUE;
diff --git a/src/tube-stream.c b/src/tube-stream.c
index d4c5149..d8e78be 100644
--- a/src/tube-stream.c
+++ b/src/tube-stream.c
@@ -48,7 +48,6 @@
 #include "connection.h"
 #include "debug.h"
 #include "disco.h"
-#include "exportable-channel.h"
 #include "gabble-signals-marshal.h"
 #include "muc-channel.h"
 #include "namespaces.h"
@@ -65,7 +64,6 @@ G_DEFINE_TYPE_WITH_CODE (GabbleTubeStream, gabble_tube_stream, G_TYPE_OBJECT,
     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 (GABBLE_TYPE_SVC_CHANNEL_FUTURE, NULL);
     G_IMPLEMENT_INTERFACE (GABBLE_TYPE_TUBE_IFACE, tube_iface_init);
     G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_CHANNEL_TYPE_STREAM_TUBE,
       streamtube_iface_init);
@@ -73,7 +71,7 @@ G_DEFINE_TYPE_WITH_CODE (GabbleTubeStream, gabble_tube_stream, G_TYPE_OBJECT,
       NULL);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
         tp_external_group_mixin_iface_init);
-    G_IMPLEMENT_INTERFACE (GABBLE_TYPE_EXPORTABLE_CHANNEL, NULL);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL);
     G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));
 
 static const gchar *gabble_tube_stream_interfaces[] = {
@@ -81,7 +79,6 @@ static const gchar *gabble_tube_stream_interfaces[] = {
     /* If more interfaces are added, either keep Group as the first, or change
      * the implementations of gabble_tube_stream_get_interfaces () and
      * gabble_tube_stream_get_property () too */
-    GABBLE_IFACE_CHANNEL_FUTURE,
     GABBLE_IFACE_CHANNEL_INTERFACE_TUBE,
     NULL
 };
@@ -1037,14 +1034,14 @@ gabble_tube_stream_get_property (GObject *object,
         break;
       case PROP_CHANNEL_PROPERTIES:
         g_value_set_boxed (value,
-            gabble_tp_dbus_properties_mixin_make_properties_hash (object,
+            tp_dbus_properties_mixin_make_properties_hash (object,
                 TP_IFACE_CHANNEL, "TargetHandle",
                 TP_IFACE_CHANNEL, "TargetHandleType",
                 TP_IFACE_CHANNEL, "ChannelType",
                 TP_IFACE_CHANNEL, "TargetID",
-                GABBLE_IFACE_CHANNEL_FUTURE, "InitiatorHandle",
-                GABBLE_IFACE_CHANNEL_FUTURE, "InitiatorID",
-                GABBLE_IFACE_CHANNEL_FUTURE, "Requested",
+                TP_IFACE_CHANNEL, "InitiatorHandle",
+                TP_IFACE_CHANNEL, "InitiatorID",
+                TP_IFACE_CHANNEL, "Requested",
                 NULL));
         break;
       case PROP_REQUESTED:
@@ -1155,7 +1152,7 @@ gabble_tube_stream_set_property (GObject *object,
         break;
       case PROP_INITIATOR_HANDLE:
         /* PROP_INITIATOR_HANDLE and PROP_INITIATOR are the same property from
-         * two different interfaces (Channel.FUTURE and
+         * two different interfaces (Channel and
          * Channel.Interface.Tube.DRAFT). In case of tube channels, this can
          * never be 0. The value is stored in priv->initiator. The object is
          * created only with PROP_INITIATOR set, so do nothing here. */
@@ -1257,9 +1254,6 @@ gabble_tube_stream_class_init (GabbleTubeStreamClass *gabble_tube_stream_class)
       { "ChannelType", "channel-type", NULL },
       { "TargetID", "target-id", NULL },
       { "Interfaces", "interfaces", NULL },
-      { NULL }
-  };
-  static TpDBusPropertiesMixinPropImpl future_props[] = {
       { "Requested", "requested", NULL },
       { "InitiatorHandle", "initiator-handle", NULL },
       { "InitiatorID", "initiator-id", NULL },
@@ -1282,11 +1276,6 @@ gabble_tube_stream_class_init (GabbleTubeStreamClass *gabble_tube_stream_class)
         NULL,
         channel_props,
       },
-      { GABBLE_IFACE_CHANNEL_FUTURE,
-        tp_dbus_properties_mixin_getter_gobject_properties,
-        NULL,
-        future_props,
-      },
       { GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE,
         tp_dbus_properties_mixin_getter_gobject_properties,
         NULL,
diff --git a/src/tubes-channel.c b/src/tubes-channel.c
index 508b58a..938d765 100644
--- a/src/tubes-channel.c
+++ b/src/tubes-channel.c
@@ -663,7 +663,7 @@ _emit_d_bus_names_changed_foreach_data
 
 struct _ForeachData
 {
-  GabbleExportableChannelFunc foreach;
+  TpExportableChannelFunc foreach;
   gpointer user_data;
 };
 
@@ -675,11 +675,11 @@ foreach_slave (gpointer key,
   GabbleTubeIface *tube = GABBLE_TUBE_IFACE (value);
   struct _ForeachData *data = (struct _ForeachData *) user_data;
 
-  data->foreach (GABBLE_EXPORTABLE_CHANNEL (tube), data->user_data);
+  data->foreach (TP_EXPORTABLE_CHANNEL (tube), data->user_data);
 }
 
 void gabble_tubes_channel_foreach (GabbleTubesChannel *self,
-    GabbleExportableChannelFunc foreach, gpointer user_data)
+    TpExportableChannelFunc foreach, gpointer user_data)
 {
   struct _ForeachData data;
   GabbleTubesChannelPrivate *priv = GABBLE_TUBES_CHANNEL_GET_PRIVATE (self);
@@ -1623,6 +1623,10 @@ GabbleTubeIface *gabble_tubes_channel_tube_request (GabbleTubesChannel *self,
           (GDestroyNotify) tp_g_value_slice_free);
     }
 
+  /* if the service property is missing, the requestotron rejects the request
+   */
+  g_assert (service != NULL);
+
   DEBUG ("Request a tube channel with type='%s' and service='%s'",
       channel_type, service);
 
diff --git a/src/tubes-channel.h b/src/tubes-channel.h
index 92f25a9..05b128d 100644
--- a/src/tubes-channel.h
+++ b/src/tubes-channel.h
@@ -26,7 +26,7 @@
 #include <telepathy-glib/base-connection.h>
 
 #include "bytestream-iface.h"
-#include "exportable-channel.h"
+#include <telepathy-glib/exportable-channel.h>
 #include "muc-channel.h"
 #include "tube-iface.h"
 
@@ -70,7 +70,7 @@ GType gabble_tubes_channel_get_type (void);
                               GabbleTubesChannelClass))
 
 void gabble_tubes_channel_foreach (GabbleTubesChannel *self,
-    GabbleExportableChannelFunc foreach, gpointer user_data);
+    TpExportableChannelFunc foreach, gpointer user_data);
 
 GabbleTubeIface *gabble_tubes_channel_tube_request (GabbleTubesChannel *self,
     gpointer request_token, GHashTable *request_properties,
diff --git a/tests/twisted/tubes/test-si-tubes.py b/tests/twisted/tubes/test-si-tubes.py
index 32e275c..8bb3a89 100644
--- a/tests/twisted/tubes/test-si-tubes.py
+++ b/tests/twisted/tubes/test-si-tubes.py
@@ -76,7 +76,8 @@ def test(q, bus, conn, stream):
                 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT',
              'org.freedesktop.Telepathy.Channel.TargetHandleType': 1,
              },
-             ['org.freedesktop.Telepathy.Channel.TargetHandle'],
+             ['org.freedesktop.Telepathy.Channel.TargetHandle',
+              'org.freedesktop.Telepathy.Channel.TargetID'],
              ) in properties.get('RequestableChannelClasses'),\
                      properties['RequestableChannelClasses']
 
@@ -179,7 +180,7 @@ def test(q, bus, conn, stream):
 #    ret = q.expect_many(EventPattern('dbus-error', method='CreateChannel'))
 
     call_async(q, requestotron, 'CreateChannel',
-            {'org.freedesktop.Telepathy.Channel.ChannelType':
+            dbus.Dictionary({'org.freedesktop.Telepathy.Channel.ChannelType':
                 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT',
              'org.freedesktop.Telepathy.Channel.TargetHandleType':
                 1,
@@ -189,7 +190,7 @@ def test(q, bus, conn, stream):
                 "newecho",
              'org.freedesktop.Telepathy.Channel.Interface.Tube.DRAFT.Parameters':
                 dbus.Dictionary({'foo': 'bar'}, signature='sv'),
-            });
+            }, signature='sv'));
 
     ret, old_sig, new_sig = q.expect_many(
         EventPattern('dbus-return', method='CreateChannel'),
@@ -226,12 +227,12 @@ def test(q, bus, conn, stream):
     assert emitted_props[tp_name_prefix + '.Channel.TargetHandleType'] == 1
     assert emitted_props[tp_name_prefix + '.Channel.TargetHandle'] ==\
             bob_handle
-    assert emitted_props[tp_name_prefix + '.Channel.FUTURE.Requested'] == True
+    assert emitted_props[tp_name_prefix + '.Channel.Requested'] == True
     assert emitted_props[tp_name_prefix + '.Channel.TargetID'] == \
             'bob at localhost', emitted_props[tp_name_prefix + '.Channel.TargetID']
-    assert emitted_props[tp_name_prefix + '.Channel.FUTURE.InitiatorHandle'] \
+    assert emitted_props[tp_name_prefix + '.Channel.InitiatorHandle'] \
             == conn.GetSelfHandle()
-    assert emitted_props[tp_name_prefix + '.Channel.FUTURE.InitiatorID'] == \
+    assert emitted_props[tp_name_prefix + '.Channel.InitiatorID'] == \
             'test at localhost'
 
     properties = conn.GetAll(
@@ -360,15 +361,9 @@ def test(q, bus, conn, stream):
             channel_props['Interfaces'], \
             channel_props['Interfaces']
     assert channel_props['TargetID'] == 'bob at localhost'
-
-    # Exercise FUTURE properties
-    # on the Channel.Type.StreamTube channel
-    future_props = tube_chan.GetAll(
-            'org.freedesktop.Telepathy.Channel.FUTURE',
-            dbus_interface='org.freedesktop.DBus.Properties')
-    assert future_props['Requested'] == True
-    assert future_props['InitiatorID'] == 'test at localhost'
-    assert future_props['InitiatorHandle'] == self_handle
+    assert channel_props['Requested'] == True
+    assert channel_props['InitiatorID'] == 'test at localhost'
+    assert channel_props['InitiatorHandle'] == self_handle
 
     # Offer the tube, new API
     path2 = os.getcwd() + '/stream2'
-- 
1.5.6.5




More information about the Telepathy-commits mailing list