[Telepathy] Empathy and Requestable Channel Classes

Sjoerd Simons sjoerd.simons at collabora.co.uk
Thu Feb 12 06:40:13 PST 2009


As requested by Cosimo here are some of my ideas of how an API for dealing with
requestable channel classes could look like.  But first some background as
these things might be somewhat confusing for people just reading the spec :).

Once upon a time we only had RequestChannel, which you could ask for a Channel
with a ChannelType, HandleType, Handle and a suppress handler value. While this
worked fine for simple cases, it falls short when more complicated Channels are
involved especially when the application requesting it isn't actually the
handler. It also meant that for more complicated Channel types, one first had
to request a Channel, set a bunch of properites, tell the CM that the
properties are nicely set and only then the channel was actually usefull.

With the new Requests interface, we instead pass a set of properties directly
to the channel, which means it is usefull from the start. Also the NewChannels
signal contains a nice set of properties for each Channel, which means
applications have much more information when channels pop up.

Now you can't request a DBusTube channel with the old interface anymore, but
imagine one could. Also imagine Empathy would allow one to start a Game of Go
with friend, the actual Go game is an external application. With the old
RequestChannel, Empathy would request a new DBusTubeChannel, poke in some
properties, tell the channel it's done and now the channel is ready to be
passed on to the actual application. With the Request interface, Empathy would
just request the channel with the necessary properties and of you go. Saving
not only round trips, but also makes the NewChannels signal more usefull as
everyone can see it's going to be a Tube for a Go game from the start :) Which
also means the channel dispatcher can do something usefull with it.


Anyway, nice new features and more flexibility has the downside of adding some
complexity. Specifically we need to know not only what channels we can request,
but also what parameters are valid when requesting them. This is where
RequestableChannelClasses come in. These tell which of the parameters should
have certain fixed values and which you are allowed to give. Note that it
doesn't tell you which ones from the allowed properties are mandatory, that's
something that's documented in the spec per channel type. So for example for FT
you could have these classes:

0: ({ ChannelType = FT, TargetHandleType = CONTACT },
  [ TargetHandle, TargetId, ContactFilename, ContentType,
    ContentHashType, ContentHash, Description ])

1: ({ ChannelType = FT, TargetHandleType = CONTACT, ContentHashType=MD5 },
  [ Filename, ContentType, ContentHashType, ContentHash, Description ])

So if you have class 0, you can request a filetransfer channel without giving a
hash (as ContentHashType and ContentHash) are optional. While in case 1, you
should set the ContentHashType to MD5 on request and thus set ContentHash to
the MD5 hash of the file you're going to sent (as documented in the spec).


What you normally want to do with these classes is to look for one or more that
you can support with a given type. For example, if you don't know how to hash a
file, you'd look for classes without ContentHashType. So i think the api should
be a bit like (in pseudocode):

  classes ** _find_channel_classes (channel_type, target_handle_type,
    [ knownparameter0, knownparameter1, knownparameter2, NULL]);

So in case you can't hash files you would just do:
  _find_channel_classes (FT, CONTACT, [ NULL ]);
While if you're able to hash files you'd do:
  _find_channel_classes (FT, CONTACT, [ ContentHashType ]);
Or if you knew about encrypted file transfers (and they existed):
  _find_channel_classes (FT, CONTACT, [ ContentHashType, Encryption ]);

As a result you get a list of classes matching your query, which you might
need to filter a little bit yourself (Do you actually support the hash type?)
and select the one that matches your needs the closest (e.g. prefer the one
with encryption).


Now you'll find the classes in two locations, one is in the
RequestableChannelClasses D-Bus property on the Connections Requests
interfaces. This is the set of classes you can request from the CM, but that
doesn't mean your contact supports them (e.g. if the CM supports FT it will
have the relevant classes, but the contact might not support FT).

The second way to get classes is by querying GetContactCapabilities on the
ContactCapabilities interface, which gives you a mapping from Contacts to
Classes you can request from them. Which gives a more precise indication of
the capabilities of the other side.

So for optimal correctness, in empathy use _find_channel_classes on a contact,
which falls back on using the channel classes of a connection if there is no
ContactCapabitilities interface. Unfortunately for backwards compatibility, if
there is no ContactCapabitilities interface, but there is a Capabilities
interface we should look at that. Shouldn't be too hard, but still annoying.

  Sjoerd
-- 
You can't mend a wristwatch while falling from an airplane.


More information about the telepathy mailing list