summaryrefslogtreecommitdiff
path: root/telepathy-glib/contact.c
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.co.uk>2012-05-08 15:27:39 +0200
committerXavier Claessens <xavier.claessens@collabora.co.uk>2012-05-09 14:59:35 +0200
commitac3538ae8029988458947efda467bc035cf3d3c8 (patch)
tree1303349872335e3af30eede548f061a2c574e5ab /telepathy-glib/contact.c
parent89ee88d7a534502f6dc73653f4407098eb835d3f (diff)
downloadtelepathy-glib-ac3538ae8029988458947efda467bc035cf3d3c8.tar.gz
Add tp_connection_upgrade_contacts_async/finish
This replaces tp_connection_upgrade_contacts() but with a proper async API.
Diffstat (limited to 'telepathy-glib/contact.c')
-rw-r--r--telepathy-glib/contact.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c
index 56ec9f4d5..dc7bca045 100644
--- a/telepathy-glib/contact.c
+++ b/telepathy-glib/contact.c
@@ -4766,6 +4766,163 @@ tp_connection_dup_contact_by_id_finish (TpConnection *self,
tp_connection_dup_contact_by_id_async, g_object_ref);
}
+static void
+got_contact_attributes_cb (TpConnection *self,
+ GHashTable *attributes,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ ContactsAsyncData *data = user_data;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (error != NULL)
+ {
+ g_simple_async_result_set_from_error (data->result, error);
+ g_simple_async_result_complete_in_idle (data->result);
+ return;
+ }
+
+ g_hash_table_iter_init (&iter, attributes);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ TpHandle handle = GPOINTER_TO_UINT (key);
+ GHashTable *asv = value;
+ TpContact *contact;
+
+ /* set up the contact with its attributes */
+ contact = tp_contact_ensure (self, handle);
+ tp_contact_set_attributes (contact, asv, data->features, NULL);
+ g_object_unref (contact);
+ }
+
+ g_simple_async_result_complete (data->result);
+}
+
+/**
+ * tp_connection_upgrade_contacts_async:
+ * @self: A connection, which must have the %TP_CONNECTION_FEATURE_CONNECTED
+ * feature prepared
+ * @n_contacts: The number of contacts in @contacts (must be at least 1)
+ * @contacts: (array length=n_contacts): An array of #TpContact objects
+ * associated with @self
+ * @n_features: The number of features in @features (must be at least 1)
+ * @features: (array length=n_features): An array of features that must be
+ * ready for use (if supported) before the callback is called
+ * @callback: A user callback to call when the contacts are ready
+ * @user_data: Data to pass to the callback
+ *
+ * Given several #TpContact objects, make asynchronous method calls
+ * ensure that all the features specified in @features are ready for use
+ * (if they are supported at all).
+ *
+ * It is not an error to put features in @features even if the connection
+ * manager doesn't support them - users of this method should have a static
+ * list of features they would like to use if possible, and use it for all
+ * connection managers.
+ *
+ * Since: 0.UNRELEASED
+ */
+void
+tp_connection_upgrade_contacts_async (TpConnection *self,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_features,
+ const TpContactFeature *features,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ContactsAsyncData *data;
+ GSimpleAsyncResult *result;
+ ContactFeatureFlags feature_flags = 0;
+ guint minimal_feature_flags = G_MAXUINT;
+ const gchar **supported_interfaces;
+ GPtrArray *contacts_array;
+ GArray *handles;
+ guint i;
+
+ g_return_if_fail (tp_proxy_is_prepared (self,
+ TP_CONNECTION_FEATURE_CONNECTED));
+ g_return_if_fail (n_contacts >= 1);
+ g_return_if_fail (contacts != NULL);
+ g_return_if_fail (n_features == 0 || features != NULL);
+
+ for (i = 0; i < n_contacts; i++)
+ {
+ g_return_if_fail (contacts[i]->priv->connection == self);
+ g_return_if_fail (contacts[i]->priv->identifier != NULL);
+ }
+
+ if (!get_feature_flags (n_features, features, &feature_flags))
+ return;
+
+ handles = g_array_sized_new (FALSE, FALSE, sizeof (TpHandle), n_contacts);
+ contacts_array = g_ptr_array_new_full (n_contacts, g_object_unref);
+ for (i = 0; i < n_contacts; i++)
+ {
+ /* feature flags that all contacts have */
+ minimal_feature_flags &= contacts[i]->priv->has_features;
+
+ /* Keep handles of contacts that does not already have all features */
+ if ((feature_flags & (~contacts[i]->priv->has_features)) != 0)
+ g_array_append_val (handles, contacts[i]->priv->handle);
+
+ /* Keep a ref on all contacts to ensure they do not disappear
+ * while upgrading them */
+ g_ptr_array_add (contacts_array, g_object_ref (contacts[i]));
+ }
+
+ /* Remove features that all contacts have */
+ feature_flags &= (~minimal_feature_flags);
+
+ supported_interfaces = contacts_bind_to_signals (self, feature_flags);
+
+ result = g_simple_async_result_new ((GObject *) self, callback, user_data,
+ tp_connection_upgrade_contacts_async);
+ g_simple_async_result_set_op_res_gpointer (result, contacts_array,
+ (GDestroyNotify) g_ptr_array_unref);
+
+ if (handles->len > 0 && supported_interfaces[0] != NULL)
+ {
+ data = contacts_async_data_new (result, feature_flags);
+ tp_cli_connection_interface_contacts_call_get_contact_attributes (self,
+ -1, handles, supported_interfaces, TRUE, got_contact_attributes_cb,
+ data, (GDestroyNotify) contacts_async_data_free, NULL);
+ }
+ else
+ {
+ g_simple_async_result_complete_in_idle (result);
+ }
+
+ g_free (supported_interfaces);
+ g_object_unref (result);
+ g_array_unref (handles);
+}
+
+/**
+ * tp_connection_upgrade_contacts_finish:
+ * @self: a #TpConnection
+ * @result: a #GAsyncResult
+ * @contacts: (element-type TelepathyGLib.Contact) (transfer container) (out) (allow-none):
+ * a location to set a #GPtrArray of upgraded #TpContact, or %NULL.
+ * @error: a #GError to fill
+ *
+ * Finishes tp_connection_upgrade_contacts_async().
+ *
+ * Returns: %TRUE on success, %FALSE otherwise.
+ * Since: 0.UNRELEASED
+ */
+gboolean
+tp_connection_upgrade_contacts_finish (TpConnection *self,
+ GAsyncResult *result,
+ GPtrArray **contacts,
+ GError **error)
+{
+ _tp_implement_finish_copy_pointer (self,
+ tp_connection_upgrade_contacts_async, g_ptr_array_ref, contacts);
+}
+
void
_tp_contact_set_is_blocked (TpContact *self,
gboolean is_blocked)