Use MAM for MUC initial history retrieval

If the MUC supports MAM (XEP-0313), use it to retrieve the history
when joining.
This commit is contained in:
saqura 2015-10-05 00:45:16 +02:00 committed by Daniel Gultsch
parent 05d0c9f4fe
commit fd61d67dab
2 changed files with 66 additions and 28 deletions

View file

@ -54,6 +54,18 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
this.execute(query); this.execute(query);
} }
public void catchupMUC(final Conversation conversation) {
if (conversation.getLastMessageTransmitted() < 0 && conversation.countMessages() == 0) {
query(conversation,
0,
System.currentTimeMillis());
} else {
query(conversation,
conversation.getLastMessageTransmitted(),
System.currentTimeMillis());
}
}
private long getLastMessageTransmitted(final Account account) { private long getLastMessageTransmitted(final Account account) {
long timestamp = 0; long timestamp = 0;
for(final Conversation conversation : mXmppConnectionService.getConversations()) { for(final Conversation conversation : mXmppConnectionService.getConversations()) {

View file

@ -1064,10 +1064,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) { public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) {
Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp));
if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation,callback)) { if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation,callback)) {
return; return;
} }
Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp));
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
@ -1480,7 +1480,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
public void joinMuc(Conversation conversation) { public void joinMuc(Conversation conversation) {
joinMuc(conversation,false); joinMuc(conversation, false);
} }
private void joinMuc(Conversation conversation, boolean now) { private void joinMuc(Conversation conversation, boolean now) {
@ -1489,32 +1489,47 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
account.pendingConferenceLeaves.remove(conversation); account.pendingConferenceLeaves.remove(conversation);
if (account.getStatus() == Account.State.ONLINE || now) { if (account.getStatus() == Account.State.ONLINE || now) {
conversation.resetMucOptions(); conversation.resetMucOptions();
final String nick = conversation.getMucOptions().getProposedNick(); fetchConferenceConfiguration(conversation, new OnConferenceConfigurationFetched() {
final Jid joinJid = conversation.getMucOptions().createJoinJid(nick); @Override
if (joinJid == null) { public void onConferenceConfigurationFetched(Conversation conversation) {
return; //safety net Account account = conversation.getAccount();
} final String nick = conversation.getMucOptions().getProposedNick();
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": joining conversation " + joinJid.toString()); final Jid joinJid = conversation.getMucOptions().createJoinJid(nick);
PresencePacket packet = new PresencePacket(); if (joinJid == null) {
packet.setFrom(conversation.getAccount().getJid()); return; //safety net
packet.setTo(joinJid); }
Element x = packet.addChild("x", "http://jabber.org/protocol/muc"); Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": joining conversation " + joinJid.toString());
if (conversation.getMucOptions().getPassword() != null) { PresencePacket packet = new PresencePacket();
x.addChild("password").setContent(conversation.getMucOptions().getPassword()); packet.setFrom(conversation.getAccount().getJid());
} packet.setTo(joinJid);
x.addChild("history").setAttribute("since", PresenceGenerator.getTimestamp(conversation.getLastMessageTransmitted())); Element x = packet.addChild("x", "http://jabber.org/protocol/muc");
String sig = account.getPgpSignature(); if (conversation.getMucOptions().getPassword() != null) {
if (sig != null) { x.addChild("password").setContent(conversation.getMucOptions().getPassword());
packet.addChild("status").setContent("online"); }
packet.addChild("x", "jabber:x:signed").setContent(sig);
} if (conversation.getMucOptions().mamSupport()) {
sendPresencePacket(account, packet); // Use MAM instead of the limited muc history to get history
fetchConferenceConfiguration(conversation); x.addChild("history").setAttribute("maxchars", "0");
if (!joinJid.equals(conversation.getJid())) { getMessageArchiveService().catchupMUC(conversation);
conversation.setContactJid(joinJid); } else {
databaseBackend.updateConversation(conversation); // Fallback to muc history
} x.addChild("history").setAttribute("since", PresenceGenerator.getTimestamp(conversation.getLastMessageTransmitted()));
conversation.setHasMessagesLeftOnServer(false); }
String sig = account.getPgpSignature();
if (sig != null) {
packet.addChild("status").setContent("online");
packet.addChild("x", "jabber:x:signed").setContent(sig);
}
sendPresencePacket(account, packet);
fetchConferenceConfiguration(conversation);
if (!joinJid.equals(conversation.getJid())) {
conversation.setContactJid(joinJid);
databaseBackend.updateConversation(conversation);
}
conversation.setHasMessagesLeftOnServer(false);
}
});
} else { } else {
account.pendingConferenceJoins.add(conversation); account.pendingConferenceJoins.add(conversation);
} }
@ -1674,6 +1689,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
public void fetchConferenceConfiguration(final Conversation conversation) { public void fetchConferenceConfiguration(final Conversation conversation) {
fetchConferenceConfiguration(conversation, null);
}
public void fetchConferenceConfiguration(final Conversation conversation, final OnConferenceConfigurationFetched callback) {
IqPacket request = new IqPacket(IqPacket.TYPE.GET); IqPacket request = new IqPacket(IqPacket.TYPE.GET);
request.setTo(conversation.getJid().toBareJid()); request.setTo(conversation.getJid().toBareJid());
request.query("http://jabber.org/protocol/disco#info"); request.query("http://jabber.org/protocol/disco#info");
@ -1691,6 +1710,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
} }
conversation.getMucOptions().updateFeatures(features); conversation.getMucOptions().updateFeatures(features);
if (callback != null) {
callback.onConferenceConfigurationFetched(conversation);
}
updateConversationUi(); updateConversationUi();
} }
} }
@ -2631,6 +2653,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public void onMucRosterUpdate(); public void onMucRosterUpdate();
} }
public interface OnConferenceConfigurationFetched {
public void onConferenceConfigurationFetched(Conversation conversation);
}
public interface OnConferenceOptionsPushed { public interface OnConferenceOptionsPushed {
public void onPushSucceeded(); public void onPushSucceeded();