Commit fe9f456a authored by Simon McVittie's avatar Simon McVittie
parent 6b005f6c
<?xml version="1.0" ?>
<node name="/Connection_FUTURE"
<tp:copyright>Copyright © 2009 Collabora Limited</tp:copyright>
<tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
<tp:license xmlns="">
<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
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,
<interface name="org.freedesktop.Telepathy.Connection.FUTURE"
<tp:requires interface="org.freedesktop.Telepathy.Connection"/>
<method name="EnsureSidecar" tp:name-for-bindings="Ensure_Sidecar">
<tp:added version="0.19.UNRELEASED"/>
<arg direction="in" name="Main_Interface" type="s"
The "primary" interface implemented by an object attached
to a connection. For example, a Gabble plugin implementing
fine-grained control of XEP-0016 privacy lists might expose an object
implementing <tt>com.example.PrivacyLists</tt>.
<arg direction="out" name="Path" type="o">
<tp:docstring>The object path of the sidecar, exported by the same bus
name as the Connection to which it is attached.</tp:docstring>
<arg direction="out" name="Properties" type="a{sv}"
<tp:docstring>Immutable properties of the sidecar.</tp:docstring>
<tp:docstring xmlns="">
<p>Request an object with a particular interface providing additional
connection-specific functionality, together with its immutable
properties. These will often be implemented by plug-ins to the
connection managers; for example, support for an XMPP XEP for which
no generic Telepathy interface exists might be implemented by a
Gabble plugin exposing a sidecar with a particular interface.</p>
<p>This method may be called at any point during the lifetime of a
connection, even before its <tp:type>Connection_Status</tp:type>
changes to Connected. It MAY take a long time to
return—perhaps it needs to wait for a connection to be established
and for all the services supported by the server to be discovered
before determining whether necessary server-side support is
available—so callers SHOULD override the default method timeout (25
seconds) with a much higher value (perhaps even MAX_INT32, meaning
“no timeout” in recent versions of libdbus).</p>
<p>There is an implicit assumption that any connection
manager plugin will only want to export one “primary” object per
feature it implements, since there is a one-to-one mapping between
interface and object. This is reasonable since Sidecars are
(intended to be) analogous to extra interfaces on the connection,
providing once-per-connection shared functionality; it also makes
client code straightforward (look up the interface you care about
in a dictionary, build a proxy object from the value). More
“plural” plugins are likely to want to implement new types of
<tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
The requested sidecar is not implemented by this connection manager,
or a necessary server-side component does not exist. (FIXME: split
these two errors out? Then again, once we list the guaranteed and
possible sidecars on a Protocol object, clients can tell the
difference themselves, because they shouldn't be calling this in the
first case.)
<tp:error name="org.freedesktop.Telepathy.Error.ServiceBusy">
A server-side component needed by the requested sidecar reported it
is currently too busy, or did not respond for some
implementation-defined time. The caller may wish to try again later.
<tp:error name="org.freedesktop.Telepathy.Error.Cancelled">
The connection was disconnected while the sidecar was being set up.
......@@ -2,7 +2,6 @@ tools_dir = $(top_srcdir)/tools
all.xml \
Connection_Future.xml \
Connection_Interface_Gabble_Decloak.xml \
Gabble_Plugin_Console.xml \
Gabble_Plugin_Gateways.xml \
......@@ -37,7 +37,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA</p>
<xi:include href="OLPC_Activity_Properties.xml"/>
<xi:include href="Connection_Interface_Gabble_Decloak.xml"/>
<xi:include href="Connection_Future.xml"/>
<xi:include href="Gabble_Plugin_Console.xml"/>
<xi:include href="Gabble_Plugin_Gateways.xml"/>
......@@ -178,7 +178,7 @@ create_sidecar_cb (
GList *l;
for (l = contexts; l != NULL; l = l->next)
gabble_svc_connection_future_return_from_ensure_sidecar (l->data,
tp_svc_connection_interface_sidecars1_return_from_ensure_sidecar (l->data,
path, props);
g_hash_table_unref (props);
......@@ -200,7 +200,7 @@ out:
static void
gabble_connection_ensure_sidecar (
GabbleSvcConnectionFUTURE *iface,
TpSvcConnectionInterfaceSidecars1 *iface,
const gchar *sidecar_iface,
DBusGMethodInvocation *context)
......@@ -238,7 +238,7 @@ gabble_connection_ensure_sidecar (
GHashTable *props = gabble_sidecar_get_immutable_properties (sidecar);
DEBUG ("sidecar %s already exists at %s", sidecar_iface, path);
gabble_svc_connection_future_return_from_ensure_sidecar (context, path,
tp_svc_connection_interface_sidecars1_return_from_ensure_sidecar (context, path,
g_free (path);
......@@ -340,14 +340,12 @@ sidecars_conn_status_changed_cb (
conn_future_iface_init (
gpointer g_iface,
gpointer iface_data)
conn_sidecars_iface_init (gpointer g_iface)
GabbleSvcConnectionFUTUREClass *klass = g_iface;
TpSvcConnectionInterfaceSidecars1Class *klass = g_iface;
#define IMPLEMENT(x) \
gabble_svc_connection_future_implement_##x (\
tp_svc_connection_interface_sidecars1_implement_##x (\
klass, gabble_connection_##x)
IMPLEMENT (ensure_sidecar);
......@@ -27,7 +27,7 @@ G_BEGIN_DECLS
void conn_sidecars_init (GabbleConnection *conn);
void conn_sidecars_dispose (GabbleConnection *conn);
void conn_future_iface_init (gpointer g_iface, gpointer iface_data);
void conn_sidecars_iface_init (gpointer g_iface);
......@@ -125,8 +125,8 @@ G_DEFINE_TYPE_WITH_CODE(GabbleConnection,
......@@ -883,7 +883,7 @@ static const gchar *implemented_interfaces[] = {
......@@ -204,6 +204,8 @@ CONN_IFACE_CONTACTS = CONN + '.Interface.Contacts'
CONN_IFACE_CONTACT_CAPS = CONN + '.Interface.ContactCapabilities'
CONN_IFACE_CONTACT_INFO = CONN + ".Interface.ContactInfo"
CONN_IFACE_PRESENCE = CONN + '.Interface.Presence'
CONN_IFACE_RENAMING = CONN + '.Interface.Renaming'
CONN_IFACE_SIDECARS1 = CONN + '.Interface.Sidecars1'
CONN_IFACE_SIMPLE_PRESENCE = CONN + '.Interface.SimplePresence'
CONN_IFACE_REQUESTS = CONN + '.Interface.Requests'
CONN_IFACE_LOCATION = CONN + '.Interface.Location'
......@@ -607,6 +609,7 @@ CR = PREFIX + '.ChannelRequest'
CDO = PREFIX + '.ChannelDispatchOperation'
CD = PREFIX + '.ChannelDispatcher'
CD_IFACE_MESSAGES1 = PREFIX + '.ChannelDispatcher.Interface.Messages1'
CD_IFACE_OP_LIST = PREFIX + '.ChannelDispatcher.Interface.OperationList'
CD_PATH = PATH_PREFIX + '/ChannelDispatcher'
CD_REDISPATCH = CD + '.Interface.Redispatch.DRAFT'
......@@ -63,7 +63,7 @@ def test_not_acceptable(q, gateways_iface, stream):
def test(q, bus, conn, stream):
# Request a sidecar thate we support before we're connected; it should just
# wait around until we're connected.
call_async(q, conn.Future, 'EnsureSidecar', PLUGIN_IFACE)
call_async(q, conn.Sidecars1, 'EnsureSidecar', PLUGIN_IFACE)
q.expect('dbus-signal', signal='StatusChanged',
......@@ -633,7 +633,6 @@ def wrap_connection(conn):
('ContactCapabilities', cs.CONN_IFACE_CONTACT_CAPS),
('ContactInfo', cs.CONN_IFACE_CONTACT_INFO),
('Location', cs.CONN_IFACE_LOCATION),
('Future', tp_name_prefix + '.Connection.FUTURE'),
('MailNotification', cs.CONN_IFACE_MAIL_NOTIFICATION),
('ContactList', cs.CONN_IFACE_CONTACT_LIST),
('ContactGroups', cs.CONN_IFACE_CONTACT_GROUPS),
......@@ -641,6 +640,8 @@ def wrap_connection(conn):
('PowerSaving', cs.CONN_IFACE_POWER_SAVING),
('Addressing', cs.CONN_IFACE_ADDRESSING),
('ClientTypes', cs.CONN_IFACE_CLIENT_TYPES),
('Renaming', cs.CONN_IFACE_RENAMING),
('Sidecars1', cs.CONN_IFACE_SIDECARS1),
class ChannelWrapper(ProxyWrapper):
......@@ -23,7 +23,7 @@ def test(q, bus, conn, stream):
# created.
pattern = EventPattern('stream-iq', to='',
call_async(q, conn.Future, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ")
call_async(q, conn.Sidecars1, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ")
e = q.expect_many(pattern)[0]
# The server said yes, so we should get a sidecar back!
......@@ -18,7 +18,7 @@ if not PLUGINS_ENABLED:
def test(q, bus, conn, stream):
# Request a sidecar thate we support before we're connected; it should just
# wait around until we're connected.
call_async(q, conn.Future, 'EnsureSidecar', TEST_PLUGIN_IFACE)
call_async(q, conn.Sidecars1, 'EnsureSidecar', TEST_PLUGIN_IFACE)
# Now we're connected, the call we made earlier should return.
......@@ -28,30 +28,30 @@ def test(q, bus, conn, stream):
assertEquals({}, props)
# We should get the same sidecar if we request it again
path2, props2 = conn.Future.EnsureSidecar(TEST_PLUGIN_IFACE)
path2, props2 = conn.Sidecars1.EnsureSidecar(TEST_PLUGIN_IFACE)
assertEquals((path, props), (path2, props2))
# Only now does it fail.
q.expect('dbus-error', method='EnsureSidecar')
# This is not a valid interface name
call_async(q, conn.Future, 'EnsureSidecar', 'not an interface')
call_async(q, conn.Sidecars1, 'EnsureSidecar', 'not an interface')
q.expect('dbus-error', name=cs.INVALID_ARGUMENT)
# The test plugin makes no reference to this interface.
call_async(q, conn.Future, 'EnsureSidecar', 'unsupported.sidecar')
call_async(q, conn.Sidecars1, 'EnsureSidecar', 'unsupported.sidecar')
q.expect('dbus-error', name=cs.NOT_IMPLEMENTED)
# This sidecar does have some properties:
path, props = conn.Future.EnsureSidecar(TEST_PLUGIN_IFACE + ".Props")
path, props = conn.Sidecars1.EnsureSidecar(TEST_PLUGIN_IFACE + ".Props")
assertContains(TEST_PLUGIN_IFACE + ".Props.Greeting", props)
# The plugin claims it implements this sidecar, but actually doesn't.
# Check that we don't blow up (although this is no different from
# Gabble's perspective to creating a sidecar failing because a network
# service wasn't there, for instance).
call_async(q, conn.Future, 'EnsureSidecar',
call_async(q, conn.Sidecars1, 'EnsureSidecar',
q.expect('dbus-error', name=cs.NOT_IMPLEMENTED)
......@@ -59,7 +59,7 @@ def test(q, bus, conn, stream):
# created.
pattern = EventPattern('stream-iq', to='',
call_async(q, conn.Future, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ")
call_async(q, conn.Sidecars1, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ")
e = q.expect_many(pattern)[0]
sync_dbus(bus, q, conn)
......@@ -70,7 +70,7 @@ def test(q, bus, conn, stream):
# Let's try again. The plugin should get a chance to ping the server
# again.
call_async(q, conn.Future, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ")
call_async(q, conn.Sidecars1, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ")
e = q.expect_many(pattern)[0]
# The server said yes, so we should get a sidecar back!
......@@ -80,7 +80,7 @@ def test(q, bus, conn, stream):
# If we ask again once the plugin has been created, it should return at
# once without any more network traffic.
conn.Future.EnsureSidecar(TEST_PLUGIN_IFACE + ".IQ")
conn.Sidecars1.EnsureSidecar(TEST_PLUGIN_IFACE + ".IQ")
sync_stream(q, stream)
# TODO: test ensuring a sidecar that waits for something from the
......@@ -96,7 +96,7 @@ def test(q, bus, conn, stream):
call_async(q, conn.Future, 'EnsureSidecar', 'zomg.what')
call_async(q, conn.Sidecars1, 'EnsureSidecar', 'zomg.what')
# With older telepathy-glib this would be DISCONNECTED;
# with newer telepathy-glib the Connection disappears from the bus
# sooner, and you get UnknownMethod or something from dbus-glib.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment