diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services')
3 files changed, 182 insertions, 136 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/ExportLogsService.java b/src/main/java/eu/siacs/conversations/services/ExportLogsService.java index 8501c04ad..76983a905 100644 --- a/src/main/java/eu/siacs/conversations/services/ExportLogsService.java +++ b/src/main/java/eu/siacs/conversations/services/ExportLogsService.java @@ -4,18 +4,8 @@ import android.app.NotificationManager; import android.app.Service; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.os.IBinder; import android.support.v4.app.NotificationCompat; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.persistance.DatabaseBackend; -import eu.siacs.conversations.persistance.FileBackend; -import eu.siacs.conversations.xmpp.jid.Jid; - import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; @@ -25,6 +15,14 @@ import java.util.Date; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.persistance.DatabaseBackend; +import eu.siacs.conversations.persistance.FileBackend; +import eu.siacs.conversations.xmpp.jid.Jid; + public class ExportLogsService extends Service { private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); @@ -32,107 +30,113 @@ public class ExportLogsService extends Service { private static final String MESSAGE_STRING_FORMAT = "(%s) %s: %s\n"; private static final int NOTIFICATION_ID = 1; private static AtomicBoolean running = new AtomicBoolean(false); + private DatabaseBackend mDatabaseBackend; + private List<Account> mAccounts; + + @Override + public void onCreate() { + mDatabaseBackend = DatabaseBackend.getInstance(getBaseContext()); + mAccounts = mDatabaseBackend.getAccounts(); + } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (running.compareAndSet(false, true)) { - new Thread( - new Runnable() { - DatabaseBackend databaseBackend = DatabaseBackend.getInstance(getBaseContext()); - List<Account> accounts = databaseBackend.getAccounts(); - - @Override - public void run() { - List<Conversation> conversations = databaseBackend.getConversations(Conversation.STATUS_AVAILABLE); - conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_ARCHIVED)); - - NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext()); - mBuilder.setContentTitle(getString(R.string.notification_export_logs_title)) - .setSmallIcon(R.drawable.ic_import_export_white_24dp) - .setProgress(conversations.size(), 0, false); - startForeground(NOTIFICATION_ID, mBuilder.build()); - - int progress = 0; - for (Conversation conversation : conversations) { - writeToFile(conversation); - progress++; - mBuilder.setProgress(conversations.size(), progress, false); - mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); - } - - running.set(false); - stopForeground(true); - } - - private void writeToFile(Conversation conversation) { - Jid accountJid = resolveAccountUuid(conversation.getAccountUuid()); - Jid contactJid = conversation.getJid(); + new Thread(new Runnable() { + @Override + public void run() { + running.set(false); + export(); + stopForeground(true); + stopSelf(); + } + }).start(); + } + return START_NOT_STICKY; + } - File dir = new File(String.format(DIRECTORY_STRING_FORMAT, - accountJid.toBareJid().toString())); - dir.mkdirs(); + private void export() { + List<Conversation> conversations = mDatabaseBackend.getConversations(Conversation.STATUS_AVAILABLE); + conversations.addAll(mDatabaseBackend.getConversations(Conversation.STATUS_ARCHIVED)); + NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext()); + mBuilder.setContentTitle(getString(R.string.notification_export_logs_title)) + .setSmallIcon(R.drawable.ic_import_export_white_24dp) + .setProgress(conversations.size(), 0, false); + startForeground(NOTIFICATION_ID, mBuilder.build()); + + int progress = 0; + for (Conversation conversation : conversations) { + writeToFile(conversation); + progress++; + mBuilder.setProgress(conversations.size(), progress, false); + mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); + } + } - BufferedWriter bw = null; - try { - for (Message message : databaseBackend.getMessagesIterable(conversation)) { - if (message.getType() == Message.TYPE_TEXT || message.hasFileOnRemoteHost()) { - String date = simpleDateFormat.format(new Date(message.getTimeSent())); - if (bw == null) { - bw = new BufferedWriter(new FileWriter( - new File(dir, contactJid.toBareJid().toString() + ".txt"))); - } - String jid = null; - switch (message.getStatus()) { - case Message.STATUS_RECEIVED: - jid = getMessageCounterpart(message); - break; - case Message.STATUS_SEND: - case Message.STATUS_SEND_RECEIVED: - case Message.STATUS_SEND_DISPLAYED: - jid = accountJid.toBareJid().toString(); - break; - } - if (jid != null) { - String body = message.hasFileOnRemoteHost() ? message.getFileParams().url.toString() : message.getBody(); - bw.write(String.format(MESSAGE_STRING_FORMAT, date, jid, - body.replace("\\\n", "\\ \n").replace("\n", "\\ \n"))); - } - } - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - if (bw != null) { - bw.close(); - } - } catch (IOException e1) { - e1.printStackTrace(); - } - } - } + private void writeToFile(Conversation conversation) { + Jid accountJid = resolveAccountUuid(conversation.getAccountUuid()); + Jid contactJid = conversation.getJid(); + + File dir = new File(String.format(DIRECTORY_STRING_FORMAT,accountJid.toBareJid().toString())); + dir.mkdirs(); + + BufferedWriter bw = null; + try { + for (Message message : mDatabaseBackend.getMessagesIterable(conversation)) { + if (message.getType() == Message.TYPE_TEXT || message.hasFileOnRemoteHost()) { + String date = simpleDateFormat.format(new Date(message.getTimeSent())); + if (bw == null) { + bw = new BufferedWriter(new FileWriter( + new File(dir, contactJid.toBareJid().toString() + ".txt"))); + } + String jid = null; + switch (message.getStatus()) { + case Message.STATUS_RECEIVED: + jid = getMessageCounterpart(message); + break; + case Message.STATUS_SEND: + case Message.STATUS_SEND_RECEIVED: + case Message.STATUS_SEND_DISPLAYED: + jid = accountJid.toBareJid().toString(); + break; + } + if (jid != null) { + String body = message.hasFileOnRemoteHost() ? message.getFileParams().url.toString() : message.getBody(); + bw.write(String.format(MESSAGE_STRING_FORMAT, date, jid, + body.replace("\\\n", "\\ \n").replace("\n", "\\ \n"))); + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (bw != null) { + bw.close(); + } + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } - private Jid resolveAccountUuid(String accountUuid) { - for (Account account : accounts) { - if (account.getUuid().equals(accountUuid)) { - return account.getJid(); - } - } - return null; - } + private Jid resolveAccountUuid(String accountUuid) { + for (Account account : mAccounts) { + if (account.getUuid().equals(accountUuid)) { + return account.getJid(); + } + } + return null; + } - private String getMessageCounterpart(Message message) { - String trueCounterpart = (String) message.getContentValues().get(Message.TRUE_COUNTERPART); - if (trueCounterpart != null) { - return trueCounterpart; - } else { - return message.getCounterpart().toString(); - } - } - }).start(); + private String getMessageCounterpart(Message message) { + String trueCounterpart = (String) message.getContentValues().get(Message.TRUE_COUNTERPART); + if (trueCounterpart != null) { + return trueCounterpart; + } else { + return message.getCounterpart().toString(); } - return START_STICKY; } @Override diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java index 351ded0b8..ae81cc17f 100644 --- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java +++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java @@ -54,6 +54,18 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { 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) { long timestamp = 0; for(final Conversation conversation : mXmppConnectionService.getConversations()) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 2f00083f8..8326766e5 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1064,10 +1064,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } 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)) { return; } + Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp)); Runnable runnable = new Runnable() { @Override public void run() { @@ -1078,13 +1078,15 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa checkDeletedFiles(conversation); callback.onMoreMessagesLoaded(messages.size(), conversation); } else if (conversation.hasMessagesLeftOnServer() - && account.isOnlineAndConnected() - && account.getXmppConnection().getFeatures().mam()) { - MessageArchiveService.Query query = getMessageArchiveService().query(conversation,0,timestamp - 1); - if (query != null) { - query.setCallback(callback); + && account.isOnlineAndConnected()) { + 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); + if (query != null) { + query.setCallback(callback); + } + callback.informUser(R.string.fetching_history_from_server); } - callback.informUser(R.string.fetching_history_from_server); } } }; @@ -1478,7 +1480,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void joinMuc(Conversation conversation) { - joinMuc(conversation,false); + joinMuc(conversation, false); } private void joinMuc(Conversation conversation, boolean now) { @@ -1487,32 +1489,49 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa account.pendingConferenceLeaves.remove(conversation); if (account.getStatus() == Account.State.ONLINE || now) { conversation.resetMucOptions(); - final String nick = conversation.getMucOptions().getProposedNick(); - final Jid joinJid = conversation.getMucOptions().createJoinJid(nick); - if (joinJid == null) { - return; //safety net - } - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": joining conversation " + joinJid.toString()); - PresencePacket packet = new PresencePacket(); - packet.setFrom(conversation.getAccount().getJid()); - packet.setTo(joinJid); - Element x = packet.addChild("x", "http://jabber.org/protocol/muc"); - if (conversation.getMucOptions().getPassword() != null) { - x.addChild("password").setContent(conversation.getMucOptions().getPassword()); - } - x.addChild("history").setAttribute("since", PresenceGenerator.getTimestamp(conversation.getLastMessageTransmitted())); - 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); + fetchConferenceConfiguration(conversation, new OnConferenceConfigurationFetched() { + @Override + public void onConferenceConfigurationFetched(Conversation conversation) { + Account account = conversation.getAccount(); + final String nick = conversation.getMucOptions().getProposedNick(); + final Jid joinJid = conversation.getMucOptions().createJoinJid(nick); + if (joinJid == null) { + return; //safety net + } + Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": joining conversation " + joinJid.toString()); + PresencePacket packet = new PresencePacket(); + packet.setFrom(conversation.getAccount().getJid()); + packet.setTo(joinJid); + Element x = packet.addChild("x", "http://jabber.org/protocol/muc"); + if (conversation.getMucOptions().getPassword() != null) { + x.addChild("password").setContent(conversation.getMucOptions().getPassword()); + } + + if (conversation.getMucOptions().mamSupport()) { + // Use MAM instead of the limited muc history to get history + x.addChild("history").setAttribute("maxchars", "0"); + } else { + // Fallback to muc history + x.addChild("history").setAttribute("since", PresenceGenerator.getTimestamp(conversation.getLastMessageTransmitted())); + } + 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); + if (conversation.getMucOptions().mamSupport()) { + getMessageArchiveService().catchupMUC(conversation); + } + } + }); + } else { account.pendingConferenceJoins.add(conversation); } @@ -1672,6 +1691,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } 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); request.setTo(conversation.getJid().toBareJid()); request.query("http://jabber.org/protocol/disco#info"); @@ -1689,6 +1712,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } conversation.getMucOptions().updateFeatures(features); + if (callback != null) { + callback.onConferenceConfigurationFetched(conversation); + } updateConversationUi(); } } @@ -2629,6 +2655,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onMucRosterUpdate(); } + public interface OnConferenceConfigurationFetched { + public void onConferenceConfigurationFetched(Conversation conversation); + } + public interface OnConferenceOptionsPushed { public void onPushSucceeded(); |