OTR: Fix onContactStatusChanged & dont archive OTR

BrianBlade created

- Fix session handling on contact status change: Do not reset
  potentially active sessions; check peer's OTR-resource on disconnect
- use no-permanent-store hint instead of no-store to ensure
  finished messages are delivered to offline/disconnected clients
- add no-permanent-store to ask compliant servers not to archive
  OTR messages

Change summary

src/main/java/eu/siacs/conversations/crypto/OtrEngine.java               |  2 
src/main/java/eu/siacs/conversations/generator/MessageGenerator.java     |  1 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 20 
3 files changed, 17 insertions(+), 6 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/crypto/OtrEngine.java 🔗

@@ -182,7 +182,7 @@ public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost {
 		packet.setBody(body);
 		packet.addChild("private", "urn:xmpp:carbons:2");
 		packet.addChild("no-copy", "urn:xmpp:hints");
-		packet.addChild("no-store", "urn:xmpp:hints");
+		packet.addChild("no-permanent-store", "urn:xmpp:hints");
 
 		try {
 			Jid jid = Jid.fromSessionID(session);

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

@@ -71,6 +71,7 @@ public class MessageGenerator extends AbstractGenerator {
 		MessagePacket packet = preparePacket(message, addDelay);
 		packet.addChild("private", "urn:xmpp:carbons:2");
 		packet.addChild("no-copy", "urn:xmpp:hints");
+		packet.addChild("no-permanent-store", "urn:xmpp:hints");
 		try {
 			packet.setBody(otrSession.transformSending(message.getBody())[0]);
 			return packet;

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

@@ -36,6 +36,7 @@ import org.openintents.openpgp.util.OpenPgpServiceConnection;
 import java.math.BigInteger;
 import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -174,13 +175,22 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 		public void onContactStatusChanged(Contact contact, boolean online) {
 			Conversation conversation = find(getConversations(), contact);
 			if (conversation != null) {
-				if (online && contact.getPresences().size() > 1) {
+				if (online) {
 					conversation.endOtrIfNeeded();
+					if (contact.getPresences().size() == 1) {
+						sendUnsentMessages(conversation);
+					}
 				} else {
-					conversation.resetOtrSession();
-				}
-				if (online && (contact.getPresences().size() == 1)) {
-					sendUnsentMessages(conversation);
+					if (contact.getPresences().size() >= 1) {
+						if (conversation.hasValidOtrSession()) {
+							String otrResource = conversation.getOtrSession().getSessionID().getUserID();
+							if (!(Arrays.asList(contact.getPresences().asStringArray()).contains(otrResource))) {
+								conversation.endOtrIfNeeded();
+							}
+						}
+					} else {
+						conversation.endOtrIfNeeded();
+					}
 				}
 			}
 		}