summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2012-05-04 19:08:59 +0100
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2014-03-18 14:26:43 +0100
commit1fa8f827b9e04b28a85f9fd3dc66ca7092474797 (patch)
tree3ba70e9b64c0476a85547a5ac2a5bca2d9b45551
parentd5393c760c76f328847bcc116999d6d7317702ce (diff)
downloadtelepathy-glib-1fa8f827b9e04b28a85f9fd3dc66ca7092474797.tar.gz
TpChannelFilter: add
This is the object-oriented/GVariant-flavoured version of GHashTable-based filtering. Also use it in code examples, for much simplification.
-rw-r--r--docs/reference/telepathy-glib/telepathy-glib-sections.txt40
-rw-r--r--examples/client/approver.c26
-rw-r--r--examples/client/dbus-tubes/accepter.c10
-rw-r--r--examples/client/media-observer.c7
-rw-r--r--examples/client/python/ft-handler.py11
-rwxr-xr-xexamples/client/python/text-handler.py9
-rw-r--r--examples/client/stream-tubes/accepter.c10
-rw-r--r--examples/client/text-handler.c16
-rw-r--r--telepathy-glib/Makefile.am3
-rw-r--r--telepathy-glib/account-channel-request.c2
-rw-r--r--telepathy-glib/base-client.c172
-rw-r--r--telepathy-glib/base-client.h23
-rw-r--r--telepathy-glib/channel-filter-internal.h33
-rw-r--r--telepathy-glib/channel-filter.c561
-rw-r--r--telepathy-glib/channel-filter.h105
-rw-r--r--telepathy-glib/file-transfer-channel.c14
-rw-r--r--telepathy-glib/introspection.am1
-rw-r--r--telepathy-glib/simple-approver.c6
-rw-r--r--telepathy-glib/simple-handler.c6
-rw-r--r--telepathy-glib/simple-observer.c6
-rw-r--r--telepathy-glib/telepathy-glib.h1
-rw-r--r--tests/Makefile.am11
-rw-r--r--tests/channel-filter.c216
-rw-r--r--tests/dbus/base-client.c70
24 files changed, 1245 insertions, 114 deletions
diff --git a/docs/reference/telepathy-glib/telepathy-glib-sections.txt b/docs/reference/telepathy-glib/telepathy-glib-sections.txt
index 6fe372619..2c84eb945 100644
--- a/docs/reference/telepathy-glib/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib/telepathy-glib-sections.txt
@@ -4532,17 +4532,23 @@ TpDebugSenderPrivate
TpBaseClient
TpBaseClientClass
tp_base_client_add_observer_filter
+tp_base_client_add_observer_filter_object
+tp_base_client_take_observer_filter_object
tp_base_client_set_observer_recover
tp_base_client_set_observer_delay_approvers
TpBaseClientClassObserveChannelImpl
tp_base_client_implement_observe_channel
tp_base_client_add_approver_filter
+tp_base_client_add_approver_filter_object
+tp_base_client_take_approver_filter_object
TpBaseClientClassAddDispatchOperationImpl
tp_base_client_implement_add_dispatch_operation
tp_base_client_add_handler_capabilities
tp_base_client_add_handler_capabilities_varargs
tp_base_client_add_handler_capability
tp_base_client_add_handler_filter
+tp_base_client_add_handler_filter_object
+tp_base_client_take_handler_filter_object
tp_base_client_be_a_handler
TpBaseClientClassHandleChannelImpl
tp_base_client_implement_handle_channel
@@ -6187,6 +6193,40 @@ TpRoomInfoPriv
</SECTION>
<SECTION>
+<FILE>channel-filter</FILE>
+<TITLE>channel-filter</TITLE>
+<INCLUDE>telepathy-glib/telepathy-glib.h</INCLUDE>
+TpChannelFilter
+tp_channel_filter_new
+tp_channel_filter_new_for_calls
+tp_channel_filter_new_for_dbus_tubes
+tp_channel_filter_new_for_file_transfers
+tp_channel_filter_new_for_stream_tubes
+tp_channel_filter_new_for_text_chatrooms
+tp_channel_filter_new_for_text_chats
+<SUBSECTION>
+tp_channel_filter_require_channel_type
+tp_channel_filter_require_locally_requested
+<SUBSECTION>
+tp_channel_filter_require_no_target
+tp_channel_filter_require_target_is_contact
+tp_channel_filter_require_target_is_room
+tp_channel_filter_require_target_type
+<SUBSECTION>
+tp_channel_filter_require_property
+<SUBSECTION Standard>
+tp_channel_filter_get_type
+TpChannelFilterClass
+TpChannelFilterPrivate
+TP_CHANNEL_FILTER
+TP_CHANNEL_FILTER_CLASS
+TP_CHANNEL_FILTER_GET_CLASS
+TP_IS_CHANNEL_FILTER
+TP_IS_CHANNEL_FILTER_CLASS
+TP_TYPE_CHANNEL_FILTER
+</SECTION>
+
+<SECTION>
<FILE>tls-certificate</FILE>
<INCLUDE>telepathy-glib/telepathy-glib.h</INCLUDE>
<TITLE>TpTLSCertificate</TITLE>
diff --git a/examples/client/approver.c b/examples/client/approver.c
index 3063171c5..e1f0b572a 100644
--- a/examples/client/approver.c
+++ b/examples/client/approver.c
@@ -142,28 +142,20 @@ main (int argc,
FALSE, add_dispatch_operation_cb, NULL, NULL);
/* contact text chat */
- tp_base_client_add_approver_filter (approver,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_TEXT,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT));
+ tp_base_client_take_approver_filter_object (approver,
+ tp_channel_filter_new_for_text_chats ());
- /* calls */
- tp_base_client_add_approver_filter (approver,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_CALL1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT));
+ /* call */
+ tp_base_client_take_approver_filter_object (approver,
+ tp_channel_filter_new_for_calls (TP_ENTITY_TYPE_CONTACT));
/* room text chat */
- tp_base_client_add_approver_filter (approver,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_TEXT,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_ROOM));
+ tp_base_client_take_approver_filter_object (approver,
+ tp_channel_filter_new_for_text_chatrooms ());
/* file transfer */
- tp_base_client_add_approver_filter (approver,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT));
+ tp_base_client_take_approver_filter_object (approver,
+ tp_channel_filter_new_for_file_transfers (NULL));
if (!tp_base_client_register (approver, &error))
{
diff --git a/examples/client/dbus-tubes/accepter.c b/examples/client/dbus-tubes/accepter.c
index 882074a27..264add37f 100644
--- a/examples/client/dbus-tubes/accepter.c
+++ b/examples/client/dbus-tubes/accepter.c
@@ -163,17 +163,17 @@ main (int argc,
{
TpAccountManager *manager;
TpBaseClient *handler;
+ TpChannelFilter *filter;
GError *error = NULL;
manager = tp_account_manager_dup ();
handler = tp_simple_handler_new_with_am (manager, FALSE, FALSE,
"ExampleServiceHandler", FALSE, handle_channel, NULL, NULL);
- tp_base_client_add_handler_filter (handler,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u>, %s: <%s> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT,
- TP_PROP_CHANNEL_TYPE_DBUS_TUBE1_SERVICE_NAME, EXAMPLE_SERVICE_NAME));
+ filter = tp_channel_filter_new_for_dbus_tubes (EXAMPLE_SERVICE_NAME);
+ tp_channel_filter_require_locally_requested (filter, FALSE);
+ tp_channel_filter_require_target_is_contact (filter);
+ tp_base_client_take_handler_filter_object (handler, filter);
tp_base_client_register (handler, &error);
g_assert_no_error (error);
diff --git a/examples/client/media-observer.c b/examples/client/media-observer.c
index b19dc8876..55791a91e 100644
--- a/examples/client/media-observer.c
+++ b/examples/client/media-observer.c
@@ -72,11 +72,8 @@ main (int argc,
observer = tp_simple_observer_new_with_am (manager, FALSE,
"ExampleMediaObserver", FALSE, observe_channel_cb, NULL, NULL);
- tp_base_client_add_observer_filter (observer,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_CALL1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT,
- NULL));
+ tp_base_client_take_observer_filter_object (observer,
+ tp_channel_filter_new_for_calls (TP_ENTITY_TYPE_CONTACT));
if (!tp_base_client_register (observer, &error))
{
diff --git a/examples/client/python/ft-handler.py b/examples/client/python/ft-handler.py
index 5f47ca427..62e43a9ff 100644
--- a/examples/client/python/ft-handler.py
+++ b/examples/client/python/ft-handler.py
@@ -53,13 +53,10 @@ if __name__ == '__main__':
handler = TelepathyGLib.SimpleHandler.new(dbus, False, False,
'ExampleFTHandler', False, handle_channels_cb, filename)
- handler.add_handler_filter({
- TelepathyGLib.PROP_CHANNEL_CHANNEL_TYPE:
- TelepathyGLib.IFACE_CHANNEL_TYPE_FILE_TRANSFER,
- TelepathyGLib.PROP_CHANNEL_TARGET_ENTITY_TYPE:
- int(TelepathyGLib.HandleType.CONTACT),
- TelepathyGLib.PROP_CHANNEL_REQUESTED: False
- })
+ channel_filter = TelepathyGLib.ChannelFilter.new_for_file_transfers()
+ channel_filter.require_locally_requested(FALSE)
+ channel_filter.require_target_is_contact()
+ handler.add_handler_filter_object(channel_filter)
handler.register()
diff --git a/examples/client/python/text-handler.py b/examples/client/python/text-handler.py
index 4d6a9f8d1..06677a754 100755
--- a/examples/client/python/text-handler.py
+++ b/examples/client/python/text-handler.py
@@ -58,12 +58,9 @@ if __name__ == '__main__':
handler = TelepathyGLib.SimpleHandler.new_with_am(am, False, False,
'ExampleHandler', False, handle_channels_cb, None)
- handler.add_handler_filter({
- TelepathyGLib.PROP_CHANNEL_CHANNEL_TYPE: TelepathyGLib.IFACE_CHANNEL_TYPE_TEXT,
- # bgo #637466
- TelepathyGLib.PROP_CHANNEL_TARGET_ENTITY_TYPE: int(TelepathyGLib.HandleType.CONTACT),
- TelepathyGLib.PROP_CHANNEL_REQUESTED: False,
- })
+ channel_filter = TelepathyGLib.ChannelFilter.new_for_text_chats()
+ channel_filter.require_locally_requested(False)
+ handler.add_handler_filter_object(channel_filter)
handler.register()
diff --git a/examples/client/stream-tubes/accepter.c b/examples/client/stream-tubes/accepter.c
index 3e771ceb5..a747ee857 100644
--- a/examples/client/stream-tubes/accepter.c
+++ b/examples/client/stream-tubes/accepter.c
@@ -105,17 +105,17 @@ main (int argc,
{
TpAccountManager *manager;
TpBaseClient *handler;
+ TpChannelFilter *filter;
GError *error = NULL;
manager = tp_account_manager_dup ();
handler = tp_simple_handler_new_with_am (manager, FALSE, FALSE,
"ExampleServiceHandler", FALSE, _handle_channel, NULL, NULL);
- tp_base_client_add_handler_filter (handler,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u>, %s: <%s> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT,
- TP_PROP_CHANNEL_TYPE_STREAM_TUBE1_SERVICE, "ExampleService"));
+ filter = tp_channel_filter_new_for_stream_tubes ("ExampleService");
+ tp_channel_filter_require_locally_requested (filter, FALSE);
+ tp_channel_filter_require_target_is_contact (filter);
+ tp_base_client_take_handler_filter_object (handler, filter);
tp_base_client_register (handler, &error);
g_assert_no_error (error);
diff --git a/examples/client/text-handler.c b/examples/client/text-handler.c
index f4074bac0..dd14cf895 100644
--- a/examples/client/text-handler.c
+++ b/examples/client/text-handler.c
@@ -106,22 +106,18 @@ main (int argc,
GMainLoop *mainloop;
GError *error = NULL;
TpBaseClient *handler;
- GVariantDict dict;
+ TpChannelFilter *filter;
tp_debug_set_flags (g_getenv ("EXAMPLE_DEBUG"));
handler = tp_simple_handler_new (NULL, FALSE, FALSE,
"ExampleHandler", FALSE, handle_channel_cb, NULL, NULL);
- g_variant_dict_init (&dict, NULL);
- g_variant_dict_insert (&dict, TP_PROP_CHANNEL_CHANNEL_TYPE, "s",
- TP_IFACE_CHANNEL_TYPE_TEXT);
- g_variant_dict_insert (&dict, TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, "u",
- (guint32) TP_ENTITY_TYPE_CONTACT);
- g_variant_dict_insert (&dict, TP_PROP_CHANNEL_REQUESTED, "b", FALSE);
-
- tp_base_client_add_handler_filter (handler,
- g_variant_dict_end (&dict));
+ /* be a handler for 1-1 text chats which are initiated by the other
+ * contact */
+ filter = tp_channel_filter_new_for_text_chats ();
+ tp_channel_filter_require_locally_requested (filter, FALSE);
+ tp_base_client_take_handler_filter_object (handler, filter);
if (!tp_base_client_register (handler, &error))
{
diff --git a/telepathy-glib/Makefile.am b/telepathy-glib/Makefile.am
index fd16a958c..f5537008c 100644
--- a/telepathy-glib/Makefile.am
+++ b/telepathy-glib/Makefile.am
@@ -69,6 +69,7 @@ tpginclude_HEADERS = \
channel-iface.h \
channel-dispatcher.h \
channel-dispatch-operation.h \
+ channel-filter.h \
channel-manager.h \
channel-manager-request.h \
channel-request.h \
@@ -250,6 +251,8 @@ libtelepathy_glib_main_internal_la_SOURCES = \
call-stream.c \
call-stream-endpoint.c \
channel.c \
+ channel-filter.c \
+ channel-filter-internal.h \
channel-group.c \
channel-internal.h \
channel-dispatcher.c \
diff --git a/telepathy-glib/account-channel-request.c b/telepathy-glib/account-channel-request.c
index 8b92815c5..39347b6e0 100644
--- a/telepathy-glib/account-channel-request.c
+++ b/telepathy-glib/account-channel-request.c
@@ -909,7 +909,7 @@ going_to_request (TpAccountChannelRequest *self,
self->priv->ensure = ensure;
- /* Set TargetHandleType: TP_HANDLE_TYPE_NONE if no TargetHandleType has been
+ /* Set TargetHandleType: TP_ENTITY_TYPE_NONE if no TargetHandleType has been
* defined. */
if (g_hash_table_lookup (self->priv->request,
TP_PROP_CHANNEL_TARGET_ENTITY_TYPE) == NULL)
diff --git a/telepathy-glib/base-client.c b/telepathy-glib/base-client.c
index 930f6d972..6ff04dbbc 100644
--- a/telepathy-glib/base-client.c
+++ b/telepathy-glib/base-client.c
@@ -177,6 +177,7 @@
#include <telepathy-glib/add-dispatch-operation-context-internal.h>
#include <telepathy-glib/automatic-client-factory.h>
#include <telepathy-glib/channel-dispatcher.h>
+#include <telepathy-glib/channel-filter-internal.h>
#include <telepathy-glib/channel-request.h>
#include <telepathy-glib/channel.h>
#include <telepathy-glib/cli-misc.h>
@@ -318,6 +319,73 @@ tp_base_client_dup_account (TpBaseClient *self,
}
/**
+ * tp_base_client_add_observer_filter_object:
+ * @self: a #TpBaseClient
+ * @filter: a filter
+ *
+ * Register a new filter to match channels as an Observer.
+ *
+ * The #TpBaseClientClass.observe_channel virtual method will be called
+ * whenever a new channel's properties match the ones in @filter.
+ *
+ * This method can be called more than once. If it is, the client will
+ * be an Observer for any channel that matches any of the filters.
+ * For instance, this Client:
+ *
+ * |[
+ * filter = tp_channel_filter_new_for_text_chats ();
+ * tp_base_client_add_observer_filter_object (client, filter);
+ * g_object_unref (filter);
+ *
+ * filter = tp_channel_filter_new_for_file_transfer (NULL);
+ * tp_channel_filter_require_target_is_contact (filter);
+ * tp_channel_filter_require_requested (filter, FALSE);
+ * tp_base_client_add_observer_filter_object (client, filter);
+ * g_object_unref (filter);
+ * ]|
+ *
+ * will be notified about all Text channels, and also about 1-1 incoming
+ * Call channels.
+ *
+ * This method may only be called before tp_base_client_register() is
+ * called, and may only be called on objects whose class implements
+ * #TpBaseClientClass.observe_channel.
+ *
+ * Since: 0.UNRELEASED
+ */
+void
+tp_base_client_add_observer_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter)
+{
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (filter));
+ tp_base_client_add_observer_filter (self, _tp_channel_filter_use (filter));
+}
+
+/**
+ * tp_base_client_take_observer_filter_object: (skip)
+ * @self: a #TpBaseClient
+ * @filter: (transfer full): a filter
+ *
+ * The same as tp_base_client_add_observer_filter_object(), but also
+ * takes ownership of the filter. This makes it more convenient to call
+ * in simple situations:
+ *
+ * |[
+ * tp_base_client_take_observer_filter_object (client,
+ * tp_channel_filter_new_for_text_chats ());
+ * ]|
+ *
+ * Since: 0.UNRELEASED
+ */
+void
+tp_base_client_take_observer_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter)
+{
+ tp_base_client_add_observer_filter_object (self, filter);
+ g_object_unref (filter);
+}
+
+/**
* tp_base_client_add_observer_filter:
* @self: a client
* @filter: (transfer none): a variant of type %G_VARIANT_TYPE_VARDICT
@@ -447,6 +515,58 @@ tp_base_client_set_observer_delay_approvers (TpBaseClient *self,
}
/**
+ * tp_base_client_add_approver_filter_object:
+ * @self: a #TpBaseClient
+ * @filter: a filter
+ *
+ * Register a new filter to match channels as an Approver.
+ *
+ * The #TpBaseClientClass.add_dispatch_operation virtual method will be called
+ * whenever a new channel's properties match the ones in @filter.
+ *
+ * This method can be called more than once. If it is, the client will
+ * be an Approver for any channel that matches any of the filters.
+ * See tp_base_client_add_observer_filter_object().
+ *
+ * This method may only be called before tp_base_client_register() is
+ * called, and may only be called on objects whose class implements
+ * #TpBaseClientClass.add_dispatch_operation.
+ *
+ * Since: 0.UNRELEASED
+ */
+void
+tp_base_client_add_approver_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter)
+{
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (filter));
+ tp_base_client_add_approver_filter (self, _tp_channel_filter_use (filter));
+}
+
+/**
+ * tp_base_client_take_approver_filter_object: (skip)
+ * @self: a #TpBaseClient
+ * @filter: (transfer full): a filter
+ *
+ * The same as tp_base_client_add_approver_filter_object(), but also
+ * takes ownership of the filter. This makes it more convenient to call
+ * in simple situations:
+ *
+ * |[
+ * tp_base_client_take_approver_filter_object (client,
+ * tp_channel_filter_new_for_text_chats ());
+ * ]|
+ *
+ * Since: 0.UNRELEASED
+ */
+void
+tp_base_client_take_approver_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter)
+{
+ tp_base_client_add_approver_filter_object (self, filter);
+ g_object_unref (filter);
+}
+
+/**
* tp_base_client_add_approver_filter:
* @self: a client
* @filter: (transfer none): a variant of type %G_VARIANT_TYPE_VARDICT
@@ -509,6 +629,34 @@ tp_base_client_be_a_handler (TpBaseClient *self)
}
/**
+ * tp_base_client_add_handler_filter_object:
+ * @self: a #TpBaseClient
+ * @filter: a filter
+ *
+ * Register a new filter to match channels as a Handler.
+ *
+ * The #TpBaseClientClass.handle_channel virtual method will be called
+ * whenever a new channel's properties match the ones in @filter.
+ *
+ * This method can be called more than once. If it is, the client will
+ * be a Handler for any channel that matches any of the filters.
+ * See tp_base_client_add_observer_filter_object().
+ *
+ * This method may only be called before tp_base_client_register() is
+ * called, and may only be called on objects whose class implements
+ * #TpBaseClientClass.handle_channel.
+ *
+ * Since: 0.UNRELEASED
+ */
+void
+tp_base_client_add_handler_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter)
+{
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (filter));
+ tp_base_client_add_handler_filter (self, _tp_channel_filter_use (filter));
+}
+
+/**
* tp_base_client_add_handler_filter:
* @self: a client
* @filter: (transfer none): a variant of type %G_VARIANT_TYPE_VARDICT
@@ -545,6 +693,30 @@ tp_base_client_add_handler_filter (TpBaseClient *self,
}
/**
+ * tp_base_client_take_handler_filter_object: (skip)
+ * @self: a #TpBaseClient
+ * @filter: (transfer full): a filter
+ *
+ * The same as tp_base_client_add_handler_filter_object(), but also
+ * takes ownership of the filter. This makes it more convenient to call
+ * in simple situations:
+ *
+ * |[
+ * tp_base_client_take_handler_filter_object (client,
+ * tp_channel_filter_new_for_text_chats ());
+ * ]|
+ *
+ * Since: 0.UNRELEASED
+ */
+void
+tp_base_client_take_handler_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter)
+{
+ tp_base_client_add_handler_filter_object (self, filter);
+ g_object_unref (filter);
+}
+
+/**
* tp_base_client_set_handler_bypass_approval:
* @self: a #TpBaseClient
* @bypass_approval: the value of the Handler.BypassApproval property
diff --git a/telepathy-glib/base-client.h b/telepathy-glib/base-client.h
index 1d01149fc..37fac2ea5 100644
--- a/telepathy-glib/base-client.h
+++ b/telepathy-glib/base-client.h
@@ -31,6 +31,7 @@
#include <telepathy-glib/account.h>
#include <telepathy-glib/add-dispatch-operation-context.h>
#include <telepathy-glib/channel.h>
+#include <telepathy-glib/channel-filter.h>
#include <telepathy-glib/handle-channel-context.h>
#include <telepathy-glib/observe-channel-context.h>
#include <telepathy-glib/connection.h>
@@ -112,6 +113,13 @@ _TP_AVAILABLE_IN_0_20
void tp_base_client_add_observer_filter (TpBaseClient *self,
GVariant *filter);
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_base_client_add_observer_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_base_client_take_observer_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
+
void tp_base_client_set_observer_recover (TpBaseClient *self,
gboolean recover);
void tp_base_client_set_observer_delay_approvers (TpBaseClient *self,
@@ -121,11 +129,26 @@ _TP_AVAILABLE_IN_0_20
void tp_base_client_add_approver_filter (TpBaseClient *self,
GVariant *filter);
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_base_client_add_approver_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_base_client_take_approver_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
+
void tp_base_client_be_a_handler (TpBaseClient *self);
_TP_AVAILABLE_IN_0_20
void tp_base_client_add_handler_filter (TpBaseClient *self,
GVariant *filter);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_base_client_add_handler_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_base_client_take_handler_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
+
void tp_base_client_set_handler_bypass_approval (TpBaseClient *self,
gboolean bypass_approval);
diff --git a/telepathy-glib/channel-filter-internal.h b/telepathy-glib/channel-filter-internal.h
new file mode 100644
index 000000000..315fb3dcb
--- /dev/null
+++ b/telepathy-glib/channel-filter-internal.h
@@ -0,0 +1,33 @@
+/*<private_header>*/
+/*
+ * A filter matching certain channels.
+ *
+ * Copyright © 2010-2014 Collabora Ltd.
+ *
+ * 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 TP_CHANNEL_FILTER_INTERNAL_H
+#define TP_CHANNEL_FILTER_INTERNAL_H
+
+#include <telepathy-glib/channel-filter.h>
+
+G_BEGIN_DECLS
+
+GVariant * _tp_channel_filter_use (TpChannelFilter *self);
+
+G_END_DECLS
+
+#endif
diff --git a/telepathy-glib/channel-filter.c b/telepathy-glib/channel-filter.c
new file mode 100644
index 000000000..c5da02e11
--- /dev/null
+++ b/telepathy-glib/channel-filter.c
@@ -0,0 +1,561 @@
+/*
+ * A filter matching certain channels.
+ *
+ * Copyright © 2010-2014 Collabora Ltd.
+ *
+ * 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
+ */
+
+#include "config.h"
+#include <telepathy-glib/channel-filter.h>
+#include <telepathy-glib/channel-filter-internal.h>
+
+#define DEBUG_FLAG TP_DEBUG_MISC
+#include "debug-internal.h"
+
+#include <dbus/dbus-glib.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/util.h>
+#include <telepathy-glib/variant-util.h>
+
+/**
+ * SECTION:channel-filter
+ * @title: TpChannelFilter
+ * @short_description: a filter matching certain channels
+ * @see_also: #TpBaseClient, #TpSimpleApprover, #TpSimpleHandler,
+ * #TpSimpleObserver
+ *
+ * Telepathy clients are notified about "interesting" #TpChannels
+ * by the Channel Dispatcher. To do this efficiently, the clients have
+ * lists of "channel filters", describing the channels that each client
+ * considers to be "interesting".
+ *
+ * In telepathy-glib, these lists take the form of lists of #TpChannelFilter
+ * objects. Each #TpChannelFilter matches certain properties of the channel,
+ * and the channel dispatcher dispatches a channel to a client if that
+ * channel matches any of the filters in the client's list:
+ *
+ * |[
+ * channel is interesting to this client = (
+ * ((channel matches property A from filter 1) &&
+ * (channel matches property B from filter 1) && ...)
+ * ||
+ * ((channel matches property P from filter 2) &&
+ * (channel matches property Q from filter 2) && ...)
+ * || ...)
+ * ]|
+ *
+ * An empty list of filters does not match any channels, but a list
+ * containing an empty filter matches every channel.
+ *
+ * To construct a filter, either create an empty filter with
+ * tp_channel_filter_new(), or create a pre-populated filter with
+ * certain properties using one of the convenience constructors like
+ * tp_channel_filter_new_for_text_chats().
+ *
+ * After creating a filter, you can make it more specific by using
+ * methods like tp_channel_filter_require_locally_requested(), if
+ * required.
+ *
+ * Finally, add it to a #TpBaseClient using
+ * tp_base_client_add_observer_filter_object(),
+ * tp_base_client_add_approver_filter_object() and/or
+ * tp_base_client_add_handler_filter_object() (depending on the type
+ * of client required), and release the filter object with g_object_unref().
+ *
+ * If you would like the #TpBaseClient to act on particular channels in
+ * more than one role - for instance, an Approver for Text channels which
+ * is also a Handler for Text channels - you can add the same
+ * #TpChannelFilter object via more than one method.
+ *
+ * Once you have added a filter object to a #TpBaseClient, you may not
+ * modify it further.
+ */
+
+/**
+ * TpChannelFilterClass:
+ *
+ * The class of a #TpChannelFilter.
+ */
+
+struct _TpChannelFilterClass {
+ /*<private>*/
+ GObjectClass parent_class;
+};
+
+/**
+ * TpChannelFilter:
+ *
+ * A filter matching certain channels.
+ */
+
+struct _TpChannelFilter {
+ /*<private>*/
+ GObject parent;
+ TpChannelFilterPrivate *priv;
+};
+
+struct _TpChannelFilterPrivate {
+ /* dup'd string => slice-allocated GValue
+ *
+ * Do not use tp_asv_new() and friends, because they expect static
+ * string keys. */
+ GHashTable *asv;
+
+ gboolean already_used;
+};
+
+G_DEFINE_TYPE (TpChannelFilter, tp_channel_filter, G_TYPE_OBJECT)
+
+static void
+tp_channel_filter_init (TpChannelFilter *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TYPE_CHANNEL_FILTER,
+ TpChannelFilterPrivate);
+
+ self->priv->asv = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) tp_g_value_slice_free);
+
+ self->priv->already_used = FALSE;
+}
+
+static void
+tp_channel_filter_dispose (GObject *object)
+{
+ TpChannelFilter *self = TP_CHANNEL_FILTER (object);
+
+ tp_clear_pointer (&self->priv->asv, g_hash_table_unref);
+
+ G_OBJECT_CLASS (tp_channel_filter_parent_class)->dispose (object);
+}
+
+static void
+tp_channel_filter_class_init (TpChannelFilterClass *cls)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (cls);
+
+ g_type_class_add_private (cls, sizeof (TpChannelFilterPrivate));
+
+ object_class->dispose = tp_channel_filter_dispose;
+}
+
+/**
+ * tp_channel_filter_new:
+ *
+ * Return a channel filter that matches every channel.
+ *
+ * You can make the filter more restrictive by setting properties. In
+ * practice, to make a filter useful, you should set at least a channel
+ * type (text, call, file transfer etc.) and a target type
+ * (contact, chatroom, etc.).
+ */
+TpChannelFilter *
+tp_channel_filter_new (void)
+{
+ return g_object_new (TP_TYPE_CHANNEL_FILTER,
+ NULL);
+}
+
+/**
+ * tp_channel_filter_new_for_text_chats:
+ *
+ * Return a channel filter that matches 1-1 text chats,
+ * such as #TpTextChannels carrying private messages or SMSs.
+ *
+ * It is not necessary to call tp_channel_filter_require_target_is_contact()
+ * on the returned filter.
+ */
+TpChannelFilter *
+tp_channel_filter_new_for_text_chats (void)
+{
+ TpChannelFilter *self = tp_channel_filter_new ();
+
+ tp_channel_filter_require_target_is_contact (self);
+ tp_channel_filter_require_channel_type (self, TP_IFACE_CHANNEL_TYPE_TEXT);
+ return self;
+}
+
+/**
+ * tp_channel_filter_new_for_text_chatrooms:
+ *
+ * Return a channel filter that matches participation in named text
+ * chatrooms, such as #TpTextChannels communicating with
+ * an XMPP Multi-User Chat room or an IRC channel.
+ *
+ * It is not necessary to call tp_channel_filter_require_target_is_room()
+ * on the returned filter.
+ */
+TpChannelFilter *
+tp_channel_filter_new_for_text_chatrooms (void)
+{
+ TpChannelFilter *self = tp_channel_filter_new ();
+
+ tp_channel_filter_require_target_is_room (self);
+ tp_channel_filter_require_channel_type (self, TP_IFACE_CHANNEL_TYPE_TEXT);
+ return self;
+}
+
+/**
+ * tp_channel_filter_require_target_is_contact:
+ * @self: a channel filter
+ *
+ * Narrow @self to require that the channel communicates with a single
+ * #TpContact.
+ *
+ * For instance, the filter would match #TpTextChannels carrying private
+ * messages or SMSs, #TpCallChannels for ordinary 1-1 audio and/or video calls,
+ * #TpFileTransferChannels for file transfers to or from a contact, and so on.
+ *
+ * It would not match channels communicating with a chatroom, ad-hoc
+ * chatrooms with no name, or conference-calls (in protocols that can tell
+ * the difference between a conference call and an ordinary 1-1 call).
+ *
+ * It is an error to call this method if the channel filter has already
+ * been passed to a #TpBaseClient.
+ */
+void
+tp_channel_filter_require_target_is_contact (TpChannelFilter *self)
+{
+ tp_channel_filter_require_target_type (self, TP_ENTITY_TYPE_CONTACT);
+}
+
+/**
+ * tp_channel_filter_require_target_is_room:
+ * @self: a channel filter
+ *
+ * Narrow @self to require that the channel communicates with a named
+ * chatroom.
+ *
+ * For instance, this filter would match #TpTextChannels communicating with
+ * an XMPP Multi-User Chat room or an IRC channel. It would also match
+ * #TpDBusTubeChannels or #TpStreamTubeChannels that communicate through
+ * a chatroom, and multi-user audio and/or video calls that use a named,
+ * chatroom-like object on the server.
+ *
+ * It is an error to call this method if the channel filter has already
+ * been passed to a #TpBaseClient.
+ */
+void
+tp_channel_filter_require_target_is_room (TpChannelFilter *self)
+{
+ tp_channel_filter_require_target_type (self, TP_ENTITY_TYPE_ROOM);
+}
+
+/**
+ * tp_channel_filter_require_no_target:
+ * @self: a channel filter
+ *
+ * Narrow @self to require that the channel communicates with an
+ * ad-hoc, unnamed group of contacts.
+ *
+ * For instance, among other things, this filter would match #TpCallChannels
+ * for conference calls in cellular telephony.
+ *
+ * This is equivalent to tp_channel_filter_require_target_type()
+ * with argument %TP_ENTITY_TYPE_NONE.
+ *
+ * It is an error to call this method if the channel filter has already
+ * been passed to a #TpBaseClient.
+ */
+void
+tp_channel_filter_require_no_target (TpChannelFilter *self)
+{
+ tp_channel_filter_require_target_type (self, TP_ENTITY_TYPE_NONE);
+}
+
+/**
+ * tp_channel_filter_require_target_type:
+ * @self: a channel filter
+ * @entity_type: the desired value for #TpChannel:entity-type
+ *
+ * Narrow @self to require a particular target entity type.
+ *
+ * For instance, setting @entity_type to %TP_ENTITY_TYPE_CONTACT
+ * is equivalent to tp_channel_filter_require_target_is_contact().
+ *
+ * It is an error to call this method if the channel filter has already
+ * been passed to a #TpBaseClient.
+ */
+void
+tp_channel_filter_require_target_type (TpChannelFilter *self,
+ TpEntityType entity_type)
+{
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (self));
+ g_return_if_fail (((guint) entity_type) < TP_NUM_ENTITY_TYPES);
+
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_TARGET_ENTITY_TYPE),
+ tp_g_value_slice_new_uint (entity_type));
+}
+
+/**
+ * tp_channel_filter_new_for_calls:
+ * @entity_type: the desired entity type
+ *
+ * Return a channel filter that matches audio and video calls,
+ * including VoIP and telephony.
+ *
+ * @entity_type is passed to tp_channel_filter_require_target_type().
+ * Use %TP_ENTITY_TYPE_CONTACT for ordinary 1-1 calls.
+ */
+TpChannelFilter *
+tp_channel_filter_new_for_calls (TpEntityType entity_type)
+{
+ TpChannelFilter *self = tp_channel_filter_new ();
+
+ tp_channel_filter_require_target_type (self, entity_type);
+ tp_channel_filter_require_channel_type (self, TP_IFACE_CHANNEL_TYPE_CALL1);
+ return self;
+}
+
+/**
+ * tp_channel_filter_require_channel_type:
+ * @self: a channel filter
+ * @channel_type: the desired value for #TpChannel:channel-type
+ *
+ * Narrow @self to require a particular channel type, given as a D-Bus
+ * interface name.
+ *
+ * It is an error to call this method if the channel filter has already
+ * been passed to a #TpBaseClient.
+ */
+void
+tp_channel_filter_require_channel_type (TpChannelFilter *self,
+ const gchar *channel_type)
+{
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (self));
+ g_return_if_fail (g_dbus_is_interface_name (channel_type));
+
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_CHANNEL_TYPE),
+ tp_g_value_slice_new_string (channel_type));
+}
+
+/**
+ * tp_channel_filter_new_for_stream_tubes:
+ * @service: (allow-none): the desired value of #TpStreamTubeChannel:service,
+ * or %NULL to match any service
+ *
+ * Return a channel filter that matches stream tube channels, as used by
+ * #TpStreamTubeChannel, and optionally also match a particular service.
+ * This filter can be narrowed further via other methods.
+ *
+ * For instance, to match RFB display-sharing being offered by another
+ * participant in a chatroom:
+ *
+ * |[
+ * filter = tp_channel_filter_new_for_stream_tubes ("rfb");
+ * tp_channel_filter_require_target_is_room (filter);
+ * tp_channel_filter_require_locally_requested (filter, FALSE);
+ * ]|
+ */
+TpChannelFilter *
+tp_channel_filter_new_for_stream_tubes (const gchar *service)
+{
+ TpChannelFilter *self = tp_channel_filter_new ();
+
+ tp_channel_filter_require_channel_type (self,
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE1);
+
+ if (service != NULL)
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_TYPE_STREAM_TUBE1_SERVICE),
+ tp_g_value_slice_new_string (service));
+
+ return self;
+}
+
+/**
+ * tp_channel_filter_new_for_dbus_tubes:
+ * @service: (allow-none): the desired value of
+ * #TpDBusTubeChannel:service-name, or %NULL to match any service
+ *
+ * Return a channel filter that matches D-Bus tube channels, as used by
+ * #TpDBusTubeChannel, and optionally also match a particular service.
+ * This filter can be narrowed further via other methods.
+ *
+ * For instance, to match a "com.example.Chess" tube being offered by
+ * the local user to a peer:
+ *
+ * |[
+ * filter = tp_channel_filter_new_for_dbus_tube ("com.example.Chess");
+ * tp_channel_filter_require_target_is_contact (filter);
+ * tp_channel_filter_require_locally_requested (filter, TRUE);
+ * ]|
+ */
+TpChannelFilter *
+tp_channel_filter_new_for_dbus_tubes (const gchar *service)
+{
+ TpChannelFilter *self = tp_channel_filter_new ();
+
+ tp_channel_filter_require_channel_type (self,
+ TP_IFACE_CHANNEL_TYPE_DBUS_TUBE1);
+
+ if (service != NULL)
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_TYPE_DBUS_TUBE1_SERVICE_NAME),
+ tp_g_value_slice_new_string (service));
+
+ return self;
+}
+
+/**
+ * tp_channel_filter_new_for_file_transfers:
+ * @service: (allow-none): a service name, or %NULL
+ *
+ * Return a channel filter that matches file transfer channels with
+ * a #TpContact, as used by #TpFileTransferChannel.
+ *
+ * At the time of writing, file transfers with other types of target
+ * (like chatrooms) have not been implemented. If they are, they will
+ * use a different filter.
+ *
+ * Using this method will match both incoming and outgoing file transfers.
+ * If you only want to match one direction, use
+ * tp_channel_filter_require_locally_requested() to select it.
+ *
+ * For instance, to match outgoing file transfers (sending a file to
+ * a contact), you can use:
+ *
+ * |[
+ * filter = tp_channel_filter_new_for_file_transfer (NULL);
+ * tp_channel_filter_require_locally_requested (filter, TRUE);
+ * ]|
+ *
+ * @service can be used by collaborative applications to match a particular
+ * #TpFileTransferChannel:service-name. For instance, if an application
+ * wants to be the handler for incoming file transfers that are marked
+ * as belonging to that application, it could use a filter like this:
+ *
+ * |[
+ * filter = tp_channel_filter_new_for_file_transfer ("com.example.MyApp");
+ * tp_channel_filter_require_locally_requested (filter, FALSE);
+ * tp_base_client_take_handler_filter_object (client, filter);
+ * ]|
+ */
+TpChannelFilter *
+tp_channel_filter_new_for_file_transfers (const gchar *service)
+{
+ TpChannelFilter *self = tp_channel_filter_new ();
+
+ tp_channel_filter_require_target_is_contact (self);
+ tp_channel_filter_require_channel_type (self,
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER1);
+
+ if (service != NULL)
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA1_SERVICE_NAME),
+ tp_g_value_slice_new_string (service));
+
+ return self;
+}
+
+/**
+ * tp_channel_filter_require_locally_requested:
+ * @self: a channel filter
+ * @requested: the desired value for tp_channel_get_requested()
+ *
+ * Narrow @self to require that the channel was requested by the local
+ * user, or to require that the channel was <emphasis>not</emphasis>
+ * requested by the local user, depending on the value of @requested.
+ *
+ * For instance, to match an outgoing (locally-requested) 1-1 call:
+ *
+ * |[
+ * filter = tp_channel_filter_new_for_calls (TP_ENTITY_TYPE_CONTACT);
+ * tp_channel_filter_require_locally_requested (filter, TRUE);
+ * ]|
+ *
+ * or to match an incoming (not locally-requested) file transfer:
+ *
+ * |[
+ * filter = tp_channel_filter_new_for_file_transfer ();
+ * tp_channel_filter_require_locally_requested (filter, FALSE);
+ * ]|
+ *
+ * It is an error to call this method if the channel filter has already
+ * been passed to a #TpBaseClient.
+ */
+void
+tp_channel_filter_require_locally_requested (TpChannelFilter *self,
+ gboolean requested)
+{
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (self));
+ g_return_if_fail (!self->priv->already_used);
+
+ /* Do not use tp_asv_set_uint32 or similar - the key is dup'd */
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_REQUESTED),
+ tp_g_value_slice_new_boolean (requested));
+}
+
+/**
+ * tp_channel_filter_require_property:
+ * @self: a channel filter
+ * @name: a fully-qualified D-Bus property name (in the format
+ * "interface.name.propertyname") as described by the Telepathy
+ * D-Bus API Specification
+ * @value: the value required for @name
+ *
+ * Narrow @self to require that the immutable channel property @name
+ * has the given value.
+ *
+ * If @value is a floating reference, this method will take ownership
+ * of it.
+ *
+ * @value must not contain any GVariant extensions not supported by
+ * dbus-glib, such as %G_VARIANT_TYPE_UNIT or %G_VARIANT_TYPE_HANDLE.
+ *
+ * For instance, tp_channel_filter_require_target_is_contact() is equivalent
+ * to:
+ *
+ * |[
+ * tp_channel_filter_require_property (filter,
+ * TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ * g_variant_new_uint32 (TP_ENTITY_TYPE_CONTACT));
+ * ]|
+ *
+ * It is an error to call this method if the channel filter has already
+ * been passed to a #TpBaseClient.
+ */
+void
+tp_channel_filter_require_property (TpChannelFilter *self,
+ const gchar *name,
+ GVariant *value)
+{
+ GValue *gvalue;
+
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (self));
+ g_return_if_fail (!self->priv->already_used);
+ g_return_if_fail (name != NULL);
+
+ g_variant_ref_sink (value);
+
+ gvalue = g_slice_new0 (GValue);
+ dbus_g_value_parse_g_variant (value, gvalue);
+
+ g_variant_unref (value);
+
+ g_hash_table_insert (self->priv->asv, g_strdup (name), gvalue);
+}
+
+GVariant *
+_tp_channel_filter_use (TpChannelFilter *self)
+{
+ g_return_val_if_fail (TP_IS_CHANNEL_FILTER (self), NULL);
+
+ self->priv->already_used = TRUE;
+ return tp_asv_to_vardict (self->priv->asv);
+}
diff --git a/telepathy-glib/channel-filter.h b/telepathy-glib/channel-filter.h
new file mode 100644
index 000000000..ba7b4b6a4
--- /dev/null
+++ b/telepathy-glib/channel-filter.h
@@ -0,0 +1,105 @@
+/*
+ * A filter matching certain channels.
+ *
+ * Copyright © 2010-2014 Collabora Ltd.
+ *
+ * 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 TP_CHANNEL_FILTER_H
+#define TP_CHANNEL_FILTER_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <telepathy-glib/defs.h>
+#include <telepathy-glib/enums.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpChannelFilter TpChannelFilter;
+typedef struct _TpChannelFilterClass TpChannelFilterClass;
+typedef struct _TpChannelFilterPrivate TpChannelFilterPrivate;
+
+GType tp_channel_filter_get_type (void);
+
+#define TP_TYPE_CHANNEL_FILTER \
+ (tp_channel_filter_get_type ())
+#define TP_CHANNEL_FILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TYPE_CHANNEL_FILTER, \
+ TpChannelFilter))
+#define TP_CHANNEL_FILTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TYPE_CHANNEL_FILTER, \
+ TpChannelFilterClass))
+#define TP_IS_CHANNEL_FILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TYPE_CHANNEL_FILTER))
+#define TP_IS_CHANNEL_FILTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TYPE_CHANNEL_FILTER))
+#define TP_CHANNEL_FILTER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_CHANNEL_FILTER, \
+ TpChannelFilterClass))
+
+_TP_AVAILABLE_IN_UNRELEASED G_GNUC_WARN_UNUSED_RESULT
+TpChannelFilter *tp_channel_filter_new (void);
+
+_TP_AVAILABLE_IN_UNRELEASED G_GNUC_WARN_UNUSED_RESULT
+TpChannelFilter *tp_channel_filter_new_for_text_chats (void);
+
+_TP_AVAILABLE_IN_UNRELEASED G_GNUC_WARN_UNUSED_RESULT
+TpChannelFilter *tp_channel_filter_new_for_text_chatrooms (void);
+
+_TP_AVAILABLE_IN_UNRELEASED G_GNUC_WARN_UNUSED_RESULT
+TpChannelFilter *tp_channel_filter_new_for_calls (TpEntityType entity_type);
+
+_TP_AVAILABLE_IN_UNRELEASED G_GNUC_WARN_UNUSED_RESULT
+TpChannelFilter *tp_channel_filter_new_for_stream_tubes (const gchar *service);
+
+_TP_AVAILABLE_IN_UNRELEASED G_GNUC_WARN_UNUSED_RESULT
+TpChannelFilter *tp_channel_filter_new_for_dbus_tubes (const gchar *service);
+
+_TP_AVAILABLE_IN_UNRELEASED G_GNUC_WARN_UNUSED_RESULT
+TpChannelFilter *tp_channel_filter_new_for_file_transfers (
+ const gchar *service);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_channel_filter_require_target_is_contact (TpChannelFilter *self);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_channel_filter_require_target_is_room (TpChannelFilter *self);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_channel_filter_require_no_target (TpChannelFilter *self);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_channel_filter_require_target_type (TpChannelFilter *self,
+ TpEntityType entity_type);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_channel_filter_require_locally_requested (TpChannelFilter *self,
+ gboolean requested);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_channel_filter_require_channel_type (TpChannelFilter *self,
+ const gchar *channel_type);
+
+_TP_AVAILABLE_IN_UNRELEASED
+void tp_channel_filter_require_property (TpChannelFilter *self,
+ const gchar *name,
+ GVariant *value);
+
+G_END_DECLS
+
+#endif
diff --git a/telepathy-glib/file-transfer-channel.c b/telepathy-glib/file-transfer-channel.c
index 6392ce753..118f43487 100644
--- a/telepathy-glib/file-transfer-channel.c
+++ b/telepathy-glib/file-transfer-channel.c
@@ -937,17 +937,9 @@ tp_file_transfer_channel_class_init (TpFileTransferChannelClass *klass)
* contact who also supports the metadata extension; see the
* requestable channel classes for said contact), this property will
* be set to the same value on the remote incoming channel and
- * handlers can match on this in their handler filter. For example,
- * a remote handler could call the following:
- *
- * |[
- * tp_base_client_take_handler_filter (handler, tp_asv_new (
- * TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER1,
- * TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, G_TYPE_UINT, TP_ENTITY_TYPE_CONTACT,
- * TP_PROP_CHANNEL_REQUESTED, G_TYPE_BOOLEAN, FALSE,
- * TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_SERVICE_NAME, G_TYPE_STRING, "service.name",
- * NULL));
- * ]|
+ * handlers can match on this in their handler filter by passing
+ * a non-%NULL @service argument to
+ * tp_channel_filter_new_for_file_transfers().
*
* The %TP_FILE_TRANSFER_CHANNEL_FEATURE_CORE feature has to be
* prepared for this property to be meaningful.
diff --git a/telepathy-glib/introspection.am b/telepathy-glib/introspection.am
index 86417c7f1..00fd42798 100644
--- a/telepathy-glib/introspection.am
+++ b/telepathy-glib/introspection.am
@@ -24,6 +24,7 @@ TelepathyGLib_1_gir_FILES = \
$(srcdir)/account-channel-request.c $(srcdir)/account-channel-request.h \
$(srcdir)/account-manager.c $(srcdir)/account-manager.h \
$(srcdir)/automatic-client-factory.c $(srcdir)/automatic-client-factory.h \
+ $(srcdir)/channel-filter.c $(srcdir)/channel-filter.h \
$(srcdir)/connection.c $(srcdir)/connection.h \
$(srcdir)/connection-contact-list.c $(srcdir)/connection-contact-list.h \
$(srcdir)/connection-contact-info.c \
diff --git a/telepathy-glib/simple-approver.c b/telepathy-glib/simple-approver.c
index ec3046f19..2f820e047 100644
--- a/telepathy-glib/simple-approver.c
+++ b/telepathy-glib/simple-approver.c
@@ -47,10 +47,8 @@
* client = tp_simple_approver_new (NULL, "MyApprover", FALSE,
* my_add_dispatch_operation, user_data);
*
- * tp_base_client_take_approver_filter (client, tp_asv_new (
- * TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
- * TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, G_TYPE_UINT, TP_ENTITY_TYPE_CONTACT,
- * NULL));
+ * tp_base_client_take_approver_filter_object (client,
+ * tp_channel_filter_new_for_text_chats ());
*
* tp_base_client_register (client, NULL);
* ]|
diff --git a/telepathy-glib/simple-handler.c b/telepathy-glib/simple-handler.c
index be4a2ec2c..7484a729f 100644
--- a/telepathy-glib/simple-handler.c
+++ b/telepathy-glib/simple-handler.c
@@ -48,10 +48,8 @@
* client = tp_simple_handler_new (NULL, FALSE, FALSE,
* "MyHandler", FALSE, my_handle_channel, user_data);
*
- * tp_base_client_take_handler_filter (client, tp_asv_new (
- * TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
- * TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, G_TYPE_UINT, TP_ENTITY_TYPE_CONTACT,
- * NULL));
+ * tp_base_client_take_handler_filter_object (client,
+ * tp_channel_filter_new_for_text_chats ());
*
* tp_base_client_register (client, NULL);
* ]|
diff --git a/telepathy-glib/simple-observer.c b/telepathy-glib/simple-observer.c
index 96093434a..99233971e 100644
--- a/telepathy-glib/simple-observer.c
+++ b/telepathy-glib/simple-observer.c
@@ -47,10 +47,8 @@
* client = tp_simple_observer_new (NULL, TRUE, "MyObserver",
* FALSE, my_observe_channel, user_data);
*
- * tp_base_client_take_observer_filter (client, tp_asv_new (
- * TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
- * TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, G_TYPE_UINT, TP_ENTITY_TYPE_CONTACT,
- * NULL));
+ * tp_base_client_take_observer_filter_object (client,
+ * tp_channel_filter_new_for_text_chats ());
*
* tp_base_client_register (client, NULL);
* ]|
diff --git a/telepathy-glib/telepathy-glib.h b/telepathy-glib/telepathy-glib.h
index 491f4d37a..6cfc7bbd1 100644
--- a/telepathy-glib/telepathy-glib.h
+++ b/telepathy-glib/telepathy-glib.h
@@ -60,6 +60,7 @@
#include <telepathy-glib/capabilities.h>
#include <telepathy-glib/channel-dispatch-operation.h>
#include <telepathy-glib/channel-dispatcher.h>
+#include <telepathy-glib/channel-filter.h>
#include <telepathy-glib/channel-iface.h>
#include <telepathy-glib/channel-manager.h>
#include <telepathy-glib/channel-request.h>
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 41987cc33..3e162a616 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,6 +12,7 @@ endif
programs_list = \
test-asv \
test-capabilities \
+ test-channel-filter \
test-availability-cmp \
test-dtmf-player \
test-enums \
@@ -94,6 +95,16 @@ test_capabilities_LDADD = \
$(GLIB_LIBS)
# this one uses internal ABI
+test_channel_filter_SOURCES = \
+ channel-filter.c
+test_channel_filter_LDADD = \
+ $(top_builddir)/tests/lib/libtp-glib-tests-internal.la \
+ $(top_builddir)/telepathy-glib/libtelepathy-glib-main-internal.la \
+ $(top_builddir)/telepathy-glib/libtelepathy-glib-1-dbus.la \
+ $(top_builddir)/telepathy-glib/libtelepathy-glib-1-core.la \
+ $(GLIB_LIBS)
+
+# this one uses internal ABI
test_contact_search_result_SOURCES = \
contact-search-result.c
test_contact_search_result_LDADD = \
diff --git a/tests/channel-filter.c b/tests/channel-filter.c
new file mode 100644
index 000000000..f645ffc9a
--- /dev/null
+++ b/tests/channel-filter.c
@@ -0,0 +1,216 @@
+#include "config.h"
+
+#include "telepathy-glib/channel-filter-internal.h"
+
+#include "tests/lib/util.h"
+
+typedef struct {
+ TpChannelFilter *filter;
+} Fixture;
+
+static void
+setup (Fixture *f,
+ gconstpointer data)
+{
+ tp_debug_set_flags ("all");
+}
+
+static void
+test_basics (Fixture *f,
+ gconstpointer data)
+{
+ GVariant *vardict;
+ /*
+ gboolean valid;
+ guint i;
+ TpEntityType call_entity_types[] = { TP_ENTITY_TYPE_CONTACT,
+ TP_ENTITY_TYPE_ROOM,
+ TP_ENTITY_TYPE_NONE };
+ */
+
+ f->filter = tp_channel_filter_new ();
+ vardict = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (g_variant_n_children (vardict), ==, 0);
+ g_variant_unref (vardict);
+ g_clear_object (&f->filter);
+
+#if 0
+ f->filter = tp_channel_filter_new_for_text_chats ();
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 2);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_TEXT);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_CONTACT);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new_for_text_chatrooms ();
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 2);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_TEXT);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_ROOM);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ for (i = 0; i < G_N_ELEMENTS (call_handle_types); i++)
+ {
+ f->filter = tp_channel_filter_new_for_calls (call_handle_types[i]);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 2);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_CALL);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, call_handle_types[i]);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+ }
+
+ f->filter = tp_channel_filter_new_for_stream_tubes ("rfb");
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 2);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE), ==, "rfb");
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new_for_dbus_tubes ("com.example.Chess");
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 2);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME), ==, "com.example.Chess");
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new_for_file_transfers (NULL);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 2);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_CONTACT);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new_for_file_transfers ("com.example.AbiWord");
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 3);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ /* our constant naming strategy is unstoppable */
+ TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_SERVICE_NAME), ==,
+ "com.example.AbiWord");
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_CONTACT);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_target_is_contact (f->filter);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_CONTACT);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_target_is_room (f->filter);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_ROOM);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_no_target (f->filter);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_NONE);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_target_type (f->filter, TP_ENTITY_TYPE_ROOM);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid),
+ ==, TP_ENTITY_TYPE_ROOM);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_channel_type (f->filter, "com.example.Bees");
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpstr (tp_asv_get_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE), ==, "com.example.Bees");
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_locally_requested (f->filter, TRUE);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpuint (tp_asv_get_boolean (asv,
+ TP_PROP_CHANNEL_REQUESTED, &valid), ==, TRUE);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_locally_requested (f->filter, FALSE);
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpuint (tp_asv_get_boolean (asv,
+ TP_PROP_CHANNEL_REQUESTED, &valid), ==, FALSE);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+
+ f->filter = tp_channel_filter_new ();
+ tp_channel_filter_require_property (f->filter,
+ "com.example.Answer", g_variant_new_uint32 (42));
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 1);
+ g_assert_cmpuint (tp_asv_get_uint32 (asv,
+ "com.example.Answer", &valid), ==, 42);
+ g_assert (valid);
+ g_clear_object (&f->filter);
+#endif
+}
+
+static void
+teardown (Fixture *f,
+ gconstpointer data)
+{
+ g_clear_object (&f->filter);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+#define TEST_PREFIX "/channel-filter/"
+
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
+
+ g_test_add (TEST_PREFIX "basics", Fixture, NULL, setup, test_basics,
+ teardown);
+
+ return g_test_run ();
+}
diff --git a/tests/dbus/base-client.c b/tests/dbus/base-client.c
index d4fa8f2f7..bacbe6fae 100644
--- a/tests/dbus/base-client.c
+++ b/tests/dbus/base-client.c
@@ -467,18 +467,20 @@ static void
test_observer (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- GHashTable *requests_satisfied, *chan_props;
+ TpChannelFilter *filter;
GHashTable *info;
TpChannel *chan;
+ GHashTable *chan_props, *requests_satisfied;
- tp_base_client_add_observer_filter (test->base_client,
- g_variant_new_parsed ("{ %s: <%s> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_TEXT));
+ filter = tp_channel_filter_new ();
+ tp_channel_filter_require_channel_type (filter, TP_IFACE_CHANNEL_TYPE_TEXT);
+ tp_base_client_add_observer_filter_object (test->base_client, filter);
+ g_object_unref (filter);
- tp_base_client_add_observer_filter (test->base_client,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT));
+ filter = tp_channel_filter_new_for_stream_tubes (NULL);
+ tp_channel_filter_require_target_is_contact (filter);
+ tp_base_client_add_observer_filter_object (test->base_client, filter);
+ g_object_unref (filter);
tp_base_client_set_observer_recover (test->base_client, TRUE);
tp_base_client_set_observer_delay_approvers (test->base_client, TRUE);
@@ -602,21 +604,23 @@ static void
test_approver (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- GHashTable *chan_props;
- TpChannel *chan;
+ TpChannelFilter *filter;
GHashTable *properties;
static const char *interfaces[] = { NULL };
static const gchar *possible_handlers[] = {
TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
+ GHashTable *chan_props;
+ TpChannel *chan;
- tp_base_client_add_approver_filter (test->base_client,
- g_variant_new_parsed ("{ %s: <%s> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_TEXT));
+ filter = tp_channel_filter_new ();
+ tp_channel_filter_require_channel_type (filter, TP_IFACE_CHANNEL_TYPE_TEXT);
+ tp_base_client_add_approver_filter_object (test->base_client, filter);
+ g_object_unref (filter);
- tp_base_client_add_approver_filter (test->base_client,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, TP_ENTITY_TYPE_CONTACT));
+ filter = tp_channel_filter_new_for_stream_tubes (NULL);
+ tp_channel_filter_require_target_is_contact (filter);
+ tp_base_client_add_approver_filter_object (test->base_client, filter);
+ g_object_unref (filter);
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
@@ -787,25 +791,20 @@ static void
test_handler (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- GHashTable *filter;
+ TpChannelFilter *filter;
const gchar *caps[] = { "mushroom", "snake", NULL };
GList *chans;
TpTestsSimpleClient *client_2;
- filter = tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
- NULL);
+ filter = tp_channel_filter_new ();
+ tp_channel_filter_require_channel_type (filter, TP_IFACE_CHANNEL_TYPE_TEXT);
+ tp_base_client_add_handler_filter_object (test->base_client, filter);
+ g_object_unref (filter);
- tp_base_client_add_handler_filter (test->base_client,
- g_variant_new_parsed ("{ %s: <%s> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_TEXT));
-
- g_hash_table_unref (filter);
-
- tp_base_client_add_handler_filter (test->base_client,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT));
+ filter = tp_channel_filter_new_for_stream_tubes (NULL);
+ tp_channel_filter_require_target_is_contact (filter);
+ tp_base_client_add_handler_filter_object (test->base_client, filter);
+ g_object_unref (filter);
tp_base_client_set_handler_bypass_approval (test->base_client, TRUE);
@@ -951,11 +950,12 @@ test_handler_requests (Test *test,
GHashTable *properties, *requests_satisfied;
TpChannelRequest *request;
GList *requests;
+ TpChannelFilter *filter;
- tp_base_client_add_handler_filter (test->base_client,
- g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
- TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE1,
- TP_PROP_CHANNEL_TARGET_ENTITY_TYPE, (guint32) TP_ENTITY_TYPE_CONTACT));
+ filter = tp_channel_filter_new_for_stream_tubes (NULL);
+ tp_channel_filter_require_target_is_contact (filter);
+ tp_base_client_add_handler_filter_object (test->base_client, filter);
+ g_object_unref (filter);
tp_base_client_set_handler_request_notification (test->base_client);