changeset 27775:1ea1aee71848

jabber: Fix setting Google Talk avatar at login. Google Talk (at some point) started returning IQ errors when setting the avatar in the first 10 seconds of login. This was reported by Bill Lovett to the jdev mailing list and he included the 10-second "magic number".
author Paul Aurich <paul@darkrain42.org>
date Sat, 01 Aug 2009 01:53:02 +0000
parents 9d43d9d33477
children cbbde19ce02d
files libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jabber.h
diffstat 3 files changed, 38 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/buddy.c	Fri Jul 31 14:40:03 2009 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Sat Aug 01 01:53:02 2009 +0000
@@ -463,6 +463,11 @@
 	if(!js->vcard_fetched)
 		return;
 
+	if (js->vcard_timer) {
+		purple_timeout_remove(js->vcard_timer);
+		js->vcard_timer = 0;
+	}
+
 	g_free(js->avatar_hash);
 	js->avatar_hash = NULL;
 
@@ -854,12 +859,26 @@
 	}
 }
 
+static gboolean
+set_own_vcard_cb(gpointer data)
+{
+	JabberStream *js = data;
+	PurpleAccount *account = purple_connection_get_account(js->gc);
+
+	js->vcard_timer = 0;
+
+	jabber_set_info(js->gc, purple_account_get_user_info(account));
+
+	return FALSE;
+}
+
 static void jabber_vcard_save_mine(JabberStream *js, const char *from,
                                    JabberIqType type, const char *id,
                                    xmlnode *packet, gpointer data)
 {
 	xmlnode *vcard, *photo, *binval;
 	char *txt, *vcard_hash = NULL;
+	PurpleAccount *account;
 
 	if (type == JABBER_IQ_ERROR) {
 		xmlnode *error;
@@ -870,12 +889,13 @@
 			return;
 	}
 
+	account = purple_connection_get_account(js->gc);
+
 	if((vcard = xmlnode_get_child(packet, "vCard")) ||
 			(vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp")))
 	{
 		txt = xmlnode_to_str(vcard, NULL);
-		purple_account_set_user_info(purple_connection_get_account(js->gc), txt);
-
+		purple_account_set_user_info(account, txt);
 		g_free(txt);
 	} else {
 		/* if we have no vCard, then lets not overwrite what we might have locally */
@@ -898,8 +918,17 @@
 
 	/* Republish our vcard if the photo is different than the server's */
 	if (!purple_strequal(vcard_hash, js->initial_avatar_hash)) {
-		PurpleAccount *account = purple_connection_get_account(js->gc);
-		jabber_set_info(js->gc, purple_account_get_user_info(account));
+		/*
+		 * Google Talk has developed the behavior that it will not accept
+		 * a vcard set in the first 10 seconds (or so) of the connection;
+		 * it returns an error (namespaces trimmed):
+		 * <error code="500" type="wait"><internal-server-error/></error>.
+		 */
+		if (js->googletalk)
+			js->vcard_timer = purple_timeout_add_seconds(10, set_own_vcard_cb,
+			                                             js);
+		else
+			jabber_set_info(js->gc, purple_account_get_user_info(account));
 	} else if (js->initial_avatar_hash) {
 		/* Our photo is in the vcard, so advertise vcard-temp updates */
 		js->avatar_hash = g_strdup(js->initial_avatar_hash);
--- a/libpurple/protocols/jabber/jabber.c	Fri Jul 31 14:40:03 2009 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Sat Aug 01 01:53:02 2009 +0000
@@ -1542,6 +1542,9 @@
 	g_free(js->old_track);
 	g_free(js->expected_rspauth);
 
+	if (js->vcard_timer != 0)
+		purple_timeout_remove(js->vcard_timer);
+
 	if (js->keepalive_timeout != 0)
 		purple_timeout_remove(js->keepalive_timeout);
 
--- a/libpurple/protocols/jabber/jabber.h	Fri Jul 31 14:40:03 2009 +0000
+++ b/libpurple/protocols/jabber/jabber.h	Sat Aug 01 01:53:02 2009 +0000
@@ -214,6 +214,8 @@
 	void *unregistration_user_data;
 
 	gboolean vcard_fetched;
+	/* Timer at login to push updated avatar */
+	guint vcard_timer;
 
 	/* Entity Capabilities hash */
 	char *caps_hash;