[telepathy-mission-control/master] fd.o #21176: update Handler API from telepathy-spec master

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Apr 17 10:23:10 PDT 2009


This is an API break.

* Split out RequestNotification interface
* Move AddRequest to that interface
* Rename RemoveFailedRequest to RemoveRequest and move it to that interface

Brief rationale: Handlers that don't care about the requests don't want
to be service-activated.
---
 src/client.xml                                     |    1 +
 src/mcd-account-requests.c                         |    2 +-
 src/mcd-dispatcher.c                               |   29 +++-
 test/twisted/account-requests/cancel.py            |    3 +-
 test/twisted/account-requests/create-text.py       |    3 +-
 .../delete-account-during-request.py               |   19 +-
 test/twisted/constants.py                          |    1 +
 test/twisted/dispatcher/cancel.py                  |    4 +-
 test/twisted/dispatcher/create-text.py             |    4 +-
 test/twisted/mctest.py                             |    7 +-
 xml/Client_Handler.xml                             |  156 +++++++-----------
 ...ient_Handler_Interface_Request_Notification.xml |  173 ++++++++++++++++++++
 xml/Makefile.am                                    |    1 +
 xml/nmc5.xml                                       |    1 +
 14 files changed, 287 insertions(+), 117 deletions(-)
 create mode 100644 xml/Client_Handler_Interface_Request_Notification.xml

diff --git a/src/client.xml b/src/client.xml
index 93bb711..e8d3b43 100644
--- a/src/client.xml
+++ b/src/client.xml
@@ -5,6 +5,7 @@
 <xi:include href="../xml/Client.xml"/>
 <xi:include href="../xml/Client_Approver.xml"/>
 <xi:include href="../xml/Client_Handler.xml"/>
+<xi:include href="../xml/Client_Handler_Interface_Request_Notification.xml"/>
 <xi:include href="../xml/Client_Observer.xml"/>
 
 </tp:spec>
diff --git a/src/mcd-account-requests.c b/src/mcd-account-requests.c
index 3150473..9240de0 100644
--- a/src/mcd-account-requests.c
+++ b/src/mcd-account-requests.c
@@ -186,7 +186,7 @@ _mcd_account_create_request (McdAccount *account, GHashTable *properties,
      * immediately cause a failure to be signalled. It'll do for now though. */
 
     /* we use connect_after, to make sure that other signals (such as
-     * RemoveFailedRequest) are emitted before the Failed signal */
+     * RemoveRequest) are emitted before the Failed signal */
     /* WARNING: on_channel_status_changed unrefs the McdChannel (!), so we
      * give it an extra reference, so that we can return a ref from this
      * function */
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index e9f539b..78edef4 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -144,6 +144,7 @@ typedef enum
     MCD_CLIENT_APPROVER = 0x1,
     MCD_CLIENT_HANDLER  = 0x2,
     MCD_CLIENT_OBSERVER = 0x4,
+    MCD_CLIENT_HANDLER_REQUEST_NOTIFICATION  = 0x8,
 } McdClientInterface;
 
 typedef struct _McdClient
@@ -192,6 +193,8 @@ typedef struct _McdClient
     "org.freedesktop.Telepathy.Client.Approver"
 #define MC_FILE_IFACE_CLIENT_HANDLER \
     "org.freedesktop.Telepathy.Client.Handler"
+#define MC_FILE_IFACE_CLIENT_HANDLER_INTERFACE_REQUEST_NOTIFICATION \
+    "org.freedesktop.Telepathy.Client.Handler.Interface.RequestNotification"
 #define MC_FILE_IFACE_CLIENT_OBSERVER \
     "org.freedesktop.Telepathy.Client.Observer"
 
@@ -2073,6 +2076,9 @@ client_add_interface_by_id (McdClient *client)
     if (client->interfaces & MCD_CLIENT_HANDLER)
         tp_proxy_add_interface_by_id (client->proxy,
                                       MC_IFACE_QUARK_CLIENT_HANDLER);
+    if (client->interfaces & MCD_CLIENT_HANDLER_REQUEST_NOTIFICATION)
+        tp_proxy_add_interface_by_id (client->proxy,
+            MC_IFACE_QUARK_CLIENT_HANDLER_INTERFACE_REQUEST_NOTIFICATION);
     if (client->interfaces & MCD_CLIENT_OBSERVER)
         tp_proxy_add_interface_by_id (client->proxy,
                                       MC_IFACE_QUARK_CLIENT_OBSERVER);
@@ -2098,6 +2104,8 @@ get_interfaces_cb (TpProxy *proxy,
             client->interfaces |= MCD_CLIENT_APPROVER;
         if (strcmp (*arr, MC_IFACE_CLIENT_HANDLER) == 0)
             client->interfaces |= MCD_CLIENT_HANDLER;
+        if (strcmp (*arr, MC_IFACE_CLIENT_HANDLER_INTERFACE_REQUEST_NOTIFICATION) == 0)
+            client->interfaces |= MCD_CLIENT_HANDLER_REQUEST_NOTIFICATION;
         if (strcmp (*arr, MC_IFACE_CLIENT_OBSERVER) == 0)
             client->interfaces |= MCD_CLIENT_OBSERVER;
         arr++;
@@ -2163,6 +2171,8 @@ parse_client_file (McdClient *client, GKeyFile *file)
             client->interfaces |= MCD_CLIENT_APPROVER;
         else if (strcmp (iface_names[i], MC_FILE_IFACE_CLIENT_HANDLER) == 0)
             client->interfaces |= MCD_CLIENT_HANDLER;
+        else if (strcmp (iface_names[i], MC_FILE_IFACE_CLIENT_HANDLER_INTERFACE_REQUEST_NOTIFICATION) == 0)
+            client->interfaces |= MCD_CLIENT_HANDLER_REQUEST_NOTIFICATION;
         else if (strcmp (iface_names[i], MC_FILE_IFACE_CLIENT_OBSERVER) == 0)
             client->interfaces |= MCD_CLIENT_OBSERVER;
     }
@@ -3018,7 +3028,7 @@ on_request_status_changed (McdChannel *channel, McdChannelStatus status,
         error = mcd_channel_get_error (channel);
         err_string = _mcd_build_error_string (error);
         /* no callback, as we don't really care */
-        mc_cli_client_handler_call_remove_failed_request
+        mc_cli_client_handler_interface_request_notification_call_remove_request
             (rrd->handler, -1, rrd->request_path, err_string, error->message,
              NULL, NULL, NULL, NULL);
         g_free (err_string);
@@ -3070,6 +3080,16 @@ _mcd_dispatcher_add_request (McdDispatcher *dispatcher, McdAccount *account,
         return;
     }
 
+    if (!(handler->interfaces & MCD_CLIENT_HANDLER_REQUEST_NOTIFICATION))
+    {
+        DEBUG ("Default handler %s for request %s doesn't want AddRequest",
+               handler->name, _mcd_channel_get_request_path (channel));
+        return;
+    }
+
+    DEBUG ("Calling AddRequest on default handler %s for request %s",
+           handler->name, _mcd_channel_get_request_path (channel));
+
     properties = g_hash_table_new (g_str_hash, g_str_equal);
 
     g_value_init (&v_user_time, G_TYPE_UINT64);
@@ -3104,14 +3124,15 @@ _mcd_dispatcher_add_request (McdDispatcher *dispatcher, McdAccount *account,
     g_hash_table_insert (properties, "org.freedesktop.Telepathy.ChannelRequest"
                          ".PreferredHandler", &v_preferred_handler);
 
-    mc_cli_client_handler_call_add_request (handler->proxy, -1,
+    mc_cli_client_handler_interface_request_notification_call_add_request (
+        handler->proxy, -1,
         _mcd_channel_get_request_path (channel), properties,
         NULL, NULL, NULL, NULL);
 
     g_hash_table_unref (properties);
     g_ptr_array_free (requests, TRUE);
 
-    /* Prepare for a RemoveFailedRequest */
+    /* Prepare for a RemoveRequest */
     rrd = g_slice_new (McdRemoveRequestData);
     /* store the request path, because it might not be available when the
      * channel status changes */
@@ -3119,7 +3140,7 @@ _mcd_dispatcher_add_request (McdDispatcher *dispatcher, McdAccount *account,
     rrd->handler = handler->proxy;
     g_object_ref (handler->proxy);
     /* we must watch whether the request fails and in that case call
-     * RemoveFailedRequest */
+     * RemoveRequest */
     g_signal_connect (channel, "status-changed",
                       G_CALLBACK (on_request_status_changed), rrd);
 }
diff --git a/test/twisted/account-requests/cancel.py b/test/twisted/account-requests/cancel.py
index c99956c..e605607 100644
--- a/test/twisted/account-requests/cancel.py
+++ b/test/twisted/account-requests/cancel.py
@@ -93,7 +93,8 @@ def test(q, bus, mc):
     # call precedes this
 
     e = q.expect('dbus-method-call', handled=False,
-        interface=cs.HANDLER, method='AddRequest', path=client.object_path)
+        interface=cs.HANDLER_IFACE_REQUEST_NOTIFICATION, method='AddRequest',
+        path=client.object_path)
     assert e.args[0] == request_path
     q.dbus_return(e.message, signature='')
 
diff --git a/test/twisted/account-requests/create-text.py b/test/twisted/account-requests/create-text.py
index 435d299..15c23e8 100644
--- a/test/twisted/account-requests/create-text.py
+++ b/test/twisted/account-requests/create-text.py
@@ -100,7 +100,8 @@ def test_channel_creation(q, bus, account, client, conn, ensure):
     # call precedes this
 
     e = q.expect('dbus-method-call', handled=False,
-        interface=cs.HANDLER, method='AddRequest', path=client.object_path)
+        interface=cs.HANDLER_IFACE_REQUEST_NOTIFICATION, method='AddRequest',
+        path=client.object_path)
     assert e.args[0] == request_path
     request_props = e.args[1]
     assert request_props[cs.CR + '.Account'] == account.object_path
diff --git a/test/twisted/account-requests/delete-account-during-request.py b/test/twisted/account-requests/delete-account-during-request.py
index 942e475..7c1afa6 100644
--- a/test/twisted/account-requests/delete-account-during-request.py
+++ b/test/twisted/account-requests/delete-account-during-request.py
@@ -74,7 +74,8 @@ def test(q, bus, mc):
     request_path = ret.value[0]
 
     e = q.expect('dbus-method-call', handled=False,
-        interface=cs.HANDLER, method='AddRequest', path=client.object_path)
+        interface=cs.HANDLER_IFACE_REQUEST_NOTIFICATION, method='AddRequest',
+        path=client.object_path)
     assert e.args[0] == request_path
 
     q.dbus_return(e.message, signature='')
@@ -99,29 +100,29 @@ def test(q, bus, mc):
         )
 
     # You know that request I told you about? Not going to happen.
-    remove_failed_request = q.expect('dbus-method-call',
-            interface=cs.HANDLER,
-            method='RemoveFailedRequest',
+    remove_request = q.expect('dbus-method-call',
+            interface=cs.HANDLER_IFACE_REQUEST_NOTIFICATION,
+            method='RemoveRequest',
             handled=False)
-    assert remove_failed_request.args[0] == request_path
+    assert remove_request.args[0] == request_path
     # FIXME: the spec should maybe define what error this will be. Currently,
     # it's Disconnected
-    assert remove_failed_request.args[1].startswith(tp_name_prefix + '.Error.')
+    assert remove_request.args[1].startswith(tp_name_prefix + '.Error.')
 
     q.expect_many(
             EventPattern('dbus-signal',
                 path=request_path,
                 interface=cs.CR + '.DRAFT',
                 signal='Failed',
-                args=remove_failed_request.args[1:]),
+                args=remove_request.args[1:]),
             EventPattern('dbus-signal',
                 path=account.object_path,
                 interface=cs.ACCOUNT_IFACE_NOKIA_REQUESTS,
                 signal='Failed',
-                args=remove_failed_request.args),
+                args=remove_request.args),
             )
 
-    q.dbus_return(remove_failed_request.message, signature='')
+    q.dbus_return(remove_request.message, signature='')
 
     # ... and the Connection is told to disconnect, hopefully before the
     # Channel has actually been established
diff --git a/test/twisted/constants.py b/test/twisted/constants.py
index 6408bde..65e3505 100644
--- a/test/twisted/constants.py
+++ b/test/twisted/constants.py
@@ -124,6 +124,7 @@ CLIENT_PATH = tp_path_prefix + '/Client'
 OBSERVER = tp_name_prefix + '.Client.Observer.DRAFT'
 APPROVER = tp_name_prefix + '.Client.Approver.DRAFT'
 HANDLER = tp_name_prefix + '.Client.Handler.DRAFT'
+HANDLER_IFACE_REQUEST_NOTIFICATION = tp_name_prefix + '.Client.Handler.Interface.RequestNotification.DRAFT'
 
 ACCOUNT = tp_name_prefix + '.Account'
 ACCOUNT_IFACE_AVATAR = ACCOUNT + '.Interface.Avatar'
diff --git a/test/twisted/dispatcher/cancel.py b/test/twisted/dispatcher/cancel.py
index 43978bf..44c900d 100644
--- a/test/twisted/dispatcher/cancel.py
+++ b/test/twisted/dispatcher/cancel.py
@@ -118,8 +118,8 @@ def test_channel_creation(q, bus, account, client, conn,
                 interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel',
                 path=conn.object_path, args=[request], handled=False),
             EventPattern('dbus-method-call', handled=False,
-                interface=cs.HANDLER, method='AddRequest',
-                path=client.object_path),
+                interface=cs.HANDLER_IFACE_REQUEST_NOTIFICATION,
+                method='AddRequest', path=client.object_path),
             )
 
     assert add_request_call.args[0] == request_path
diff --git a/test/twisted/dispatcher/create-text.py b/test/twisted/dispatcher/create-text.py
index 2acae66..825c6d6 100644
--- a/test/twisted/dispatcher/create-text.py
+++ b/test/twisted/dispatcher/create-text.py
@@ -103,8 +103,8 @@ def test_channel_creation(q, bus, account, client, conn, ensure):
                 method=(ensure and 'EnsureChannel' or 'CreateChannel'),
                 path=conn.object_path, args=[request], handled=False),
             EventPattern('dbus-method-call', handled=False,
-                interface=cs.HANDLER, method='AddRequest',
-                path=client.object_path),
+                interface=cs.HANDLER_IFACE_REQUEST_NOTIFICATION,
+                method='AddRequest', path=client.object_path),
             )
 
     assert add_request_call.args[0] == request_path
diff --git a/test/twisted/mctest.py b/test/twisted/mctest.py
index 4751bff..c61c46d 100644
--- a/test/twisted/mctest.py
+++ b/test/twisted/mctest.py
@@ -326,7 +326,8 @@ def aasv(x):
 
 class SimulatedClient(object):
     def __init__(self, q, bus, clientname,
-            observe=[], approve=[], handle=[], bypass_approval=False):
+            observe=[], approve=[], handle=[], bypass_approval=False,
+            request_notification=True):
         self.q = q
         self.bus = bus
         self.bus_name = '.'.join([cs.tp_name_prefix, 'Client', clientname])
@@ -336,6 +337,7 @@ class SimulatedClient(object):
         self.approve = aasv(approve)
         self.handle = aasv(handle)
         self.bypass_approval = bool(bypass_approval)
+        self.request_notification = bool(request_notification)
         self.handled_channels = dbus.Array([], signature='o')
 
         q.add_dbus_method_impl(self.Get_Interfaces,
@@ -378,6 +380,9 @@ class SimulatedClient(object):
         if self.handle:
             ret.append(cs.HANDLER)
 
+        if self.request_notification:
+            ret.append(cs.HANDLER_IFACE_REQUEST_NOTIFICATION)
+
         return ret
 
     def Get_Interfaces(self, e):
diff --git a/xml/Client_Handler.xml b/xml/Client_Handler.xml
index 3d75f0b..01dcaa4 100644
--- a/xml/Client_Handler.xml
+++ b/xml/Client_Handler.xml
@@ -27,9 +27,24 @@
     <tp:requires interface="org.freedesktop.Telepathy.Client.DRAFT"/>
 
     <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
-      <p>Channel handlers are the eventual handler for a channel or a
-        channel bundle; a typical channel handler is a user interface
-        process handling channels of a particular type.</p>
+      <p>Handlers are the user interface for a channel. They turn an abstract
+        Telepathy channel into something the user wants to see, like a text
+        message stream or an audio and/or video call.</p>
+
+      <p>For its entire lifetime, each channel on a connection known to the
+        channel dispatcher is either being processed by the channel dispatcher,
+        or being handled by precisely one Handler.</p>
+
+      <p>Because each channel is only handled by one Handler, handlers may
+        perform actions that only make sense to do once, such as acknowledging
+        <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
+        messages, doing the actual streaming for <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+        channels with the <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy.Channel.Interface">MediaSignalling</tp:dbus-ref>
+        interface, or transferring the file in <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy.Channel.Type">FileTransfer</tp:dbus-ref>
+        channels.</p>
 
       <p>When a new incoming channel (one with
         <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">Requested</tp:dbus-ref>
@@ -61,7 +76,10 @@
 
         <p>This property works in exactly the same way as the
           <tp:dbus-ref namespace="org.freedesktop.Telepathy">Client.Observer.DRAFT.ObserverChannelFilter</tp:dbus-ref>
-          property. In the .client file, it is represented in the
+          property. In particular, it cannot change while the handler process
+          continues to own the corresponding Client bus name.</p>
+
+        <p>In the .client file, it is represented in the
           same way as ObserverChannelFilter, but the group has the same
           name as this interface and the keys start with
           HandlerChannelFilter instead of ObserverChannelFilter.</p>
@@ -105,13 +123,14 @@
             paths.</p>
         </tp:rationale>
 
-        <p>This method can raise any D-Bus error. If it does, or if the
-          handler loses its bus name before all the channels have closed, the
+        <p>This method can raise any D-Bus error. If it does, the
           handler is assumed to have failed or crashed, and the channel
-          dispatcher MUST recover in an implementation-specific way.</p>
+          dispatcher MUST recover in an implementation-specific way; it MAY
+          attempt to dispatch the channels to another handler, or close the
+          channels.</p>
 
-        <p>It is RECOMMENDED that the channel dispatcher attempts to
-          close the channels using
+        <p>If closing the channels, it is RECOMMENDED that the channel
+          dispatcher attempts to close the channels using
           <tp:dbus-ref
             namespace="org.freedesktop.Telepathy">Channel.Close</tp:dbus-ref>,
           but resorts to calling
@@ -119,6 +138,17 @@
             namespace="org.freedesktop.Telepathy">Channel.Interface.Destroyable.Destroy</tp:dbus-ref>
           (if available) or ignoring the channel (if not) if the same handler
           repeatedly fails to handle channels.</p>
+
+        <p>After HandleChannels returns successfully, the client process is
+          considered to be responsible for the channel until it its unique
+          name disappears from the bus.</p>
+
+        <tp:rationale>
+          <p>If a process has multiple Client bus names - some temporary and
+            some long-lived - and drops one of the temporary bus names in order
+            to reduce the set of channels that it will handle, any channels
+            that it is already handling should remain unaffected.</p>
+        </tp:rationale>
       </tp:docstring>
 
       <arg name="Account" type="o" direction="in">
@@ -149,12 +179,17 @@
       </arg>
 
       <arg name="Requests_Satisfied" type="ao" direction="in">
-        <tp:docstring>
-          The requests satisfied by these channels.
+        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+          <p>The requests satisfied by these channels.</p>
 
           <tp:rationale>
-            There can be more than one, if they were EnsureChannel
-            requests.
+            <p>If the handler implements RequestNotification, this tells it
+              that these channels match previous <tp:dbus-ref
+                namespace="org.freedesktop.Telepathy.Client.Handler.Interface.RequestNotification.DRAFT">AddRequest</tp:dbus-ref>
+              calls that it may have received.</p>
+
+            <p>There can be more than one, if they were EnsureChannel
+              requests.</p>
           </tp:rationale>
         </tp:docstring>
       </arg>
@@ -171,92 +206,10 @@
       <!-- FIXME: invent a way to say "any error is possible" in spec markup -->
     </method>
 
-    <method name="AddRequest" tp:name-for-bindings="Add_Request">
-      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
-        <p>Called by the ChannelDispatcher to indicate that channels have been
-          requested, and that if the request is successful, they will be
-          handled by this Handler.</p>
-
-        <tp:rationale>
-          <p>This allows the UI to start preparing to handle the channels
-            in advance (e.g. render a window with an "in progress" message),
-            improving perceived responsiveness.</p>
-        </tp:rationale>
-
-        <p>(FIXME: how do we know the returned channels will be handled by
-          this handler? Do we just assume that they'll match the
-          HandlerChannelFilter iff the request does?)</p>
-      </tp:docstring>
-
-      <arg name="Request" type="o" direction="in">
-        <tp:docstring>
-          The <tp:dbus-ref
-            namespace="org.freedesktop.Telepathy">ChannelRequest.DRAFT</tp:dbus-ref>
-          object, which MUST have been returned by <tp:dbus-ref
-            namespace="org.freedesktop.Telepathy.ChannelDispatcher.DRAFT">CreateChannel</tp:dbus-ref>
-          or <tp:dbus-ref
-            namespace="org.freedesktop.Telepathy.ChannelDispatcher.DRAFT">EnsureChannel</tp:dbus-ref>
-          before this method is called.
-
-          <tp:rationale>
-            See those methods for the rationale of this ordering.
-          </tp:rationale>
-        </tp:docstring>
-      </arg>
-
-      <arg name="Properties" type="a{sv}"
-        tp:type="Qualified_Property_Value_Map" direction="in">
-        <tp:docstring>
-          <p>Some of the properties of the ChannelRequest. To avoid race
-            conditions, this dictionary MUST NOT include properties whose
-            values could subsequently change. It SHOULD include as many
-            properties as possible, given that constraint.</p>
-
-          <p>In particular, the properties <tp:dbus-ref
-              namespace="org.freedesktop.Telepathy.ChannelRequest.DRAFT">Requests</tp:dbus-ref>
-            and <tp:dbus-ref
-              namespace="org.freedesktop.Telepathy.ChannelRequest.DRAFT">UserActionTime</tp:dbus-ref>
-            MUST be included.</p>
-        </tp:docstring>
-      </arg>
-    </method>
-
-    <method name="RemoveFailedRequest"
-      tp:name-for-bindings="Remove_Failed_Request">
-      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
-        <p>Called by the ChannelDispatcher to indicate that a request
-          previously passed to <tp:member-ref>AddRequest</tp:member-ref>
-          has failed and should be disregarded.</p>
-      </tp:docstring>
-
-      <arg name="Request" type="o" direction="in">
-        <tp:docstring>
-          The request that failed.
-        </tp:docstring>
-      </arg>
-
-      <arg name="Error" type="s" tp:type="DBus_Error_Name" direction="in">
-        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
-          <p>The name of the D-Bus error with which the request failed.</p>
-
-          <p>If this is <code>org.freedesktop.Telepathy.Error.NotYours</code>,
-            this indicates that the request succeeded, but all the resulting
-            channels were given to some other handler.</p>
-        </tp:docstring>
-      </arg>
-
-      <arg name="Message" type="s" direction="in">
-        <tp:docstring>
-          Any message supplied with the D-Bus error.
-        </tp:docstring>
-      </arg>
-    </method>
-
     <property name="HandledChannels" tp:name-for-bindings="Handled_Channels"
       type="ao" access="read">
       <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
-        <p>A list of the channels that this Handler is currently handling.
-        </p>
+        <p>A list of the channels that this process is currently handling.</p>
 
         <p>There is no change notification.</p>
 
@@ -272,6 +225,17 @@
             the user is that unhandled channels that they have already
             approved might be sent back to Approvers.</p>
         </tp:rationale>
+
+        <p>The value of this property SHOULD be the same for all Client
+          instances that share a unique bus name, and SHOULD include all
+          channels that are being handled, even if they were conceptually
+          handled by a different Client instance.</p>
+
+        <tp:rationale>
+          <p>Otherwise, when a process released a temporary Client name,
+            channels that it handled because of that Client name would no
+            longer be state-recoverable.</p>
+        </tp:rationale>
       </tp:docstring>
     </property>
 
diff --git a/xml/Client_Handler_Interface_Request_Notification.xml b/xml/Client_Handler_Interface_Request_Notification.xml
new file mode 100644
index 0000000..4e9d7ed
--- /dev/null
+++ b/xml/Client_Handler_Interface_Request_Notification.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" ?>
+<node name="/Client_Handler_Interface_Request_Notification"
+  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.Handler.Interface.RequestNotification.DRAFT"
+    tp:causes-havoc="experimental">
+    <tp:added version="0.17.UNRELEASED">(as a draft; functionality
+      moved from Handler)</tp:added>
+
+    <tp:requires interface="org.freedesktop.Telepathy.Client.DRAFT"/>
+    <tp:requires interface="org.freedesktop.Telepathy.Client.Handler.DRAFT"/>
+
+    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+      <p>This interface can be implemented by a Handler to be notified about
+        requests for channels that it is likely to be asked to handle.</p>
+    </tp:docstring>
+
+    <method name="AddRequest" tp:name-for-bindings="Add_Request">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>Called by the ChannelDispatcher to indicate that channels have been
+          requested, and that if the request is successful, they will probably
+          be handled by this Handler. The ChannelDispatcher SHOULD only
+          call this method on one handler per request.</p>
+
+        <tp:rationale>
+          <p>This allows the UI to start preparing to handle the channels
+            in advance (e.g. render a window with an "in progress" message),
+            improving perceived responsiveness.</p>
+
+          <p>The use of "probably" is because you can't necessarily tell from
+            a channel request which handler will handle particular channels.
+            A reasonable heuristic would be to match the request against the
+            <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.Client.Handler.DRAFT">HandlerChannelFilter</tp:dbus-ref>,
+            and respect the preferred handler (if any).</p>
+        </tp:rationale>
+
+        <p>If the request succeeds and is given to the expected Handler,
+          the Requests_Satisfied parameter to
+          <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.Client.Handler.DRAFT">HandleChannels</tp:dbus-ref>
+          can be used to match the channel to a previous AddRequest call.</p>
+
+        <tp:rationale>
+          <p>This lets the UI direct the channels to the window that it
+            already opened.</p>
+        </tp:rationale>
+
+        <p>If the request fails, the expected handler is notified by the
+          channel dispatcher calling its
+          <tp:member-ref>RemoveRequest</tp:member-ref> method.</p>
+
+        <tp:rationale>
+          <p>This lets the UI close the window or display the error.</p>
+        </tp:rationale>
+
+        <p>The channel dispatcher SHOULD remember which handler was notified,
+          and if the channel request succeeds, it SHOULD dispatch the channels
+          to the expected handler, unless the channels do not match that
+          handler's <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.Client.Handler.DRAFT">HandlerChannelFilter</tp:dbus-ref>.
+          If the channels are not dispatched to the expected handler, the
+          handler that was expected is notified by the channel dispatcher
+          calling its <tp:member-ref>RemoveRequest</tp:member-ref> method
+          with the NotYours error.</p>
+
+        <tp:rationale>
+          <p>Expected handling is for the UI to close the window it
+            previously opened.</p>
+        </tp:rationale>
+
+        <p>Handlers SHOULD NOT return an error from this method; errors
+          returned from this method SHOULD NOT alter the channel dispatcher's
+          behaviour.</p>
+
+        <tp:rationale>
+          <p>Calls to this method are merely a notification.</p>
+        </tp:rationale>
+      </tp:docstring>
+
+      <arg name="Request" type="o" direction="in">
+        <tp:docstring>
+          The <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy">ChannelRequest.DRAFT</tp:dbus-ref>
+          object, which MUST have been returned by <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.ChannelDispatcher.DRAFT">CreateChannel</tp:dbus-ref>
+          or <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.ChannelDispatcher.DRAFT">EnsureChannel</tp:dbus-ref>
+          before this method is called.
+
+          <tp:rationale>
+            See those methods for the rationale of this ordering.
+          </tp:rationale>
+        </tp:docstring>
+      </arg>
+
+      <arg name="Properties" type="a{sv}"
+        tp:type="Qualified_Property_Value_Map" direction="in">
+        <tp:docstring>
+          <p>Some of the properties of the ChannelRequest. To avoid race
+            conditions, this dictionary MUST NOT include properties whose
+            values could subsequently change. It SHOULD include as many
+            properties as possible, given that constraint.</p>
+
+          <p>In particular, the properties <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.ChannelRequest.DRAFT">Requests</tp:dbus-ref>
+            and <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.ChannelRequest.DRAFT">UserActionTime</tp:dbus-ref>
+            MUST be included.</p>
+        </tp:docstring>
+      </arg>
+    </method>
+
+    <method name="RemoveRequest"
+      tp:name-for-bindings="Remove_Request">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>Called by the ChannelDispatcher to indicate that a request
+          previously passed to <tp:member-ref>AddRequest</tp:member-ref>
+          has failed and should be disregarded.</p>
+
+        <p>Handlers SHOULD NOT return an error from this method; errors
+          returned from this method SHOULD NOT alter the channel dispatcher's
+          behaviour.</p>
+
+        <tp:rationale>
+          <p>Calls to this method are merely a notification.</p>
+        </tp:rationale>
+      </tp:docstring>
+
+      <arg name="Request" type="o" direction="in">
+        <tp:docstring>
+          The request that failed.
+        </tp:docstring>
+      </arg>
+
+      <arg name="Error" type="s" tp:type="DBus_Error_Name" direction="in">
+        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+          <p>The name of the D-Bus error with which the request failed.</p>
+
+          <p>If this is <code>org.freedesktop.Telepathy.Error.NotYours</code>,
+            this indicates that the request succeeded, but all the resulting
+            channels were given to some other handler.</p>
+        </tp:docstring>
+      </arg>
+
+      <arg name="Message" type="s" direction="in">
+        <tp:docstring>
+          Any message supplied with the D-Bus error.
+        </tp:docstring>
+      </arg>
+    </method>
+
+  </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/xml/Makefile.am b/xml/Makefile.am
index 967ac9a..3a73015 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -21,6 +21,7 @@ SPECS = \
 	Client.xml \
 	Client_Approver.xml \
 	Client_Handler.xml \
+	Client_Handler_Interface_Request_Notification.xml \
 	Client_Observer.xml \
         Connection_Interface_Contact_Capabilities.xml
 
diff --git a/xml/nmc5.xml b/xml/nmc5.xml
index 330a814..50a8926 100644
--- a/xml/nmc5.xml
+++ b/xml/nmc5.xml
@@ -17,6 +17,7 @@
 <xi:include href="Client.xml"/>
 <xi:include href="Client_Approver.xml"/>
 <xi:include href="Client_Handler.xml"/>
+<xi:include href="Client_Handler_Interface_Request_Notification.xml"/>
 <xi:include href="Client_Observer.xml"/>
 
 <xi:include href="Channel_Dispatcher.xml"/>
-- 
1.5.6.5




More information about the telepathy-commits mailing list