Bug 24906 (tp-Conference) - GSM-compatible conference calls
Summary: GSM-compatible conference calls
Status: RESOLVED FIXED
Alias: tp-Conference
Product: Telepathy
Classification: Unclassified
Component: tp-spec (show other bugs)
Version: unspecified
Hardware: Other All
: medium enhancement
Assignee: Telepathy bugs list
QA Contact: Telepathy bugs list
URL: http://git.collabora.co.uk/?p=user/wj...
Whiteboard: review+ as draft, undraft?
Keywords: patch
: 29817 (view as bug list)
Depends on: 25991
Blocks: 24894 25302 71228
  Show dependency treegraph
 
Reported: 2009-11-04 06:07 UTC by Simon McVittie
Modified: 2013-11-04 18:05 UTC (History)
7 users (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Simon McVittie 2009-11-04 06:07:27 UTC
Maemo 5 uses various extended interfaces beyond what's in telepathy-spec. One such interface is an API for GSM conference calls:

http://git.collabora.co.uk/?p=rtcom-telepathy-glib.git;a=blob;f=rtcom-telepathy-glib/Channel_Interface_Conference.xml

http://git.collabora.co.uk/?p=rtcom-telepathy-glib.git;a=blob;f=rtcom-telepathy-glib/Channel_Interface_Conference_Member.xml

We should incorporate this functionality into the main telepathy-spec. The current proposal is to do this as part of a replacement for the StreamedMedia channel type.
Comment 1 Simon McVittie 2009-11-16 06:25:19 UTC
CallMerging <http://telepathy.freedesktop.org/spec/org.freedesktop.Telepathy.Channel.Interface.CallMerging.html> was an early attempt to represent this. The current proposal is for this to be part of the new Call channel type (Bug #24936).

It would be great if this could have a common API with the "upgrading 1-1 to multi-user" API from Bug #24939.
Comment 2 Simon McVittie 2009-11-16 06:46:25 UTC
The Conference interface as it exists in Maemo 5, with some brief notes.

interface Conference requires StreamedMedia, Group, Hold

    Interface for creating centralized conference with streamed media
    channels.

    This interface assumes that you have a centralized conferencing
    server, either hosted locally or controlled within the network. The
    conference model assumes that you first set up connection to each
    conferencing party and then refer the parties to the conferencing
    server.

    [As far as I can remember, the rationale for using channel-specific
    handles is that in a GSM conference, you can't necessarily know who else
    is in the conference, so we need a way to represent "smcv, mikhailz,
    and two unknown others", say. This is achieved by giving smcv and
    mikhailz channel-specific handles with known owners, and giving the two
    others distinct CSHs with an unknown owner. -smcv]

    method GetMemberChannels () -> a(oa{uu}): Channels)
        List of member channels in the conference along with the optional
        mapping of channel-specific handles on the conference channel to
        the global handles on the added channels.

        [Redundant with MemberChannels, should be removed? -smcv]

        out a(oa{uu}) (Member_Channel[]): Channels

    readable property InitialMembers: ao
        List of initial member channels. This is used by requestron
        interface to initiate the conference channel.

        [This property is immutable. From context I assume you make a
        conference by calling CreateChannel({InitialMembers: [C1, C2], ...})
        -smcv]

    readable property CurrentMemberChannels: ao
        List of current member channels in the conference.

        [This is mutable. -smcv]

    readable property MemberChannels: a(oa{uu}) (Member_Channel[])
        List of member channels in the conference along with the optional
        mapping of channel-specific handles on the conference channel to
        the global handles on the added channels. The list includes both
        the current members as well as pending members.

        [This is mutable. -smcv]

    struct Member_Channel
        o: Channel
        a{uu} (Handle_Owner_Map): Owner_Map

    signal MemberChannelAdded (o, a{uu})
        o: Channel
        a{uu} (Handle_Owner_Map): Handles
            Mapping of channel-specific handles on the conference channel to
            the global handles handles on the newly added member channel.

    signal MemberChannelRemoved (o, u, u)
        [Is this only ever triggered by a channel closing, or can channels
        be detached from the conference? If so, how? -smcv]

        o: Channel
        u (Contact_Handle): Actor
        u (Channel_Group_Change_Reason): Reason

    method AddMemberChannels ( ao: Members ) -> aa{uu}: Handles
        Not implemented. Going away in next release.

        [How does MemberChannelAdded ever happen, then? -smcv]

        in ao: Members
            The other channels to add into this one.
        out aa{uu}: Handles
            Mapping of handles on the conference channel to the handles on the
            added channels.
Comment 3 Simon McVittie 2009-11-16 06:51:05 UTC
interface ConferenceMember requires StreamedMedia

    Interface for managing channels that are used as conference members.

    This interface augments com.nokia.Telepathy.Channel.Interface.Conference.

    method JoinConference (o)
        Joins this channel to an existing conference channel.

        [Ah, this answers my previous question: this is how you join an existing conference. -smcv]

        in o: ConferenceChannel

    method GetConference () -> o
        Returns the conference channel of which this channel is member.

        [redundant with Conference, should probably be removed -smcv]

        out o: ConferenceChannel

    readable property Conference: o
        The conference channel of which this channel is member, "/" if not a member.

    method LeaveConference ()
        Removes this channel from the conference. This implies
        that the media streams within the conference are put on hold and
        the media streams within the member channel leaving the
        conference are unhold.

        [Ah, this answers my previous question: this is how you detach from a conference. -smcv]

    signal JoinedConference (o: ConferenceChannel)

    signal LeftConference
Comment 4 Simon McVittie 2009-11-16 06:55:39 UTC
The conceptual model used here matches GSM, but is more general (I think).

In GSM, a conference call is formed by gluing together two existing calls: the active call, and the call that is on hold. It might be possible to put the conference on hold, make more calls, and bridge those in too?

It may also be possible for us to tell that the other end of the call has turned into a conference.

To work with this interface, every call has the ConferenceMember interface, indicating that it is potentially a member of a conference. Making a call into a conference can be done either by creating a Conference then attaching ConferenceMember channels to it with JoinConference, or by putting the member calls in the InitialMembers property while calling CreateChannel.

While in a conference, I infer from the description of LeaveConference that all streams in the conference member are automatically put on hold by the CM?
Comment 5 Simon McVittie 2009-11-16 10:08:08 UTC
In the GSM case, we ought to at least be able to do everything that Ofono can. From <http://git.kernel.org/?p=network/ofono/ofono.git;a=blob_plain;f=doc/voicecallmanager-api.txt;hb=HEAD>:

>       object Dial(string number, string hide_callerid)
>
>           Initiates a new outgoing call. Returns the object path
>           to the newly created call. The clir variable holds
>           the CLIR override for this call.
>           The defines values are:
>               "" or "default" - Default (Netowrk) CLIR mode
>                           is used
>               "enabled" - Hides callerid, CLIR Invocation
>                       is used
>               "disabled" - Shows callerid, CLIR Suppression
>                       is used
>
>           This is usually implemented using the ATD AT command.

Out of scope for this bug; this is the normal CreateChannel/EnsureChannel, and CLIR is Bug #24909.

>       void Transfer()
>
>           Joins the currently Active (or Outgoing, depending
>           on network support) and Held calls together and
>           disconnects both calls. In effect transfering
>           one party to the other. This procedure requires
>           an Active and Held call and the Explicit Call Transfer
>           (ECT) supplementary service to be active.
>
>           This functionality is generally implemented by using
>           the +CHLD=4 AT command.

Out of scope for this bug; this is the Transfer interface, which was drafted
but never implemented. I'll make a new bug for it.

>       void SwapCalls()
>
>           Swaps Active and Held calls.  The effect of this
>           is that all calls (0 or more including calls in a 
>           multi-party conversation) that were Active are now Held,
>           and all calls (0 or more) that were Held are now Active.
>
>           GSM specification does not allow calls to be swapped 
>           in the case where Held, Active and Waiting calls exist.
>           Some modems implement this anyway, thus it is manufacturer
>           specific whether this method will succeed in the case
>           of Held, Active and Waiting calls.
>
>           This functionality is generally implemented by using
>           the +CHLD=2 AT command.

In StreamedMedia, we implement this by: you unhold the held call, and the
active call automatically becomes held. I suggest we do the same in Call.

This does have the problem that UIs can't know what effect this will have - it's a somewhat startling side-effect.

>       void ReleaseAndAnswer()
>
>           Releases currently active call and answers the currently
>           waiting call. Please note that if the current call is
>           a multiparty call, then all parties in the multi-party
>           call will be released.

Telepathy implementation: define "accept" as "move from LocalPending to
Members" (or the equivalent in Call). When you accept the waiting call:

* if there is a held call, no problem
* if there is an active call and no held call, the active call is automatically
  held by the CM
* if there is an active call and a held call, ??? - possibilities are
  - the active call is terminated by the CM
  - the held call is terminated by the CM and the active call gets held
  - the acceptance fails

Again this has the problem of a somewhat startling side-effect (particularly if the CM starts terminating calls spontaneously).

>       void HoldAndAnswer()
>
>           Puts the current call (including multi-party calls) on 
>           hold and answers the currently waiting call. Calling
>           this function when a user already has a both Active and
>           Held calls is invalid, since in GSM a user can have
>           only a single Held call at a time.

Used to implement the above.

>       void HangupAll()
>
>           Releases all calls. 

Could be used to implement Close() etc.

>       array{object} PrivateChat(object call)
>
>           Places the multi-party call on hold and makes desired
>           call active. This is used to accomplish private chat
>           functionality.  Note that if there are only two calls
>           (three parties) in the multi-party call the result will
>           be two regular calls, one held and one active. The
>           Multiparty call will need to be setup again by using the
>           CreateMultiparty method.  Returns the new list of calls
>           participating in the multiparty call.
>
>           This is usually implemented using the +CHLD=2X command.

Needs to be part of this interface. In Maemo 5, you call LeaveConference()
on the desired call.

>       array{object} CreateMultiparty()
>
>           Joins active and held calls together into a multi-party
>           call. If one of the calls is already a multi-party
>           call, then the other call is added to the multiparty
>           conversation. Returns the new list of calls
>           participating in the multiparty call.
>
>           There can only be one subscriber controlled multi-party
>           call according to the GSM specification.  
>
>           This is usually implemented using the +CHLD=3 AT
>           command.

Needs to be part of this interface. In Maemo 5, you call CreateChannel
with InitialMembers = [the held call, the active call]. It's unclear what
would happen if you tried to have InitialMembers take a different value.

>       void HangupMultiparty()
>
>           Hangs up the multi-party call.  All participating
>           calls are released.

Remove your self-handle from the Conference

>       void SendTones(string tones)
>
>           Sends the DTMF tones to the network.  Under GSM the
>           tones have a fixed duration.  Tones can be one of:
>           '0' - '9', '*', '#', 'A', 'B', 'C', 'D'. The last four
>           are typically not used in normal circumstances.

Out of scope, DTMF interface

>       array{object} MultipartyCalls [readonly]
>
>           Returns the list of calls that are currently
>           participating in the multi-party (MPTY) call.  The list
>           will be empty if no multi-party call is active, or a
>           list with at least two elements otherwise.

This implicitly assumes that there can only ever be one multi-party call.
Is this actually an invariant of GSM? I hear rumours that some
networks/providers/contracts allow more than one multi-party call on some
hardware?
Comment 6 Simon McVittie 2009-11-16 13:25:29 UTC
I discussed this with Sjoerd this afternoon and we came up with a proposal.
Basically, GSM only supports merging two or more calls (but in fact it can
never have three calls in a suitable state, so it can only really merge
exactly two calls), but XMPP supports creating a conference (in a chatroom)
from zero, one or many chats/calls. We can represent this by having an
interface whose presence implies at least the GSM functionality, and a flag
to indicate that in fact, XMPP-like functionality is also present.

Random side notes from our discussion:

[1] GSM connection managers can only really put one call on hold, but for
    least-astonishment I think they should be prepared to emulate hold for
    the active call too, by applying a bidirectional version of Mute;
    "unholding" the active call would unmute it in both directions, and
    "unholding" the held call would result in swapping the held and active
    calls in order to have the previously-held call continue.

    (Does Maemo's telepathy-ring already do this?)

    (Does telepathy-yafono already do this?)

[2] Sjoerd thinks there should be something in RequestableChannelClasses to
    represent whether calls merged with InitialChannels or Merge are placed
    in a "frozen" state (as in GSM), or ended, or left intact (as in Jingle).
    Possibly having this as a property on the 1-1 calls and/or the conference
    call would be enough, or possibly we do need a representation in the RCCs?

API sketch:

Channel.Interface.Conference
============================

requires Channel, Group

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).
|
| 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. [???] 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.

readable property Channels (ao: Channels)
    The individual channels that are continued by this conference.

    This property MUST NOT be requestable. [???]

    Change notification is via [FIXME: some sort of signal].

readable property InitialChannels (ao)
    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.

    [FIXME: we need some definition of the channels that can be continued
    into a conference like this: perhaps channels with Handle_Type_Contact
    and the same ChannelType as the conference?]

    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 Merge on them.
    [[2] would give a way to discover this]

    | 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 [because of [1]]. Not doing
    | an implicit hold/unhold seems to preserve least-astonishment.
    |
    | 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.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.

readable property SupportsNonMerges (b)
    [FIXME: needs a better name]

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

    | 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.

    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]

method Merge (o: Channel)
    Request that the given channel be incorporated into this channel.

    The given channel SHOULD be added to Channels if and only if the
    underlying protocol signals the merge in some way. It MUST NOT be added
    to InitialChannels (to preserve immutability).

    [FIXME: we need some definition of the channels that can be merged like
    this, as for InitialChannels]

    | In GSM it is possible to merge additional calls into an ongoing
    | conference.
    |
    | In XMPP this method could be implemented to merge a 1-1 Text channel
    | into a MUC Text channel by inviting the peer from the Text channel into
    | the MUC, or to merge a 1-1 Jingle call into a Muji call by inviting
    | the peer from the Jingle call into the Muji call. (MUC and Muji
    | channels are both implemented by XMPP MUCs, with Handle_Type_Room.)

Channel.Interface.Splittable
============================

An interface for channels that can be made conceptually part of a conference,
and can then be detached from that conference.

method Split ()
    Removes this channel from the conference.

    This implies that the media streams within the conference are put on
    hold and the media streams within the member channel leaving the
    conference are unhold. [... or, maybe it'd be less surprising if it
    didn't do this?]
Comment 7 Simon McVittie 2009-11-16 13:33:49 UTC
(In reply to comment #2)
>     [As far as I can remember, the rationale for using channel-specific
>     handles is that in a GSM conference, you can't necessarily know who else
>     is in the conference, so we need a way to represent "smcv, mikhailz,
>     and two unknown others", say. This is achieved by giving smcv and
>     mikhailz channel-specific handles with known owners, and giving the two
>     others distinct CSHs with an unknown owner. -smcv]

The other rationale for channel-specific handles is that more than one of the merged calls can have the same phone number, if it's a multi-line phone. For instance, if Rob and I are both in the same conference call, from different lines in Collabora head office, other participants in the conference call will see two distinct channel-specific handles, both of which will have the office's switchboard phone number as their handle owner.
Comment 8 Simon McVittie 2009-11-17 10:19:05 UTC
(In reply to comment #5)
> Out of scope for this bug; this is the Transfer interface, which was drafted
> but never implemented. I'll make a new bug for it.

Bug #25146, for the record.
Comment 10 Simon McVittie 2009-11-27 03:53:40 UTC
I've updated the branch, with:

* ChannelMerged, ChannelRemoved signals (the missing change notification for Channels)

* the CallMerging interface deleted to avoid confusion (this is the new way to do it)

* InitialInvitees as discussed on the mailing list, and InvitationMessage

* more cross-references
Comment 11 Simon McVittie 2009-11-27 05:59:13 UTC
If the spec cabal accept the clarification from Bug #25316, then we could solve the problem of "who can I invite?" by adding this additional patch:

http://git.collabora.co.uk/?p=user/smcv/telepathy-spec-smcv.git;a=shortlog;h=refs/heads/contact-caps-rooms

http://people.freedesktop.org/~smcv/telepathy-spec-contact_caps_rooms/spec/org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities.html#org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities.Contact_Capabilities_Map

commit 2afc284698e4a96c466d7382ddd46da64fa535e3
Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
Date:   2009-11-27 13:42:00 +0000

    ContactCapabilities: specify what channel classes with Handle_Type_Room or Handle_Type_None mean
    
    They wouldn't be meaningful otherwise, and we need a representation for
    this information.

diff --git a/spec/Connection_Interface_Contact_Capabilities.xml b/spec/Connection_Interface_Contact_Capabilities.xml
index 97b7cbc..803ab06 100644
--- a/spec/Connection_Interface_Contact_Capabilities.xml
+++ b/spec/Connection_Interface_Contact_Capabilities.xml
@@ -263,6 +263,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
             capabilities with the same code.</p>
         </tp:rationale>
 
+        <p>Channel classes with target handle type Handle_Type_Room or
+          Handle_Type_None indicate that if a channel matching the channel
+          class is created, then inviting the contact to that channel
+          can be expected to succeed.</p>
+
+        <tp:rationale>
+          <p>To support room-based XMPP protocols like
+            <a href="http://telepathy.freedesktop.org/wiki/Muji">Muji</a>
+            and MUC Tubes, it's necessary to be able to discover who can be
+            invited to a given room channel; most XMPP contacts won't
+            support being invited into a Muji conference call, at least
+            in the short to medium term.</p>
+        </tp:rationale>
+
         <p>No interpretation is defined for channel classes with any other
           target handle type, or for channel classes that do not fix a
           target handle type, in this version of the Telepathy
Comment 12 Simon McVittie 2009-11-30 10:03:26 UTC
(In reply to comment #11)
> If the spec cabal accept the clarification from Bug #25316, then we could solve
> the problem of "who can I invite?" by adding this additional patch:
> 
> http://git.collabora.co.uk/?p=user/smcv/telepathy-spec-smcv.git;a=shortlog;h=refs/heads/contact-caps-rooms

That patch has been merged, and will be in 0.19.0.

I've also updated my smcv/conference branch, with:

* InitialInvitees -> InitialInviteeHandles
* InitialInviteeIDs added
* Handler.FUTURE.RelatedConferencesBypassApproval added, as per discussion in real life (particularly useful for Text UIs)
Comment 13 Will Thompson 2009-12-01 05:22:40 UTC
(In reply to comment #12)
> I've also updated my smcv/conference branch, with:
> 
> * InitialInvitees -> InitialInviteeHandles
> * InitialInviteeIDs added
> * Handler.FUTURE.RelatedConferencesBypassApproval added, as per discussion in
> real life (particularly useful for Text UIs)

Semantics:

I think in practice no-one will create a conference from more than one text channel, and only calls will use Merge(). Maybe we could simplify accordingly? Moar interfaces? A property to say whether Merge() works? Currently Merge() vs. AddMembers() is confusing: when would you use one and when would you use the other?

From the definition of Merge():

	“The given channel SHOULD be added to Channels if and only if the underlying protocol signals the merge in some way.”

Maybe Merge() should only work if the underlying protocol signals the merge in some way, and if it does not you should just use AddMembers()?

Lint:

Should ChannelMerged include that channel's immutable props? Or is the UI expected either to not care, or already know them?
Comment 14 Mikhail Zabaluev 2009-12-01 05:54:02 UTC
(In reply to comment #13)
> I think in practice no-one will create a conference from more than one text
> channel, and only calls will use Merge(). Maybe we could simplify accordingly?
> Moar interfaces?

I support taking Merge out into a dedicated interface.
Maybe also, rename the Conference interface (to MultiUser?) to deemphasize the call case.
Comment 15 Simon McVittie 2009-12-01 06:42:57 UTC
(In reply to comment #14)
> I support taking Merge out into a dedicated interface.

We should certainly consider this. It's a tradeoff between:

* move Merge to Conn.I.Mergeable (requires Conference, Group, Channel) - proliferation of interfaces doesn't really benefit anyone

* keep Merge in Conn.I.Conference - Conference is bigger and more confusing for clients; CMs that can't *really* merge channels have to add simple boilerplate to implement Merge() as equivalent to AddMembers([TargetHandle])

neither of which is really desirable.

If nobody objects strongly, I'm going to merge Conference in its current draft state for 0.19.0 (a merged draft is better than nothing), and require a resolution for this problem before we undraft it. We need to gather implementation experience before undrafting anyway.

> Maybe also, rename the Conference interface (to MultiUser?) to deemphasize the
> call case.

XMPP MUCs are "multi-user conferences", so I don't see this as a problem :-)
Comment 16 Simon McVittie 2009-12-01 07:00:32 UTC
(In reply to comment #15)
> If nobody objects strongly, I'm going to merge Conference in its current draft
> state for 0.19.0

Thinking about it, the conservative thing to do is to have more interfaces with less functionality - it's easier to merge them than to split them - so we should split out Merge into its own interface at least for now, regardless of whether I think Merge should go back into Conference later.

I've commited a patch to separate it into a new MergeableConference interface.
Comment 17 Simon McVittie 2009-12-01 09:09:24 UTC
Arguments against Merge being in Conference:

* it's another mandatory-to-implement vtable slot for CMs

* in protocols where the CM really just falls back to inviting the target handle, the API is lying

* it makes the desired API for text clients harder to explain: "you upgrade channels like *this* (you can also Merge(), but ignore that)"

* in practice, UIs are more likely to want to invite people than they are to want to merge channels (Empathy's current invitation UI is merge-like, which isn't discoverable enough - people keep asking in #empathy "why can't I invite people?", followed eventually by "oh, *that's* how you do it")

Arguments for Merge being in Conference:

* clients that prefer to Merge (if there are any? possibly only Call clients, not Text?) need to look at whether the interface is present

16:55 * sjoerd dislikes having a new interface for one method that has a 
        completely obvious fallback path in protcools that don't support it

Relatedly:

16:58 < sjoerd> smcv: btw does the MergableBadgers interface have a way of 
                saying you can't merge more channels in ?
16:58 < smcv> sjoerd: no. it could, if you want it to
16:58 < smcv> sjoerd: I don't know what protocol could support that, though
16:59 < smcv> sjoerd: in XMPP it's unlimited, in GSM I think it's unlimited 
              until the network tells you you can't?
16:59 < sjoerd> Not sure if say GSM has a limit on how many people you can 
                merge into a conference
16:59 * sjoerd was just idly wondering about stuff
Comment 18 Simon McVittie 2009-12-01 09:46:55 UTC
Current draft merged to master, will be in 0.19.0.
Comment 19 Guillaume Desmottes 2009-12-22 03:23:15 UTC
Empathy now implements Conferences for text channels. We'd like to get it undrafted before 2.30 if possible (29th Mar): https://bugzilla.gnome.org/show_bug.cgi?id=605214
Comment 20 Simon McVittie 2010-01-25 03:16:01 UTC
Proposals in Bug #25991, which should be incorporated into the spec:

* Conference spec shouldn't forbid using both InitialIds and InitialChannels

(Use-case: I've got a 1-to-1 chat in a channel and i want to invite a@b in it so i
request a new one with   InitialChannels = [ MyChannel] , InitialIds = [ "a@b"
]; the new channel should then be a continuation only of MyChannel and not of any
channel you may already have open with a@b.)

* It might make sense to have InitialIds on the new channel be the union of the requested InitialIds and the TargetIds of the channels in InitialChannels.
Comment 21 Lassi Syrjala 2010-02-25 03:20:24 UTC
(In reply to comment #10)
> I've updated the branch, with:
> 
> * ChannelMerged, ChannelRemoved signals (the missing change notification for
> Channels)

The interface seems to be missing the mapping from channel-specific handles[*] to member channel object paths. Also, for client authors not wanting to deal with the Group interface, it might be useful to provide the change reason and the actor in ChannelRemoved as well.

[*] these are needed as the conference can contain two (or more) channels with the same contact
Comment 22 Andre Moreira Magalhaes 2010-03-01 07:52:16 UTC
It would be good if Conference.ChannelMerged could contain the channel immutable properties as a param so we can avoid having to introspect Channel in tpqt4 in some cases.
Comment 23 Simon McVittie 2010-03-11 05:29:32 UTC
(In reply to comment #21)
> The interface seems to be missing the mapping from channel-specific handles[*]
> to member channel object paths.

A fair point, we should think about adding that.

> Also, for client authors not wanting to deal
> with the Group interface, it might be useful to provide the change reason and
> the actor in ChannelRemoved as well.

I can only see two possibilities: the channel closed (=> more details available from the channel's invalidation reason), and the channel was split away.

Perhaps we should define that if the channel was removed because it terminated, then the channel must signal that it closed (and hopefully why) before ChannelRemoved is signalled?

I don't think "client authors not wanting to deal with the Group interface" are necessarily something we want to support. Every Conference is also a Group, and duplicating information sems counter-productive. Is there a specific bit of information that's too hard in the Group interface, and can we fix it in Group instead? (Note that telepathy-qt4 and telepathy-glib both provide some convenience API for Groups.)
Comment 24 Simon McVittie 2010-03-11 05:30:57 UTC
(In reply to comment #22)
> It would be good if Conference.ChannelMerged could contain the channel
> immutable properties as a param so we can avoid having to introspect Channel in
> tpqt4 in some cases.

Yeah, we can do that in draft 2.
Comment 25 Lassi Syrjala 2010-03-11 05:59:10 UTC
(In reply to comment #23)
> Is there a specific bit of information that's too hard in the Group interface,
> and can we fix it in Group instead? (Note that telepathy-qt4 and telepathy-glib
> both provide some convenience API for Groups.)

The channel-specific handles might make the Group interface inconvenient compared to tracking the ChannelMerged and ChannelRemoved signals.
Comment 26 Simon McVittie 2010-04-14 10:47:00 UTC
Regarding EnsureChannel with InitialInvitee{ID,}s:

18:09 < smcv> jonnylamb: if ensuring, their semantics would be quite odd - "if 
              no existing channel, make one and invite these, else do nothing 
              to the existing channel"
...
18:27 < smcv> jonnylamb: the "what does it mean when ensuring?" thing is 
              irritating, and could do with either a special case (when there's 
              an existing channel, those people/channels get invited/merged) or 
              a warning

Regarding InitialInvitee{ID,}s vs. InitialChannels:

18:32 < smcv> so there are two purposes
18:32 < smcv> 1) request merges
18:33 < smcv> 2) when seeing a new channel, know wtf is going on
18:33 < smcv> for the former you can use any or all of the three properties, 
              and what you're actually asking for is the union
18:33 < smcv> for the latter, it seems best to offer as much information as 
              possible
18:33 < smcv> "this channel is an upgrade/continuation of C1 and C2, and is 
              talking to H1, H2, H3 (that's I1, I2, I3)"
18:34 < smcv> where Cn are channels, Hn are handles, In are identifiers
18:34 < smcv> constrained by the need to decide what you're going to announce 
              before you announce it, and not change it thereafter
18:34 < smcv> does that make sense or am *I* not being clear this time? :-)
18:35 < jonnylamb> Okay, yes I get this now. I think I was just confused with 
                   the InitialInvitee* name.
18:35 < smcv> do you think the current semantics make sense, assuming we rename 
              to InitialMembers/InitialMemberIDs or something?
18:36 < smcv> I think you're right that the name is confusing
18:37 < jonnylamb> Well I'm not /so/ sure about making Initial* a union. We can 
                   find out the members using the group interface (and in 
                   practice that's what everyone will do).
18:37 < smcv> yeah, true
18:37 < jonnylamb> I'm more in favour of keeping the name Invitee and making it 
                   do what it sounds like it will do.
18:38 < smcv> fair enough
18:38 < jonnylamb> So when your new channel is announced, if InitialInvitee* is 
                   set, you can know that that contact(s) was invited when the 
                   channel was created, and in practice: "this is the contact 
                   that necessitated this new channel".
18:39 < smcv> ok
18:39 < jonnylamb> Does that sound reasonable?
18:39 < smcv> to a point
18:39 < smcv> InitialInvitees should still be the union of the requested 
              InitialInvitees and the handles of the requested InitialInviteeIDs
18:39 < smcv> and vice versa
18:40 < smcv> (so you can look at the one you prefer to work with, and ignore 
              the other)
18:40 < jonnylamb> Oh, yes I totally agree with that.
18:40 < jonnylamb> Same semantics as Target{Handle,ID} really.
18:40 < smcv> bonus points if you devise a good wording for requiring them to 
              be in a corresponding order on channels, without requiring them 
              to match up in requests
18:41 < smcv> but yes, that makes sense
Comment 27 Simon McVittie 2010-04-14 11:04:54 UTC
(In reply to comment #25)
> (In reply to comment #23)
> > Is there a specific bit of information that's too hard in the Group interface,
> > and can we fix it in Group instead? (Note that telepathy-qt4 and telepathy-glib
> > both provide some convenience API for Groups.)
> 
> The channel-specific handles might make the Group interface inconvenient
> compared to tracking the ChannelMerged and ChannelRemoved signals.

If we do this:

(In reply to comment #23)
> Perhaps we should define that if the channel was removed because it terminated,
> then the channel must signal that it closed (and hopefully why) before
> ChannelRemoved is signalled?

and we also make ChannelMerged contain the immutable properties, then I think that's sufficient to tell you what's going on?

* on startup, make a TpChannel for each channel in Channels

* on ChannelMerged, make a TpChannel for it (using those immutable properties) and put it in a map { object path => TpChannel }

* on ChannelRemoved, look up the TpChannel and see whether it has been invalidated yet (or, for Call channels, whether it has moved to Error state). If it has, tp_proxy_get_invalidated() (or for Call channels, a yet-to-be-added accessor) tells you the error; if it hasn't, then by elimination, the reason for removal must have been that it was detached.

Does that seem reasonable?

On StreamedMedia, the sub-channel's TpChannel will automatically pick up the error reason from its Group interface without your help, hence the ability to use TpProxy:invalidated.
Comment 28 Will Thompson 2010-07-14 09:21:59 UTC
I have been beavering away at this, and I have now arrived at something I think should make people happy: http://people.freedesktop.org/~wjt/telepathy-spec-conference/spec/Channel_Interface_Conference.html

Summary of what's changed:

• ChannelMerged now contains the immutable properties, and channel-specific handle (if any), of the merged channel;
• There's an OriginalChannels property mapping channel-specific handles to member channel paths (better name very welcome);
• SupportsNonMerges has been removed in favour of using the presence or absence of Initiator{Handles,IDs} in Allowed (I tried to explain it to someone in real life, failed, and decided that this was a good reason to just delete it);
• I've removed a bunch of the FIXMEs surrounding how GSM calls get magically frozen/unfrozen, in favour of just saying “Hey, GSM calls are a bit strange”;
• Closed is required to be signalled before ChannelRemoved if they're both firing;
• You can merge to a named text MUC you're already in using EnsureChannel;
• Better docstrings a-plenty.

I'd love some feedback on whether this solves people's issues above (which I think it does).
Comment 29 Guillaume Desmottes 2010-08-26 04:42:25 UTC
*** Bug 29817 has been marked as a duplicate of this bug. ***
Comment 30 Will Thompson 2010-08-26 09:51:29 UTC
(In reply to comment #28)
> I'd love some feedback on whether this solves people's issues above (which I
> think it does).

Oh, it doesn't address Lassi's comment 21. From Ring:

    /* XXX: this used to take actor and reason which could be
       useful */
    ring_svc_channel_interface_conference_emit_channel_removed(
      self, object_path);
Comment 31 Simon McVittie 2010-09-13 05:50:08 UTC
This branch looks good. If everyone involved is happy with this API then I think we're ready to undraft for 0.20.0.

(In reply to comment #30)
>     /* XXX: this used to take actor and reason which could be
>        useful */
>     ring_svc_channel_interface_conference_emit_channel_removed(
>       self, object_path);

I'm very tempted to say "let's add an a{sv} to ChannelRemoved and get on with our lives". We can define keys for that a{sv} later.
Comment 32 Simon McVittie 2010-09-16 07:13:10 UTC
This was undrafted shortly before 0.20.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.