diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 69276d9512e1cf91f2a0ae337e4287f80b423aab..4f2def45574c7d051be8c70237240d4f4a55ca2e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -3551,27 +3551,40 @@ public class XmppConnectionService extends Service { } public void deleteAvatar(final Account account) { - final AtomicBoolean executed = new AtomicBoolean(false); - final Runnable onDeleted = - () -> { - if (executed.compareAndSet(false, true)) { + final var connection = account.getXmppConnection(); + + final var vCardPhotoDeletionFuture = + connection.getManager(VCardManager.class).deletePhoto(); + final var pepDeletionFuture = connection.getManager(AvatarManager.class).delete(); + + final var deletionFuture = Futures.allAsList(vCardPhotoDeletionFuture, pepDeletionFuture); + + Futures.addCallback( + deletionFuture, + new FutureCallback<>() { + @Override + public void onSuccess(List result) { + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + ": deleted avatar from server"); account.setAvatar(null); databaseBackend.updateAccount(account); getAvatarService().clear(account); updateAccountUi(); } - }; - // TODO execute this via the respective Managers - deleteVcardAvatar(account, onDeleted); - deletePepNode(account, Namespace.AVATAR_DATA); - deletePepNode(account, Namespace.AVATAR_METADATA, onDeleted); - } - public void deletePepNode(final Account account, final String node) { - deletePepNode(account, node, null); + @Override + public void onFailure(Throwable t) { + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + ": could not delete avatar", + t); + } + }, + MoreExecutors.directExecutor()); } - private void deletePepNode(final Account account, final String node, final Runnable runnable) { + public void deletePepNode(final Account account, final String node) { final Iq request = mIqGenerator.deleteNode(node); sendIqPacket( account, @@ -3583,9 +3596,6 @@ public class XmppConnectionService extends Service { account.getJid().asBareJid() + ": successfully deleted pep node " + node); - if (runnable != null) { - runnable.run(); - } } else { Log.d( Config.LOGTAG, @@ -3594,53 +3604,6 @@ public class XmppConnectionService extends Service { }); } - private void deleteVcardAvatar(final Account account, @NonNull final Runnable runnable) { - final Iq retrieveVcard = mIqGenerator.retrieveVcardAvatar(account.getJid().asBareJid()); - sendIqPacket( - account, - retrieveVcard, - (response) -> { - if (response.getType() != Iq.Type.RESULT) { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() + ": no vCard set. nothing to do"); - return; - } - final Element vcard = response.findChild("vCard", "vcard-temp"); - if (vcard == null) { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() + ": no vCard set. nothing to do"); - return; - } - Element photo = vcard.findChild("PHOTO"); - if (photo == null) { - photo = vcard.addChild("PHOTO"); - } - photo.clearChildren(); - final Iq publication = new Iq(Iq.Type.SET); - publication.setTo(account.getJid().asBareJid()); - publication.addChild(vcard); - sendIqPacket( - account, - publication, - (publicationResponse) -> { - if (publicationResponse.getType() == Iq.Type.RESULT) { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() - + ": successfully deleted vcard avatar"); - runnable.run(); - } else { - Log.d( - Config.LOGTAG, - "failed to publish vcard " - + publicationResponse.getErrorCondition()); - } - }); - }); - } - private boolean hasEnabledAccounts() { if (this.accounts == null) { return false; @@ -4576,12 +4539,9 @@ public class XmppConnectionService extends Service { public void onFailure(@NonNull Throwable t) { Log.d( Config.LOGTAG, - "could not retrieve avatar from " - + address - + " (" - + avatar.sha1sum - + ")", - t); + account.getJid().asBareJid() + + ": could not retrieve vCard avatar of " + + avatar.owner); } }, MoreExecutors.directExecutor()); diff --git a/src/main/java/eu/siacs/conversations/xmpp/manager/AvatarManager.java b/src/main/java/eu/siacs/conversations/xmpp/manager/AvatarManager.java index 53960dbbd1b7aae1192e6d3eac0a691b70ba8627..1f3660a10e3669749880360346b089a7cdd20444 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/manager/AvatarManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/manager/AvatarManager.java @@ -159,4 +159,14 @@ public class AvatarManager extends AbstractManager { public boolean hasPepToVCardConversion() { return getManager(DiscoManager.class).hasAccountFeature(Namespace.AVATAR_CONVERSION); } + + public ListenableFuture delete() { + final var pepManager = getManager(PepManager.class); + final var deleteMetaDataFuture = pepManager.delete(Namespace.AVATAR_METADATA); + final var deleteDataFuture = pepManager.delete(Namespace.AVATAR_DATA); + return Futures.transform( + Futures.allAsList(deleteDataFuture, deleteMetaDataFuture), + vs -> null, + MoreExecutors.directExecutor()); + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/manager/VCardManager.java b/src/main/java/eu/siacs/conversations/xmpp/manager/VCardManager.java index a2d5873664a2d3ca75b386fc262ad2cd1d11e41c..76f8c6fdb724d1ca4e1a75c7a80e304dbf5a3705 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/manager/VCardManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/manager/VCardManager.java @@ -1,13 +1,16 @@ package eu.siacs.conversations.xmpp.manager; import android.content.Context; +import android.util.Log; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import eu.siacs.conversations.Config; import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.XmppConnection; import im.conversations.android.xmpp.model.stanza.Iq; import im.conversations.android.xmpp.model.vcard.VCard; +import java.util.Objects; public class VCardManager extends AbstractManager { @@ -49,4 +52,30 @@ public class VCardManager extends AbstractManager { }, MoreExecutors.directExecutor()); } + + public ListenableFuture publish(final VCard vCard) { + final var iq = new Iq(Iq.Type.SET, vCard); + iq.setTo(getAccount().getJid().asBareJid()); + return Futures.transform( + connection.sendIqPacket(iq), result -> null, MoreExecutors.directExecutor()); + } + + public ListenableFuture deletePhoto() { + final var vCardFuture = retrieve(getAccount().getJid().asBareJid()); + return Futures.transformAsync( + vCardFuture, + vCard -> { + final var photo = vCard.getPhoto(); + if (photo == null) { + return Futures.immediateFuture(null); + } + Log.d( + Config.LOGTAG, + "deleting photo from vCard. binaryValue=" + + Objects.nonNull(photo.getBinaryValue())); + photo.clearChildren(); + return publish(vCard); + }, + MoreExecutors.directExecutor()); + } }