aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/services
diff options
context:
space:
mode:
authorChristian S <christian@pix-art.de>2016-02-04 18:02:03 +0100
committerChristian S <christian@pix-art.de>2016-02-04 18:02:03 +0100
commit14b688e0fbe62a0fef0fadcc20763faa21801d7a (patch)
tree37fc7b87aa21326b0ca7ba97fee84aaf0ea6d3c2 /src/main/java/eu/siacs/conversations/services
parent9e96d80e31c5d0455c4b15984eef5709cf1071fc (diff)
parent91ec4839acef3e395e83815f211dd9771af1287e (diff)
Merge remote-tracking branch 'siacs/master' into development
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services')
-rw-r--r--src/main/java/eu/siacs/conversations/services/MessageArchiveService.java39
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java91
2 files changed, 101 insertions, 29 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java
index 4403f99cd..165c7c2a8 100644
--- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java
+++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java
@@ -24,13 +24,13 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
private final XmppConnectionService mXmppConnectionService;
- private final HashSet<Query> queries = new HashSet<Query>();
- private final ArrayList<Query> pendingQueries = new ArrayList<Query>();
+ private final HashSet<Query> queries = new HashSet<>();
+ private final ArrayList<Query> pendingQueries = new ArrayList<>();
public enum PagingOrder {
NORMAL,
REVERSE
- };
+ }
public MessageArchiveService(final XmppConnectionService service) {
this.mXmppConnectionService = service;
@@ -102,6 +102,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
return null;
}
final Query query = new Query(conversation, start, end,PagingOrder.REVERSE);
+ query.reference = conversation.getFirstMamReference();
this.queries.add(query);
this.execute(query);
return query;
@@ -136,12 +137,12 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
synchronized (MessageArchiveService.this.queries) {
MessageArchiveService.this.queries.remove(query);
if (query.hasCallback()) {
- query.callback();
+ query.callback(false);
}
}
} else if (packet.getType() != IqPacket.TYPE.RESULT) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": error executing mam: " + packet.toString());
- finalizeQuery(query);
+ finalizeQuery(query, true);
}
}
});
@@ -152,14 +153,14 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
}
}
- private void finalizeQuery(Query query) {
+ private void finalizeQuery(Query query, boolean done) {
synchronized (this.queries) {
this.queries.remove(query);
}
final Conversation conversation = query.getConversation();
if (conversation != null) {
conversation.sort();
- conversation.setHasMessagesLeftOnServer(query.getMessageCount() > 0);
+ conversation.setHasMessagesLeftOnServer(!done);
} else {
for(Conversation tmp : this.mXmppConnectionService.getConversations()) {
if (tmp.getAccount() == query.getAccount()) {
@@ -168,7 +169,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
}
}
if (query.hasCallback()) {
- query.callback();
+ query.callback(done);
} else {
this.mXmppConnectionService.updateConversationUi();
}
@@ -202,9 +203,13 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
Element first = set == null ? null : set.findChild("first");
Element relevant = query.getPagingOrder() == PagingOrder.NORMAL ? last : first;
boolean abort = (query.getStart() == 0 && query.getTotalCount() >= Config.PAGE_SIZE) || query.getTotalCount() >= Config.MAM_MAX_MESSAGES;
+ if (query.getConversation() != null) {
+ query.getConversation().setFirstMamReference(first == null ? null : first.getContent());
+ }
if (complete || relevant == null || abort) {
- this.finalizeQuery(query);
- Log.d(Config.LOGTAG,query.getAccount().getJid().toBareJid().toString()+": finished mam after "+query.getTotalCount()+" messages");
+ final boolean done = (complete || query.getMessageCount() == 0) && query.getStart() == 0;
+ this.finalizeQuery(query, done);
+ Log.d(Config.LOGTAG,query.getAccount().getJid().toBareJid()+": finished mam after "+query.getTotalCount()+" messages. messages left="+Boolean.toString(!done));
if (query.getWith() == null && query.getMessageCount() > 0) {
mXmppConnectionService.getNotificationService().finishBacklog(true);
}
@@ -216,7 +221,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
nextQuery = query.prev(first == null ? null : first.getContent());
}
this.execute(nextQuery);
- this.finalizeQuery(query);
+ this.finalizeQuery(query, false);
synchronized (this.queries) {
this.queries.remove(query);
this.queries.add(nextQuery);
@@ -324,10 +329,10 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
this.callback = callback;
}
- public void callback() {
+ public void callback(boolean done) {
if (this.callback != null) {
this.callback.onMoreMessagesLoaded(messageCount,conversation);
- if (messageCount == 0) {
+ if (done) {
this.callback.informUser(R.string.no_more_history_on_server);
}
}
@@ -345,12 +350,9 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
return this.account;
}
- public void incrementTotalCount() {
- this.totalCount++;
- }
-
public void incrementMessageCount() {
this.messageCount++;
+ this.totalCount++;
}
public int getTotalCount() {
@@ -373,7 +375,8 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
public String toString() {
StringBuilder builder = new StringBuilder();
if (this.muc()) {
- builder.append("to="+this.getWith().toString());
+ builder.append("to=");
+ builder.append(this.getWith().toString());
} else {
builder.append("with=");
if (this.getWith() == null) {
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);