Bug 29479

Summary: Contact presence API is confusing
Product: Telepathy Reporter: Olli Salli <ollisal>
Component: tp-qtAssignee: Andre Moreira Magalhaes <andrunko>
Status: RESOLVED FIXED QA Contact: Telepathy bugs list <telepathy-bugs>
Severity: minor    
Priority: medium    
Version: git master   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 29486    

Description Olli Salli 2010-08-10 03:28:20 UTC
Tp-Qt4 currently exposes contact presence on the Tp::Contact objects as QString presenceStatus(), uint presenceType() and QString presenceMessage(). This is essentially the same as what's on the D-Bus level, with the presence status and presence type being at first glance mutually redundant (without reading the D-Bus specification, anyway). This has caused some confusion at least in the KDE Telepathy integration efforts already.

From the Telepathy D-Bus spec:

---

Each status has an arbitrary string identifier which should have an agreed meaning between the connection manager and any client which is expected to make use of it. The following well-known values should be used where possible to allow clients to identify common choices:

status identifier  Connection_Presence_Type                comments
available          Connection_Presence_Type_Available	
away               Connection_Presence_Type_Away	
brb                Connection_Presence_Type_Away           Be Right Back (a more specific form of Away)
busy               Connection_Presence_Type_Busy	
dnd                Connection_Presence_Type_Busy           Do Not Disturb (a more specific form of Busy)
xa                 Connection_Presence_Type_Extended_Away  Extended Away
hidden             Connection_Presence_Type_Hidden	   Also known as "Invisible" or "Appear Offline"
offline            Connection_Presence_Type_Offline	
unknown            Connection_Presence_Type_Unknown        special, see below
error              Connection_Presence_Type_Error          special, see below

As well as these well-known status identifiers, every status also has a numerical type value chosen from Connection_Presence_Type which can be used by the client to classify even unknown statuses into different fundamental types.

These numerical types exist so that even if a client does not understand the string identifier being used, and hence cannot present the presence to the user to set on themselves, it may display an approximation of the presence if it is set on a contact.

---

In the above table, the status identifier is what Contact::presenceStatus() would give you, and Connection_Presence_Type the Tp::ConnectionPresenceType... value Contact::presenceType() would return.

Currently, we don't expose the well-known string identifiers for the statuses, as constants or otherwise. Also, Tp::Contact completely lacks any documentation for said accessors :)

Possible solutions:
 - Define the well-known contact presence types as string constants, and document Contact::presenceStatus() as most often (but not always!) returning one of them
 - Define a small Contact(::?)Presence class
   * has the status and the type as properties
   * accepts any string identifier in the constructor, but has const static instances for the well-known statuses listed in the spec
   * documented usage: first try if you can display the status given by presenceStatus() (have icon for it), if not, fall back to displaying the status indicated by the presenceType()
   * document that a client should at least be able to display all of the static instances, but may allow plugins/themes/etc to be able to provide icons for more based on the string id
   * equality comparison by the string identifier, warn if the string id is the same but the type different (indicates spec noncompliance somewhere)
   * would then be Contact::presence(), deprecating Contact::presence{Status,Type}(), presenceMessage() would remain as-is

The reason for not having a distinct ConnectionPresenceType for every possible string identifier (such that the string id could be removed) in the first place is twofold:
 i) Allows older clients to display refined statuses added in newer spec / CM versions using the small set of the fallback enum status type categories
 ii) Allows protocol-specific (or extension) statuses. Some protocols have statuses like "out-to-lunch" which we don't necessarily want to require every client to be able to represent as anything more specific than the generic away status given by presenceType(). However, protocol-specific UIs/plugins are able to present the specific status using the string id.

This bug actually belongs to a broader category: we shouldn't require client apps to hard-code supposedly "well-known" string ids in them. This mostly applies to variant map keys. Channel::GroupMemberChangeDetails is one example of a proper API wrapping what's actually just a variant map / string-keyed API underneath - it has accessors like hasMessage(), message() corresponding to every well-known key such as "message". I'll file this more general issue as a separate bug depending on this one.
Comment 1 Olli Salli 2010-11-05 00:59:25 UTC
Fixed in 0.3.13/0.3.14.

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.