[Telepathy] The future of Capabilities

Simon McVittie simon.mcvittie at collabora.co.uk
Tue Jul 8 09:03:49 PDT 2008


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

While working on the request/dispatch API I keep coming back to the issue of
capabilities discovery. Although we have one API claiming to address this at
the moment, it actually breaks up into 5 different problems (3 of which
are completely or partially addressed by the current API), which I think we
ought to solve separately.

Comments from anyone else on any of these?

Contents:
(1) The capabilities of our connection
(2) The capabilities of a contact
(3) Our own capabilities
(4) The capabilities of a client process
(5) The capabilities of an account

(1) The capabilities of our connection
======================================

This is requested by <http://bugs.freedesktop.org/show_bug.cgi?id=15418> and
solves the following problem: as implementor of a UI like Empathy, how
do you tell what sorts of channel you can reasonably request (i.e. what
sorts of channel you should show UI for requesting)?

In theory the Capabilities interface supports this, by querying "the
capabilities of handle 0". However, this never really worked - it was
always rather vague how things would be represented, the API wasn't
sufficiently expressive, and none of our reference connection managers has
ever implemented it anyway. In the patch merged in
<http://lists.freedesktop.org/archives/telepathy-commits/2008-July/000883.html>
I deprecated this API for the next spec release (which will be 0.17.8).

As an example of the deficiencies of that API: as far as I can tell,
you were meant to interpret the capability (channel_type = Text, handle = 0)
as "this connection supports Text channels with Handle_Type_Room", but
interpret the capability (channel_type = StreamedMedia, handle = 0) as
"this connection supports StreamedMedia channels with Handle_Type_None".
What's going on there?

In the world of the "requestotron" API, where you can request multiple
related channels simultaneously and each request is an arbitrary number
of key/value pairs, more complexity is needed in any case: we now want
Empathy to show or hide UI elements depending what properties are supported.

For instance, in XMPP you can set your nickname as part of joining a
chatroom, so we want to display a text box for the nickname if and only
if it can actually be passed as part of the request; in XMPP or IRC, you
could perhaps include a password in the request; in future extensions to XMPP
you'll be able to ask to negotiate end-to-end security.

I propose to work on this as part of the Requests interface (the
"requestotron"). My current idea is to introduce the concept of
"classes" of channels (in many cases this will correspond 1:1 to a
GObject, Python, etc. class) which each have at least a channel type, a handle
type, a list of mandatory parameters (tube service, file transfer size),
and a list of optional parameters (string nickname, boolean end-to-end
security). I'll write a follow-up email with an attempt to list
use-cases for these.

All connection managers should implement this - every CM can know,
statically, what code has been implemented (or if the CM has some sort
of plugin architecture, it can still be expected to ask the plugins what
they implement).

(2) The capabilities of a contact
=================================

This answers the following question, asked by (for instance) user interfaces:
thanks to (1) I know that in principle my Google Talk connection can make
StreamedMedia calls, but if I try to call the contact "Simon McVittie",
can he actually accept the call? For instance, Empathy displays a
microphone icon next to the names of contacts who can receive
StreamedMedia calls.

The Capabilities interface addresses this. Each contact has zero or more
capability tuples, consisting of a channel type, their own contact handle,
a bitfield of "generic flags" (generic across channel types), and a
bitfield of "type-specific flags" (defined by the channel type).

This is not without its flaws - a substantial amount of code is required
to relate the bitfields of flags to the mechanics of making a channel
request, and only Channel and Channel.Type.* can usefully define the members
of those bitfields - but it'll do.

I propose to leave this as it is for now, and perhaps come back to it later.
(We are likely to need to extend this if we want to advertise support
for particular Tubes applications, for instance.)

Not all connection managers can usefully implement this - SIP (at least
until/unless presence is implemented using SIMPLE) has no concept of
capabilities.

For connection managers that just don't have this information, it's reasonable
for clients to assume that "most" other contacts will support "most" of the
possible channel types, and at least attempt to request the channel.

(3) Our own capabilities
========================

This is how clients (in practice, Mission Control or an equivalent
process like Decibel) tell the connection manager what capabilities it
should advertise to other contacts. The connection manager also feeds back to
clients what capabilities are actually being advertised.

These are listed in the same way as other contacts' capabilities, except
that clients cannot tell the connection manager what "generic flags" to
advertise (the idea is that the connection manager can work this out for
itself).

As in (2), this isn't readily extensible except in quite tightly
constrained ways, but I think it'll do for now. We can always revisit it
later.

(4) The capabilities of a client process
========================================

These answer the following question: what sorts of channels should the
ChannelDispatcher send to which client?

The ChannelDispatcher should also use this to set (3), by taking the
union of the supported classes of channels.

Nokia's Mission Control implementation allows "channel handlers" (the
precursor of the Client concept in the new spec under development) to register
to handle a (channel type, handle type) pair; Decibel appears to allow
"components" (conceptually similar) to filter by channel type, handle
type and IM protocol.

The only use-case I can immediately see where this will be insufficient
is that we want to be able to filter Tube handlers by Tube service name -
unless we make Tubes a family of channel types
(like org.freedesktop.Telepathy.Channel.Type.DBusTube.com.abisource.AbiCollab
and org.freedesktop.Telepathy.Channel.Type.StreamTube.http perhaps?)
which might neatly circumvent this.

Does anyone have any more use-cases for fine-grained channel selection?

This doesn't have to be done for the initial Requests API, but it'll be
needed for the ChannelDispatcher <-> Client API.

(5) The capabilities of an account
==================================

In practice, particularly on embedded devices like the Nokia internet tablets,
it's sometimes desirable to request a channel on an account that isn't
actually connected yet. For instance, the internet tablets' proprietary
UI allows you to "initiate a call" when not actually connected to the
Internet at all - this will automatically prompt the user to connect to a
WLAN or other Internet connection (if possible), then bring the selected
account online (i.e. make a Connection for it), then actually make the
call.

This requires information equivalent to (1) to be available even if
there isn't actually a live Connection.

Nokia's Mission Control does this in a rather ad-hoc way, by defining
properties in the "profile" representing expected capabilities of accounts
with that profile. These keys are defined as part of NMC and do not directly
encode channel types, handle types etc. - they're things like "chatroom",
"private-chat", "voip". (There are also keys in the same namespace for
non-Channel features, like avatars.)

This is conceptually wrong - in the Telepathy framework, no assumption
is made that all Connections from the same CM are equal. Indeed,
interfaces (and perhaps even requestable channel classes) will come and go
depending on the capabilities of the server to which the Connection is
connected.

However, it's entirely reasonable to assume that for a given Account,
the available features will stay "mostly" the same. It would be fine to
cache the capabilities when an Account becomes connected, and assume
them to be valid until next time it becomes connected, for instance.
I think we should add this as an optional interface on Account, with the
understanding that an AccountManager that wants to be usable as a
drop-in replacement for Nokia's should support it.

In an AccountManager that supports "profiles" - which, for the time
being, are explicitly outside the scope of the main Telepathy
specification, although AM implementations are welcome to implement
them as an extension - the capabilities for an Account that has never
become connected could usefully be "pre-seeded" from the profile.
-----BEGIN PGP SIGNATURE-----

iD8DBQFIc4/dWSc8zVUw7HYRAmN3AJ0ffXFbDhGwuvz9HdYtYF3xaUMHPgCeKohB
vb8ZjIeagLv4VyCjixcZywk=
=7Sid
-----END PGP SIGNATURE-----


More information about the Telepathy mailing list