<?xml version="1.0" ?>
<node name="/Client_Observer"
  xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
  <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
  <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
  <tp:license xmlns="http://www.w3.org/1999/xhtml">
    <p>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.</p>

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

    <p>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.</p>
  </tp:license>

  <interface name="org.freedesktop.Telepathy.Client.Observer">
    <tp:added version="0.17.26">(as a stable interface)</tp:added>

    <tp:requires interface="org.freedesktop.Telepathy.Client"/>

    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
      <p>Observers monitor the creation of new channels. This
        functionality can be used for things like message logging.
        All observers are notified simultaneously.</p>

      <p>Observers SHOULD NOT modify the state of a channel except
        via user interaction.</p>

      <tp:rationale>
        <p>We want Observer UIs for file transfer channels (a progress
          bar for the transfer) to be able to have a Cancel button.</p>
      </tp:rationale>

      <p>Observers MUST NOT carry out actions that exactly one process
        must take responsibility for (e.g. acknowledging Text
        messages, or carrying out the actual transfer in a file transfer
        channel).</p>

      <tp:rationale>
        <p>Since arbitrarily many observers can be activated for
          each channel, it would not make sense for observers to do things
          that can only be done by one process (acknowledging
          <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
          messages, carrying out streaming for
          <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
          channels, doing the actual data transfer for file transfers,
          setting up the out-of-band connection for Tubes). The
          <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
          is responsible for such tasks.</p>

        <p>Handlers MAY, of course, delegate responsibility for these
          tasks to other processes (including those run as observers),
          but this MUST be done explicitly via a request from the Handler
          to the Observer.</p>
      </tp:rationale>

      <p>Whenever a collection of new channels is signalled, the channel
        dispatcher will notify all running or activatable observers whose
        <tp:member-ref>ObserverChannelFilter</tp:member-ref> property
        (possibly as cached in the .client file) indicates that they are
        interested in some of the channels.</p>

      <p>Observers are activated for all channels in which they have
        registered an interest - incoming, outgoing or automatically created -
        although of course the ObserverChannelFilter property can be set
        to filter on the
        <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel">Requested</tp:dbus-ref>
        property.</p>

      <p>Because it might take time for an observer to become ready (for
        instance, a Text logger needs to wait until pending messages have been
        downloaded), the channel dispatcher must wait (up to some timeout) for
        all observers to return from
        <tp:member-ref>ObserveChannels</tp:member-ref> before letting anything
        destructive happen. Destructive things (e.g. acknowledging messages)
        are defined to be done by handlers, therefore HandleWith and Claim
        aren't allowed to succeed until all observers are ready.</p>

      <p>Non-interactive approvers (for instance, to shoot down spam
        IM channels before the tray icon blinks at the user, or to grab
        a SASL channel before the user is prompted for a password) can
        be implemented as observers by following these steps:</p>

      <ol>
        <li><tp:member-ref>ObserveChannels</tp:member-ref>() is called
          on the observer.</li>
        <li>The observer calls <tp:dbus-ref
          namespace="ofdT.ChannelDispatchOperation">Claim</tp:dbus-ref>()
          on the CDO.</li>
        <li>The observer then returns from
          <tp:member-ref>ObserveChannels</tp:member-ref>().</li>
        <li><tp:dbus-ref
          namespace="ofdT.ChannelDispatchOperation">Claim</tp:dbus-ref>
          will return successfully if the channels were successfully
          claimed, or failure if someone else got there first.</li>
      </ol>

      <p>Non-interactive approvers implemented as observers SHOULD
        also set <tp:member-ref>DelayApprovers</tp:member-ref> to TRUE
        so that other Approvers are not called on until all observers
        return from <tp:member-ref>ObserveChannels</tp:member-ref>.
        This gives non-interactive approvers a chance to claim the
        channels before Approvers are called.</p>
    </tp:docstring>

    <property name="ObserverChannelFilter"
      tp:name-for-bindings="Observer_Channel_Filter"
      type="aa{sv}" access="read" tp:type="Channel_Class[]">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A specification of the channels in which this observer is
          interested. The <tp:member-ref>ObserveChannels</tp:member-ref> method
          should be called by the channel dispatcher whenever any of the new
          channels in a <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
          signal match this description.</p>

        <p>Only certain D-Bus types have useful semantics for matching like this,
          so only certain types are allowed:</p>

        <dl>
          <dt>Integers of all sizes, including byte (y, n, q, i, u, x, t)</dt>
          <dd>Matched by numeric value, regardless of type (e.g. 42 as a
            16-bit signed integer 'n' is considered equal to 42 as a 32-bit
            unsigned integer 'u')</dd>

          <dt>Booleans (b)</dt>
          <dd>Matched by equality in the obvious way; not considered equal to any
            other type</dd>

          <dt>Strings (s)</dt>
          <dd>Matched by equality in the obvious way; not considered equal to any
            other type</dd>

          <dt>Object paths (o)</dt>
          <dd>Matched by equality in the obvious way; not considered equal to any
            other type</dd>

        </dl>

        <p>This property never changes while the observer process owns its
          Client bus name. For activatable processes, the filter can change
          due to an upgrade - the channel dispatcher SHOULD observe changes to
          .client files using a mechanism like inotify.</p>

        <tp:rationale>
          <p>Not allowing this property to change is a simplification,
            particularly for activatable processes (we reject the possibility
            that a process with a .client file, when activated, has a filter
            that differs from what its .client file said).</p>

          <p>If an Observer wants to add extra channels to its list of
            interests at runtime, it can register an additional Client bus name
            (for instance, the org.freedesktop.Telepathy.Client.Empathy process
            with unique name :1.42 could additionally register
            org.freedesktop.Telepathy.Client.Empathy._1_42) with additional
            filters. To remove those filters, it can release the bus name;
            it could even re-claim the bus name immediately, with different
            filters.</p>

          <p>The same principle is applied to Approvers and Handlers.</p>
        </tp:rationale>

        <p>For observers that have a .client file, the channel dispatcher
          may discover this property from keys of the form
          "<code><em>propertyname</em> <em>type</em></code>",
          in groups in the .client file whose name is the name of this
          interface followed by <code>.ObserverChannelFilter</code>,
          a space and an ASCII decimal number starting from 0.</p>

        <p>Values in the .client file are encoded in exactly the same way as
          the <code>default-<em>p</em></code> keys in .manager files, as
          described in the <tp:dbus-ref namespace="org.freedesktop.Telepathy"
            >ConnectionManager</tp:dbus-ref> interface (but note that not all
          types supported in .manager files can appear in .client files).</p>

        <p>For instance, a .client file for an observer that is only interested
          in Text channels, with CONTACT or ROOM handles, that were requested by
          a local client:</p>

<pre>
[org.freedesktop.Telepathy.Client]
Interfaces=org.freedesktop.Telepathy.Client.Observer;

[org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 0]
org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
org.freedesktop.Telepathy.Channel.TargetHandleType u=1
org.freedesktop.Telepathy.Channel.Requested b=true

[org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 1]
org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
org.freedesktop.Telepathy.Channel.TargetHandleType u=2
org.freedesktop.Telepathy.Channel.Requested b=true
</pre>

      </tp:docstring>
    </property>

    <property name="Recover" tp:name-for-bindings="Recover" type="b"
      access="read">
      <tp:added version="0.19.4">
        When using telepathy-mission-control, version 5.4.0 or later is
        needed for this property to be useful.
      </tp:added>

      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>If true, upon the startup of this observer, <tp:dbus-ref
        namespace="org.freedesktop.Telepathy.Client.Observer">ObserveChannels</tp:dbus-ref>
        will be called for every already existing channel matching
        its <tp:dbus-ref
        namespace="org.freedesktop.Telepathy.Client.Observer">ObserverChannelFilter</tp:dbus-ref></p>

        <p>When an activatable client having this property disappears from the
          bus and there are channels matching its ObserverChannelFilter,
          ObserveChannels will be called immediately to reactivate it
          again. Such clients should specify this property in their
          <tt>.client</tt> file as follows:</p>

<pre>
[org.freedesktop.Telepathy.Client.Observer]
Recover=true
</pre>

        <tp:rationale>
          <p>This means that if an activatable Observer crashes, it will
            be restarted as soon as possible; while there is an unavoidable
            possibility that it will miss some events during this process
            (particularly <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
            messages), this window of event loss is kept to a minimum.</p>

           <p>Non-activatable observers can't take advantage of this
            mechanism, but setting this property on a non-activatable
            observer does allow it to "catch up" on channels that are
            currently active at the time that it starts up.</p>
        </tp:rationale>

        <p>When the ObserveChannels method is called due to observer recovery,
        the <var>Observer_Info</var> dictionary will contain one extra item
        mapping the key <code>"recovering"</code> to <code>True</code>.</p>
      </tp:docstring>
    </property>

    <method name="ObserveChannels" tp:name-for-bindings="Observe_Channels">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Called by the channel dispatcher when channels in which the
          observer has registered an interest are announced in a <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
          signal.</p>

        <p>If the same NewChannels signal announces some channels that match
          the filter, and some that do not, then only a subset of the channels
          (those that do match the filter) are passed to this method.</p>

        <p>If the channel dispatcher will split up the channels from a single
          NewChannels signal and dispatch them separately (for instance
          because no installed Handler can handle all of them), it will call
          ObserveChannels several times.</p>

        <p>The observer MUST NOT return from this method call until it is ready
          for a handler for the channel to run (which may change the channel's
          state).</p>

        <tp:rationale>
          <p>The channel dispatcher must wait for observers to start up,
            to avoid the following race: text channel logger (observer) gets
            ObserveChannels, text channel handler gets
            <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>
            channel handler starts up faster and acknowledges messages,
            logger never sees those messages.</p>
        </tp:rationale>

        <p>The channel dispatcher SHOULD NOT change its behaviour based on
          whether this method succeeds or fails: there are no defined D-Bus
          errors for this method, and if it fails, this only indicates that
          an Observer is somehow broken.</p>

        <tp:rationale>
          <p>The expected error response in the channel dispatcher is to
            log a warning, and otherwise continue as though this method
            had succeeded.</p>
        </tp:rationale>
      </tp:docstring>

      <arg name="Account" type="o" direction="in">
        <tp:docstring>
          The
          <tp:dbus-ref namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
          with which the channels are associated. The
          well-known bus name to use is that of the
          <tp:dbus-ref namespace="org.freedesktop.Telepathy">AccountManager</tp:dbus-ref>.
        </tp:docstring>
      </arg>

      <arg name="Connection" type="o" direction="in">
        <tp:docstring>
          The
          <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
          with which the channels are associated. The
          well-known bus name to use can be derived from this object
          path by removing the leading '/' and replacing all subsequent
          '/' by '.'.
        </tp:docstring>
      </arg>

      <arg name="Channels" type="a(oa{sv})" tp:type="Channel_Details[]"
        direction="in">
        <tp:docstring>
          The <tp:dbus-ref
            namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>s
          and their properties. Their well-known bus names are all the same as
          that of the Connection.
        </tp:docstring>
      </arg>

      <arg name="Dispatch_Operation" type="o" direction="in">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The path to the <tp:dbus-ref
              namespace="org.freedesktop.Telepathy">ChannelDispatchOperation</tp:dbus-ref>
            for these channels, or the special value '/' if there is no
            ChannelDispatchOperation (because the channels were requested, not
            incoming).</p>

          <p>If the Observer calls <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">Claim</tp:dbus-ref>
            or <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">HandleWith</tp:dbus-ref>
            on the dispatch operation, it MUST be careful to avoid deadlock,
            since these methods cannot return until the Observer has returned
            from <tp:member-ref>ObserveChannels</tp:member-ref>.</p>

          <tp:rationale>
            <p>This allows an Observer to <tp:dbus-ref
                namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">Claim</tp:dbus-ref>
              a set of channels without having to match up calls to this method
              with calls to <tp:dbus-ref
                namespace="org.freedesktop.Telepathy.Client.Approver">AddDispatchOperation</tp:dbus-ref>.</p>
          </tp:rationale>
        </tp:docstring>
      </arg>

      <arg name="Requests_Satisfied" type="ao" direction="in">
        <tp:docstring>
          The <tp:dbus-ref
          namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>s
          satisfied by these channels.

          <tp:rationale>
            If the same process is an Observer and a Handler, it can be useful
            to be given this information as soon as possible (it will also
            be passed to <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Client">Handler.HandleChannels</tp:dbus-ref>).
          </tp:rationale>
        </tp:docstring>
      </arg>

      <arg name="Observer_Info" type="a{sv}" direction="in">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Additional information about these channels. Currently defined
            keys are:</p>

          <dl>
            <dt><code>recovering</code> - b</dt>
            <dd><code>True</code> if ObserveChannels was called for an existing
              channel (due to the <tp:member-ref>Recover</tp:member-ref>
              property being <code>True</code>); <code>False</code> or omitted
              otherwise.

              <tp:rationale>
                This allows observers to distinguish between new channels (the normal
                case), and existing channels that were given to the observer in order
                to catch up on previous events (perhaps after a previous instance of
                the same observer crashed).
              </tp:rationale>
            </dd>

            <dt><code>request-properties</code> - a{oa{sv}}</dt>
            <dd>A map from <tp:dbus-ref
              namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
              paths listed in <var>Requests_Satisfied</var> to
              <tp:type>Qualified_Property_Value_Map</tp:type>s containing
              namespaced immutable properties of each request.</dd>
          </dl>

          <p>All defined keys for this dictionary are optional;
            observers MAY safely ignore any entry in this dictionary.</p>
        </tp:docstring>
      </arg>

    </method>

    <property name="DelayApprovers" type="b" access="read"
      tp:name-for-bindings="Delay_Approvers">
      <tp:added version="0.21.11"/>
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>If true, the channel dispatcher will wait for
            <tp:member-ref>ObserveChannels</tp:member-ref> to return
            before calling <tp:dbus-ref
            namespace="ofdT.Client">Approver.AddDispatchOperation</tp:dbus-ref>
            on appropriate Approvers.</p>

          <p>This property SHOULD be false unless there is a reason
            why a channel should not be given to approvers. An example
            of this is if an Observer is also a Handler and wants to
            <tp:dbus-ref
            namespace="ofdT.ChannelDispatchOperation">Claim</tp:dbus-ref>
            a channel so that it becomes its handler and doesn't want
            any approver to be called, this property should be true.</p>

          <p>Observers and Approvers should be called at the same time
            in normal operation (with this property set to false) to
            improve responsiveness. For example, if an incoming call
            appears, the approver should get the channel as fast as
            possible to show a dialog, but if an approver has to make
            round-trips to set itself up, then the approval of the
            channel is delayed. As a result, it is recommended for this
            property to remain false unless absolutely necessary.</p>

          <p>For service-activatable clients, this property should be
            specified in the observer's <tt>.client</tt> file as
            follows:</p>

          <p>If this property is not implemented (telepathy-mission-control
            5.7.5 and older), the channel dispatcher SHOULD consider it as
            being false.</p>

<pre>
[org.freedesktop.Telepathy.Client.Observer]
DelayApprovers=true
</pre>
        </tp:docstring>
    </property>

  </interface>
</node>
<!-- vim:set sw=2 sts=2 et ft=xml: -->
