summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2013-06-22 19:10:10 +0100
committerWill Thompson <will.thompson@collabora.co.uk>2013-06-23 16:06:05 +0100
commitddb451a71569bdd6b7d9a673d12e8e83eddb818e (patch)
treed98448bcb4322f7323ff12cf3ac72696c08ceacc
parente996dd8b1f69eb1367582916b92e702426dfdf25 (diff)
downloadtelepathy-gabble-ddb451a71569bdd6b7d9a673d12e8e83eddb818e.tar.gz
console: turn it into an actual channel
-rw-r--r--plugins/console/channel-manager.c103
-rw-r--r--plugins/console/channel-manager.h1
-rw-r--r--plugins/console/plugin.c59
-rw-r--r--plugins/console/sidecar.c61
-rw-r--r--tests/twisted/console.py7
5 files changed, 134 insertions, 97 deletions
diff --git a/plugins/console/channel-manager.c b/plugins/console/channel-manager.c
index 44f4a8b6d..b2a17902d 100644
--- a/plugins/console/channel-manager.c
+++ b/plugins/console/channel-manager.c
@@ -21,6 +21,7 @@
#include "console/channel-manager.h"
#include "extensions/extensions.h"
+#include "console/sidecar.h"
static void channel_manager_iface_init (gpointer, gpointer);
@@ -80,6 +81,23 @@ gabble_console_channel_manager_get_property (
}
}
+
+static void
+gabble_console_channel_manager_dispose (
+ GObject *object)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+ TpBaseChannel *channel;
+
+ while ((channel = g_queue_peek_head (&self->console_channels)) != NULL)
+ {
+ tp_base_channel_close (channel);
+ }
+
+ G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->dispose (object);
+}
+
+
static void
gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *klass)
{
@@ -87,6 +105,7 @@ gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *kla
oclass->set_property = gabble_console_channel_manager_set_property;
oclass->get_property = gabble_console_channel_manager_get_property;
+ oclass->dispose = gabble_console_channel_manager_dispose;
g_object_class_install_property (oclass, PROP_CONNECTION,
g_param_spec_object ("plugin-connection", "Gabble Plugin Connection",
@@ -95,6 +114,13 @@ gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *kla
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}
+
+static const gchar * const allowed[] = {
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ NULL
+};
+
static void
gabble_console_channel_manager_type_foreach_channel_class (GType type,
TpChannelManagerTypeChannelClassFunc func,
@@ -110,6 +136,77 @@ gabble_console_channel_manager_type_foreach_channel_class (GType type,
g_hash_table_unref (table);
}
+
+static void
+console_channel_closed_cb (
+ GabbleConsoleSidecar *channel,
+ gpointer user_data)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (user_data);
+
+ tp_channel_manager_emit_channel_closed_for_object (self,
+ TP_EXPORTABLE_CHANNEL (channel));
+
+ if (g_queue_remove (&self->console_channels, channel))
+ {
+ g_object_unref (channel);
+ }
+}
+
+
+static gboolean
+gabble_console_channel_manager_create_channel (
+ TpChannelManager *manager,
+ gpointer request_token,
+ GHashTable *request_properties)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (manager);
+ TpBaseChannel *channel = NULL;
+ GError *error = NULL;
+ GSList *request_tokens;
+
+ if (tp_strdiff (tp_asv_get_string (request_properties,
+ TP_IFACE_CHANNEL ".ChannelType"),
+ GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE))
+ return FALSE;
+
+ if (tp_asv_get_uint32 (request_properties,
+ TP_IFACE_CHANNEL ".TargetHandleType", NULL) != 0)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
+ "Console channels can't have a target handle");
+ goto error;
+ }
+
+ if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+ allowed,
+ allowed,
+ &error))
+ goto error;
+
+ channel = g_object_new (GABBLE_TYPE_CONSOLE_SIDECAR,
+ "connection", self->plugin_connection,
+ NULL);
+ tp_base_channel_register (channel);
+ g_signal_connect (channel, "closed", (GCallback) console_channel_closed_cb,
+ self);
+ g_queue_push_tail (&self->console_channels, channel);
+
+ request_tokens = g_slist_prepend (NULL, request_token);
+ tp_channel_manager_emit_new_channel (self,
+ TP_EXPORTABLE_CHANNEL (channel), request_tokens);
+ g_slist_free (request_tokens);
+
+ return TRUE;
+
+error:
+ tp_channel_manager_emit_request_failed (self, request_token,
+ error->domain, error->code, error->message);
+ g_error_free (error);
+ return TRUE;
+}
+
+
static void
channel_manager_iface_init (gpointer g_iface,
gpointer iface_data)
@@ -117,9 +214,5 @@ channel_manager_iface_init (gpointer g_iface,
TpChannelManagerIface *iface = g_iface;
iface->type_foreach_channel_class = gabble_console_channel_manager_type_foreach_channel_class;
-
- /* not requestable. */
- iface->ensure_channel = NULL;
- iface->create_channel = NULL;
- iface->request_channel = NULL;
+ iface->create_channel = gabble_console_channel_manager_create_channel;
}
diff --git a/plugins/console/channel-manager.h b/plugins/console/channel-manager.h
index a876a7b14..8ec4adc0a 100644
--- a/plugins/console/channel-manager.h
+++ b/plugins/console/channel-manager.h
@@ -31,6 +31,7 @@ struct _GabbleConsoleChannelManager {
GObject parent;
GabblePluginConnection *plugin_connection;
+ GQueue console_channels;
};
GType gabble_console_channel_manager_get_type (void);
diff --git a/plugins/console/plugin.c b/plugins/console/plugin.c
index 222c58378..52386016d 100644
--- a/plugins/console/plugin.c
+++ b/plugins/console/plugin.c
@@ -53,62 +53,6 @@ gabble_console_plugin_class_init (GabbleConsolePluginClass *klass)
{
}
-static void
-gabble_console_plugin_create_sidecar_async (
- GabblePlugin *plugin,
- const gchar *sidecar_interface,
- GabblePluginConnection *connection,
- WockySession *session,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (plugin),
- callback, user_data,
- gabble_console_plugin_create_sidecar_async);
- GabbleSidecar *sidecar = NULL;
-
- if (!tp_strdiff (sidecar_interface, GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE))
- {
- sidecar = g_object_new (GABBLE_TYPE_CONSOLE_SIDECAR,
- "connection", connection,
- "session", session,
- NULL);
- }
- else
- {
- g_simple_async_result_set_error (result, TP_ERROR,
- TP_ERROR_NOT_IMPLEMENTED, "'%s' not implemented", sidecar_interface);
- }
-
- if (sidecar != NULL)
- g_simple_async_result_set_op_res_gpointer (result, sidecar,
- g_object_unref);
-
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
-}
-
-static GabbleSidecar *
-gabble_console_plugin_create_sidecar_finish (
- GabblePlugin *plugin,
- GAsyncResult *result,
- GError **error)
-{
- GabbleSidecar *sidecar;
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
- error))
- return NULL;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result,
- G_OBJECT (plugin), gabble_console_plugin_create_sidecar_async), NULL);
-
- sidecar = GABBLE_SIDECAR (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (result)));
-
- return g_object_ref (sidecar);
-}
-
static GPtrArray *
gabble_console_plugin_create_channel_managers (GabblePlugin *plugin,
GabblePluginConnection *plugin_connection)
@@ -132,9 +76,6 @@ plugin_iface_init (
iface->name = "XMPP console";
iface->version = PACKAGE_VERSION;
- iface->sidecar_interfaces = sidecar_interfaces;
- iface->create_sidecar_async = gabble_console_plugin_create_sidecar_async;
- iface->create_sidecar_finish = gabble_console_plugin_create_sidecar_finish;
iface->create_channel_managers = gabble_console_plugin_create_channel_managers;
}
diff --git a/plugins/console/sidecar.c b/plugins/console/sidecar.c
index 5484a3ca0..b224b7f48 100644
--- a/plugins/console/sidecar.c
+++ b/plugins/console/sidecar.c
@@ -29,7 +29,6 @@
enum {
PROP_0,
- PROP_SESSION,
PROP_SPEW
};
@@ -50,23 +49,18 @@ struct _GabbleConsoleSidecarPrivate
gulong sending_id;
};
-static void sidecar_iface_init (
- gpointer g_iface,
- gpointer data);
static void console_iface_init (
gpointer g_iface,
gpointer data);
static void gabble_console_sidecar_set_spew (
GabbleConsoleSidecar *self,
gboolean spew);
+static void gabble_console_sidecar_close (TpBaseChannel *chan);
G_DEFINE_TYPE_WITH_CODE (GabbleConsoleSidecar, gabble_console_sidecar,
TP_TYPE_BASE_CHANNEL,
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SIDECAR, sidecar_iface_init);
G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_GABBLE_PLUGIN_CONSOLE,
console_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
)
static void
@@ -79,6 +73,25 @@ gabble_console_sidecar_init (GabbleConsoleSidecar *self)
self->priv->writer = wocky_xmpp_writer_new_no_stream ();
}
+
+static void
+gabble_console_sidecar_constructed (GObject *object)
+{
+ GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+ void (*chain_up)(GObject *) =
+ G_OBJECT_CLASS (gabble_console_sidecar_parent_class)->constructed;
+
+ if (chain_up != NULL)
+ chain_up (object);
+
+ self->priv->session = g_object_ref (
+ gabble_plugin_connection_get_session (
+ GABBLE_PLUGIN_CONNECTION (
+ tp_base_channel_get_connection (
+ TP_BASE_CHANNEL (self)))));
+ g_return_if_fail (self->priv->session != NULL);
+}
+
static void
gabble_console_sidecar_get_property (
GObject *object,
@@ -110,11 +123,6 @@ gabble_console_sidecar_set_property (
switch (property_id)
{
- case PROP_SESSION:
- g_assert (self->priv->session == NULL); /* construct-only */
- self->priv->session = g_value_dup_object (value);
- break;
-
case PROP_SPEW:
gabble_console_sidecar_set_spew (self, g_value_get_boolean (value));
break;
@@ -145,22 +153,21 @@ static void
gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TpBaseChannelClass *channel_class = TP_BASE_CHANNEL_CLASS (klass);
static TpDBusPropertiesMixinPropImpl console_props[] = {
{ "SpewStanzas", "spew-stanzas", "spew-stanzas" },
{ NULL },
};
+ object_class->constructed = gabble_console_sidecar_constructed;
object_class->get_property = gabble_console_sidecar_get_property;
object_class->set_property = gabble_console_sidecar_set_property;
object_class->dispose = gabble_console_sidecar_dispose;
- g_type_class_add_private (klass, sizeof (GabbleConsoleSidecarPrivate));
+ channel_class->channel_type = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE;
+ channel_class->close = gabble_console_sidecar_close;
- g_object_class_install_property (object_class, PROP_SESSION,
- g_param_spec_object ("session", "Session",
- "Wocky session",
- WOCKY_TYPE_SESSION,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_type_class_add_private (klass, sizeof (GabbleConsoleSidecarPrivate));
g_object_class_install_property (object_class, PROP_SPEW,
g_param_spec_boolean ("spew-stanzas", "SpewStanzas",
@@ -171,25 +178,17 @@ gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass)
tp_dbus_properties_mixin_implement_interface (object_class,
GABBLE_IFACE_QUARK_GABBLE_PLUGIN_CONSOLE,
tp_dbus_properties_mixin_getter_gobject_properties,
- /* FIXME: if we were feeling clever, we'd override the setter so that
- * we can monitor the bus name of any application which sets
- * SpewStanzas to TRUE and flip it back to false when that application
- * dies.
- *
- * Alternatively, we could just replace this sidecar with a channel.
- */
tp_dbus_properties_mixin_setter_gobject_properties,
console_props);
}
-static void sidecar_iface_init (
- gpointer g_iface,
- gpointer data)
+static void
+gabble_console_sidecar_close (TpBaseChannel *chan)
{
- GabbleSidecarInterface *iface = g_iface;
+ GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (chan);
- iface->interface = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE;
- iface->get_immutable_properties = NULL;
+ gabble_console_sidecar_set_spew (self, FALSE);
+ tp_base_channel_destroyed (chan);
}
static gboolean
diff --git a/tests/twisted/console.py b/tests/twisted/console.py
index 8aab65f76..b2efd658c 100644
--- a/tests/twisted/console.py
+++ b/tests/twisted/console.py
@@ -38,9 +38,10 @@ def test(q, bus, conn, stream):
allowed = []
assertContains((fixed, allowed), rccs)
- path, _ = conn.Future.EnsureSidecar(CONSOLE_PLUGIN_IFACE)
+ path, _ = conn.Requests.CreateChannel({ cs.CHANNEL_TYPE: CONSOLE_PLUGIN_IFACE })
console = ProxyWrapper(bus.get_object(conn.bus_name, path),
- CONSOLE_PLUGIN_IFACE)
+ CONSOLE_PLUGIN_IFACE,
+ {'Channel': cs.CHANNEL})
assert not console.Properties.Get(CONSOLE_PLUGIN_IFACE, 'SpewStanzas')
es = [
@@ -99,5 +100,7 @@ def test(q, bus, conn, stream):
assertEquals('body', body.name)
assertEquals(ns.CLIENT, body.uri)
+ console.Channel.Close()
+
if __name__ == '__main__':
exec_test(test)