set access model to open when publishing avatar. fixes #3291

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java  |  7 
src/main/java/eu/siacs/conversations/generator/IqGenerator.java          |  8 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 91 
src/main/java/eu/siacs/conversations/xmpp/pep/PublishOptions.java        |  9 
4 files changed, 82 insertions(+), 33 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java 🔗

@@ -586,7 +586,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 			@Override
 			public void onIqPacketReceived(Account account, IqPacket packet) {
 				final Element error = packet.getType() == IqPacket.TYPE.ERROR ? packet.findChild("error") : null;
-				final boolean preConditionNotMet = error != null && error.hasChild("precondition-not-met", Namespace.PUBSUB_ERROR);
+				final boolean preConditionNotMet = PublishOptions.preconditionNotMet(packet);
 				if (firstAttempt && preConditionNotMet) {
 					Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": precondition wasn't met for device list. pushing node configuration");
 					mXmppConnectionService.pushNodeConfiguration(account, AxolotlService.PEP_DEVICE_LIST, publishOptions, new XmppConnectionService.OnConfigurationPushed() {
@@ -802,8 +802,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
 			@Override
 			public void onIqPacketReceived(final Account account, IqPacket packet) {
-				final Element error = packet.getType() == IqPacket.TYPE.ERROR ? packet.findChild("error") : null;
-				final boolean preconditionNotMet = error != null && error.hasChild("precondition-not-met", Namespace.PUBSUB_ERROR);
+				final boolean preconditionNotMet = PublishOptions.preconditionNotMet(packet);
 				if (firstAttempt && preconditionNotMet) {
 					Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": precondition wasn't met for bundle. pushing node configuration");
 					final String node = AxolotlService.PEP_BUNDLES + ":" + getOwnDeviceId();
@@ -830,7 +829,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 					if (preconditionNotMet) {
 						Log.d(Config.LOGTAG,getLogprefix(account) + "bundle precondition still not met after second attempt");
 					} else {
-						Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing bundle: " + error);
+						Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing bundle: " + packet.toString());
 					}
 					pepBroken = true;
 				}

src/main/java/eu/siacs/conversations/generator/IqGenerator.java 🔗

@@ -138,12 +138,12 @@ public class IqGenerator extends AbstractGenerator {
 		return packet;
 	}
 
-	public IqPacket publishAvatar(Avatar avatar) {
+	public IqPacket publishAvatar(Avatar avatar, Bundle options) {
 		final Element item = new Element("item");
 		item.setAttribute("id", avatar.sha1sum);
 		final Element data = item.addChild("data", "urn:xmpp:avatar:data");
 		data.setContent(avatar.image);
-		return publish("urn:xmpp:avatar:data", item);
+		return publish("urn:xmpp:avatar:data", item, options);
 	}
 
 	public IqPacket publishElement(final String namespace,final Element element, final Bundle options) {
@@ -153,7 +153,7 @@ public class IqGenerator extends AbstractGenerator {
 		return publish(namespace, item, options);
 	}
 
-	public IqPacket publishAvatarMetadata(final Avatar avatar) {
+	public IqPacket publishAvatarMetadata(final Avatar avatar, final Bundle options) {
 		final Element item = new Element("item");
 		item.setAttribute("id", avatar.sha1sum);
 		final Element metadata = item
@@ -164,7 +164,7 @@ public class IqGenerator extends AbstractGenerator {
 		info.setAttribute("height", avatar.height);
 		info.setAttribute("width", avatar.height);
 		info.setAttribute("type", avatar.type);
-		return publish("urn:xmpp:avatar:metadata", item);
+		return publish("urn:xmpp:avatar:metadata", item, options);
 	}
 
 	public IqPacket retrievePepAvatar(final Avatar avatar) {

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -1473,9 +1473,7 @@ public class XmppConnectionService extends Service {
             if (response.getType() == IqPacket.TYPE.RESULT) {
                 return;
             }
-            final Element error = response.getType() == IqPacket.TYPE.ERROR ? response.findChild("error") : null;
-            final boolean preconditionNotMet = error != null && error.hasChild("precondition-not-met", Namespace.PUBSUB_ERROR);
-            if (retry && preconditionNotMet) {
+            if (retry && PublishOptions.preconditionNotMet(response)) {
                 pushNodeConfiguration(account, node, options, new OnConfigurationPushed() {
                     @Override
                     public void onPushSucceeded() {
@@ -2940,33 +2938,39 @@ public class XmppConnectionService extends Service {
 		});
 	}
 
-	public void publishAvatar(Account account, final Avatar avatar, final OnAvatarPublication callback) {
-		IqPacket packet = this.mIqGenerator.publishAvatar(avatar);
+    public void publishAvatar(Account account, final Avatar avatar, final OnAvatarPublication callback) {
+        final Bundle options;
+        if (account.getXmppConnection().getFeatures().pepPublishOptions()) {
+            options = PublishOptions.openAccess();
+        } else {
+            options = null;
+        }
+        publishAvatar(account, avatar, options, true, callback);
+    }
+
+	public void publishAvatar(Account account, final Avatar avatar, final Bundle options, final boolean retry, final OnAvatarPublication callback) {
+        Log.d(Config.LOGTAG,account.getJid().asBareJid()+": publishing avatar. options="+options);
+		IqPacket packet = this.mIqGenerator.publishAvatar(avatar, options);
 		this.sendIqPacket(account, packet, new OnIqPacketReceived() {
 
 			@Override
 			public void onIqPacketReceived(Account account, IqPacket result) {
 				if (result.getType() == IqPacket.TYPE.RESULT) {
-					final IqPacket packet = XmppConnectionService.this.mIqGenerator.publishAvatarMetadata(avatar);
-					sendIqPacket(account, packet, new OnIqPacketReceived() {
-						@Override
-						public void onIqPacketReceived(Account account, IqPacket result) {
-							if (result.getType() == IqPacket.TYPE.RESULT) {
-								if (account.setAvatar(avatar.getFilename())) {
-									getAvatarService().clear(account);
-									databaseBackend.updateAccount(account);
-								}
-								Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": published avatar " + (avatar.size / 1024) + "KiB");
-								if (callback != null) {
-									callback.onAvatarPublicationSucceeded();
-								}
-							} else {
-								if (callback != null) {
-									callback.onAvatarPublicationFailed(R.string.error_publish_avatar_server_reject);
-								}
-							}
-						}
-					});
+                    publishAvatarMetadata(account, avatar, options,true, callback);
+                } else if (retry && PublishOptions.preconditionNotMet(result)) {
+				    pushNodeConfiguration(account, "urn:xmpp:avatar:data", options, new OnConfigurationPushed() {
+                        @Override
+                        public void onPushSucceeded() {
+                            Log.d(Config.LOGTAG,account.getJid().asBareJid()+": changed node configuration for avatar node");
+                            publishAvatar(account, avatar, options, false, callback);
+                        }
+
+                        @Override
+                        public void onPushFailed() {
+                            Log.d(Config.LOGTAG,account.getJid().asBareJid()+": unable to change node configuration for avatar node");
+                            publishAvatar(account, avatar, null, false, callback);
+                        }
+                    });
 				} else {
 					Element error = result.findChild("error");
 					Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": server rejected avatar " + (avatar.size / 1024) + "KiB " + (error != null ? error.toString() : ""));
@@ -2978,6 +2982,43 @@ public class XmppConnectionService extends Service {
 		});
 	}
 
+	public void publishAvatarMetadata(Account account, final Avatar avatar, final Bundle options, final boolean retry, final OnAvatarPublication callback) {
+        final IqPacket packet = XmppConnectionService.this.mIqGenerator.publishAvatarMetadata(avatar, options);
+        sendIqPacket(account, packet, new OnIqPacketReceived() {
+            @Override
+            public void onIqPacketReceived(Account account, IqPacket result) {
+                if (result.getType() == IqPacket.TYPE.RESULT) {
+                    if (account.setAvatar(avatar.getFilename())) {
+                        getAvatarService().clear(account);
+                        databaseBackend.updateAccount(account);
+                    }
+                    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": published avatar " + (avatar.size / 1024) + "KiB");
+                    if (callback != null) {
+                        callback.onAvatarPublicationSucceeded();
+                    }
+                } else if (retry && PublishOptions.preconditionNotMet(result)) {
+                    pushNodeConfiguration(account, "urn:xmpp:avatar:metadata", options, new OnConfigurationPushed() {
+                        @Override
+                        public void onPushSucceeded() {
+                            Log.d(Config.LOGTAG,account.getJid().asBareJid()+": changed node configuration for avatar meta data node");
+                            publishAvatarMetadata(account, avatar, options,false, callback);
+                        }
+
+                        @Override
+                        public void onPushFailed() {
+                            Log.d(Config.LOGTAG,account.getJid().asBareJid()+": unable to change node configuration for avatar meta data node");
+                            publishAvatarMetadata(account, avatar,  null,false, callback);
+                        }
+                    });
+                } else {
+                    if (callback != null) {
+                        callback.onAvatarPublicationFailed(R.string.error_publish_avatar_server_reject);
+                    }
+                }
+            }
+        });
+    }
+
 	public void republishAvatarIfNeeded(Account account) {
 		if (account.getAxolotlService().isPepBroken()) {
 			Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": skipping republication of avatar because pep is broken");

src/main/java/eu/siacs/conversations/xmpp/pep/PublishOptions.java 🔗

@@ -2,6 +2,10 @@ package eu.siacs.conversations.xmpp.pep;
 
 import android.os.Bundle;
 
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xml.Namespace;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
+
 public class PublishOptions {
 
     private PublishOptions() {
@@ -21,4 +25,9 @@ public class PublishOptions {
         return options;
     }
 
+    public static boolean preconditionNotMet(IqPacket response) {
+        final Element error = response.getType() == IqPacket.TYPE.ERROR ? response.findChild("error") : null;
+        return error != null && error.hasChild("precondition-not-met", Namespace.PUBSUB_ERROR);
+    }
+
 }