diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2011-09-09 13:29:55 +0100 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2012-05-15 10:58:23 +0100 |
commit | 7e1c6dd5060edb917838435193ea1e9601a16a5d (patch) | |
tree | e2be732bde5a919c72ff5bd01a652a13f3244218 | |
parent | 6c79a8d71d16c615b416c7b45b24ed0701e7540d (diff) |
Implement Channel.I.Room
This is really trivial, I'm happy to report.
-rw-r--r-- | src/idle-muc-channel.c | 26 | ||||
-rw-r--r-- | src/idle-muc-manager.c | 70 | ||||
-rw-r--r-- | tests/twisted/channels/requests-muc.py | 61 | ||||
-rw-r--r-- | tests/twisted/constants.py | 3 |
4 files changed, 130 insertions, 30 deletions
diff --git a/src/idle-muc-channel.c b/src/idle-muc-channel.c index 294193b..2c101a5 100644 --- a/src/idle-muc-channel.c +++ b/src/idle-muc-channel.c @@ -55,6 +55,7 @@ G_DEFINE_TYPE_WITH_CODE(IdleMUCChannel, idle_muc_channel, TP_TYPE_BASE_CHANNEL, G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_INTERFACE_PASSWORD, _password_iface_init); G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_TYPE_TEXT, tp_message_mixin_text_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MESSAGES, tp_message_mixin_messages_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_ROOM, NULL); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_SUBJECT, subject_iface_init); ) @@ -66,7 +67,9 @@ enum { PROP_SUBJECT_ACTOR, PROP_SUBJECT_ACTOR_HANDLE, PROP_SUBJECT_TIMESTAMP, - PROP_CAN_SET_SUBJECT + PROP_CAN_SET_SUBJECT, + + PROP_SERVER, }; /* signal enum */ @@ -144,6 +147,7 @@ static const gchar *muc_channel_interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_PASSWORD, TP_IFACE_CHANNEL_INTERFACE_GROUP, TP_IFACE_CHANNEL_INTERFACE_MESSAGES, + TP_IFACE_CHANNEL_INTERFACE_ROOM, TP_IFACE_CHANNEL_INTERFACE_SUBJECT, NULL }; @@ -317,6 +321,9 @@ idle_muc_channel_get_property ( case PROP_CAN_SET_SUBJECT: g_value_set_boolean (value, priv->can_set_topic); break; + case PROP_SERVER: + g_value_set_static_string (value, ""); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -346,6 +353,8 @@ idle_muc_channel_fill_immutable_properties ( TP_IFACE_CHANNEL_INTERFACE_MESSAGES, "DeliveryReportingSupport", TP_IFACE_CHANNEL_INTERFACE_MESSAGES, "SupportedContentTypes", TP_IFACE_CHANNEL_INTERFACE_MESSAGES, "MessageTypes", + TP_IFACE_CHANNEL_INTERFACE_ROOM, "RoomName", + TP_IFACE_CHANNEL_INTERFACE_ROOM, "Server", NULL); } @@ -353,6 +362,11 @@ static void idle_muc_channel_class_init (IdleMUCChannelClass *idle_muc_channel_c GObjectClass *object_class = G_OBJECT_CLASS (idle_muc_channel_class); TpBaseChannelClass *base_channel_class = TP_BASE_CHANNEL_CLASS (idle_muc_channel_class); GParamSpec *param_spec; + static TpDBusPropertiesMixinPropImpl room_props[] = { + { "RoomName", "target-id", NULL }, + { "Server", "server", NULL }, + { NULL }, + }; static TpDBusPropertiesMixinPropImpl subject_props[] = { { "Subject", "subject", NULL }, { "Actor", "subject-actor", NULL }, @@ -378,6 +392,12 @@ static void idle_muc_channel_class_init (IdleMUCChannelClass *idle_muc_channel_c base_channel_class->get_object_path_suffix = idle_muc_channel_get_path_suffix; param_spec = g_param_spec_string ( + "server", "Room.Server", "always empty", + "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_SERVER, + param_spec); + + param_spec = g_param_spec_string ( "subject", "Subject.Subject", "(aka topic)", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_SUBJECT, @@ -419,6 +439,10 @@ static void idle_muc_channel_class_init (IdleMUCChannelClass *idle_muc_channel_c tp_group_mixin_class_allow_self_removal (object_class); tp_dbus_properties_mixin_implement_interface (object_class, + TP_IFACE_QUARK_CHANNEL_INTERFACE_ROOM, + tp_dbus_properties_mixin_getter_gobject_properties, NULL, + room_props); + tp_dbus_properties_mixin_implement_interface (object_class, TP_IFACE_QUARK_CHANNEL_INTERFACE_SUBJECT, tp_dbus_properties_mixin_getter_gobject_properties, NULL, subject_props); diff --git a/src/idle-muc-manager.c b/src/idle-muc-manager.c index 907cdc7..e2400cc 100644 --- a/src/idle-muc-manager.c +++ b/src/idle-muc-manager.c @@ -101,6 +101,17 @@ static const gchar * const muc_channel_allowed_properties[] = { NULL }; +static const gchar * const muc_channel_allowed_room_properties[] = { + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, /* But it must be None */ + TP_PROP_CHANNEL_INTERFACE_ROOM_ROOM_NAME, + NULL +}; + +static const gchar * const muc_channel_all_allowed_properties[] = { + TP_PROP_CHANNEL_TARGET_HANDLE, + TP_PROP_CHANNEL_TARGET_ID, + TP_PROP_CHANNEL_INTERFACE_ROOM_ROOM_NAME, +}; static GObject* _muc_manager_constructor(GType type, guint n_props, GObjectConstructParam *props) @@ -601,14 +612,21 @@ _muc_manager_type_foreach_channel_class ( TpChannelManagerTypeChannelClassFunc func, gpointer user_data) { - GHashTable *table = tp_asv_new ( - TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT, - TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_ROOM, - NULL); + static GHashTable *handle_fixed = NULL, *room_name_fixed = NULL; - func (type, table, muc_channel_allowed_properties, user_data); + if (G_UNLIKELY (handle_fixed == NULL)) + { + handle_fixed = tp_asv_new ( + TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT, + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_ROOM, + NULL); + room_name_fixed = tp_asv_new ( + TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT, + NULL); + } - g_hash_table_destroy (table); + func (type, handle_fixed, muc_channel_allowed_properties, user_data); + func (type, room_name_fixed, muc_channel_allowed_room_properties, user_data); } @@ -729,6 +747,7 @@ _muc_manager_request ( TpHandleRepoIface *room_repo = tp_base_connection_get_handles (base_conn, TP_HANDLE_TYPE_ROOM); GError *error = NULL; + TpHandleType handle_type; TpHandle handle; const gchar *channel_type; IdleMUCChannel *channel; @@ -739,18 +758,41 @@ _muc_manager_request ( if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT)) return FALSE; - if (tp_asv_get_uint32 (request_properties, - TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) != TP_HANDLE_TYPE_ROOM) - return FALSE; + handle_type = tp_asv_get_uint32 (request_properties, + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL); + + switch (handle_type) + { + case TP_HANDLE_TYPE_ROOM: + handle = tp_asv_get_uint32 (request_properties, + TP_PROP_CHANNEL_TARGET_HANDLE, NULL); - handle = tp_asv_get_uint32 (request_properties, - TP_PROP_CHANNEL_TARGET_HANDLE, NULL); + if (!tp_handle_is_valid (room_repo, handle, &error)) + goto error; - if (!tp_handle_is_valid (room_repo, handle, &error)) - goto error; + break; + + case TP_HANDLE_TYPE_NONE: + { + const gchar *room_name = tp_asv_get_string (request_properties, + TP_PROP_CHANNEL_INTERFACE_ROOM_ROOM_NAME); + + if (room_name == NULL) + return FALSE; + + handle = tp_handle_ensure (room_repo, room_name, NULL, &error); + if (handle == 0) + goto error; + + break; + } + + default: + return FALSE; + } if (tp_channel_manager_asv_has_unknown_properties (request_properties, - muc_channel_fixed_properties, muc_channel_allowed_properties, + muc_channel_fixed_properties, muc_channel_all_allowed_properties, &error)) goto error; diff --git a/tests/twisted/channels/requests-muc.py b/tests/twisted/channels/requests-muc.py index 58704b6..b43a494 100644 --- a/tests/twisted/channels/requests-muc.py +++ b/tests/twisted/channels/requests-muc.py @@ -2,9 +2,11 @@ Test connecting to a IRC channel via the Requests interface """ +import functools from idletest import exec_test, BaseIRCServer from servicetest import ( EventPattern, call_async, sync_dbus, make_channel_proxy, assertEquals, + assertSameSets, assertContains, ) import constants as cs import dbus @@ -14,7 +16,38 @@ class DelayJoinServer(BaseIRCServer): # do nothing; wait for the test to call sendJoin(). return -def test(q, bus, conn, stream): +def build_request(conn, channel_name, use_room): + rccs = conn.Properties.Get(cs.CONN_IFACE_REQUESTS, + 'RequestableChannelClasses') + + if use_room: + # We allow TargetHandleType in Room-flavoured requests, but it has to + # be None if specified. + assertContains( + ({ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT }, + [cs.TARGET_HANDLE_TYPE, cs.ROOM_NAME], + ), rccs) + + request = { + cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, + cs.ROOM_NAME: '#idletest' + } + else: + assertContains( + ({ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, + cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, + }, + [cs.TARGET_HANDLE, cs.TARGET_ID] + ), rccs) + request = { + cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, + cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, + cs.TARGET_ID: '#idletest', + } + + return dbus.Dictionary(request, signature='sv') + +def test(q, bus, conn, stream, use_room=False): conn.Connect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[1, 1]), @@ -24,14 +57,8 @@ def test(q, bus, conn, stream): self_handle = conn.GetSelfHandle() - request = dbus.Dictionary({ - cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, - cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, - cs.TARGET_ID: '#idletest', - }, signature='sv') - - call_async(q, conn, 'CreateChannel', request, - dbus_interface=cs.CONN_IFACE_REQUESTS) + request = build_request(conn, '#idletest', use_room) + call_async(q, conn.Requests, 'CreateChannel', request) # Idle should try to join the channel. q.expect('stream-JOIN') @@ -55,14 +82,17 @@ def test(q, bus, conn, stream): path, props = cc.value assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT - assert sorted(props[cs.INTERFACES]) == \ - sorted([cs.CHANNEL_IFACE_GROUP, - cs.CHANNEL_IFACE_PASSWORD, - cs.CHANNEL_IFACE_MESSAGES, - cs.CHANNEL_IFACE_SUBJECT, - ]) + assertSameSets( + [cs.CHANNEL_IFACE_GROUP, + cs.CHANNEL_IFACE_PASSWORD, + cs.CHANNEL_IFACE_MESSAGES, + cs.CHANNEL_IFACE_ROOM, + cs.CHANNEL_IFACE_SUBJECT, + ], props[cs.INTERFACES]) assert props[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert props[cs.TARGET_ID] == '#idletest' + assertEquals('#idletest', props[cs.ROOM_NAME]) + assertEquals('', props[cs.ROOM_SERVER]) assert props[cs.TARGET_HANDLE] == \ conn.RequestHandles(cs.HT_ROOM, ['#idletest'])[0] assert props[cs.REQUESTED] @@ -117,4 +147,5 @@ def test(q, bus, conn, stream): if __name__ == '__main__': exec_test(test, protocol=DelayJoinServer) + exec_test(functools.partial(test, use_room=True), protocol=DelayJoinServer) diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py index 6462a0c..5602985 100644 --- a/tests/twisted/constants.py +++ b/tests/twisted/constants.py @@ -58,6 +58,9 @@ INITIATOR_HANDLE = CHANNEL + '.InitiatorHandle' INITIATOR_ID = CHANNEL + '.InitiatorID' INTERFACES = CHANNEL + '.Interfaces' +ROOM_NAME = CHANNEL_IFACE_ROOM + '.RoomName' +ROOM_SERVER = CHANNEL_IFACE_ROOM + '.Server' + INITIAL_AUDIO = CHANNEL_TYPE_STREAMED_MEDIA + '.InitialAudio' INITIAL_VIDEO = CHANNEL_TYPE_STREAMED_MEDIA + '.InitialVideo' IMMUTABLE_STREAMS = CHANNEL_TYPE_STREAMED_MEDIA + '.ImmutableStreams' |