Fix asynchronous axolotl message sending

XmppConnectionService.sendMessage() now dispatches messages to the
AxolotlService, where they only are prepared for sending and cached.
AxolotlService now triggers a XmppConnectionService.resendMessage(),
which then handles sending the cached message packet.

This transparently fixes, e.g., handling of messages sent while we are
offline.
This commit is contained in:
Andreas Straub 2015-07-03 13:31:14 +02:00
parent c5596b34bc
commit 12fc24dd42
2 changed files with 27 additions and 8 deletions

View File

@ -67,6 +67,7 @@ public class AxolotlService {
private final SQLiteAxolotlStore axolotlStore; private final SQLiteAxolotlStore axolotlStore;
private final SessionMap sessions; private final SessionMap sessions;
private final Map<Jid, Set<Integer>> deviceIds; private final Map<Jid, Set<Integer>> deviceIds;
private final Map<String, MessagePacket> messageCache;
private final FetchStatusMap fetchStatusMap; private final FetchStatusMap fetchStatusMap;
private final SerialSingleThreadExecutor executor; private final SerialSingleThreadExecutor executor;
private int ownDeviceId; private int ownDeviceId;
@ -580,6 +581,7 @@ public class AxolotlService {
this.account = account; this.account = account;
this.axolotlStore = new SQLiteAxolotlStore(this.account, this.mXmppConnectionService); this.axolotlStore = new SQLiteAxolotlStore(this.account, this.mXmppConnectionService);
this.deviceIds = new HashMap<>(); this.deviceIds = new HashMap<>();
this.messageCache = new HashMap<>();
this.sessions = new SessionMap(axolotlStore, account); this.sessions = new SessionMap(axolotlStore, account);
this.fetchStatusMap = new FetchStatusMap(); this.fetchStatusMap = new FetchStatusMap();
this.executor = new SerialSingleThreadExecutor(); this.executor = new SerialSingleThreadExecutor();
@ -892,22 +894,37 @@ public class AxolotlService {
.generateAxolotlChat(message); .generateAxolotlChat(message);
if (packet == null) { if (packet == null) {
mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED);
//mXmppConnectionService.updateConversationUi();
} else { } else {
mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND); Log.d(Config.LOGTAG, "Generated message, caching: " + message.getUuid());
mXmppConnectionService.sendMessagePacket(account, packet); messageCache.put(message.getUuid(), packet);
mXmppConnectionService.resendMessage(message);
} }
} }
}); });
} }
public void sendMessage(Message message) { public void prepareMessage(Message message) {
boolean newSessions = createSessionsIfNeeded(message.getConversation()); if (!messageCache.containsKey(message.getUuid())) {
boolean newSessions = createSessionsIfNeeded(message.getConversation());
if (!newSessions) { if (!newSessions) {
this.processSending(message); this.processSending(message);
}
} }
} }
public MessagePacket fetchPacketFromCache(Message message) {
MessagePacket packet = messageCache.get(message.getUuid());
if (packet != null) {
Log.d(Config.LOGTAG, "Cache hit: " + message.getUuid());
messageCache.remove(message.getUuid());
} else {
Log.d(Config.LOGTAG, "Cache miss: " + message.getUuid());
}
return packet;
}
public XmppAxolotlMessage.XmppAxolotlPlaintextMessage processReceiving(XmppAxolotlMessage message) { public XmppAxolotlMessage.XmppAxolotlPlaintextMessage processReceiving(XmppAxolotlMessage message) {
XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = null; XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = null;
AxolotlAddress senderAddress = new AxolotlAddress(message.getFrom().toString(), AxolotlAddress senderAddress = new AxolotlAddress(message.getFrom().toString(),

View File

@ -52,7 +52,6 @@ import de.duenndns.ssl.MemorizingTrustManager;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.crypto.axolotl.NoSessionsCreatedException;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Blockable;
import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Bookmark;
@ -759,7 +758,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
break; break;
case Message.ENCRYPTION_AXOLOTL: case Message.ENCRYPTION_AXOLOTL:
message.setStatus(Message.STATUS_WAITING); message.setStatus(Message.STATUS_WAITING);
account.getAxolotlService().sendMessage(message); packet = account.getAxolotlService().fetchPacketFromCache(message);
if (packet == null && account.isOnlineAndConnected()) {
account.getAxolotlService().prepareMessage(message);
}
break; break;
} }