summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2012-05-04 19:08:59 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2012-05-04 19:08:59 +0100
commite16911e38022d67e96a5527774388d37595b8e08 (patch)
tree984a3b6356ddfb3f8a4f4dd6ab253232f90ca59f
parent34752d004ced4ce4ac75e7ab0c601bf444bed864 (diff)
TpChannelFilter: addfiltration
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-sections.txt40
-rw-r--r--examples/client/approver.c32
-rw-r--r--examples/client/dbus-tubes/accepter.c19
-rw-r--r--examples/client/media-observer.c8
-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.c19
-rw-r--r--examples/client/text-handler.c13
-rw-r--r--telepathy-glib/Makefile.am3
-rw-r--r--telepathy-glib/base-client.c174
-rw-r--r--telepathy-glib/base-client.h21
-rw-r--r--telepathy-glib/channel-filter-internal.h33
-rw-r--r--telepathy-glib/channel-filter.c560
-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.am8
-rw-r--r--tests/channel-filter.c212
-rw-r--r--tests/dbus/base-client.c77
23 files changed, 1232 insertions, 146 deletions
diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index ca2a4ec22..887c76574 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -5629,12 +5629,16 @@ TpDebugSenderPrivate
<TITLE>base-client</TITLE>
TpBaseClient
TpBaseClientClass
+tp_base_client_add_observer_filter_object
+tp_base_client_take_observer_filter_object
tp_base_client_add_observer_filter
tp_base_client_take_observer_filter
tp_base_client_set_observer_recover
tp_base_client_set_observer_delay_approvers
TpBaseClientClassObserveChannelsImpl
tp_base_client_implement_observe_channels
+tp_base_client_add_approver_filter_object
+tp_base_client_take_approver_filter_object
tp_base_client_add_approver_filter
tp_base_client_take_approver_filter
TpBaseClientClassAddDispatchOperationImpl
@@ -5642,6 +5646,8 @@ 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_object
+tp_base_client_take_handler_filter_object
tp_base_client_add_handler_filter
tp_base_client_take_handler_filter
tp_base_client_be_a_handler
@@ -7323,3 +7329,37 @@ tp_room_info_get_type
<SUBSECTION Private>
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>
diff --git a/examples/client/approver.c b/examples/client/approver.c
index cbe4801cb..1eafbf922 100644
--- a/examples/client/approver.c
+++ b/examples/client/approver.c
@@ -153,36 +153,20 @@ main (int argc,
FALSE, add_dispatch_operation_cb, NULL, NULL);
/* contact text chat */
- tp_base_client_take_approver_filter (approver, 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_CONTACT,
- NULL));
+ tp_base_client_take_approver_filter_object (approver,
+ tp_channel_filter_new_for_text_chats ());
/* call */
- tp_base_client_take_approver_filter (approver, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_CALL,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL));
+ tp_base_client_take_approver_filter_object (approver,
+ tp_channel_filter_new_for_calls (TP_HANDLE_TYPE_CONTACT));
/* room text chat */
- tp_base_client_take_approver_filter (approver, 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));
+ tp_base_client_take_approver_filter_object (approver,
+ tp_channel_filter_new_for_text_chatrooms ());
/* file transfer */
- tp_base_client_take_approver_filter (approver, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL));
+ 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 e9c3835b1..163d63cb1 100644
--- a/examples/client/dbus-tubes/accepter.c
+++ b/examples/client/dbus-tubes/accepter.c
@@ -181,6 +181,7 @@ main (int argc,
{
TpAccountManager *manager;
TpBaseClient *handler;
+ TpChannelFilter *filter;
GError *error = NULL;
g_type_init ();
@@ -189,20 +190,10 @@ main (int argc,
handler = tp_simple_handler_new_with_am (manager, FALSE, FALSE,
"ExampleServiceHandler", FALSE, handle_channels, NULL, NULL);
- tp_base_client_take_handler_filter (handler, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE,
- G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
-
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
- G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
-
- TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME,
- G_TYPE_STRING,
- EXAMPLE_SERVICE_NAME,
-
- NULL));
+ 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 3c2ebe8cf..f2b86c2f6 100644
--- a/examples/client/media-observer.c
+++ b/examples/client/media-observer.c
@@ -85,12 +85,8 @@ main (int argc,
observer = tp_simple_observer_new_with_am (manager, FALSE,
"ExampleMediaObserver", FALSE, observe_channels_cb, NULL, NULL);
- tp_base_client_take_observer_filter (observer, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_CALL,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL));
+ tp_base_client_take_observer_filter_object (observer,
+ tp_channel_filter_new_for_calls (TP_HANDLE_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 2e042f782..e43842ddd 100644
--- a/examples/client/python/ft-handler.py
+++ b/examples/client/python/ft-handler.py
@@ -52,13 +52,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_HANDLE_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 352d81955..62b0dfab1 100755
--- a/examples/client/python/text-handler.py
+++ b/examples/client/python/text-handler.py
@@ -55,12 +55,9 @@ if __name__ == '__main__':
handler = TelepathyGLib.SimpleHandler.new(dbus, 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_HANDLE_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 79e8eff80..7c7055c8b 100644
--- a/examples/client/stream-tubes/accepter.c
+++ b/examples/client/stream-tubes/accepter.c
@@ -142,6 +142,7 @@ main (int argc,
{
TpAccountManager *manager;
TpBaseClient *handler;
+ TpChannelFilter *filter;
GError *error = NULL;
g_type_init ();
@@ -150,20 +151,10 @@ main (int argc,
handler = tp_simple_handler_new_with_am (manager, FALSE, FALSE,
"ExampleServiceHandler", FALSE, _handle_channels, NULL, NULL);
- tp_base_client_take_handler_filter (handler, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE,
- G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
-
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
- G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
-
- TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE,
- G_TYPE_STRING,
- "ExampleService",
-
- NULL));
+ 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 d2c0aa232..be230ce85 100644
--- a/examples/client/text-handler.c
+++ b/examples/client/text-handler.c
@@ -123,6 +123,7 @@ main (int argc,
TpAccountManager *manager;
GError *error = NULL;
TpBaseClient *handler;
+ TpChannelFilter *filter;
g_type_init ();
tp_debug_set_flags (g_getenv ("EXAMPLE_DEBUG"));
@@ -131,13 +132,11 @@ main (int argc,
handler = tp_simple_handler_new_with_am (manager, FALSE, FALSE,
"ExampleHandler", FALSE, handle_channels_cb, NULL, NULL);
- tp_base_client_take_handler_filter (handler, 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_CONTACT,
- TP_PROP_CHANNEL_REQUESTED, G_TYPE_BOOLEAN, FALSE,
- NULL));
+ /* 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 30efdb618..1091e2af7 100644
--- a/telepathy-glib/Makefile.am
+++ b/telepathy-glib/Makefile.am
@@ -54,6 +54,7 @@ our_headers = \
channel-dispatcher.h \
channel-dispatch-operation.h \
channel-factory-iface.h \
+ channel-filter.h \
channel-manager.h \
channel-request.h \
client.h \
@@ -205,6 +206,8 @@ libtelepathy_glib_internal_la_SOURCES = \
call-stream-endpoint.c \
channel.c \
channel-contacts.c \
+ channel-filter.c \
+ channel-filter-internal.h \
channel-group.c \
channel-internal.h \
channel-dispatcher.c \
diff --git a/telepathy-glib/base-client.c b/telepathy-glib/base-client.c
index 0704e2e20..2efcbbc33 100644
--- a/telepathy-glib/base-client.c
+++ b/telepathy-glib/base-client.c
@@ -188,6 +188,7 @@
#include <telepathy-glib/automatic-proxy-factory.h>
#include <telepathy-glib/channel-dispatch-operation-internal.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/dbus-internal.h>
@@ -372,6 +373,75 @@ tp_base_client_add_observer_filter (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_channels 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 ();
+ * tp_channel_filter_require_type_is_text (filter);
+ * tp_base_client_add_observer_filter_object (client, filter);
+ * g_object_unref (filter);
+ *
+ * filter = tp_channel_filter_new ();
+ * tp_channel_filter_require_target_is_contact (filter);
+ * tp_channel_filter_require_type_is_call (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_channels.
+ *
+ * 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_take_observer_filter: (skip)
* @self: a client
* @filter: (transfer full) (element-type utf8 GObject.Value):
@@ -518,6 +588,34 @@ tp_base_client_add_approver_filter (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: (skip)
* @self: a client
* @filter: (transfer full) (element-type utf8 GObject.Value):
@@ -553,6 +651,30 @@ tp_base_client_take_approver_filter (TpBaseClient *self,
}
/**
+ * 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_be_a_handler:
* @self: a #TpBaseClient
*
@@ -605,6 +727,34 @@ tp_base_client_add_handler_filter (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_channels 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_channels.
+ *
+ * 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_take_handler_filter: (skip)
* @self: a #TpBaseClient
* @filter: (transfer full) (element-type utf8 GObject.Value):
@@ -640,6 +790,30 @@ tp_base_client_take_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 9550b4260..38232ee57 100644
--- a/telepathy-glib/base-client.h
+++ b/telepathy-glib/base-client.h
@@ -27,6 +27,7 @@
#include <telepathy-glib/account.h>
#include <telepathy-glib/account-manager.h>
#include <telepathy-glib/add-dispatch-operation-context.h>
+#include <telepathy-glib/channel-filter.h>
#include <telepathy-glib/client-channel-factory.h>
#include <telepathy-glib/handle-channels-context.h>
#include <telepathy-glib/observe-channels-context.h>
@@ -108,9 +109,17 @@ void tp_base_client_implement_handle_channels (TpBaseClientClass *klass,
void tp_base_client_add_observer_filter (TpBaseClient *self,
GHashTable *filter);
+_TP_AVAILABLE_IN_0_20
+void tp_base_client_add_observer_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
+
void tp_base_client_take_observer_filter (TpBaseClient *self,
GHashTable *filter);
+_TP_AVAILABLE_IN_0_20
+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,
@@ -118,15 +127,27 @@ void tp_base_client_set_observer_delay_approvers (TpBaseClient *self,
void tp_base_client_add_approver_filter (TpBaseClient *self,
GHashTable *filter);
+_TP_AVAILABLE_IN_0_20
+void tp_base_client_add_approver_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
void tp_base_client_take_approver_filter (TpBaseClient *self,
GHashTable *filter);
+_TP_AVAILABLE_IN_0_20
+void tp_base_client_take_approver_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
void tp_base_client_be_a_handler (TpBaseClient *self);
void tp_base_client_add_handler_filter (TpBaseClient *self,
GHashTable *filter);
+_TP_AVAILABLE_IN_0_20
+void tp_base_client_add_handler_filter_object (TpBaseClient *self,
+ TpChannelFilter *filter);
void tp_base_client_take_handler_filter (TpBaseClient *self,
GHashTable *filter);
+_TP_AVAILABLE_IN_0_20
+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..fdf547524
--- /dev/null
+++ b/telepathy-glib/channel-filter-internal.h
@@ -0,0 +1,33 @@
+/*<private_header>*/
+/*
+ * A filter matching certain channels.
+ *
+ * Copyright © 2010-2012 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
+
+GHashTable *_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..2fc54fc71
--- /dev/null
+++ b/telepathy-glib/channel-filter.c
@@ -0,0 +1,560 @@
+/*
+ * A filter matching certain channels.
+ *
+ * Copyright © 2010-2012 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>
+
+/**
+ * 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_room()
+ * 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_HANDLE_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_HANDLE_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_HANDLE_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_HANDLE_TYPE_NONE);
+}
+
+/**
+ * tp_channel_filter_require_target_type:
+ * @self: a channel filter
+ * @target_type: the desired value for #TpChannel:handle-type
+ *
+ * Narrow @self to require a particular target handle type.
+ *
+ * For instance, setting @target_type to %TP_HANDLE_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,
+ TpHandleType target_type)
+{
+ g_return_if_fail (TP_IS_CHANNEL_FILTER (self));
+ g_return_if_fail (((guint) target_type) < TP_NUM_HANDLE_TYPES);
+
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_TARGET_HANDLE_TYPE),
+ tp_g_value_slice_new_uint (target_type));
+}
+
+/**
+ * tp_channel_filter_new_for_calls:
+ * @handle_type: the desired handle type
+ *
+ * Return a channel filter that matches audio and video calls,
+ * including VoIP and telephony.
+ *
+ * @handle_type is passed to tp_channel_filter_require_target_type().
+ * Use %TP_HANDLE_TYPE_CONTACT for ordinary 1-1 calls.
+ */
+TpChannelFilter *
+tp_channel_filter_new_for_calls (TpHandleType handle_type)
+{
+ TpChannelFilter *self = tp_channel_filter_new ();
+
+ tp_channel_filter_require_target_type (self, handle_type);
+ tp_channel_filter_require_channel_type (self, TP_IFACE_CHANNEL_TYPE_CALL);
+ 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_TUBE);
+
+ if (service != NULL)
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_TYPE_STREAM_TUBE_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_TUBE);
+
+ if (service != NULL)
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_TYPE_DBUS_TUBE_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_TRANSFER);
+
+ if (service != NULL)
+ g_hash_table_insert (self->priv->asv,
+ g_strdup (TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_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_HANDLE_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_HANDLE_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);
+}
+
+GHashTable *
+_tp_channel_filter_use (TpChannelFilter *self)
+{
+ g_return_val_if_fail (TP_IS_CHANNEL_FILTER (self), NULL);
+
+ self->priv->already_used = TRUE;
+ return self->priv->asv;
+}
diff --git a/telepathy-glib/channel-filter.h b/telepathy-glib/channel-filter.h
new file mode 100644
index 000000000..2e9a2d167
--- /dev/null
+++ b/telepathy-glib/channel-filter.h
@@ -0,0 +1,105 @@
+/*
+ * A filter matching certain channels.
+ *
+ * Copyright © 2010-2012 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 (TpHandleType handle_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,
+ TpHandleType target_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 db39bff5d..e5438bc79 100644
--- a/telepathy-glib/file-transfer-channel.c
+++ b/telepathy-glib/file-transfer-channel.c
@@ -935,17 +935,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_TRANSFER,
- * TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_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 f55520f04..a25018dcb 100644
--- a/telepathy-glib/introspection.am
+++ b/telepathy-glib/introspection.am
@@ -20,6 +20,7 @@ TelepathyGLib_0_12_gir_FILES = \
$(srcdir)/automatic-client-factory.c $(srcdir)/automatic-client-factory.h \
$(srcdir)/automatic-proxy-factory.c $(srcdir)/automatic-proxy-factory.h \
$(srcdir)/basic-proxy-factory.c $(srcdir)/basic-proxy-factory.h \
+ $(srcdir)/channel-filter.c $(srcdir)/channel-filter.h \
$(srcdir)/client-channel-factory.c $(srcdir)/client-channel-factory.h \
$(srcdir)/connection.c $(srcdir)/connection.h \
$(srcdir)/connection-contact-list.c $(srcdir)/connection-contact-list.h \
diff --git a/telepathy-glib/simple-approver.c b/telepathy-glib/simple-approver.c
index da9666d11..e2c6c281c 100644
--- a/telepathy-glib/simple-approver.c
+++ b/telepathy-glib/simple-approver.c
@@ -49,10 +49,8 @@
* my_add_dispatch_operation, user_data);
* g_object_unref (factory);
*
- * 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_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_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 0fcba4a54..e761ec2cd 100644
--- a/telepathy-glib/simple-handler.c
+++ b/telepathy-glib/simple-handler.c
@@ -50,10 +50,8 @@
* "MyHandler", FALSE, my_handle_channels, user_data);
* g_object_unref (factory);
*
- * 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_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_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 ee74a8478..9725bca64 100644
--- a/telepathy-glib/simple-observer.c
+++ b/telepathy-glib/simple-observer.c
@@ -49,10 +49,8 @@
* FALSE, my_observe_channels, user_data);
* g_object_unref (factory);
*
- * 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_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_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 2af1f72f9..3762f61b8 100644
--- a/telepathy-glib/telepathy-glib.h
+++ b/telepathy-glib/telepathy-glib.h
@@ -45,6 +45,7 @@
#include <telepathy-glib/call-stream.h>
#include <telepathy-glib/channel-dispatch-operation.h>
#include <telepathy-glib/channel-dispatcher.h>
+#include <telepathy-glib/channel-filter.h>
#include <telepathy-glib/channel-request.h>
#include <telepathy-glib/channel.h>
#include <telepathy-glib/client-channel-factory.h>
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 63abac55a..69b924474 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -7,6 +7,7 @@ SUBDIRS = \
programs_list = \
test-asv \
test-capabilities \
+ test-channel-filter \
test-availability-cmp \
test-dtmf-player \
test-enums \
@@ -81,6 +82,13 @@ test_capabilities_LDADD = \
$(GLIB_LIBS)
# this one uses internal ABI
+test_channel_filter_SOURCES = \
+ channel-filter.c
+test_channel_filter_LDADD = \
+ $(top_builddir)/telepathy-glib/libtelepathy-glib-internal.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..41cd9457b
--- /dev/null
+++ b/tests/channel-filter.c
@@ -0,0 +1,212 @@
+#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)
+{
+ g_type_init ();
+ tp_debug_set_flags ("all");
+}
+
+static void
+test_basics (Fixture *f,
+ gconstpointer data)
+{
+ const GHashTable *asv;
+ gboolean valid;
+ guint i;
+ TpHandleType call_handle_types[] = { TP_HANDLE_TYPE_CONTACT,
+ TP_HANDLE_TYPE_ROOM,
+ TP_HANDLE_TYPE_NONE };
+
+ f->filter = tp_channel_filter_new ();
+ asv = _tp_channel_filter_use (f->filter);
+ g_assert_cmpuint (tp_asv_size (asv), ==, 0);
+ g_clear_object (&f->filter);
+
+ 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_HANDLE_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_HANDLE_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_HANDLE_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_HANDLE_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_HANDLE_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_HANDLE_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_HANDLE_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_HANDLE_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_HANDLE_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);
+}
+
+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 843391510..75018021c 100644
--- a/tests/dbus/base-client.c
+++ b/tests/dbus/base-client.c
@@ -494,24 +494,20 @@ static void
test_observer (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- GHashTable *filter;
+ TpChannelFilter *filter;
GPtrArray *channels, *requests_satisified;
GHashTable *info;
TpChannel *chan;
- filter = tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
- NULL);
-
- tp_base_client_add_observer_filter (test->base_client, filter);
- g_hash_table_unref (filter);
+ 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_take_observer_filter (test->base_client, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL));
+ 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);
@@ -634,7 +630,7 @@ static void
test_approver (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- GHashTable *filter;
+ TpChannelFilter *filter;
GPtrArray *channels, *chans;
GHashTable *properties;
static const char *interfaces[] = { NULL };
@@ -642,19 +638,15 @@ test_approver (Test *test,
TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
guint i;
- filter = tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
- NULL);
-
- tp_base_client_add_approver_filter (test->base_client, filter);
- g_hash_table_unref (filter);
+ 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_take_approver_filter (test->base_client, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL));
+ 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);
@@ -836,7 +828,7 @@ static void
test_handler (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- GHashTable *filter;
+ TpChannelFilter *filter;
const gchar *caps[] = { "mushroom", "snake", NULL };
GPtrArray *channels;
GPtrArray *requests_satisified;
@@ -844,19 +836,15 @@ test_handler (Test *test,
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, filter);
- g_hash_table_unref (filter);
-
- tp_base_client_take_handler_filter (test->base_client, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL));
+ 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);
@@ -1028,13 +1016,12 @@ test_handler_requests (Test *test,
GHashTable *info;
TpChannelRequest *request;
GList *requests;
+ TpChannelFilter *filter;
- tp_base_client_take_handler_filter (test->base_client, tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL));
+ 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);