diff options
Diffstat (limited to 'qt4/tests/lib/glib/contact-search-chan.c')
-rw-r--r-- | qt4/tests/lib/glib/contact-search-chan.c | 708 |
1 files changed, 708 insertions, 0 deletions
diff --git a/qt4/tests/lib/glib/contact-search-chan.c b/qt4/tests/lib/glib/contact-search-chan.c new file mode 100644 index 000000000..0002acacd --- /dev/null +++ b/qt4/tests/lib/glib/contact-search-chan.c @@ -0,0 +1,708 @@ +/* + * contact-search-channel.c - an tp_tests contact search channel + * + * Copyright © 2010 Collabora Ltd. <http://www.collabora.co.uk/> + * Copyright © 2010 Nokia Corporation + * + * 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 "contact-search-chan.h" + +#include <string.h> + +#include <gobject/gvaluecollector.h> + +#include <telepathy-glib/channel-iface.h> +#include <telepathy-glib/dbus.h> +#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/svc-channel.h> +#include <telepathy-glib/svc-properties-interface.h> + +static void contact_search_iface_init (gpointer iface, gpointer data); +static void channel_iface_init (gpointer iface, gpointer data); + +G_DEFINE_TYPE_WITH_CODE (TpTestsContactSearchChannel, + tp_tests_contact_search_channel, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, + tp_dbus_properties_mixin_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_CONTACT_SEARCH, + contact_search_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP, + tp_group_mixin_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL); + G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL)) + +enum +{ + PROP_OBJECT_PATH = 1, + PROP_CHANNEL_TYPE, + PROP_HANDLE_TYPE, + PROP_HANDLE, + PROP_TARGET_ID, + PROP_REQUESTED, + PROP_INITIATOR_HANDLE, + PROP_INITIATOR_ID, + PROP_CONNECTION, + PROP_INTERFACES, + PROP_CHANNEL_DESTROYED, + PROP_CHANNEL_PROPERTIES, + PROP_CONTACT_SEARCH_STATE, + PROP_CONTACT_SEARCH_LIMIT, + PROP_CONTACT_SEARCH_AVAILABLE_SEARCH_KEYS, + PROP_CONTACT_SEARCH_SERVER, + N_PROPS +}; + +typedef struct +{ + gchar *id; + gchar *employer; + GPtrArray *contact_info; +} TpTestsContactSearchContact; + +struct _TpTestsContactSearchChannelPrivate +{ + TpBaseConnection *conn; + gchar *object_path; + + guint contact_search_state; + guint contact_search_limit; + gchar **contact_search_available_search_keys; + gchar *contact_search_server; + + GSList *contact_search_contacts; + + gboolean disposed; + gboolean closed; +}; + +static const gchar * tp_tests_contact_search_channel_interfaces[] = { + TP_IFACE_CHANNEL_INTERFACE_GROUP, + NULL +}; + +static void +tp_tests_contact_search_channel_init (TpTestsContactSearchChannel *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL, + TpTestsContactSearchChannelPrivate); +} + +static TpTestsContactSearchContact * +new_contact (const gchar *id, const gchar *employer, const gchar *fn) +{ + TpTestsContactSearchContact *contact = g_new (TpTestsContactSearchContact, 1); + GPtrArray *contact_info = dbus_g_type_specialized_construct ( + TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST); + const gchar * const field_values[2] = { fn, NULL }; + + contact->id = g_strdup (id); + contact->employer = g_strdup (employer); + + g_ptr_array_add (contact_info, tp_value_array_build (3, + G_TYPE_STRING, "fn", + G_TYPE_STRV, NULL, + G_TYPE_STRV, field_values, + G_TYPE_INVALID)); + + contact->contact_info = contact_info; + + return contact; +} + +static void +free_contact (TpTestsContactSearchContact *contact) +{ + g_free (contact->id); + g_free (contact->employer); + g_boxed_free (TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, contact->contact_info); + g_free (contact); +} + +static void +constructed (GObject *object) +{ + void (*chain_up) (GObject *) = + ((GObjectClass *) tp_tests_contact_search_channel_parent_class)->constructed; + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object); + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles + (self->priv->conn, TP_HANDLE_TYPE_CONTACT); + TpDBusDaemon *bus; + + if (chain_up != NULL) + { + chain_up (object); + } + + bus = tp_dbus_daemon_dup (NULL); + tp_dbus_daemon_register_object (bus, self->priv->object_path, object); + + tp_group_mixin_init (object, + G_STRUCT_OFFSET (TpTestsContactSearchChannel, group), + contact_repo, self->priv->conn->self_handle); + + self->priv->contact_search_state = TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED; + self->priv->contact_search_limit = 0; + self->priv->contact_search_available_search_keys = g_new0 (gchar *, 2); + self->priv->contact_search_available_search_keys[0] = g_strdup ("employer"); + self->priv->contact_search_server = g_strdup ("characters.shakespeare.lit"); + + self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts, + new_contact ("oggis", "Collabora", "Olli Salli")); + self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts, + new_contact ("andrunko", "Collabora", "Andre Moreira Magalhaes")); + self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts, + new_contact ("wjt", "Collabora", "Will Thompson")); + + self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts, + new_contact ("foo", "Other Employer", "Foo")); + self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts, + new_contact ("bar", "Other Employer", "Bar")); +} + +static void +get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object); + + switch (property_id) + { + case PROP_OBJECT_PATH: + g_value_set_string (value, self->priv->object_path); + break; + + case PROP_CHANNEL_TYPE: + g_value_set_static_string (value, TP_IFACE_CHANNEL); + break; + + case PROP_HANDLE_TYPE: + g_value_set_uint (value, TP_HANDLE_TYPE_NONE); + break; + + case PROP_HANDLE: + g_value_set_uint (value, 0); + break; + + case PROP_TARGET_ID: + g_value_set_string (value, ""); + break; + + case PROP_REQUESTED: + g_value_set_boolean (value, TRUE); + break; + + case PROP_INITIATOR_HANDLE: + g_value_set_uint (value, 0); + break; + + case PROP_INITIATOR_ID: + g_value_set_string (value, ""); + break; + + case PROP_CONNECTION: + g_value_set_object (value, self->priv->conn); + break; + + case PROP_INTERFACES: + g_value_set_boxed (value, tp_tests_contact_search_channel_interfaces); + break; + + case PROP_CHANNEL_DESTROYED: + g_value_set_boolean (value, self->priv->closed); + break; + + case PROP_CHANNEL_PROPERTIES: + g_value_take_boxed (value, + tp_dbus_properties_mixin_make_properties_hash (object, + TP_IFACE_CHANNEL, "ChannelType", + TP_IFACE_CHANNEL, "TargetHandleType", + TP_IFACE_CHANNEL, "TargetHandle", + TP_IFACE_CHANNEL, "TargetID", + TP_IFACE_CHANNEL, "InitiatorHandle", + TP_IFACE_CHANNEL, "InitiatorID", + TP_IFACE_CHANNEL, "Requested", + TP_IFACE_CHANNEL, "Interfaces", + TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "SearchState", + TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "Limit", + TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "AvailableSearchKeys", + TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "Server", + NULL)); + break; + + case PROP_CONTACT_SEARCH_STATE: + g_value_set_uint (value, self->priv->contact_search_state); + g_assert (G_VALUE_HOLDS (value, G_TYPE_UINT)); + break; + + case PROP_CONTACT_SEARCH_LIMIT: + g_value_set_uint (value, self->priv->contact_search_limit); + g_assert (G_VALUE_HOLDS (value, G_TYPE_UINT)); + break; + + case PROP_CONTACT_SEARCH_AVAILABLE_SEARCH_KEYS: + g_value_set_boxed (value, self->priv->contact_search_available_search_keys); + g_assert (G_VALUE_HOLDS (value, G_TYPE_STRV)); + break; + + case PROP_CONTACT_SEARCH_SERVER: + g_value_set_string (value, self->priv->contact_search_server); + g_assert (G_VALUE_HOLDS (value, G_TYPE_STRING)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object); + + switch (property_id) + { + case PROP_OBJECT_PATH: + self->priv->object_path = g_value_dup_string (value); + break; + + case PROP_CONNECTION: + self->priv->conn = g_value_get_object (value); + break; + + case PROP_CHANNEL_TYPE: + case PROP_HANDLE: + case PROP_HANDLE_TYPE: + case PROP_TARGET_ID: + case PROP_REQUESTED: + case PROP_INITIATOR_HANDLE: + case PROP_INITIATOR_ID: + /* these properties are not actually meaningfully changeable on this + * channel, so we do nothing */ + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object); + GSList *l; + + if (self->priv->disposed) + { + return; + } + + self->priv->disposed = TRUE; + + g_strfreev (self->priv->contact_search_available_search_keys); + self->priv->contact_search_available_search_keys = NULL; + g_free (self->priv->contact_search_server); + self->priv->contact_search_server = NULL; + + for (l = self->priv->contact_search_contacts; l != NULL; l = g_slist_next (l)) + { + free_contact ((TpTestsContactSearchContact *) l->data); + } + g_slist_free (self->priv->contact_search_contacts); + + if (!self->priv->closed) + { + self->priv->closed = TRUE; + tp_svc_channel_emit_closed (self); + } + + ((GObjectClass *) tp_tests_contact_search_channel_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object); + + g_free (self->priv->object_path); + + tp_group_mixin_finalize (object); + + ((GObjectClass *) tp_tests_contact_search_channel_parent_class)->finalize (object); +} + +static void +tp_tests_contact_search_channel_class_init (TpTestsContactSearchChannelClass *klass) +{ + static TpDBusPropertiesMixinPropImpl channel_props[] = { + { "TargetHandleType", "handle-type", NULL }, + { "TargetHandle", "handle", NULL }, + { "ChannelType", "channel-type", NULL }, + { "Interfaces", "interfaces", NULL }, + { "TargetID", "target-id", NULL }, + { "Requested", "requested", NULL }, + { "InitiatorHandle", "initiator-handle", NULL }, + { "InitiatorID", "initiator-id", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinPropImpl contact_search_props[] = { + { "SearchState", "search-state", NULL }, + { "Limit", "limit", NULL }, + { "AvailableSearchKeys", "available-search-keys", NULL }, + { "Server", "server", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { + { TP_IFACE_CHANNEL, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + channel_props, + }, + { TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + contact_search_props, + }, + { NULL } + }; + GObjectClass *object_class = (GObjectClass *) klass; + GParamSpec *param_spec; + + g_type_class_add_private (klass, + sizeof (TpTestsContactSearchChannelPrivate)); + + object_class->constructed = constructed; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + g_object_class_override_property (object_class, PROP_OBJECT_PATH, + "object-path"); + g_object_class_override_property (object_class, PROP_CHANNEL_TYPE, + "channel-type"); + g_object_class_override_property (object_class, PROP_HANDLE_TYPE, + "handle-type"); + g_object_class_override_property (object_class, PROP_HANDLE, + "handle"); + g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED, + "channel-destroyed"); + g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES, + "channel-properties"); + + param_spec = g_param_spec_object ("connection", "TpBaseConnection object", + "Connection object that owns this channel", + TP_TYPE_BASE_CONNECTION, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CONNECTION, param_spec); + + param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces", + "Additional Channel.Interface.* interfaces", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INTERFACES, param_spec); + + param_spec = g_param_spec_string ("target-id", "Peer's ID", + "The string obtained by inspecting the target handle", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec); + + param_spec = g_param_spec_uint ("initiator-handle", "Initiator's handle", + "The contact who initiated the channel", + 0, G_MAXUINT32, 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INITIATOR_HANDLE, + param_spec); + + param_spec = g_param_spec_string ("initiator-id", "Initiator's ID", + "The string obtained by inspecting the initiator-handle", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INITIATOR_ID, + param_spec); + + param_spec = g_param_spec_boolean ("requested", "Requested?", + "True if this channel was requested by the local user", + FALSE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_REQUESTED, param_spec); + + param_spec = g_param_spec_uint ("search-state", "Search state", + "The search state", + 0, NUM_TP_CHANNEL_CONTACT_SEARCH_STATES, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_STATE, + param_spec); + + param_spec = g_param_spec_uint ("limit", "Search limit", + "The search limit", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_LIMIT, + param_spec); + + param_spec = g_param_spec_boxed ("available-search-keys", "Available Search Keys", + "The available search keys", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_AVAILABLE_SEARCH_KEYS, param_spec); + + param_spec = g_param_spec_string ("server", "Server", + "The search server", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_SERVER, + param_spec); + + klass->dbus_properties_class.interfaces = prop_interfaces; + tp_dbus_properties_mixin_class_init (object_class, + G_STRUCT_OFFSET (TpTestsContactSearchChannelClass, + dbus_properties_class)); + + tp_group_mixin_class_init (object_class, + G_STRUCT_OFFSET (TpTestsContactSearchChannelClass, group_class), + NULL, NULL); + tp_group_mixin_init_dbus_properties (object_class); +} + +static void +channel_close (TpSvcChannel *iface, + DBusGMethodInvocation *context) +{ + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (iface); + + if (!self->priv->closed) + { + self->priv->closed = TRUE; + tp_svc_channel_emit_closed (self); + } + + tp_svc_channel_return_from_close (context); +} + +static void +channel_get_channel_type (TpSvcChannel *iface G_GNUC_UNUSED, + DBusGMethodInvocation *context) +{ + tp_svc_channel_return_from_get_channel_type (context, + TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH); +} + +static void +channel_get_handle (TpSvcChannel *iface, + DBusGMethodInvocation *context) +{ + tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_NONE, 0); +} + +static void +channel_get_interfaces (TpSvcChannel *iface G_GNUC_UNUSED, + DBusGMethodInvocation *context) +{ + tp_svc_channel_return_from_get_interfaces (context, + tp_tests_contact_search_channel_interfaces); +} + +static void +channel_iface_init (gpointer iface, + gpointer data) +{ + TpSvcChannelClass *klass = iface; + +#define IMPLEMENT(x) tp_svc_channel_implement_##x (klass, channel_##x) + IMPLEMENT (close); + IMPLEMENT (get_channel_type); + IMPLEMENT (get_handle); + IMPLEMENT (get_interfaces); +#undef IMPLEMENT +} + +static void +change_search_state (TpTestsContactSearchChannel *self, + guint state, + const gchar *debug_message) +{ + GHashTable *details = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, (GDestroyNotify) tp_g_value_slice_free); + + g_hash_table_insert (details, "debug-message", tp_g_value_slice_new_string (debug_message)); + + self->priv->contact_search_state = state; + tp_svc_channel_type_contact_search_emit_search_state_changed (self, + self->priv->contact_search_state, "", details); + + g_hash_table_destroy (details); +} + +static gboolean +validate_terms (TpTestsContactSearchChannel *self, + GHashTable *terms, + GError **error) +{ + const gchar * const *asks = + (const gchar * const *) self->priv->contact_search_available_search_keys; + GHashTableIter iter; + gpointer key; + + g_hash_table_iter_init (&iter, terms); + + while (g_hash_table_iter_next (&iter, &key, NULL)) + { + gchar *field = key; + + if (!tp_strv_contains (asks, field)) + { + g_debug ("%s is not in AvailableSearchKeys", field); + g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + "%s is not in AvailableSearchKeys", field); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +do_search (TpTestsContactSearchChannel *self, + GHashTable *terms, + GError **error) +{ + GHashTable *results = g_hash_table_new (g_str_hash, g_str_equal); + GHashTableIter iter; + gchar *key, *value; + + if (!validate_terms (self, terms, error)) + { + return FALSE; + } + + g_debug ("Doing search"); + change_search_state (self, TP_CHANNEL_CONTACT_SEARCH_STATE_IN_PROGRESS, "in progress"); + + g_hash_table_iter_init (&iter, terms); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) + { + GSList *l; + + for (l = self->priv->contact_search_contacts; l != NULL; l = g_slist_next (l)) + { + TpTestsContactSearchContact *contact = (TpTestsContactSearchContact *) l->data; + if (strcmp (contact->employer, value) == 0) + { + g_hash_table_insert (results, contact->id, contact->contact_info); + } + } + } + + tp_svc_channel_type_contact_search_emit_search_result_received (self, + results); + + change_search_state (self, TP_CHANNEL_CONTACT_SEARCH_STATE_COMPLETED, "completed"); + + g_hash_table_destroy (results); + + return TRUE; +} + +static void +contact_search_search (TpSvcChannelTypeContactSearch *iface G_GNUC_UNUSED, + GHashTable *terms, + DBusGMethodInvocation *context) +{ + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (iface); + TpTestsContactSearchChannelPrivate *priv = self->priv; + GError *error = NULL; + + if (priv->contact_search_state != TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED) + { + g_debug ("Search state is %d", priv->contact_search_state); + error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + "SearchState is %d", priv->contact_search_state); + goto err; + } + + if (do_search (self, terms, &error)) + { + tp_svc_channel_type_contact_search_return_from_search (context); + return; + } + +err: + dbus_g_method_return_error (context, error); + g_error_free (error); +} + +static void +contact_search_more (TpSvcChannelTypeContactSearch *iface G_GNUC_UNUSED, + DBusGMethodInvocation *context) +{ + tp_svc_channel_type_contact_search_return_from_more (context); +} + +static void +contact_search_stop (TpSvcChannelTypeContactSearch *iface, + DBusGMethodInvocation *context) +{ + TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (iface); + TpTestsContactSearchChannelPrivate *priv = self->priv; + + switch (priv->contact_search_state) + { + case TP_CHANNEL_CONTACT_SEARCH_STATE_IN_PROGRESS: + change_search_state (self, + TP_CHANNEL_CONTACT_SEARCH_STATE_FAILED, "stopped while in progress"); + case TP_CHANNEL_CONTACT_SEARCH_STATE_COMPLETED: + tp_svc_channel_type_contact_search_return_from_stop (context); + break; + case TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED: + { + GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + "Search() hasn't been called yet" }; + + g_debug ("%s", e.message); + dbus_g_method_return_error (context, &e); + break; + } + case TP_CHANNEL_CONTACT_SEARCH_STATE_FAILED: + case TP_CHANNEL_CONTACT_SEARCH_STATE_MORE_AVAILABLE: + g_assert_not_reached (); + } +} + +static void +contact_search_iface_init (gpointer iface, + gpointer data) +{ + TpSvcChannelTypeContactSearchClass *klass = iface; + +#define IMPLEMENT(x) tp_svc_channel_type_contact_search_implement_##x (klass, contact_search_##x) + IMPLEMENT (search); + IMPLEMENT (more); + IMPLEMENT (stop); +#undef IMPLEMENT +} |