diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services/XmppConnectionService.java')
-rw-r--r-- | src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 91 |
1 files changed, 80 insertions, 11 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index d4fda1b86..4fa5ddfff 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -72,7 +72,10 @@ import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; +import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Presences; +import eu.siacs.conversations.entities.Roster; +import eu.siacs.conversations.entities.ServiceDiscoveryResult; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.generator.IqGenerator; @@ -244,6 +247,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private OnKeyStatusUpdated mOnKeyStatusUpdated = null; private int keyStatusUpdatedListenerCount = 0; private SecureRandom mRandom; + private LruCache<Pair<String,String>,ServiceDiscoveryResult> discoCache = new LruCache<>(20); private final OnBindListener mOnBindListener = new OnBindListener() { @Override @@ -334,7 +338,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public PgpEngine getPgpEngine() { - if (pgpServiceConnection.isBound()) { + if (pgpServiceConnection != null && pgpServiceConnection.isBound()) { if (this.mPgpEngine == null) { this.mPgpEngine = new PgpEngine(new OpenPgpApi( getApplicationContext(), @@ -596,13 +600,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return getPreferences().getString("picture_compression", "auto"); } - private int getTargetPresence() { + private Presence.Status getTargetPresence() { if (xaOnSilentMode() && isPhoneSilenced()) { - return Presences.XA; + return Presence.Status.XA; } else if (awayWhenScreenOff() && !isInteractive()) { - return Presences.AWAY; + return Presence.Status.AWAY; } else { - return Presences.ONLINE; + return Presence.Status.ONLINE; } } @@ -1001,6 +1005,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final Element query = packet.query(); final HashMap<Jid, Bookmark> bookmarks = new HashMap<>(); final Element storage = query.findChild("storage", "storage:bookmarks"); + final boolean autojoin = respectAutojoin(); if (storage != null) { for (final Element item : storage.getChildren()) { if (item.getName().equals("conference")) { @@ -1012,7 +1017,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Conversation conversation = find(bookmark); if (conversation != null) { conversation.setBookmark(bookmark); - } else if (bookmark.autojoin() && bookmark.getJid() != null) { + } else if (bookmark.autojoin() && bookmark.getJid() != null && autojoin) { conversation = findOrCreateConversation( account, bookmark.getJid(), true); conversation.setBookmark(bookmark); @@ -1210,6 +1215,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) { if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation, callback)) { return; + } else if (timestamp == 0) { + return; } Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp)); Runnable runnable = new Runnable() { @@ -1222,10 +1229,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa checkDeletedFiles(conversation); callback.onMoreMessagesLoaded(messages.size(), conversation); } else if (conversation.hasMessagesLeftOnServer() - && account.isOnlineAndConnected()) { + && account.isOnlineAndConnected() + && conversation.getLastClearHistory() == 0) { if ((conversation.getMode() == Conversation.MODE_SINGLE && account.getXmppConnection().getFeatures().mam()) || (conversation.getMode() == Conversation.MODE_MULTI && conversation.getMucOptions().mamSupport())) { - MessageArchiveService.Query query = getMessageArchiveService().query(conversation, 0, timestamp - 1); + MessageArchiveService.Query query = getMessageArchiveService().query(conversation, 0, timestamp); if (query != null) { query.setCallback(callback); } @@ -1330,7 +1338,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getAccount().getStatus() == Account.State.ONLINE) { Bookmark bookmark = conversation.getBookmark(); - if (bookmark != null && bookmark.autojoin()) { + if (bookmark != null && bookmark.autojoin() && respectAutojoin()) { bookmark.setAutojoin(false); pushBookmarks(bookmark.getAccount()); } @@ -1791,7 +1799,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (conversation.getMode() == Conversation.MODE_MULTI) { conversation.getMucOptions().setPassword(password); if (conversation.getBookmark() != null) { - conversation.getBookmark().setAutojoin(true); + if (respectAutojoin()) { + conversation.getBookmark().setAutojoin(true); + } pushBookmarks(conversation.getAccount()); } databaseBackend.updateConversation(conversation); @@ -2578,6 +2588,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return !getPreferences().getBoolean("dont_save_encrypted", false); } + private boolean respectAutojoin() { + return getPreferences().getBoolean("autojoin", true); + } + public boolean indicateReceived() { return getPreferences().getBoolean("indicate_received", false); } @@ -2900,6 +2914,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void clearConversationHistory(final Conversation conversation) { conversation.clearMessages(); conversation.setHasMessagesLeftOnServer(false); //avoid messages getting loaded through mam + conversation.setLastClearHistory(System.currentTimeMillis()); Runnable runnable = new Runnable() { @Override public void run() { @@ -2948,13 +2963,67 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() == IqPacket.TYPE.ERROR) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not publish nick"); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not publish nick"); } } }); } } + private ServiceDiscoveryResult getCachedServiceDiscoveryResult(Pair<String,String> key) { + ServiceDiscoveryResult result = discoCache.get(key); + if (result != null) { + return result; + } else { + result = databaseBackend.findDiscoveryResult(key.first, key.second); + if (result != null) { + discoCache.put(key, result); + } + return result; + } + } + + public void fetchCaps(Account account, final Jid jid, final Presence presence) { + final Pair<String,String> key = new Pair<>(presence.getHash(), presence.getVer()); + ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key); + if (disco != null) { + presence.setServiceDiscoveryResult(disco); + } else { + if (!account.inProgressDiscoFetches.contains(key)) { + account.inProgressDiscoFetches.add(key); + IqPacket request = new IqPacket(IqPacket.TYPE.GET); + request.setTo(jid); + request.query("http://jabber.org/protocol/disco#info"); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": making disco request for "+key.second+" to "+jid); + sendIqPacket(account, request, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket discoPacket) { + if (discoPacket.getType() == IqPacket.TYPE.RESULT) { + ServiceDiscoveryResult disco = new ServiceDiscoveryResult(discoPacket); + if (presence.getVer().equals(disco.getVer())) { + databaseBackend.insertDiscoveryResult(disco); + injectServiceDiscorveryResult(account.getRoster(), presence.getHash(), presence.getVer(), disco); + } else { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": mismatch in caps for contact " + jid+" "+presence.getVer()+" vs "+disco.getVer()); + } + } + account.inProgressDiscoFetches.remove(key); + } + }); + } + } + } + + private void injectServiceDiscorveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) { + for(Contact contact : roster.getContacts()) { + for(Presence presence : contact.getPresences().getPresences().values()) { + if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) { + presence.setServiceDiscoveryResult(disco); + } + } + } + } + public interface OnAccountCreated { void onAccountCreated(Account account); |