aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2011-03-14 09:58:00 +0800
committerDanielle Madeley <danielle.madeley@collabora.co.uk>2011-03-14 09:58:00 +0800
commit8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd (patch)
tree5c1858c474144e0cd511fc6891e9d21ef978c5e3 /libempathy
parent2e3e5e8e732fbc2e4d3ed61892aefa09efabbfc2 (diff)
parentc0eca0414ca529da3b083c099ec3031436420b00 (diff)
downloadgsoc2013-empathy-8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd.tar
gsoc2013-empathy-8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd.tar.gz
gsoc2013-empathy-8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd.tar.bz2
gsoc2013-empathy-8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd.tar.lz
gsoc2013-empathy-8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd.tar.xz
gsoc2013-empathy-8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd.tar.zst
gsoc2013-empathy-8e6a977d36aea1eb4b429ddee84cb9b4bc4142cd.zip
Merge branch 'glassrose-contact-blocking-rebase'
Diffstat (limited to 'libempathy')
-rw-r--r--libempathy/empathy-contact-list.c24
-rw-r--r--libempathy/empathy-contact-list.h15
-rw-r--r--libempathy/empathy-contact-manager.c43
-rw-r--r--libempathy/empathy-individual-manager.c85
-rw-r--r--libempathy/empathy-individual-manager.h9
-rw-r--r--libempathy/empathy-tp-contact-list.c110
-rw-r--r--libempathy/empathy-tp-contact-list.h1
7 files changed, 281 insertions, 6 deletions
diff --git a/libempathy/empathy-contact-list.c b/libempathy/empathy-contact-list.c
index 631bb4a37..d28866735 100644
--- a/libempathy/empathy-contact-list.c
+++ b/libempathy/empathy-contact-list.c
@@ -278,3 +278,27 @@ empathy_contact_list_remove_from_favourites (EmpathyContactList *list,
contact);
}
}
+
+void
+empathy_contact_list_set_blocked (EmpathyContactList *list,
+ EmpathyContact *contact,
+ gboolean blocked,
+ gboolean abusive)
+{
+ EmpathyContactListIface *iface = EMPATHY_CONTACT_LIST_GET_IFACE (list);
+
+ if (iface->set_blocked != NULL)
+ iface->set_blocked (list, contact, blocked, abusive);
+}
+
+gboolean
+empathy_contact_list_get_blocked (EmpathyContactList *list,
+ EmpathyContact *contact)
+{
+ EmpathyContactListIface *iface = EMPATHY_CONTACT_LIST_GET_IFACE (list);
+
+ if (iface->get_blocked != NULL)
+ return iface->get_blocked (list, contact);
+ else
+ return FALSE;
+}
diff --git a/libempathy/empathy-contact-list.h b/libempathy/empathy-contact-list.h
index 3817af876..cf523bf2a 100644
--- a/libempathy/empathy-contact-list.h
+++ b/libempathy/empathy-contact-list.h
@@ -39,6 +39,8 @@ typedef enum {
EMPATHY_CONTACT_LIST_CAN_REMOVE = 1 << 1,
EMPATHY_CONTACT_LIST_CAN_ALIAS = 1 << 2,
EMPATHY_CONTACT_LIST_CAN_GROUP = 1 << 3,
+ EMPATHY_CONTACT_LIST_CAN_BLOCK = 1 << 4,
+ EMPATHY_CONTACT_LIST_CAN_REPORT_ABUSIVE = 1 << 5,
} EmpathyContactListFlags;
typedef struct _EmpathyContactListIface EmpathyContactListIface;
@@ -77,6 +79,12 @@ struct _EmpathyContactListIface {
EmpathyContact *contact);
void (*remove_favourite) (EmpathyContactList *list,
EmpathyContact *contact);
+ void (*set_blocked) (EmpathyContactList *list,
+ EmpathyContact *contact,
+ gboolean blocked,
+ gboolean abusive);
+ gboolean (*get_blocked) (EmpathyContactList *list,
+ EmpathyContact *contact);
};
GType empathy_contact_list_get_type (void) G_GNUC_CONST;
@@ -116,6 +124,13 @@ void empathy_contact_list_remove_from_favourites
(EmpathyContactList *list,
EmpathyContact *contact);
+void empathy_contact_list_set_blocked (EmpathyContactList *list,
+ EmpathyContact *contact,
+ gboolean blocked,
+ gboolean abusive);
+gboolean empathy_contact_list_get_blocked (EmpathyContactList *list,
+ EmpathyContact *contact);
+
G_END_DECLS
diff --git a/libempathy/empathy-contact-manager.c b/libempathy/empathy-contact-manager.c
index a900fa610..b00f82477 100644
--- a/libempathy/empathy-contact-manager.c
+++ b/libempathy/empathy-contact-manager.c
@@ -865,6 +865,47 @@ contact_manager_remove_group (EmpathyContactList *manager,
}
static void
+contact_manager_set_blocked (EmpathyContactList *manager,
+ EmpathyContact *contact,
+ gboolean blocked,
+ gboolean abusive)
+{
+ EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+ EmpathyContactList *list;
+ TpConnection *connection;
+
+ g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
+
+ connection = empathy_contact_get_connection (contact);
+ list = g_hash_table_lookup (priv->lists, connection);
+
+ if (list != NULL) {
+ empathy_contact_list_set_blocked (list, contact,
+ blocked, abusive);
+ }
+}
+
+static gboolean
+contact_manager_get_blocked (EmpathyContactList *manager,
+ EmpathyContact *contact)
+{
+ EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+ EmpathyContactList *list;
+ TpConnection *connection;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), FALSE);
+
+ connection = empathy_contact_get_connection (contact);
+ list = g_hash_table_lookup (priv->lists, connection);
+
+ if (list != NULL) {
+ return empathy_contact_list_get_blocked (list, contact);
+ } else {
+ return FALSE;
+ }
+}
+
+static void
contact_manager_iface_init (EmpathyContactListIface *iface)
{
iface->add = contact_manager_add;
@@ -880,6 +921,8 @@ contact_manager_iface_init (EmpathyContactListIface *iface)
iface->is_favourite = contact_manager_is_favourite;
iface->remove_favourite = contact_manager_remove_favourite;
iface->add_favourite = contact_manager_add_favourite;
+ iface->set_blocked = contact_manager_set_blocked;
+ iface->get_blocked = contact_manager_get_blocked;
}
EmpathyContactListFlags
diff --git a/libempathy/empathy-individual-manager.c b/libempathy/empathy-individual-manager.c
index 894ae648b..137d00f1f 100644
--- a/libempathy/empathy-individual-manager.c
+++ b/libempathy/empathy-individual-manager.c
@@ -30,12 +30,14 @@
#include <telepathy-glib/util.h>
#include <folks/folks.h>
+#include <folks/folks-telepathy.h>
#include <extensions/extensions.h>
#include "empathy-individual-manager.h"
#include "empathy-marshal.h"
#include "empathy-utils.h"
+#include "empathy-contact-manager.h"
#define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
#include "empathy-debug.h"
@@ -483,6 +485,89 @@ empathy_individual_manager_remove (EmpathyIndividualManager *self,
aggregator_remove_individual_cb, self);
}
+/* FIXME: The parameter @self is not required and the method can be placed in
+ * utilities. I left it as it is to stay coherent with empathy-2.34 */
+/**
+ * empathy_individual_manager_supports_blocking
+ * @self: the #EmpathyIndividualManager
+ * @individual: an individual to check
+ *
+ * Indicates whether any personas of an @individual can be blocked.
+ *
+ * Returns: %TRUE if any persona supports contact blocking
+ */
+gboolean
+empathy_individual_manager_supports_blocking (EmpathyIndividualManager *self,
+ FolksIndividual *individual)
+{
+ EmpathyIndividualManagerPriv *priv;
+ GList *personas, *l;
+
+ g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (self), FALSE);
+
+ priv = GET_PRIV (self);
+
+ personas = folks_individual_get_personas (individual);
+
+ for (l = personas; l != NULL; l = l->next)
+ {
+ TpfPersona *persona = l->data;
+ TpConnection *conn;
+ EmpathyContactManager *manager;
+
+ if (!TPF_IS_PERSONA (persona))
+ continue;
+
+ conn = tp_contact_get_connection (tpf_persona_get_contact (persona));
+ manager = empathy_contact_manager_dup_singleton ();
+
+ if (empathy_contact_manager_get_flags_for_connection (manager, conn) &
+ EMPATHY_CONTACT_LIST_CAN_BLOCK)
+ return TRUE;
+
+ g_object_unref (manager);
+ }
+
+ return FALSE;
+}
+
+void
+empathy_individual_manager_set_blocked (EmpathyIndividualManager *self,
+ FolksIndividual *individual,
+ gboolean blocked,
+ gboolean abusive)
+{
+ EmpathyIndividualManagerPriv *priv;
+ GList *personas, *l;
+
+ g_return_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (self));
+
+ priv = GET_PRIV (self);
+
+ personas = folks_individual_get_personas (individual);
+
+ for (l = personas; l != NULL; l = l->next)
+ {
+ TpfPersona *persona = l->data;
+ EmpathyContact *contact;
+ EmpathyContactManager *manager;
+
+ if (!TPF_IS_PERSONA (persona))
+ continue;
+
+ contact = empathy_contact_dup_from_tp_contact (
+ tpf_persona_get_contact (persona));
+ empathy_contact_set_persona (contact, FOLKS_PERSONA (persona));
+ manager = empathy_contact_manager_dup_singleton ();
+ empathy_contact_list_set_blocked (
+ EMPATHY_CONTACT_LIST (manager),
+ contact, blocked, abusive);
+
+ g_object_unref (manager);
+ g_object_unref (contact);
+ }
+}
+
static void
groups_change_group_cb (GObject *source,
GAsyncResult *result,
diff --git a/libempathy/empathy-individual-manager.h b/libempathy/empathy-individual-manager.h
index f2f5f5b56..1fec67d91 100644
--- a/libempathy/empathy-individual-manager.h
+++ b/libempathy/empathy-individual-manager.h
@@ -81,5 +81,14 @@ void empathy_individual_manager_unlink_individual (
EmpathyIndividualManager *self,
FolksIndividual *individual);
+gboolean empathy_individual_manager_supports_blocking (
+ EmpathyIndividualManager *self,
+ FolksIndividual *individual);
+
+void empathy_individual_manager_set_blocked (EmpathyIndividualManager *self,
+ FolksIndividual *individual,
+ gboolean blocked,
+ gboolean abusive);
+
G_END_DECLS
#endif /* __EMPATHY_INDIVIDUAL_MANAGER_H__ */
diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c
index 263c379f6..90932a20a 100644
--- a/libempathy/empathy-tp-contact-list.c
+++ b/libempathy/empathy-tp-contact-list.c
@@ -31,6 +31,8 @@
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/interfaces.h>
+#include <extensions/extensions.h>
+
#include "empathy-tp-contact-list.h"
#include "empathy-tp-contact-factory.h"
#include "empathy-contact-list.h"
@@ -46,6 +48,7 @@ typedef struct {
TpChannel *publish;
TpChannel *subscribe;
TpChannel *stored;
+ TpChannel *deny;
/* contact handle (TpHandle) => reffed (EmpathyContact *)
*
* Union of:
@@ -722,6 +725,10 @@ tp_contact_list_finalize (GObject *object)
g_object_unref (priv->stored);
}
+ if (priv->deny) {
+ g_object_unref (priv->deny);
+ }
+
if (priv->connection) {
g_object_unref (priv->connection);
}
@@ -773,6 +780,11 @@ got_list_channel (EmpathyTpContactList *list,
g_signal_connect (priv->subscribe, "group-members-changed",
G_CALLBACK (tp_contact_list_subscribe_group_members_changed_cb),
list);
+ } else if (!tp_strdiff (id, "deny")) {
+ if (priv->deny != NULL)
+ return;
+ DEBUG ("Got 'deny' channel");
+ priv->deny = g_object_ref (channel);
}
}
@@ -799,6 +811,27 @@ list_ensure_channel_cb (TpConnection *conn,
}
static void
+list_get_contact_blocking_capabilities_cb (TpProxy *conn,
+ const GValue *value,
+ const GError *in_error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ EmpathyTpContactList *list = EMPATHY_TP_CONTACT_LIST (weak_object);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ EmpContactBlockingCapabilities caps;
+
+ g_return_if_fail (G_VALUE_HOLDS_UINT (value));
+
+ caps = g_value_get_uint (value);
+
+ if (caps & EMP_CONTACT_BLOCKING_CAPABILITY_CAN_REPORT_ABUSIVE) {
+ DEBUG ("Connection can report abusive contacts");
+ priv->flags |= EMPATHY_CONTACT_LIST_CAN_REPORT_ABUSIVE;
+ }
+}
+
+static void
iterate_on_channels (EmpathyTpContactList *list,
const GPtrArray *channels)
{
@@ -881,8 +914,8 @@ conn_ready_cb (TpConnection *connection,
NULL, NULL, G_OBJECT (list));
request = tp_asv_new (
- TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
- TP_IFACE_CHANNEL ".TargetHandleType", G_TYPE_UINT, TP_HANDLE_TYPE_LIST,
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_LIST,
NULL);
/* Watch the NewChannels signal so if ensuring list channels fails (for
@@ -892,21 +925,39 @@ conn_ready_cb (TpConnection *connection,
priv->connection, new_channels_cb, NULL, NULL, G_OBJECT (list), NULL);
/* Request the 'stored' list. */
- tp_asv_set_static_string (request, TP_IFACE_CHANNEL ".TargetID", "stored");
+ tp_asv_set_static_string (request, TP_PROP_CHANNEL_TARGET_ID, "stored");
tp_cli_connection_interface_requests_call_ensure_channel (priv->connection,
G_MAXINT, request, list_ensure_channel_cb, list, NULL, G_OBJECT (list));
/* Request the 'publish' list. */
- tp_asv_set_static_string (request, TP_IFACE_CHANNEL ".TargetID", "publish");
+ tp_asv_set_static_string (request, TP_PROP_CHANNEL_TARGET_ID, "publish");
tp_cli_connection_interface_requests_call_ensure_channel (priv->connection,
G_MAXINT, request, list_ensure_channel_cb, list, NULL, G_OBJECT (list));
/* Request the 'subscribe' list. */
- tp_asv_set_static_string (request, TP_IFACE_CHANNEL ".TargetID", "subscribe");
+ tp_asv_set_static_string (request, TP_PROP_CHANNEL_TARGET_ID, "subscribe");
+ tp_cli_connection_interface_requests_call_ensure_channel (priv->connection,
+ G_MAXINT, request, list_ensure_channel_cb, list, NULL, G_OBJECT (list));
+
+ /* Request the 'deny' list */
+ tp_asv_set_static_string (request, TP_PROP_CHANNEL_TARGET_ID, "deny");
tp_cli_connection_interface_requests_call_ensure_channel (priv->connection,
G_MAXINT, request, list_ensure_channel_cb, list, NULL, G_OBJECT (list));
g_hash_table_unref (request);
+
+ /* Find out if we support reporting abusive contacts --
+ * this is done via the new Conn.I.ContactBlocking interface */
+ if (tp_proxy_has_interface_by_id (priv->connection,
+ EMP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING)) {
+ DEBUG ("Have Conn.I.ContactBlocking");
+
+ tp_cli_dbus_properties_call_get (priv->connection, -1,
+ EMP_IFACE_CONNECTION_INTERFACE_CONTACT_BLOCKING,
+ "ContactBlockingCapabilities",
+ list_get_contact_blocking_capabilities_cb,
+ NULL, NULL, G_OBJECT (list));
+ }
out:
g_object_unref (list);
}
@@ -1289,10 +1340,56 @@ tp_contact_list_get_flags (EmpathyContactList *list)
}
}
+ if (priv->deny != NULL)
+ flags |= EMPATHY_CONTACT_LIST_CAN_BLOCK;
+
return flags;
}
static void
+tp_contact_list_set_blocked (EmpathyContactList *list,
+ EmpathyContact *contact,
+ gboolean blocked,
+ gboolean abusive)
+{
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ TpHandle handle = empathy_contact_get_handle (contact);
+ GArray handles = { (char *) &handle, 1 };
+
+ g_return_if_fail (TP_IS_CHANNEL (priv->deny));
+
+ if (blocked && abusive) {
+ /* we have to do this via the new interface */
+ g_return_if_fail (priv->flags &
+ EMPATHY_CONTACT_LIST_CAN_REPORT_ABUSIVE);
+
+ emp_cli_connection_interface_contact_blocking_call_block_contacts (
+ TP_PROXY (priv->connection), -1,
+ &handles, TRUE, NULL, NULL, NULL, NULL);
+ } else if (blocked) {
+ tp_cli_channel_interface_group_call_add_members (
+ priv->deny, -1,
+ &handles, NULL, NULL, NULL, NULL, NULL);
+ } else {
+ tp_cli_channel_interface_group_call_remove_members (
+ priv->deny, -1,
+ &handles, NULL, NULL, NULL, NULL, NULL);
+ }
+}
+
+static gboolean
+tp_contact_list_get_blocked (EmpathyContactList *list,
+ EmpathyContact *contact)
+{
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+
+ g_return_val_if_fail (TP_IS_CHANNEL (priv->deny), FALSE);
+
+ return tp_intset_is_member (tp_channel_group_get_members (priv->deny),
+ empathy_contact_get_handle (contact));
+}
+
+static void
tp_contact_list_iface_init (EmpathyContactListIface *iface)
{
iface->add = tp_contact_list_add;
@@ -1306,6 +1403,8 @@ tp_contact_list_iface_init (EmpathyContactListIface *iface)
iface->rename_group = tp_contact_list_rename_group;
iface->remove_group = tp_contact_list_remove_group;
iface->get_flags = tp_contact_list_get_flags;
+ iface->set_blocked = tp_contact_list_set_blocked;
+ iface->get_blocked = tp_contact_list_get_blocked;
}
void
@@ -1334,4 +1433,3 @@ empathy_tp_contact_list_remove_all (EmpathyTpContactList *list)
}
g_hash_table_remove_all (priv->pendings);
}
-
diff --git a/libempathy/empathy-tp-contact-list.h b/libempathy/empathy-tp-contact-list.h
index 071fc0b91..9a555bc7a 100644
--- a/libempathy/empathy-tp-contact-list.h
+++ b/libempathy/empathy-tp-contact-list.h
@@ -26,6 +26,7 @@
#include <glib.h>
#include <telepathy-glib/connection.h>
+#include <libempathy/empathy-contact.h>
G_BEGIN_DECLS