Copyright © 2009 Collabora Limited Copyright © 2009 Nokia Corporation

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

(draft 1)

An interface for multi-user conference channels that can "continue from" one or more individual channels.

This interface addresses freedesktop.org bug #24906 (GSM-compatible conference calls) and bug #24939 (upgrading calls and chats to multi-user). See those bugs for rationale and use cases.

Examples of usage:

Active and held GSM calls C1, C2 can be merged into a single channel Cn with the Conference interface, by calling CreateChannel({...ChannelType: ...Call, ...InitialChannels: [C1, C2]}) which returns Cn.

An XMPP 1-1 conversation C1 can be continued in a newly created multi-user chatroom Cn by calling CreateChannel({...ChannelType: ...Text, ...InitialChannels: [C1]}) which returns Cn.

An XMPP 1-1 conversation C1 can be continued in a specified multi-user chatroom by calling CreateChannel({...ChannelType: ...Text, ...HandleType: ROOM, ...TargetID: 'telepathy@conf.example.com', ...InitialChannels: [C1]}) which returns a Conference channel.

Either of the XMPP cases could work for Call channels, to upgrade from 1-1 Jingle to multi-user Muji. Any of the XMPP cases could in principle work for link-local XMPP (XEP-0174).

The underlying switchboard representing an MSN 1-1 conversation C1 with a contact X can be moved to a representation as a nameless chatroom, Cn, to which more contacts can be invited, by calling CreateChannel({...ChannelType: ...Text, ...InitialChannels: [C1]}) which returns Cn. C1 SHOULD remain open, with no underlying switchboard attached. If X establishes a new switchboard with the local user, C1 SHOULD pick up that switchboard rather than letting it create a new channel. [FIXME: should it?] Similarly, if the local user sends a message in C1, then a new switchboard to X should be created and associated with C1.

XMPP and MSN do not natively have a concept of merging two or more channels C1, C2... into one channel, Cn. However, the GSM-style merging API can be supported on XMPP and MSN, as an API short-cut for upgrading C1 into a conference Cn (which invites the TargetHandle of C1 into Cn), then immediately inviting the TargetHandle of C2, the TargetHandle of C3, etc. into Cn as well.

With a suitable change of terminology, Skype has behaviour similar to MSN.

The Group MAY have channel-specific handles for participants; clients SHOULD support both Conferences that have channel-specific handles, and those that do not.

In the GSM case, the Conference's Group interface MAY have channel-specific handles, to reflect the fact that the identities of the participants might not be known - it can be possible to know that there is another participant in the Conference, but not know who they are. [FIXME: fact check from GSM gurus needed]

In the XMPP case, the Conference's Group interface SHOULD have channel-specific handles, to reflect the fact that the participants have MUC-specific identities, and the user might also be able to see their global identities, or not.

In most other cases, including MSN and link-local XMPP, the Conference's Group interface SHOULD NOT have channel-specific handles, since users' identities are always visible.

Connection managers implementing channels with this interface MUST NOT allow the object paths of channels that could be merged into a Conference to be re-used, unless the channel re-using the object path is equivalent to the channel that previously used it.

If you upgrade some channels into a conference, and then close the original channels, InitialChannels (which is immutable) will contain paths to channels which no longer exist. This implies that you should not re-use channel object paths, unless future incarnations of the path are equivalent.

For instance, on protocols where you can only have zero or one 1-1 text channels with Emily at one time, it would be OK to re-use the same object path for every 1-1 text channel with Emily; but on protocols where this is not true, it would be misleading.

The individual Channels that are continued by this conference, which have the same ChannelType as this one, but with TargetHandleType = CONTACT.

This property MUST NOT be requestable. [FIXME: or would it be better for this one, and not IC, to be requestable?]

Change notification is via the ChannelMerged and ChannelRemoved signals.

Emitted when a new channel is added to the value of Channels.

The channel that was added to Channels.

Emitted when a channel is removed from the value of Channels, either because it closed or because it was split using the Splittable.DRAFT.Split method.

[FIXME: relative ordering of this vs. Closed? Do we care?]

The channel that was removed from Channels.

The initial value of Channels.

This property SHOULD be requestable. Omitting it from a request is equivalent to providing it with an empty list as value. Requests where its value has at least two elements SHOULD be expected to succeed on any implementation of this interface.

Whether a request with 0 or 1 elements in the list will succeed is indicated by SupportsNonMerges.

In GSM, a pair of calls can be merged into a conference. In XMPP and MSN, you can create a new chatroom, or upgrade one 1-1 channel into a chatroom; however, on these protocols, it is also possible to fake GSM-style merging by upgrading the first channel, then inviting the targets of all the other channels into it.

If possible, the Channels' states SHOULD NOT be altered by merging them into a conference. However, depending on the protocol, the Channels MAY be placed in a "frozen" state by placing them in this property's value or by calling MergeableConference.DRAFT.Merge on them. [FIXME: there's nothing in RequestableChannelClasses yet to say what will happen, see #24906 comment 6]

In Jingle, nothing special will happen to merged calls. UIs MAY automatically place calls on hold before merging them, if that is the desired behaviour; this SHOULD always work. Not doing an implicit hold/unhold seems to preserve least-astonishment.

[FIXME: check whether ring supports faking Hold on both channels, as it probably should: see #24906 comment 6]

In GSM, the calls that are merged go into a state similar to Hold, but they cannot be unheld, only split from the conference call using Channel.Interface.Splittable.DRAFT.Split.

Depending on the protocol, it might be signalled to remote users that this channel is a continuation of all the requested channels, or that it is only a continuation of the first channel in the list.

In MSN, the conference steals the underlying switchboard (protocol construct) from one of its component channels, so the conference appears to remote users to be a continuation of that channel and no other. The connection manager has to make some arbitrary choice, so we arbitrarily mandate that it SHOULD choose the first channel in the list as the one to continue.

This property is immutable.

A list of additional contacts invited to this conference when it was created.

This property SHOULD be requestable, and appear in the allowed properties in RequestableChannelClasses, in all connection managers that can implement its semantics (in practice, this is likely to mean exactly those connection managers where SupportsNonMerges will be true).

If included in a request, the given contacts are automatically invited into the new channel, as if they had been added with Group.AddMembers(InitialInviteeHandles, InvitationMessage immediately after the channel was created.

This is a simple convenience API for the common case that a UI upgrades a 1-1 chat to a multi-user chat solely in order to invite someone else to participate.

At most one of InitialInviteeHandles and InitialInviteeIDs may appear in each request.

If the local user was not the initiator of this channel, the Group.SelfHandle SHOULD appear in the value of this property, together with any other contacts invited at the same time (if that information is known).

This property is immutable.

A list of additional contacts invited to this conference when it was created.

This property SHOULD be requestable, as an alternative to InitialInviteeHandles. Its semantics are the same, except that it takes a list of the string representations of contact handles.

At most one of InitialInviteeHandles and InitialInviteeIDs may appear in each request.

When a channel is created, the values of InitialInviteeHandles and InitialInviteeIDs MUST correspond to each other.

This property is immutable.

The message that was sent to the InitialInviteeHandles when they were invited.

This property SHOULD be requestable, and appear in the allowed properties in RequestableChannelClasses, in protocols where invitations can have an accompanying text message.

This allows invitations with a message to be sent when using InitialInviteeHandles or InitialInviteeIDs.

If the local user was not the initiator of this channel, the message with which they were invited (if any) SHOULD appear in the value of this property.

This property is immutable.

[FIXME: needs a better name; or perhaps it could be implied by InitialInviteeHandles being requestable in XMPP/MSN but not in GSM?]

If true, requests with InitialChannels omitted, empty, or one element long should be expected to succeed.

This property SHOULD appear in RequestableChannelClasses for conference channels if and only if its value on those channels will be true.

Putting this in RequestableChannelClasses means clients can find out whether their request will succeed early enough to do something about it.

In XMPP, you can request a channel of type ROOM without incorporating any 1-1 chats at all - indeed, this is the normal way to do it - or as a continuation of a single 1-1 chat, and then invite other people in later.

The sense of this property is a bit awkward, but it avoids making it an anti-capability. If the sense were inverted, then its presence in RequestableChannelClasses would imply that the protocol lacks a feature; as it stands, it is additive. (Contrast with ImmutableStreams, which is the wrong way around for backwards-compatibility reasons.)

If false, InitialChannels SHOULD be supplied in all requests for this channel class, and contain at least two channels. Requests where this requirement is not met SHOULD fail with NotImplemented.

In GSM, you can only make a conference call by merging at least two channels. [FIXME: the CM could conceivably fake it, but that would be rather nasty]