[Telepathy-commits] [telepathy-mission-control/master] Add initial implementation of DispatchOperation objects

Alberto Mardegan alberto.mardegan at nokia.com
Mon Nov 17 00:05:29 PST 2008


---
 src/Makefile.am                    |    8 +-
 src/dispatch-operation.xml         |    7 +
 src/mcd-dispatch-operation.c       |  343 ++++++++++++++++++++++++++++++++++++
 src/mcd-dispatch-operation.h       |   65 +++++++
 xml/Channel_Dispatch_Operation.xml |  331 ++++++++++++++++++++++++++++++++++
 xml/nmc5.xml                       |    2 +
 6 files changed, 754 insertions(+), 2 deletions(-)
 create mode 100644 src/dispatch-operation.xml
 create mode 100644 src/mcd-dispatch-operation.c
 create mode 100644 src/mcd-dispatch-operation.h
 create mode 100644 xml/Channel_Dispatch_Operation.xml

diff --git a/src/Makefile.am b/src/Makefile.am
index 2aa16e5..bc7a439 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,7 @@ mission_control_include = \
 	mcd-account-manager-query.h \
 	mcd-dbusprop.h \
 	mcd-debug.h \
+	mcd-dispatch-operation.h \
 	mcd-mission.h \
 	mcd-operation.h \
 	mcd-master.h \
@@ -52,7 +53,8 @@ nodist_geninclude_HEADERS = \
 	_gen/svc-Account_Interface_Conditions.h \
 	_gen/svc-Account_Manager.h \
 	_gen/svc-Account_Manager_Interface_Creation.h \
-	_gen/svc-Account_Manager_Interface_Query.h
+	_gen/svc-Account_Manager_Interface_Query.h \
+	_gen/svc-dispatch-operation.h
 
 nodist_libmissioncontrol_server_la_SOURCES = \
 	_gen/cli-client-body.h \
@@ -69,7 +71,8 @@ nodist_libmissioncontrol_server_la_SOURCES = \
 	_gen/svc-Account_Interface_Conditions.c \
 	_gen/svc-Account_Manager.c \
 	_gen/svc-Account_Manager_Interface_Creation.c \
-	_gen/svc-Account_Manager_Interface_Query.c
+	_gen/svc-Account_Manager_Interface_Query.c \
+	_gen/svc-dispatch-operation.c
 
 
 mission_control_include_HEADERS = \
@@ -119,6 +122,7 @@ libmissioncontrol_server_la_SOURCES = \
 	mcd-account-manager-query.c \
 	mcd-dbusprop.c \
 	mcd-debug.c \
+	mcd-dispatch-operation.c \
 	mcd-enum-types.c \
 	mcd-signals-marshal.c \
 	mcd-misc.c \
diff --git a/src/dispatch-operation.xml b/src/dispatch-operation.xml
new file mode 100644
index 0000000..6a166d2
--- /dev/null
+++ b/src/dispatch-operation.xml
@@ -0,0 +1,7 @@
+<tp:spec
+    xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+    xmlns:xi="http://www.w3.org/2001/XInclude">
+
+<xi:include href="../xml/Channel_Dispatch_Operation.xml"/>
+
+</tp:spec>
diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c
new file mode 100644
index 0000000..6326580
--- /dev/null
+++ b/src/mcd-dispatch-operation.c
@@ -0,0 +1,343 @@
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of mission-control
+ *
+ * Copyright (C) 2008 Nokia Corporation. 
+ *
+ * Contact: Alberto Mardegan  <alberto.mardegan at nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "mcd-dispatch-operation.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <dbus/dbus.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/svc-generic.h>
+#include <telepathy-glib/util.h>
+
+#include "mcd-dbusprop.h"
+#include "_gen/interfaces.h"
+#include "_gen/gtypes.h"
+
+#define MCD_DISPATCH_OPERATION_PRIV(operation) (MCD_DISPATCH_OPERATION (operation)->priv)
+
+static void
+dispatch_operation_iface_init (McSvcChannelDispatchOperationClass *iface,
+                               gpointer iface_data);
+static void properties_iface_init (TpSvcDBusPropertiesClass *iface,
+                                   gpointer iface_data);
+
+static const McdDBusProp dispatch_operation_properties[];
+
+static const McdInterfaceData dispatch_operation_interfaces[] = {
+    MCD_IMPLEMENT_IFACE (mc_svc_channel_dispatch_operation_get_type,
+                         dispatch_operation,
+                         MC_IFACE_CHANNEL_DISPATCH_OPERATION),
+    { G_TYPE_INVALID, }
+};
+
+G_DEFINE_TYPE_WITH_CODE (McdDispatchOperation, mcd_dispatch_operation,
+                         G_TYPE_OBJECT,
+    MCD_DBUS_INIT_INTERFACES (dispatch_operation_interfaces);
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, properties_iface_init);
+    )
+
+struct _McdDispatchOperationPrivate
+{
+    gchar *unique_name;
+    gchar *object_path;
+
+    /* DBUS connection */
+    TpDBusDaemon *dbus_daemon;
+
+    McdConnection *connection;
+
+    GList *channels;
+};
+
+enum
+{
+    PROP_0,
+    PROP_DBUS_DAEMON,
+    PROP_CONNECTION,
+    PROP_CHANNELS,
+};
+
+static void
+get_connection (TpSvcDBusProperties *self, const gchar *name, GValue *value)
+{
+    McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (self);
+    const gchar *object_path;
+
+    g_debug ("%s called for %s", G_STRFUNC, priv->unique_name);
+    g_value_init (value, DBUS_TYPE_G_OBJECT_PATH);
+    if (priv->connection &&
+        (object_path = mcd_connection_get_object_path (priv->connection)))
+        g_value_set_boxed (value, object_path);
+    else
+        g_value_set_static_boxed (value, "/");
+}
+
+static void
+get_account (TpSvcDBusProperties *self, const gchar *name, GValue *value)
+{
+    McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (self);
+    McdAccount *account;
+    const gchar *object_path;
+
+    g_debug ("%s called for %s", G_STRFUNC, priv->unique_name);
+    g_value_init (value, DBUS_TYPE_G_OBJECT_PATH);
+    if (priv->connection &&
+        (account = mcd_connection_get_account (priv->connection)) &&
+        (object_path = mcd_account_get_object_path (account)))
+        g_value_set_boxed (value, object_path);
+    else
+        g_value_set_static_boxed (value, "/");
+}
+
+static void
+get_channels (TpSvcDBusProperties *self, const gchar *name, GValue *value)
+{
+    McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (self);
+
+    g_debug ("%s called for %s", G_STRFUNC, priv->unique_name);
+    g_value_init (value, MC_ARRAY_TYPE_CHANNEL_DETAILS_LIST);
+    g_warning ("%s not implemented", G_STRFUNC);
+    g_value_set_static_boxed (value, NULL);
+}
+
+static void
+get_possible_handlers (TpSvcDBusProperties *self, const gchar *name,
+                       GValue *value)
+{
+    McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (self);
+
+    g_debug ("%s called for %s", G_STRFUNC, priv->unique_name);
+    g_value_init (value, G_TYPE_STRV);
+    g_warning ("%s not implemented", G_STRFUNC);
+    g_value_set_static_boxed (value, NULL);
+}
+
+
+static const McdDBusProp dispatch_operation_properties[] = {
+    { "Interfaces", NULL, mcd_dbus_get_interfaces },
+    { "Connection", NULL, get_connection },
+    { "Account", NULL, get_account },
+    { "Channels", NULL, get_channels },
+    { "PossibleHandlers", NULL, get_possible_handlers },
+    { 0 },
+};
+
+static void
+properties_iface_init (TpSvcDBusPropertiesClass *iface, gpointer iface_data)
+{
+#define IMPLEMENT(x) tp_svc_dbus_properties_implement_##x (\
+    iface, dbusprop_##x)
+    IMPLEMENT(set);
+    IMPLEMENT(get);
+    IMPLEMENT(get_all);
+#undef IMPLEMENT
+}
+
+static void
+dispatch_operation_iface_init (McSvcChannelDispatchOperationClass *iface,
+                               gpointer iface_data)
+{
+#define IMPLEMENT(x) mc_svc_dispatch_operation_implement_##x (\
+    iface, dispatch_operation_##x)
+#undef IMPLEMENT
+}
+
+static void
+create_object_path (McdDispatchOperationPrivate *priv)
+{
+    priv->object_path =
+        g_strdup_printf (MC_DISPATCH_OPERATION_DBUS_OBJECT_BASE "do%u",
+                         (guint)time (0));
+    priv->unique_name = priv->object_path +
+        (sizeof (MC_DISPATCH_OPERATION_DBUS_OBJECT_BASE) - 1);
+}
+
+static GObject *
+mcd_dispatch_operation_constructor (GType type, guint n_params,
+                                    GObjectConstructParam *params)
+{
+    GObjectClass *object_class =
+        (GObjectClass *)mcd_dispatch_operation_parent_class;
+    GObject *object;
+    McdDispatchOperation *operation;
+    McdDispatchOperationPrivate *priv;
+    DBusGConnection *dbus_connection;
+
+    object = object_class->constructor (type, n_params, params);
+    operation = MCD_DISPATCH_OPERATION (object);
+
+    g_return_val_if_fail (operation != NULL, NULL);
+    priv = operation->priv;
+
+    if (!priv->dbus_daemon) goto error;
+
+    dbus_connection = TP_PROXY (priv->dbus_daemon)->dbus_connection;
+    create_object_path (priv);
+
+    if (G_LIKELY (dbus_connection))
+        dbus_g_connection_register_g_object (dbus_connection,
+                                             priv->object_path, object);
+
+    return object;
+error:
+    g_object_unref (object);
+    return NULL;
+}
+
+static void
+mcd_dispatch_operation_set_property (GObject *obj, guint prop_id,
+                                     const GValue *val, GParamSpec *pspec)
+{
+    McdDispatchOperation *operation = MCD_DISPATCH_OPERATION (obj);
+    McdDispatchOperationPrivate *priv = operation->priv;
+
+    switch (prop_id)
+    {
+    case PROP_DBUS_DAEMON:
+        if (priv->dbus_daemon)
+            g_object_unref (priv->dbus_daemon);
+        priv->dbus_daemon = TP_DBUS_DAEMON (g_value_dup_object (val));
+        break;
+    case PROP_CONNECTION:
+        g_assert (priv->connection == NULL);
+        priv->connection = g_value_dup_object (val);
+        break;
+    case PROP_CHANNELS:
+        g_assert (priv->channels == NULL);
+        priv->channels = g_value_get_pointer (val);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+mcd_dispatch_operation_get_property (GObject *obj, guint prop_id,
+                                     GValue *val, GParamSpec *pspec)
+{
+    McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (obj);
+
+    switch (prop_id)
+    {
+    case PROP_DBUS_DAEMON:
+        g_value_set_object (val, priv->dbus_daemon);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+mcd_dispatch_operation_finalize (GObject *object)
+{
+    McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (object);
+
+    g_free (priv->object_path);
+
+    G_OBJECT_CLASS (mcd_dispatch_operation_parent_class)->finalize (object);
+}
+
+static void
+mcd_dispatch_operation_dispose (GObject *object)
+{
+    McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (object);
+
+    if (priv->connection)
+    {
+        g_object_unref (priv->connection);
+        priv->connection = NULL;
+    }
+
+    if (priv->dbus_daemon)
+    {
+        g_object_unref (priv->dbus_daemon);
+        priv->dbus_daemon = NULL;
+    }
+    G_OBJECT_CLASS (mcd_dispatch_operation_parent_class)->dispose (object);
+}
+
+static void
+mcd_dispatch_operation_class_init (McdDispatchOperationClass * klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    g_type_class_add_private (object_class,
+                              sizeof (McdDispatchOperationPrivate));
+
+    object_class->constructor = mcd_dispatch_operation_constructor;
+    object_class->dispose = mcd_dispatch_operation_dispose;
+    object_class->finalize = mcd_dispatch_operation_finalize;
+    object_class->set_property = mcd_dispatch_operation_set_property;
+    object_class->get_property = mcd_dispatch_operation_get_property;
+
+    g_object_class_install_property (object_class, PROP_DBUS_DAEMON,
+        g_param_spec_object ("dbus-daemon", "DBus daemon", "DBus daemon",
+							  TP_TYPE_DBUS_DAEMON,
+							  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property (object_class, PROP_CONNECTION,
+        g_param_spec_object ("connection", "connection", "connection",
+							  TP_TYPE_DBUS_DAEMON,
+							  G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property (object_class, PROP_CHANNELS,
+        g_param_spec_pointer ("channels", "channels", "channels",
+                              G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+mcd_dispatch_operation_init (McdDispatchOperation *operation)
+{
+    McdDispatchOperationPrivate *priv;
+
+    priv = G_TYPE_INSTANCE_GET_PRIVATE ((operation),
+                                        MCD_TYPE_DISPATCH_OPERATION,
+                                        McdDispatchOperationPrivate);
+    operation->priv = priv;
+
+    /* initializes the interfaces */
+    mcd_dbus_init_interfaces_instances (operation);
+}
+
+McdDispatchOperation *
+mcd_dispatch_operation_new (TpDBusDaemon *dbus_daemon,
+                            McdConnection *connection,
+                            GList *channels)
+{
+    gpointer *obj;
+    obj = g_object_new (MCD_TYPE_DISPATCH_OPERATION,
+                        "dbus-daemon", dbus_daemon,
+                        "connection", connection,
+                        "channels", channels,
+                        NULL);
+    return MCD_DISPATCH_OPERATION (obj);
+}
+
diff --git a/src/mcd-dispatch-operation.h b/src/mcd-dispatch-operation.h
new file mode 100644
index 0000000..5359bec
--- /dev/null
+++ b/src/mcd-dispatch-operation.h
@@ -0,0 +1,65 @@
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * mcd-operation.h - the Telepathy DispatchOperation D-Bus interface (service side)
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __MCD_DISPATCH_OPERATION_H__
+#define __MCD_DISPATCH_OPERATION_H__
+
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/enums.h>
+/* auto-generated stubs */
+#include "_gen/svc-dispatch-operation.h"
+
+G_BEGIN_DECLS
+#define MCD_TYPE_DISPATCH_OPERATION         (mcd_dispatch_operation_get_type ())
+#define MCD_DISPATCH_OPERATION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), MCD_TYPE_DISPATCH_OPERATION, McdDispatchOperation))
+#define MCD_DISPATCH_OPERATION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), MCD_TYPE_DISPATCH_OPERATION, McdDispatchOperationClass))
+#define MCD_IS_DISPATCH_OPERATION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCD_TYPE_DISPATCH_OPERATION))
+#define MCD_IS_DISPATCH_OPERATION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), MCD_TYPE_DISPATCH_OPERATION))
+#define MCD_DISPATCH_OPERATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MCD_TYPE_DISPATCH_OPERATION, McdDispatchOperationClass))
+
+typedef struct _McdDispatchOperation McdDispatchOperation;
+typedef struct _McdDispatchOperationPrivate McdDispatchOperationPrivate;
+typedef struct _McdDispatchOperationClass McdDispatchOperationClass;
+
+#include "mcd-account.h"
+
+struct _McdDispatchOperation
+{
+    GObject parent;
+    McdDispatchOperationPrivate *priv;
+};
+
+struct _McdDispatchOperationClass
+{
+    GObjectClass parent_class;
+};
+
+
+#define MC_DISPATCH_OPERATION_DBUS_OBJECT_BASE "/org/freedesktop/Telepathy/DispatchOperation/"
+
+GType mcd_dispatch_operation_get_type (void);
+McdDispatchOperation *mcd_dispatch_operation_new (TpDBusDaemon *dbus_daemon,
+                                                  McdConnection *connection,
+                                                  GList *channels);
+
+#endif
diff --git a/xml/Channel_Dispatch_Operation.xml b/xml/Channel_Dispatch_Operation.xml
new file mode 100644
index 0000000..dfd4ec3
--- /dev/null
+++ b/xml/Channel_Dispatch_Operation.xml
@@ -0,0 +1,331 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Dispatch_Operation"
+  xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+  <tp:copyright>Copyright (C) 2008 Collabora Ltd.</tp:copyright>
+  <tp:copyright>Copyright (C) 2008 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.ChannelDispatchOperation.DRAFT"
+    tp:causes-havoc="experimental">
+
+    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+      <p>A channel dispatch operation is an object in the ChannelDispatcher
+        representing a bundle of unrequested channels being announced to
+        client
+        <tp:dbus-ref namespace="org.freedesktop.Telepathy.Client">Approver.DRAFT</tp:dbus-ref>
+        processes.</p>
+
+      <p>These objects can result from new incoming channels or channels
+        which are automatically created for some reason, but cannot result
+        from outgoing requests for channels.</p>
+
+      <p>More specifically, whenever the
+        <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.NewChannels</tp:dbus-ref>
+        signal contains channels whose
+        <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.FUTURE.Requested</tp:dbus-ref>
+        property is false, or whenever the
+        <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.NewChannel</tp:dbus-ref>
+        signal contains a channel with suppress_handler false,
+        one or more ChannelDispatchOperation objects are created for those
+        channels.</p>
+
+      <p>(If some channels in a NewChannels signal are in different bundles,
+        this is an error. The channel dispatcher SHOULD recover by treating
+        the NewChannels signal as if it had been several NewChannels signals
+        each containing one channel.)</p>
+
+      <p>First, the channel dispatcher SHOULD construct a list of all the
+        channel handlers that could handle all the channels, ordered by
+        priority in some implementation-dependent way. If there are handlers
+        which could handle all the channels, one channel dispatch operation
+        SHOULD be created for all the channels. If there are not, one channel
+        dispatch operation SHOULD be created for each channel, each with
+        a list of channel handlers that could handle that channel.</p>
+
+      <p>When listing channel handlers, priority SHOULD be given to
+        channel handlers that are already handling channels from the same
+        bundle.</p>
+
+      <p>Processing of a channel dispatch operation proceeds as follows.
+        If the channels in a channel dispatch operation are in the same
+        bundle as a channel that is already being handled, and the handler
+        could also handle the channels being dispatched, the channel
+        dispatcher SHOULD call the handler's
+        HandleAdditionalChannels
+        method to see whether the handler will accept the new channels too.
+        If the handler takes responsibility for the channels,
+        processing stops, and no approvers are run.</p>
+
+      <p>(FIXME: this is far too subtle and everyone will get it wrong.
+        Open issue: how else do we address this use case?)</p>
+
+      <tp:rationale>
+        <p>Some channel types can be picked up "quietly" by an existing
+          channel handler. If a Text channel is added to an existing
+          bundle containing a StreamedMedia channel, there shouldn't be
+          any approvers, flashing icons or notification bubbles, if the
+          the UI for the StreamedMedia channel can just add a text box
+          and display the message.</p>
+      </tp:rationale>
+
+      <p>If not, the channel dispatcher SHOULD send the channel dispatch
+        operation to all relevant approvers (in parallel) and wait for an
+        approver to claim the channels or request that they are handled.
+        See
+        <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy.Client.Approver.DRAFT">AddDispatchOperation</tp:dbus-ref>
+        for more details on this.</p>
+
+      <p>Finally, if the approver requested it, the channel dispatcher SHOULD
+        send the channels to a handler.</p>
+    </tp:docstring>
+
+    <property name="Interfaces" tp:name-for-bindings="Interfaces"
+      type="as" access="read" tp:type="DBus_Interface[]">
+      <tp:docstring>
+        A list of the extra interfaces provided by this channel dispatch
+        operation. This property cannot change.
+      </tp:docstring>
+    </property>
+
+    <property name="Connection" tp:name-for-bindings="Connection"
+      type="o" access="read">
+      <tp:docstring>
+        The <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
+        with which the <tp:member-ref>Channels</tp:member-ref> 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 '.'. This property cannot change.
+      </tp:docstring>
+    </property>
+
+    <property name="Account" tp:name-for-bindings="Account"
+      type="o" access="read">
+      <tp:docstring>
+        The <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+        with which the <tp:member-ref>Connection</tp:member-ref>
+        and <tp:member-ref>Channels</tp:member-ref> are
+        associated. This property cannot change.
+      </tp:docstring>
+    </property>
+
+    <property name="Channels" tp:name-for-bindings="Channels"
+      type="a(oa{sv})" access="read" tp:type="Channel_Details[]">
+      <tp:docstring>
+        The <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>s
+        to be dispatched, and their properties. Change notification is via
+        the <tp:member-ref>ChannelLost</tp:member-ref> signal (channels
+        cannot be added to this property, only removed).
+      </tp:docstring>
+    </property>
+
+    <signal name="ChannelLost" tp:name-for-bindings="Channel_Lost">
+      <tp:docstring>
+        A channel has closed before it could be claimed or handled.
+      </tp:docstring>
+
+      <arg name="Error" type="s" tp:type="DBus_Error_Name">
+        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+          <p>The name of a D-Bus error indicating why the channel closed. If
+            no better reason can be found,
+            <code>org.freedesktop.Telepathy.Errors.NotAvailable</code> MAY
+            be used as a fallback; this means that this error SHOULD NOT be
+            given any more specific meaning.</p>
+
+          <p>FIXME: or should we invent a new OtherError for that purpose?</p>
+
+          <p>FIXME: we need to specify errors for these situations:</p>
+
+          <ul>
+            <li>kicked from a chatroom</li>
+            <li>outgoing call rejected</li>
+            <li>outgoing call timed out</li>
+            <li>incoming call terminated</li>
+          </ul>
+        </tp:docstring>
+      </arg>
+
+      <arg name="Message" type="s">
+        <tp:docstring>
+          A string associated with the D-Bus error.
+        </tp:docstring>
+      </arg>
+    </signal>
+
+    <property name="PossibleHandlers" tp:name-for-bindings="Possible_Handlers"
+      type="as" access="read" tp:type="DBus_Well_Known_Name[]">
+      <tp:docstring>
+        The well known bus names (starting with
+        <code>org.freedesktop.Telepathy.Client.</code>) of the possible
+        <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>s
+        for these channels. The channel dispatcher MUST place the most
+        preferred handlers first, according to some reasonable heuristic.
+        As a result, approvers SHOULD use the first handler by default.
+      </tp:docstring>
+    </property>
+
+    <method name="HandleWith" tp:name-for-bindings="Handle_With">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>Called by an approver to accept a channel bundle and request that
+          the given handler be used to handle it.</p>
+
+        <p>If successful, this method will cause the ChannelDispatchOperation
+          object to disappear, emitting
+          <tp:member-ref>Finished</tp:member-ref>.</p>
+
+        <p>However, this method may fail because the dispatch has already been
+          completed and the object has already gone. If this occurs, it
+          indicates that another approver has asked for the bundle to be
+          handled by a particular handler. The approver MUST NOT attempt
+          to interact with the channels further in this case, unless it is
+          separately invoked as the handler.</p>
+
+        <p>Approvers which are also channel handlers SHOULD use Claim instead
+          of HandleWith to request that they can handle a channel bundle
+          themselves.</p>
+
+        <p>(FIXME: list some possible errors)</p>
+
+        <p>If the channel handler raises an error from Handle, this method
+          MAY respond by raising that same error, even if it is not
+          specifically documented here.</p>
+      </tp:docstring>
+
+      <arg direction="in" type="s" tp:type="DBus_Bus_Name" name="Handler">
+        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+          <p>The well-known bus name (starting with
+            <code>org.freedesktop.Telepathy.Client.</code>) of the channel
+            handler that should handle the channel.</p>
+        </tp:docstring>
+      </arg>
+
+      <tp:possible-errors>
+        <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+          <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+            The selected handler is not a syntactically correct
+            <tp:type>DBus_Bus_Name</tp:type> or does not start with
+            "<code>org.freedesktop.Telepathy.Client.</code>".
+          </tp:docstring>
+        </tp:error>
+        <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+          <tp:docstring>
+            The selected handler is temporarily unable to handle these
+            channels.
+          </tp:docstring>
+        </tp:error>
+        <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+          <tp:docstring>
+            The selected handler is syntactically correct, but will never
+            be able to handle these channels (for instance because the channels
+            do not match its HandlerChannelFilter, or because HandleChannels
+            raised NotImplemented).
+          </tp:docstring>
+        </tp:error>
+        <tp:error name="org.freedesktop.Telepathy.Error.NotYours">
+          <tp:docstring>
+            At the time that HandleWith was called, this dispatch operation was
+            processing an earlier call to HandleWith. The earlier call has
+            now succeeded, so some Handler nominated by another approver is
+            now responsible for the channels. In this situation, the second
+            call to HandleWith MUST NOT return until the first one has
+            returned successfully or unsuccessfully, and if the first call
+            to HandleChannels fails, the channel dispatcher SHOULD try to obey
+            the choice of Handler made by the second call to HandleWith.
+          </tp:docstring>
+        </tp:error>
+      </tp:possible-errors>
+    </method>
+
+    <method name="Claim" tp:name-for-bindings="Claim">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>Called by an approver to claim channels for handling
+          internally. If this method is called successfully, the process
+          calling this method becomes the handler for the channel, but
+          <em>does not</em> have the HandleChannels method called on it.</p>
+        <!-- FIXME: tp:dbus-ref -->
+
+        <p>Clients that call Claim on channels but do not immediately
+          close them SHOULD implement the Handler interface and its
+          CurrentlyHandledChannels property.</p>
+        <!-- FIXME: tp:dbus-ref -->
+
+        <p>Approvers wishing to reject channels MUST call this method to
+          claim ownership of them, and MUST NOT call
+          <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>
+          on the channels unless/until this method returns successfully.</p>
+
+        <tp:rationale>
+          <p>The channel dispatcher can't know how best to close arbitrary
+            channel types, so it leaves it up to the approver to do so.
+            For instance, for Text channels it is necessary
+            to acknowledge any messages that have already been displayed to
+            the user first - ideally, the approver would display and then
+            acknowledge the messages.</p>
+        </tp:rationale>
+
+        <p>If successful, this method will cause the ChannelDispatchOperation
+          object to disappear, emitting
+          <tp:member-ref>Finished</tp:member-ref>, in the same way as for
+          <tp:member-ref>HandleWith</tp:member-ref>.</p>
+
+        <p>This method may fail because the dispatch operation has already
+          been completed. Again, see HandleWith for more details. The approver
+          MUST NOT attempt to interact with the channels further in this
+          case.</p>
+
+        <p>(FIXME: list some other possible errors)</p>
+      </tp:docstring>
+
+      <tp:possible-errors>
+        <tp:error name="org.freedesktop.Telepathy.Error.NotYours">
+          <tp:docstring>
+            At the time that Claim was called, this dispatch operation was
+            processing a call to HandleWith which has now succeeded, so
+            some Handler nominated by another approver is now responsible for
+            the channel.
+          </tp:docstring>
+        </tp:error>
+      </tp:possible-errors>
+    </method>
+
+    <signal name="Finished" tp:name-for-bindings="Finished">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>Emitted when this dispatch operation finishes. The dispatch
+          operation is no longer present and further methods must not be
+          called on it.</p>
+
+        <p>Its object path SHOULD NOT be reused for a subsequent dispatch
+          operation; the ChannelDispatcher MUST choose object paths
+          in a way that avoids immediate re-use.</p>
+
+        <tp:rationale>
+          <p>Otherwise, clients might accidentally call HandleWith or Claim
+            on a new dispatch operation instead of the one they
+            intended to handle.</p>
+        </tp:rationale>
+      </tp:docstring>
+    </signal>
+
+  </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/xml/nmc5.xml b/xml/nmc5.xml
index 8f19419..7d2e775 100644
--- a/xml/nmc5.xml
+++ b/xml/nmc5.xml
@@ -18,4 +18,6 @@
 <xi:include href="Client_Handler.xml"/>
 <xi:include href="Client_Observer.xml"/>
 
+<xi:include href="Channel_Dispatch_Operation.xml"/>
+
 </tp:spec>
-- 
1.5.6.5




More information about the Telepathy-commits mailing list