disable offline messages. postpone prekey handling until after mam catchup
This commit is contained in:
parent
036dd82698
commit
6009b8ebf0
|
@ -55,6 +55,7 @@ import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
import eu.siacs.conversations.xmpp.pep.PublishOptions;
|
import eu.siacs.conversations.xmpp.pep.PublishOptions;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||||
|
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||||
|
|
||||||
public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
private int numPublishTriesOnEmptyPep = 0;
|
private int numPublishTriesOnEmptyPep = 0;
|
||||||
private boolean pepBroken = false;
|
private boolean pepBroken = false;
|
||||||
private int lastDeviceListNotificationHash = 0;
|
private int lastDeviceListNotificationHash = 0;
|
||||||
|
private Set<XmppAxolotlSession> postponedSessions = new HashSet<>(); //sessions stored here will receive after mam catchup treatment
|
||||||
|
|
||||||
private AtomicBoolean changeAccessMode = new AtomicBoolean(false);
|
private AtomicBoolean changeAccessMode = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
@ -325,7 +327,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Collection<XmppAxolotlSession> findSessionsForContact(Contact contact) {
|
public Collection<XmppAxolotlSession> findSessionsForContact(Contact contact) {
|
||||||
SignalProtocolAddress contactAddress = getAddressForJid(contact.getJid());
|
SignalProtocolAddress contactAddress = getAddressForJid(contact.getJid());
|
||||||
ArrayList<XmppAxolotlSession> s = new ArrayList<>(this.sessions.getAll(contactAddress.getName()).values());
|
ArrayList<XmppAxolotlSession> s = new ArrayList<>(this.sessions.getAll(contactAddress.getName()).values());
|
||||||
|
@ -1243,6 +1244,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage());
|
Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
//TODO: fix this for MUC PMs - Don't encrypt to all participants
|
||||||
if (!buildHeader(axolotlMessage, message.getConversation())) {
|
if (!buildHeader(axolotlMessage, message.getConversation())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1335,10 +1337,38 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postPreKeyMessageHandling(final XmppAxolotlSession session, int preKeyId, final boolean postpone) {
|
private void postPreKeyMessageHandling(final XmppAxolotlSession session, int preKeyId, final boolean postpone) {
|
||||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": postPreKeyMessageHandling() preKeyId="+preKeyId+", postpone="+Boolean.toString(postpone));
|
if (postpone) {
|
||||||
|
postponedSessions.add(session);
|
||||||
|
} else {
|
||||||
//TODO: do not republish if we already removed this preKeyId
|
//TODO: do not republish if we already removed this preKeyId
|
||||||
publishBundlesIfNeeded(false, false);
|
publishBundlesIfNeeded(false, false);
|
||||||
|
completeSession(session);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processPostponed() {
|
||||||
|
if (postponedSessions.size() > 0) {
|
||||||
|
publishBundlesIfNeeded(false, false);
|
||||||
|
}
|
||||||
|
Iterator<XmppAxolotlSession> iterator = postponedSessions.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
completeSession(iterator.next());
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void completeSession(XmppAxolotlSession session) {
|
||||||
|
final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().toBareJid(), getOwnDeviceId());
|
||||||
|
axolotlMessage.addDevice(session);
|
||||||
|
try {
|
||||||
|
Jid jid = Jid.fromString(session.getRemoteAddress().getName());
|
||||||
|
MessagePacket packet = mXmppConnectionService.getMessageGenerator().generateKeyTransportMessage(jid, axolotlMessage);
|
||||||
|
mXmppConnectionService.sendMessagePacket(account, packet);
|
||||||
|
} catch (InvalidJidException e) {
|
||||||
|
throw new Error("Remote addresses are created from jid and should convert back to jid", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public XmppAxolotlMessage.XmppAxolotlKeyTransportMessage processReceivingKeyTransportMessage(XmppAxolotlMessage message, final boolean postponePreKeyMessageHandling) {
|
public XmppAxolotlMessage.XmppAxolotlKeyTransportMessage processReceivingKeyTransportMessage(XmppAxolotlMessage message, final boolean postponePreKeyMessageHandling) {
|
||||||
XmppAxolotlMessage.XmppAxolotlKeyTransportMessage keyTransportMessage;
|
XmppAxolotlMessage.XmppAxolotlKeyTransportMessage keyTransportMessage;
|
||||||
|
|
|
@ -45,8 +45,7 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
final IqPacket packet = new IqPacket(IqPacket.TYPE.RESULT);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE.RESULT);
|
||||||
packet.setId(request.getId());
|
packet.setId(request.getId());
|
||||||
packet.setTo(request.getFrom());
|
packet.setTo(request.getFrom());
|
||||||
final Element query = packet.addChild("query",
|
final Element query = packet.addChild("query", "http://jabber.org/protocol/disco#info");
|
||||||
"http://jabber.org/protocol/disco#info");
|
|
||||||
query.setAttribute("node", request.query().getAttribute("node"));
|
query.setAttribute("node", request.query().getAttribute("node"));
|
||||||
final Element identity = query.addChild("identity");
|
final Element identity = query.addChild("identity");
|
||||||
identity.setAttribute("category", "client");
|
identity.setAttribute("category", "client");
|
||||||
|
@ -91,6 +90,12 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IqPacket purgeOfflineMessages() {
|
||||||
|
final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
|
||||||
|
packet.addChild("offline",Namespace.FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL).addChild("purge");
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
protected IqPacket publish(final String node, final Element item, final Bundle options) {
|
protected IqPacket publish(final String node, final Element item, final Bundle options) {
|
||||||
final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
|
||||||
final Element pubsub = packet.addChild("pubsub",
|
final Element pubsub = packet.addChild("pubsub",
|
||||||
|
|
|
@ -91,6 +91,15 @@ public class MessageGenerator extends AbstractGenerator {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MessagePacket generateKeyTransportMessage(Jid to, XmppAxolotlMessage axolotlMessage) {
|
||||||
|
MessagePacket packet = new MessagePacket();
|
||||||
|
packet.setType(MessagePacket.TYPE_CHAT);
|
||||||
|
packet.setTo(to);
|
||||||
|
packet.setAxolotlMessage(axolotlMessage.toElement());
|
||||||
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean recipientSupportsOmemo(Message message) {
|
private static boolean recipientSupportsOmemo(Message message) {
|
||||||
Contact c = message.getContact();
|
Contact c = message.getContact();
|
||||||
return c != null && c.getPresences().allOrNonSupport(AxolotlService.PEP_DEVICE_LIST_NOTIFY);
|
return c != null && c.getPresences().allOrNonSupport(AxolotlService.PEP_DEVICE_LIST_NOTIFY);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
|
|
||||||
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.axolotl.AxolotlService;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.generator.AbstractGenerator;
|
import eu.siacs.conversations.generator.AbstractGenerator;
|
||||||
|
@ -222,6 +223,17 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean inCatchup(Account account) {
|
||||||
|
synchronized (this.queries) {
|
||||||
|
for(Query query : queries) {
|
||||||
|
if (query.account == account && query.isCatchup() && query.getWith() == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean queryInProgress(Conversation conversation, XmppConnectionService.OnMoreMessagesLoaded callback) {
|
public boolean queryInProgress(Conversation conversation, XmppConnectionService.OnMoreMessagesLoaded callback) {
|
||||||
synchronized (this.queries) {
|
synchronized (this.queries) {
|
||||||
for(Query query : queries) {
|
for(Query query : queries) {
|
||||||
|
@ -268,6 +280,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
if (query.isCatchup() && query.getActualMessageCount() > 0) {
|
if (query.isCatchup() && query.getActualMessageCount() > 0) {
|
||||||
mXmppConnectionService.getNotificationService().finishBacklog(true,query.getAccount());
|
mXmppConnectionService.getNotificationService().finishBacklog(true,query.getAccount());
|
||||||
}
|
}
|
||||||
|
query.account.getAxolotlService().processPostponed();
|
||||||
} else {
|
} else {
|
||||||
final Query nextQuery;
|
final Query nextQuery;
|
||||||
if (query.getPagingOrder() == PagingOrder.NORMAL) {
|
if (query.getPagingOrder() == PagingOrder.NORMAL) {
|
||||||
|
|
|
@ -303,6 +303,15 @@ public class XmppConnectionService extends Service {
|
||||||
mJingleConnectionManager.cancelInTransmission();
|
mJingleConnectionManager.cancelInTransmission();
|
||||||
fetchRosterFromServer(account);
|
fetchRosterFromServer(account);
|
||||||
fetchBookmarks(account);
|
fetchBookmarks(account);
|
||||||
|
final boolean flexible= account.getXmppConnection().getFeatures().flexibleOfflineMessageRetrieval();
|
||||||
|
final boolean catchup = getMessageArchiveService().inCatchup(account);
|
||||||
|
if (flexible && catchup) {
|
||||||
|
sendIqPacket(account, mIqGenerator.purgeOfflineMessages(), (acc, packet) -> {
|
||||||
|
if (packet.getType() == IqPacket.TYPE.RESULT) {
|
||||||
|
Log.d(Config.LOGTAG, acc.getJid().toBareJid()+": successfully purged offline messages");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
sendPresence(account);
|
sendPresence(account);
|
||||||
if (mPushManagementService.available(account)) {
|
if (mPushManagementService.available(account)) {
|
||||||
mPushManagementService.registerPushTokenOnServer(account);
|
mPushManagementService.registerPushTokenOnServer(account);
|
||||||
|
|
|
@ -16,4 +16,5 @@ public final class Namespace {
|
||||||
public static final String PUBSUB_PUBLISH_OPTIONS = "http://jabber.org/protocol/pubsub#publish-options";
|
public static final String PUBSUB_PUBLISH_OPTIONS = "http://jabber.org/protocol/pubsub#publish-options";
|
||||||
public static final String PUBSUB_ERROR = "http://jabber.org/protocol/pubsub#errors";
|
public static final String PUBSUB_ERROR = "http://jabber.org/protocol/pubsub#errors";
|
||||||
public static final String NICK = "http://jabber.org/protocol/nick";
|
public static final String NICK = "http://jabber.org/protocol/nick";
|
||||||
|
public static final String FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL = "http://jabber.org/protocol/offline";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1681,6 +1681,10 @@ public class XmppConnection implements Runnable {
|
||||||
return hasDiscoFeature(account.getServer(), "urn:xmpp:reporting:reason:spam:0");
|
return hasDiscoFeature(account.getServer(), "urn:xmpp:reporting:reason:spam:0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean flexibleOfflineMessageRetrieval() {
|
||||||
|
return hasDiscoFeature(account.getServer(), Namespace.FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean register() {
|
public boolean register() {
|
||||||
return hasDiscoFeature(account.getServer(), Namespace.REGISTER);
|
return hasDiscoFeature(account.getServer(), Namespace.REGISTER);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue