resend presence to muc avatar update. fixes #3175

This commit is contained in:
Daniel Gultsch 2019-01-17 17:55:47 +01:00
parent e714d7cd29
commit a53774bc6d
5 changed files with 53 additions and 17 deletions

View file

@ -415,10 +415,14 @@ public class Contact implements ListItem, Blockable {
} }
public boolean setAvatar(Avatar avatar) { public boolean setAvatar(Avatar avatar) {
return setAvatar(avatar, false);
}
public boolean setAvatar(Avatar avatar, boolean previouslyOmittedPepFetch) {
if (this.avatar != null && this.avatar.equals(avatar)) { if (this.avatar != null && this.avatar.equals(avatar)) {
return false; return false;
} else { } else {
if (this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) { if (!previouslyOmittedPepFetch && this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) {
return false; return false;
} }
this.avatar = avatar; this.avatar = avatar;

View file

@ -185,6 +185,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
if (account.getJid().asBareJid().equals(from)) { if (account.getJid().asBareJid().equals(from)) {
if (account.setAvatar(avatar.getFilename())) { if (account.setAvatar(avatar.getFilename())) {
mXmppConnectionService.databaseBackend.updateAccount(account); mXmppConnectionService.databaseBackend.updateAccount(account);
mXmppConnectionService.notifyAccountAvatarHasChanged(account);
} }
mXmppConnectionService.getAvatarService().clear(account); mXmppConnectionService.getAvatarService().clear(account);
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateConversationUi();

View file

@ -180,7 +180,8 @@ public class XmppConnectionService extends Service {
private final IBinder mBinder = new XmppConnectionBinder(); private final IBinder mBinder = new XmppConnectionBinder();
private final List<Conversation> conversations = new CopyOnWriteArrayList<>(); private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
private final IqGenerator mIqGenerator = new IqGenerator(this); private final IqGenerator mIqGenerator = new IqGenerator(this);
private final List<String> mInProgressAvatarFetches = new ArrayList<>(); private final Set<String> mInProgressAvatarFetches = new HashSet<>();
private final Set<String> mOmittedPepAvatarFetches = new HashSet<>();
private final HashSet<Jid> mLowPingTimeoutMode = new HashSet<>(); private final HashSet<Jid> mLowPingTimeoutMode = new HashSet<>();
private final OnIqPacketReceived mDefaultIqHandler = (account, packet) -> { private final OnIqPacketReceived mDefaultIqHandler = (account, packet) -> {
if (packet.getType() != IqPacket.TYPE.RESULT) { if (packet.getType() != IqPacket.TYPE.RESULT) {
@ -3122,6 +3123,7 @@ public class XmppConnectionService extends Service {
if (account.setAvatar(avatar.getFilename())) { if (account.setAvatar(avatar.getFilename())) {
getAvatarService().clear(account); getAvatarService().clear(account);
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
notifyAccountAvatarHasChanged(account);
} }
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": published avatar " + (avatar.size / 1024) + "KiB"); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": published avatar " + (avatar.size / 1024) + "KiB");
if (callback != null) { if (callback != null) {
@ -3201,18 +3203,22 @@ public class XmppConnectionService extends Service {
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); final String KEY = generateFetchKey(account, avatar);
synchronized (this.mInProgressAvatarFetches) { synchronized (this.mInProgressAvatarFetches) {
if (!this.mInProgressAvatarFetches.contains(KEY)) { if (mInProgressAvatarFetches.add(KEY)) {
switch (avatar.origin) { switch (avatar.origin) {
case PEP: case PEP:
this.mInProgressAvatarFetches.add(KEY); this.mInProgressAvatarFetches.add(KEY);
fetchAvatarPep(account, avatar, callback); fetchAvatarPep(account, avatar, callback);
break; break;
case VCARD: case VCARD:
this.mInProgressAvatarFetches.add(KEY); this.mInProgressAvatarFetches.add(KEY);
fetchAvatarVcard(account, avatar, callback); fetchAvatarVcard(account, avatar, callback);
break; break;
} }
} } else if (avatar.origin == Avatar.Origin.PEP) {
mOmittedPepAvatarFetches.add(KEY);
} else {
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": already fetching "+avatar.origin+" avatar for "+avatar.owner);
}
} }
} }
@ -3274,8 +3280,11 @@ public class XmppConnectionService extends Service {
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) {
final boolean previouslyOmittedPepFetch;
synchronized (mInProgressAvatarFetches) { synchronized (mInProgressAvatarFetches) {
mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); final String KEY = generateFetchKey(account, avatar);
mInProgressAvatarFetches.remove(KEY);
previouslyOmittedPepFetch = mOmittedPepAvatarFetches.remove(KEY);
} }
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");
@ -3285,7 +3294,7 @@ public class XmppConnectionService extends Service {
avatar.image = image; avatar.image = image;
if (getFileBackend().save(avatar)) { if (getFileBackend().save(avatar)) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() Log.d(Config.LOGTAG, account.getJid().asBareJid()
+ ": successfully fetched vCard avatar for " + avatar.owner); + ": successfully fetched vCard avatar for " + avatar.owner+" omittedPep="+previouslyOmittedPepFetch);
if (avatar.owner.isBareJid()) { if (avatar.owner.isBareJid()) {
if (account.getJid().asBareJid().equals(avatar.owner) && account.getAvatar() == null) { if (account.getJid().asBareJid().equals(avatar.owner) && account.getAvatar() == null) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": had no avatar. replacing with vcard"); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": had no avatar. replacing with vcard");
@ -3295,7 +3304,7 @@ public class XmppConnectionService extends Service {
updateAccountUi(); updateAccountUi();
} else { } else {
Contact contact = account.getRoster().getContact(avatar.owner); Contact contact = account.getRoster().getContact(avatar.owner);
if (contact.setAvatar(avatar)) { if (contact.setAvatar(avatar, previouslyOmittedPepFetch)) {
syncRoster(account); syncRoster(account);
getAvatarService().clear(contact); getAvatarService().clear(contact);
updateRosterUi(); updateRosterUi();
@ -3363,6 +3372,23 @@ public class XmppConnectionService extends Service {
}); });
} }
public void notifyAccountAvatarHasChanged(final Account account) {
final XmppConnection connection = account.getXmppConnection();
if (connection != null && connection.getFeatures().bookmarksConversion()) {
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": avatar changed. resending presence to online group chats");
for(Conversation conversation : conversations) {
if (conversation.getAccount() == account && conversation.getMode() == Conversational.MODE_MULTI) {
final MucOptions mucOptions = conversation.getMucOptions();
if (mucOptions.online()) {
PresencePacket packet = mPresenceGenerator.selfPresence(account, Presence.Status.ONLINE, mucOptions.nonanonymous());
packet.setTo(mucOptions.getSelf().getFullJid());
connection.sendPresencePacket(packet);
}
}
}
}
}
public void deleteContactOnServer(Contact contact) { public void deleteContactOnServer(Contact contact) {
contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
contact.resetOption(Contact.Options.DIRTY_PUSH); contact.resetOption(Contact.Options.DIRTY_PUSH);

View file

@ -24,4 +24,5 @@ public final class Namespace {
public static final String BOOKMARKS_CONVERSION = "urn:xmpp:bookmarks-conversion:0"; public static final String BOOKMARKS_CONVERSION = "urn:xmpp:bookmarks-conversion:0";
public static final String BOOKMARKS = "storage:bookmarks"; public static final String BOOKMARKS = "storage:bookmarks";
public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0"; public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0";
public static final String AVATAR_CONVERSION = "urn:xmpp:pep-vcard-conversion:0";
} }

View file

@ -1755,6 +1755,10 @@ public class XmppConnection implements Runnable {
return hasDiscoFeature(account.getJid().asBareJid(), Namespace.BOOKMARKS_CONVERSION) && pepPublishOptions(); return hasDiscoFeature(account.getJid().asBareJid(), Namespace.BOOKMARKS_CONVERSION) && pepPublishOptions();
} }
public boolean avatarConversion() {
return hasDiscoFeature(account.getJid().asBareJid(), Namespace.AVATAR_CONVERSION) && pepPublishOptions();
}
public boolean blocking() { public boolean blocking() {
return hasDiscoFeature(Jid.of(account.getServer()), Namespace.BLOCKING); return hasDiscoFeature(Jid.of(account.getServer()), Namespace.BLOCKING);
} }