aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy/empathy-dispatcher.c124
-rw-r--r--libempathy/empathy-dispatcher.h6
-rw-r--r--libempathy/empathy-ft-handler.c146
-rw-r--r--libempathy/empathy-tp-chat.c24
-rw-r--r--src/empathy-chat-manager.c8
-rw-r--r--src/empathy-event-manager.c4
6 files changed, 101 insertions, 211 deletions
diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c
index 2a009b34a..558767751 100644
--- a/libempathy/empathy-dispatcher.c
+++ b/libempathy/empathy-dispatcher.c
@@ -59,7 +59,6 @@ typedef struct
GHashTable *connections;
GHashTable *outstanding_classes_requests;
- GHashTable *request_channel_class_async_ids;
/* reffed (TpAccount *) => gulong
* Signal handler ID of the "status-changed" signal */
GHashTable *status_changed_handlers;
@@ -262,17 +261,6 @@ dispatcher_status_changed_cb (TpAccount *account,
dispatcher_init_connection_if_needed (self, conn);
}
-static void
-remove_idle_handlers (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- guint source_id;
-
- source_id = GPOINTER_TO_UINT (value);
- g_source_remove (source_id);
-}
-
static GObject *
dispatcher_constructor (GType type,
guint n_construct_params,
@@ -329,13 +317,6 @@ dispatcher_finalize (GObject *object)
GList *list;
gpointer account, id;
- if (priv->request_channel_class_async_ids != NULL)
- {
- g_hash_table_foreach (priv->request_channel_class_async_ids,
- remove_idle_handlers, NULL);
- g_hash_table_destroy (priv->request_channel_class_async_ids);
- }
-
g_hash_table_iter_init (&iter, priv->outstanding_classes_requests);
while (g_hash_table_iter_next (&iter, &connection, (gpointer *) &list))
{
@@ -473,8 +454,6 @@ empathy_dispatcher_init (EmpathyDispatcher *self)
"account-validity-changed", G_CALLBACK (account_validity_changed_cb),
self, 0);
- priv->request_channel_class_async_ids = g_hash_table_new (g_direct_hash,
- g_direct_equal);
priv->status_changed_handlers = g_hash_table_new_full (NULL, NULL,
(GDestroyNotify) g_object_unref, NULL);
}
@@ -679,48 +658,6 @@ empathy_dispatcher_find_channel_classes (EmpathyDispatcher *self,
return matching_classes;
}
-static gboolean
-find_channel_class_idle_cb (gpointer user_data)
-{
- GList *retval;
- GList *requests;
- FindChannelRequest *request = user_data;
- ConnectionData *cd;
- gboolean is_ready = TRUE;
- EmpathyDispatcherPriv *priv = GET_PRIV (request->dispatcher);
-
- g_hash_table_remove (priv->request_channel_class_async_ids, request);
-
- cd = g_hash_table_lookup (priv->connections, request->connection);
-
- if (cd == NULL)
- is_ready = FALSE;
- else if (cd->requestable_channels == NULL)
- is_ready = FALSE;
-
- if (is_ready)
- {
- retval = empathy_dispatcher_find_channel_classes (request->dispatcher,
- request->connection, request->channel_type, request->handle_type,
- request->properties);
-
- request->callback (retval, request->user_data);
- free_find_channel_request (request);
- g_list_free (retval);
-
- return FALSE;
- }
-
- requests = g_hash_table_lookup (priv->outstanding_classes_requests,
- request->connection);
- requests = g_list_prepend (requests, request);
-
- g_hash_table_insert (priv->outstanding_classes_requests,
- request->connection, requests);
-
- return FALSE;
-}
-
static GArray *
setup_varargs (va_list var_args,
const char *channel_namespace,
@@ -822,64 +759,3 @@ empathy_dispatcher_find_requestable_channel_classes
return retval;
}
-
-/**
- * empathy_dispatcher_find_requestable_channel_classes_async:
- * @dispatcher: an #EmpathyDispatcher
- * @connection: a #TpConnection
- * @channel_type: a string identifying the type of the channel to lookup
- * @handle_type: the handle type for the channel
- * @callback: the callback to call when @connection is ready
- * @user_data: the user data to pass to @callback
- * @first_property_name: %NULL, or the name of the first fixed property,
- * followed optionally by more names, followed by %NULL.
- *
- * Please see the documentation of
- * empathy_dispatcher_find_requestable_channel_classes() for a detailed
- * description of this function.
- */
-void
-empathy_dispatcher_find_requestable_channel_classes_async
- (EmpathyDispatcher *self,
- TpConnection *connection,
- const gchar *channel_type,
- guint handle_type,
- EmpathyDispatcherFindChannelClassCb callback,
- gpointer user_data,
- const char *first_property_name,
- ...)
-{
- va_list var_args;
- GArray *properties;
- FindChannelRequest *request;
- EmpathyDispatcherPriv *priv;
- guint source_id;
-
- g_return_if_fail (EMPATHY_IS_DISPATCHER (self));
- g_return_if_fail (TP_IS_CONNECTION (connection));
- g_return_if_fail (channel_type != NULL);
- g_return_if_fail (handle_type != 0);
-
- priv = GET_PRIV (self);
-
- va_start (var_args, first_property_name);
-
- properties = setup_varargs (var_args, channel_type, first_property_name);
-
- va_end (var_args);
-
- /* append another request for this connection */
- request = g_slice_new0 (FindChannelRequest);
- request->dispatcher = g_object_ref (self);
- request->channel_type = g_strdup (channel_type);
- request->handle_type = handle_type;
- request->connection = connection;
- request->callback = callback;
- request->user_data = user_data;
- request->properties = properties;
-
- source_id = g_idle_add (find_channel_class_idle_cb, request);
-
- g_hash_table_insert (priv->request_channel_class_async_ids,
- request, GUINT_TO_POINTER (source_id));
-}
diff --git a/libempathy/empathy-dispatcher.h b/libempathy/empathy-dispatcher.h
index cd54fa5d1..2f786db7a 100644
--- a/libempathy/empathy-dispatcher.h
+++ b/libempathy/empathy-dispatcher.h
@@ -70,12 +70,6 @@ void empathy_dispatcher_join_muc (TpAccount *account,
const gchar *roomname,
gint64 timestamp);
-void empathy_dispatcher_find_requestable_channel_classes_async
- (EmpathyDispatcher *dispatcher, TpConnection *connection,
- const gchar *channel_type, guint handle_type,
- EmpathyDispatcherFindChannelClassCb callback, gpointer user_data,
- const char *first_property_name, ...);
-
GList * empathy_dispatcher_find_requestable_channel_classes
(EmpathyDispatcher *dispatcher, TpConnection *connection,
const gchar *channel_type, guint handle_type,
diff --git a/libempathy/empathy-ft-handler.c b/libempathy/empathy-ft-handler.c
index f18278a71..9b77abffd 100644
--- a/libempathy/empathy-ft-handler.c
+++ b/libempathy/empathy-ft-handler.c
@@ -773,46 +773,26 @@ static void
ft_handler_populate_outgoing_request (EmpathyFTHandler *handler)
{
guint contact_handle;
- GHashTable *request;
- GValue *value;
EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
- request = priv->request = g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL, (GDestroyNotify) tp_g_value_slice_free);
-
contact_handle = empathy_contact_get_handle (priv->contact);
- /* org.freedesktop.Telepathy.Channel.ChannelType */
- value = tp_g_value_slice_new_string (TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER);
- g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value);
-
- /* org.freedesktop.Telepathy.Channel.TargetHandleType */
- value = tp_g_value_slice_new_uint (TP_HANDLE_TYPE_CONTACT);
- g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value);
-
- /* org.freedesktop.Telepathy.Channel.TargetHandle */
- value = tp_g_value_slice_new_uint (contact_handle);
- g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);
-
- /* org.freedesktop.Telepathy.Channel.Type.FileTransfer.ContentType */
- value = tp_g_value_slice_new_string (priv->content_type);
- g_hash_table_insert (request,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".ContentType", value);
-
- /* org.freedesktop.Telepathy.Channel.Type.FileTransfer.Filename */
- value = tp_g_value_slice_new_string (priv->filename);
- g_hash_table_insert (request,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".Filename", value);
-
- /* org.freedesktop.Telepathy.Channel.Type.FileTransfer.Size */
- value = tp_g_value_slice_new_uint64 (priv->total_bytes);
- g_hash_table_insert (request,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".Size", value);
-
- /* org.freedesktop.Telepathy.Channel.Type.FileTransfer.Date */
- value = tp_g_value_slice_new_uint64 ((guint64) priv->mtime);
- g_hash_table_insert (request,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".Date", value);
+ priv->request = 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_TARGET_HANDLE, G_TYPE_UINT,
+ contact_handle,
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE, G_TYPE_STRING,
+ priv->content_type,
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME, G_TYPE_STRING,
+ priv->filename,
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, G_TYPE_UINT64,
+ priv->total_bytes,
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DATE, G_TYPE_UINT64,
+ priv->mtime,
+ NULL);
}
static gboolean
@@ -822,7 +802,6 @@ hash_job_done (gpointer user_data)
EmpathyFTHandler *handler = hash_data->handler;
EmpathyFTHandlerPriv *priv;
GError *error = NULL;
- GValue *value;
DEBUG ("Closing stream after hashing.");
@@ -864,10 +843,9 @@ hash_job_done (gpointer user_data)
/* set the checksum in the request...
* org.freedesktop.Telepathy.Channel.Type.FileTransfer.ContentHash
*/
- value = tp_g_value_slice_new_string
- (g_checksum_get_string (hash_data->checksum));
- g_hash_table_insert (priv->request,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".ContentHash", value);
+ tp_asv_set_string (priv->request,
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH,
+ g_checksum_get_string (hash_data->checksum));
}
cleanup:
@@ -987,7 +965,6 @@ ft_handler_read_async_cb (GObject *source,
GFileInputStream *stream;
GError *error = NULL;
HashingData *hash_data;
- GValue *value;
EmpathyFTHandler *handler = user_data;
EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
@@ -1009,10 +986,9 @@ ft_handler_read_async_cb (GObject *source,
/* FIXME: MD5 is the only ContentHashType supported right now */
hash_data->checksum = g_checksum_new (G_CHECKSUM_MD5);
- /* org.freedesktop.Telepathy.Channel.Type.FileTransfer.ContentHashType */
- value = tp_g_value_slice_new_uint (TP_FILE_HASH_TYPE_MD5);
- g_hash_table_insert (priv->request,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".ContentHashType", value);
+ tp_asv_set_uint32 (priv->request,
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH_TYPE,
+ TP_FILE_HASH_TYPE_MD5);
g_signal_emit (handler, signals[HASHING_STARTED], 0);
@@ -1031,35 +1007,53 @@ callbacks_data_free (gpointer user_data)
g_slice_free (CallbacksData, data);
}
-static void
+static gboolean
set_content_hash_type_from_classes (EmpathyFTHandler *handler,
- GList *classes)
+ GPtrArray *classes)
{
- GValueArray *class;
- GValue *v;
- GList *l;
GArray *possible_values;
guint value;
- GHashTable *fprops;
gboolean valid;
EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
+ gboolean support_ft = FALSE;
+ guint i;
possible_values = g_array_new (TRUE, TRUE, sizeof (guint));
- for (l = classes; l != NULL; l = l->next)
+ for (i = 0; i < classes->len; i++)
{
- class = l->data;
- v = g_value_array_get_nth (class, 0);
- fprops = g_value_get_boxed (v);
+ GHashTable *fixed;
+ GStrv allowed;
+ const gchar *chan_type;
+
+ tp_value_array_unpack (g_ptr_array_index (classes, i), 2,
+ &fixed, &allowed);
+
+ chan_type = tp_asv_get_string (fixed, TP_PROP_CHANNEL_CHANNEL_TYPE);
+
+ if (tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER))
+ continue;
+
+ if (tp_asv_get_uint32 (fixed, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) !=
+ TP_HANDLE_TYPE_CONTACT)
+ continue;
+
+ support_ft = TRUE;
value = tp_asv_get_uint32
- (fprops, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".ContentHashType",
+ (fixed, TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH_TYPE,
&valid);
if (valid)
g_array_append_val (possible_values, value);
}
+ if (!support_ft)
+ {
+ g_array_free (possible_values, TRUE);
+ return FALSE;
+ }
+
if (possible_values->len == 0)
{
/* there are no channel classes with hash support, disable it. */
@@ -1093,18 +1087,35 @@ out:
DEBUG ("Hash enabled %s; setting content hash type as %u",
priv->use_hash ? "True" : "False", priv->content_hash_type);
+
+ return TRUE;
}
static void
-find_ft_channel_classes_cb (GList *channel_classes,
+conn_prepared_cb (GObject *conn,
+ GAsyncResult *result,
gpointer user_data)
{
CallbacksData *data = user_data;
EmpathyFTHandler *handler = data->handler;
EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
GError *myerr = NULL;
+ TpCapabilities *caps;
+ GPtrArray *classes;
- if (channel_classes == NULL)
+ if (!tp_proxy_prepare_finish (conn, result, &myerr))
+ {
+ DEBUG ("Failed to prepare connection: %s", myerr->message);
+
+ data->callback (handler, myerr, data->user_data);
+ goto out;
+ }
+
+ caps = tp_connection_get_capabilities (TP_CONNECTION (conn));
+ classes = tp_capabilities_get_channel_classes (caps);
+
+ /* set whether we support hash and the type of it */
+ if (!set_content_hash_type_from_classes (handler, classes))
{
g_set_error_literal (&myerr, EMPATHY_FT_ERROR_QUARK,
EMPATHY_FT_ERROR_NOT_SUPPORTED,
@@ -1118,13 +1129,11 @@ find_ft_channel_classes_cb (GList *channel_classes,
}
else
{
- /* set whether we support hash and the type of it */
- set_content_hash_type_from_classes (handler, channel_classes);
-
/* get back to the caller now */
data->callback (handler, NULL, data->user_data);
}
+out:
callbacks_data_free (data);
}
@@ -1202,11 +1211,14 @@ out:
else
{
/* see if FT/hashing are allowed */
- empathy_dispatcher_find_requestable_channel_classes_async
- (priv->dispatcher, empathy_contact_get_connection (priv->contact),
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, TP_HANDLE_TYPE_CONTACT,
- find_ft_channel_classes_cb, cb_data,
- TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".ContentHashType", NULL);
+ TpConnection *connection;
+ GQuark features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 };
+
+ connection = empathy_contact_get_connection (priv->contact);
+ g_assert (connection != NULL);
+
+ tp_proxy_prepare_async (connection, features,
+ conn_prepared_cb, cb_data);
}
}
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index c1e911e65..f1351049a 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -30,7 +30,6 @@
#include "empathy-tp-chat.h"
#include "empathy-tp-contact-factory.h"
#include "empathy-contact-list.h"
-#include "empathy-dispatcher.h"
#include "empathy-marshal.h"
#include "empathy-time.h"
#include "empathy-utils.h"
@@ -1272,6 +1271,9 @@ tp_chat_constructor (GType type,
G_CALLBACK (tp_chat_invalidated_cb),
chat, 0);
+ g_assert (tp_proxy_is_prepared (priv->connection,
+ TP_CONNECTION_FEATURE_CAPABILITIES));
+
if (tp_proxy_has_interface_by_id (priv->channel,
TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) {
const TpIntSet *members;
@@ -1295,8 +1297,9 @@ tp_chat_constructor (GType type,
tp_g_signal_connect_object (priv->channel, "group-members-changed",
G_CALLBACK (tp_chat_group_members_changed_cb), chat, 0);
} else {
- EmpathyDispatcher *dispatcher = empathy_dispatcher_dup_singleton ();
- GList *list, *ptr;
+ TpCapabilities *caps;
+ GPtrArray *classes;
+ guint i;
/* Get the self contact from the connection's self handle */
handle = tp_connection_get_self_handle (priv->connection);
@@ -1310,13 +1313,13 @@ tp_chat_constructor (GType type,
handle, tp_chat_got_remote_contact_cb,
NULL, NULL, chat);
- list = empathy_dispatcher_find_requestable_channel_classes (
- dispatcher, priv->connection,
- tp_channel_get_channel_type (priv->channel),
- TP_UNKNOWN_HANDLE_TYPE, NULL);
+ caps = tp_connection_get_capabilities (priv->connection);
+ g_assert (caps != NULL);
+
+ classes = tp_capabilities_get_channel_classes (caps);
- for (ptr = list; ptr; ptr = ptr->next) {
- GValueArray *array = ptr->data;
+ for (i = 0; i < classes->len; i++) {
+ GValueArray *array = g_ptr_array_index (classes, i);
const char **oprops = g_value_get_boxed (
g_value_array_get_nth (array, 1));
@@ -1325,9 +1328,6 @@ tp_chat_constructor (GType type,
break;
}
}
-
- g_list_free (list);
- g_object_unref (dispatcher);
}
if (tp_proxy_has_interface_by_id (priv->channel,
diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c
index cfa38ec84..d16be299d 100644
--- a/src/empathy-chat-manager.c
+++ b/src/empathy-chat-manager.c
@@ -255,8 +255,12 @@ empathy_chat_manager_init (EmpathyChatManager *self)
}
/* Text channels handler */
- priv->handler = tp_simple_handler_new (dbus, FALSE, FALSE, "Empathy", FALSE,
- handle_channels, self, NULL);
+ priv->handler = tp_simple_handler_new (dbus, FALSE, FALSE, "Empathy",
+ FALSE, handle_channels, self, NULL);
+
+ /* EmpathyTpChat relies on this feature being prepared */
+ tp_base_client_add_connection_features_varargs (priv->handler,
+ TP_CONNECTION_FEATURE_CAPABILITIES, 0);
g_object_unref (dbus);
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c
index fdd0672ee..0216eeab4 100644
--- a/src/empathy-event-manager.c
+++ b/src/empathy-event-manager.c
@@ -1206,6 +1206,10 @@ empathy_event_manager_init (EmpathyEventManager *manager)
priv->approver = tp_simple_approver_new (dbus, "Empathy.EventManager", FALSE,
approve_channels, manager, NULL);
+ /* EmpathyTpChat relies on this feature being prepared */
+ tp_base_client_add_connection_features_varargs (priv->approver,
+ TP_CONNECTION_FEATURE_CAPABILITIES, 0);
+
/* Private text channels */
tp_base_client_take_approver_filter (priv->approver,
tp_asv_new (