avoid fetching avatars multiple times in parallel

This commit is contained in:
Daniel Gultsch 2015-05-05 10:29:41 +02:00
parent 9eaa6800ca
commit b7c672e10e
1 changed files with 39 additions and 8 deletions

View File

@ -41,6 +41,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -210,6 +211,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager(
this); this);
private AvatarService mAvatarService = new AvatarService(this); private AvatarService mAvatarService = new AvatarService(this);
private final List<String> mInProgressAvatarFetches = new ArrayList<>();
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
private OnConversationUpdate mOnConversationUpdate = null; private OnConversationUpdate mOnConversationUpdate = null;
private Integer convChangedListenerCount = 0; private Integer convChangedListenerCount = 0;
@ -1893,16 +1895,29 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
fetchAvatar(account, avatar, null); fetchAvatar(account, avatar, null);
} }
private static String generateFetchKey(Account account, final Avatar avatar) {
return account.getJid().toBareJid()+"_"+avatar.owner+"_"+avatar.sha1sum;
}
public void fetchAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) { public void fetchAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) {
final String KEY = generateFetchKey(account, avatar);
synchronized(this.mInProgressAvatarFetches) {
if (this.mInProgressAvatarFetches.contains(KEY)) {
return;
} else {
switch (avatar.origin) { switch (avatar.origin) {
case PEP: case PEP:
this.mInProgressAvatarFetches.add(KEY);
fetchAvatarPep(account, avatar, callback); fetchAvatarPep(account, avatar, callback);
break; break;
case VCARD: case VCARD:
this.mInProgressAvatarFetches.add(KEY);
fetchAvatarVcard(account, avatar, callback); fetchAvatarVcard(account, avatar, callback);
break; break;
} }
} }
}
}
private void fetchAvatarPep(Account account, final Avatar avatar, final UiCallback<Avatar> callback) { private void fetchAvatarPep(Account account, final Avatar avatar, final UiCallback<Avatar> callback) {
IqPacket packet = this.mIqGenerator.retrievePepAvatar(avatar); IqPacket packet = this.mIqGenerator.retrievePepAvatar(avatar);
@ -1910,6 +1925,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
@Override @Override
public void onIqPacketReceived(Account account, IqPacket result) { public void onIqPacketReceived(Account account, IqPacket result) {
synchronized (mInProgressAvatarFetches) {
mInProgressAvatarFetches.remove(generateFetchKey(account, avatar));
}
final String ERROR = account.getJid().toBareJid() final String ERROR = account.getJid().toBareJid()
+ ": fetching avatar for " + avatar.owner + " failed "; + ": fetching avatar for " + avatar.owner + " failed ";
if (result.getType() == IqPacket.TYPE.RESULT) { if (result.getType() == IqPacket.TYPE.RESULT) {
@ -1963,6 +1981,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
this.sendIqPacket(account,packet,new OnIqPacketReceived() { this.sendIqPacket(account,packet,new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
synchronized(mInProgressAvatarFetches) {
mInProgressAvatarFetches.remove(generateFetchKey(account,avatar));
}
if (packet.getType() == IqPacket.TYPE.RESULT) { if (packet.getType() == IqPacket.TYPE.RESULT) {
Element vCard = packet.findChild("vCard","vcard-temp"); Element vCard = packet.findChild("vCard","vcard-temp");
Element photo = vCard != null ? vCard.findChild("PHOTO") : null; Element photo = vCard != null ? vCard.findChild("PHOTO") : null;
@ -2043,6 +2064,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
disconnect(account, force); disconnect(account, force);
} }
if (!account.isOptionSet(Account.OPTION_DISABLED)) { if (!account.isOptionSet(Account.OPTION_DISABLED)) {
synchronized (this.mInProgressAvatarFetches) {
for(Iterator<String> iterator = this.mInProgressAvatarFetches.iterator(); iterator.hasNext();) {
final String KEY = iterator.next();
if (KEY.startsWith(account.getJid().toBareJid()+"_")) {
iterator.remove();
}
}
}
if (account.getXmppConnection() == null) { if (account.getXmppConnection() == null) {
account.setXmppConnection(createConnection(account)); account.setXmppConnection(createConnection(account));
} }