aboutsummaryrefslogtreecommitdiffstats
path: root/src/empathy-event-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/empathy-event-manager.c')
-rw-r--r--src/empathy-event-manager.c127
1 files changed, 104 insertions, 23 deletions
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c
index 5516328cc..93656c3a9 100644
--- a/src/empathy-event-manager.c
+++ b/src/empathy-event-manager.c
@@ -76,6 +76,7 @@ typedef struct {
typedef struct {
TpBaseClient *approver;
+ TpBaseClient *auth_approver;
EmpathyContactManager *contact_manager;
GSList *events;
/* Ongoing approvals */
@@ -165,10 +166,8 @@ event_free (EventPriv *event)
if (event->autoremove_timeout_id != 0)
g_source_remove (event->autoremove_timeout_id);
- if (event->public.contact)
- {
- g_object_unref (event->public.contact);
- }
+ tp_clear_object (&(event->public.contact));
+ tp_clear_object (&(event->public.account));
g_slice_free (EventPriv, event);
}
@@ -212,6 +211,7 @@ display_notify_area (EmpathyEventManager *self)
static void
event_manager_add (EmpathyEventManager *manager,
+ TpAccount *account,
EmpathyContact *contact,
EmpathyEventType type,
const gchar *icon_name,
@@ -225,6 +225,7 @@ event_manager_add (EmpathyEventManager *manager,
EventPriv *event;
event = g_slice_new0 (EventPriv);
+ event->public.account = account != NULL ? g_object_ref (account) : NULL;
event->public.contact = contact ? g_object_ref (contact) : NULL;
event->public.type = type;
event->public.icon_name = g_strdup (icon_name);
@@ -421,11 +422,46 @@ out:
}
static void
+reject_auth_channel_claim_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ TpChannelDispatchOperation *cdo = TP_CHANNEL_DISPATCH_OPERATION (source);
+ GError *error = NULL;
+
+ if (!tp_channel_dispatch_operation_claim_finish (cdo, result, &error))
+ {
+ DEBUG ("Failed to claim channel: %s", error->message);
+
+ g_error_free (error);
+ return;
+ }
+
+ tp_cli_channel_call_close (TP_CHANNEL (user_data), -1,
+ NULL, NULL, NULL, NULL);
+}
+
+static void
reject_approval (EventManagerApproval *approval)
{
/* We have to claim the channel before closing it */
- tp_channel_dispatch_operation_claim_async (approval->operation,
- reject_channel_claim_cb, g_object_ref (approval->handler_instance));
+
+ /* Unfortunately, we need to special case the auth channels for the
+ * time being as they don't have a wrapper object handler in
+ * approval->handler_instance as they're not actually handled by
+ * this process, so we can just use a noddy callback to call Close()
+ * directly. */
+ if (approval->handler_instance != NULL)
+ {
+ tp_channel_dispatch_operation_claim_async (approval->operation,
+ reject_channel_claim_cb, g_object_ref (approval->handler_instance));
+ }
+ else if (tp_channel_get_channel_type_id (approval->main_channel)
+ == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION)
+ {
+ tp_channel_dispatch_operation_claim_async (approval->operation,
+ reject_auth_channel_claim_cb, approval->main_channel);
+ }
}
static void
@@ -549,9 +585,9 @@ event_manager_chat_message_received_cb (EmpathyTpChat *tp_chat,
event_update (approval->manager, event, EMPATHY_IMAGE_NEW_MESSAGE, header,
msg);
else
- event_manager_add (approval->manager, sender, EMPATHY_EVENT_TYPE_CHAT,
- EMPATHY_IMAGE_NEW_MESSAGE, header, msg, approval,
- event_text_channel_process_func, NULL);
+ event_manager_add (approval->manager, NULL, sender,
+ EMPATHY_EVENT_TYPE_CHAT, EMPATHY_IMAGE_NEW_MESSAGE, header, msg,
+ approval, event_text_channel_process_func, NULL);
empathy_sound_manager_play (priv->sound_mgr, window,
EMPATHY_SOUND_CONVERSATION_NEW);
@@ -625,8 +661,8 @@ event_manager_media_channel_got_contact (EventManagerApproval *approval)
video ? _("Incoming video call from %s") :_("Incoming call from %s"),
empathy_contact_get_alias (approval->contact));
- event_manager_add (approval->manager, approval->contact,
- EMPATHY_EVENT_TYPE_VOIP,
+ event_manager_add (approval->manager, NULL,
+ approval->contact, EMPATHY_EVENT_TYPE_VOIP,
video ? EMPATHY_IMAGE_VIDEO_CALL : EMPATHY_IMAGE_VOIP,
header, NULL, approval,
event_channel_process_voip_func, NULL);
@@ -758,9 +794,10 @@ display_invite_room_dialog (EventManagerApproval *approval)
tp_channel_get_identifier (approval->main_channel));
}
- event_manager_add (approval->manager, approval->contact,
- EMPATHY_EVENT_TYPE_INVITATION, EMPATHY_IMAGE_GROUP_MESSAGE, msg,
- invite_msg, approval, event_room_channel_process_func, NULL);
+ event_manager_add (approval->manager, NULL,
+ approval->contact, EMPATHY_EVENT_TYPE_INVITATION,
+ EMPATHY_IMAGE_GROUP_MESSAGE, msg, invite_msg, approval,
+ event_room_channel_process_func, NULL);
empathy_sound_manager_play (priv->sound_mgr, window,
EMPATHY_SOUND_CONVERSATION_NEW);
@@ -807,8 +844,9 @@ event_manager_ft_got_contact_cb (TpConnection *connection,
header = g_strdup_printf (_("Incoming file transfer from %s"),
empathy_contact_get_alias (approval->contact));
- event_manager_add (approval->manager, approval->contact,
- EMPATHY_EVENT_TYPE_TRANSFER, EMPATHY_IMAGE_DOCUMENT_SEND, header, NULL,
+ event_manager_add (approval->manager, NULL,
+ approval->contact, EMPATHY_EVENT_TYPE_TRANSFER,
+ EMPATHY_IMAGE_DOCUMENT_SEND, header, NULL,
approval, event_channel_process_func, NULL);
/* FIXME better sound for incoming file transfers ?*/
@@ -819,8 +857,14 @@ event_manager_ft_got_contact_cb (TpConnection *connection,
g_object_unref (window);
}
-/* If there is a file-transfer or media channel consider it as the
- * main one. */
+static void
+event_manager_auth_process_func (EventPriv *event)
+{
+ empathy_event_approve ((EmpathyEvent *) event);
+}
+
+/* If there is a file-transfer, media, or auth channel consider it as
+ * the main one. */
static TpChannel *
find_main_channel (GList *channels)
{
@@ -838,7 +882,8 @@ find_main_channel (GList *channels)
channel_type = tp_channel_get_channel_type_id (channel);
if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA ||
- channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER)
+ channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER ||
+ channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION)
return channel;
else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)
@@ -962,6 +1007,13 @@ approve_channels (TpSimpleApprover *approver,
empathy_tp_contact_factory_get_from_handle (connection, handle,
event_manager_ft_got_contact_cb, approval, NULL, G_OBJECT (self));
}
+ else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION)
+ {
+ event_manager_add (approval->manager, account, NULL, EMPATHY_EVENT_TYPE_AUTH,
+ GTK_STOCK_DIALOG_AUTHENTICATION, tp_account_get_display_name (account),
+ _("Password required"), approval,
+ event_manager_auth_process_func, NULL);
+ }
else
{
GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
@@ -1023,7 +1075,7 @@ event_manager_pendings_changed_cb (EmpathyContactList *list,
else
event_msg = NULL;
- event_manager_add (manager, contact, EMPATHY_EVENT_TYPE_SUBSCRIPTION,
+ event_manager_add (manager, NULL, contact, EMPATHY_EVENT_TYPE_SUBSCRIPTION,
GTK_STOCK_DIALOG_QUESTION, header, event_msg, NULL,
event_pending_subscribe_func, NULL);
@@ -1066,7 +1118,7 @@ event_manager_presence_changed_cb (EmpathyContact *contact,
header = g_strdup_printf (_("%s is now offline."),
empathy_contact_get_alias (contact));
- event_manager_add (manager, contact, EMPATHY_EVENT_TYPE_PRESENCE,
+ event_manager_add (manager, NULL, contact, EMPATHY_EVENT_TYPE_PRESENCE,
EMPATHY_IMAGE_AVATAR_DEFAULT, header, NULL, NULL, NULL, NULL);
}
}
@@ -1087,7 +1139,7 @@ event_manager_presence_changed_cb (EmpathyContact *contact,
header = g_strdup_printf (_("%s is now online."),
empathy_contact_get_alias (contact));
- event_manager_add (manager, contact, EMPATHY_EVENT_TYPE_PRESENCE,
+ event_manager_add (manager, NULL, contact, EMPATHY_EVENT_TYPE_PRESENCE,
EMPATHY_IMAGE_AVATAR_DEFAULT, header, NULL, NULL, NULL, NULL);
}
}
@@ -1150,6 +1202,7 @@ event_manager_finalize (GObject *object)
g_slist_free (priv->approvals);
g_object_unref (priv->contact_manager);
g_object_unref (priv->approver);
+ g_object_unref (priv->auth_approver);
g_object_unref (priv->gsettings_notif);
g_object_unref (priv->gsettings_ui);
g_object_unref (priv->sound_mgr);
@@ -1191,7 +1244,6 @@ empathy_event_manager_class_init (EmpathyEventManagerClass *klass)
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
-
g_type_class_add_private (object_class, sizeof (EmpathyEventManagerPriv));
}
@@ -1262,12 +1314,41 @@ empathy_event_manager_init (EmpathyEventManager *manager)
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
NULL));
+ /* I don't feel good about doing this, and I'm sorry, but the
+ * capabilities connection feature is added earlier because it's
+ * needed for EmpathyTpChat. If the capabilities feature is required
+ * then preparing an auth channel (which of course appears in the
+ * CONNECTING state) will never be prepared. So the options are
+ * either to create another approver like I've done, or to port
+ * EmpathyTpChat and its users to not depend on the connection being
+ * prepared with capabilities. I chose the former, obviously. :-) */
+
+ priv->auth_approver = tp_simple_approver_new (dbus,
+ "Empathy.AuthEventManager", FALSE, approve_channels, manager,
+ NULL);
+
+ /* SASL auth channels */
+ tp_base_client_take_approver_filter (priv->auth_approver,
+ tp_asv_new (
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
+ TP_IFACE_CHANNEL_TYPE_SERVER_AUTHENTICATION,
+ TP_PROP_CHANNEL_TYPE_SERVER_AUTHENTICATION_AUTHENTICATION_METHOD,
+ G_TYPE_STRING,
+ TP_IFACE_CHANNEL_INTERFACE_SASL_AUTHENTICATION,
+ NULL));
+
if (!tp_base_client_register (priv->approver, &error))
{
DEBUG ("Failed to register Approver: %s", error->message);
g_error_free (error);
}
+ if (!tp_base_client_register (priv->auth_approver, &error))
+ {
+ DEBUG ("Failed to register auth Approver: %s", error->message);
+ g_error_free (error);
+ }
+
g_object_unref (dbus);
}