diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index c4bc86ff..0a9e5da2 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -67,18 +67,14 @@ public class Message extends AbstractEntity { } public Message(Conversation conversation, String body, int encryption) { - this(java.util.UUID.randomUUID().toString(), conversation.getUuid(), - conversation.getContactJid(), null, body, System - .currentTimeMillis(), encryption, - Message.STATUS_UNSEND, TYPE_TEXT, null); - this.conversation = conversation; + this(conversation,body,encryption,STATUS_UNSEND); } - public Message(final Conversation conversation, final Jid counterpart, final String body, - final int encryption, final int status) { + public Message(Conversation conversation, String body, int encryption, int status) { this(java.util.UUID.randomUUID().toString(), conversation.getUuid(), - counterpart, null, body, System.currentTimeMillis(), - encryption, status, TYPE_TEXT, null); + conversation.getContactJid().toBareJid(), null, body, System + .currentTimeMillis(), encryption, + status, TYPE_TEXT, null); this.conversation = conversation; } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index e40855d8..6defd91c 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -1,8 +1,11 @@ package eu.siacs.conversations.parser; +import android.util.Log; + import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -30,10 +33,10 @@ public class MessageParser extends AbstractParser implements String pgpBody = getPgpBody(packet); Message finishedMessage; if (pgpBody != null) { - finishedMessage = new Message(conversation, packet.getFrom(), + finishedMessage = new Message(conversation, pgpBody, Message.ENCRYPTION_PGP, Message.STATUS_RECEIVED); } else { - finishedMessage = new Message(conversation, packet.getFrom(), + finishedMessage = new Message(conversation, packet.getBody(), Message.ENCRYPTION_NONE, Message.STATUS_RECEIVED); } @@ -110,12 +113,12 @@ public class MessageParser extends AbstractParser implements conversation.setSymmetricKey(CryptoHelper.hexToBytes(key)); return null; } - Message finishedMessage = new Message(conversation, - packet.getFrom(), body, Message.ENCRYPTION_OTR, + Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED); finishedMessage.setTime(getTimestamp(packet)); finishedMessage.setRemoteMsgId(packet.getId()); finishedMessage.markable = isMarkable(packet); + finishedMessage.setCounterpart(from); return finishedMessage; } catch (Exception e) { String receivedId = packet.getId(); @@ -158,14 +161,15 @@ public class MessageParser extends AbstractParser implements String pgpBody = getPgpBody(packet); Message finishedMessage; if (pgpBody == null) { - finishedMessage = new Message(conversation, from, + finishedMessage = new Message(conversation, packet.getBody(), Message.ENCRYPTION_NONE, status); } else { - finishedMessage = new Message(conversation, from, pgpBody, + finishedMessage = new Message(conversation, pgpBody, Message.ENCRYPTION_PGP, status); } finishedMessage.setRemoteMsgId(packet.getId()); finishedMessage.markable = isMarkable(packet); + finishedMessage.setCounterpart(from); if (status == Message.STATUS_RECEIVED) { finishedMessage.setTrueCounterpart(conversation.getMucOptions() .getTrueCounterpart(from.getResourcepart())); @@ -206,7 +210,7 @@ public class MessageParser extends AbstractParser implements parseNonMessage(message, account); } else if (status == Message.STATUS_SEND && message.hasChild("displayed", "urn:xmpp:chat-markers:0")) { - final Jid to = message.getTo(); + final Jid to = message.getAttributeAsJid("to"); if (to != null) { final Conversation conversation = mXmppConnectionService.find( mXmppConnectionService.getConversations(), account, @@ -219,14 +223,14 @@ public class MessageParser extends AbstractParser implements return null; } if (status == Message.STATUS_RECEIVED) { - fullJid = message.getFrom(); + fullJid = message.getAttributeAsJid("from"); if (fullJid == null) { return null; } else { updateLastseen(message, account, true); } } else { - fullJid = message.getTo(); + fullJid = message.getAttributeAsJid("to"); if (fullJid == null) { return null; } @@ -236,20 +240,20 @@ public class MessageParser extends AbstractParser implements String pgpBody = getPgpBody(message); Message finishedMessage; if (pgpBody != null) { - finishedMessage = new Message(conversation, fullJid, pgpBody, + finishedMessage = new Message(conversation, pgpBody, Message.ENCRYPTION_PGP, status); } else { String body = message.findChild("body").getContent(); - finishedMessage = new Message(conversation, fullJid, body, + finishedMessage = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } finishedMessage.setTime(getTimestamp(message)); finishedMessage.setRemoteMsgId(message.getAttribute("id")); finishedMessage.markable = isMarkable(message); + finishedMessage.setCounterpart(fullJid); if (conversation.getMode() == Conversation.MODE_MULTI && !fullJid.isBareJid()) { finishedMessage.setType(Message.TYPE_PRIVATE); - finishedMessage.setCounterpart(fullJid); finishedMessage.setTrueCounterpart(conversation.getMucOptions() .getTrueCounterpart(fullJid.getResourcepart())); if (conversation.hasDuplicateMessage(finishedMessage)) { @@ -266,7 +270,7 @@ public class MessageParser extends AbstractParser implements } private void parseNonMessage(Element packet, Account account) { - final Jid from = packet.getFrom(); + final Jid from = packet.getAttributeAsJid("from"); if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event"); @@ -299,7 +303,7 @@ public class MessageParser extends AbstractParser implements if (x.hasChild("invite")) { Conversation conversation = mXmppConnectionService .findOrCreateConversation(account, - packet.getFrom(), true); + packet.getAttributeAsJid("from"), true); if (!conversation.getMucOptions().online()) { if (x.hasChild("password")) { Element password = x.findChild("password"); @@ -479,6 +483,7 @@ public class MessageParser extends AbstractParser implements && conversation.getOtrSession() != null && !conversation.getOtrSession().getSessionID().getUserID() .equals(message.getCounterpart().getResourcepart())) { + Log.d(Config.LOGTAG, "ending because of reasons"); conversation.endOtrIfNeeded(); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 787cacd0..dea0c050 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1,5 +1,40 @@ package eu.siacs.conversations.services; +import android.annotation.SuppressLint; +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.ContentObserver; +import android.graphics.Bitmap; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.Uri; +import android.os.Binder; +import android.os.Bundle; +import android.os.FileObserver; +import android.os.IBinder; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.os.SystemClock; +import android.preference.PreferenceManager; +import android.provider.ContactsContract; +import android.util.Log; +import android.util.LruCache; + +import net.java.otr4j.OtrException; +import net.java.otr4j.session.Session; +import net.java.otr4j.session.SessionID; +import net.java.otr4j.session.SessionStatus; + +import org.openintents.openpgp.util.OpenPgpApi; +import org.openintents.openpgp.util.OpenPgpServiceConnection; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; import java.security.SecureRandom; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -12,15 +47,7 @@ import java.util.Locale; import java.util.TimeZone; import java.util.concurrent.CopyOnWriteArrayList; -import org.openintents.openpgp.util.OpenPgpApi; -import org.openintents.openpgp.util.OpenPgpServiceConnection; - import de.duenndns.ssl.MemorizingTrustManager; - -import net.java.otr4j.OtrException; -import net.java.otr4j.session.Session; -import net.java.otr4j.session.SessionID; -import net.java.otr4j.session.SessionStatus; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; @@ -65,63 +92,23 @@ import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.stanzas.IqPacket; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; -import android.annotation.SuppressLint; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.ContentObserver; -import android.graphics.Bitmap; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.Uri; -import android.os.Binder; -import android.os.Bundle; -import android.os.FileObserver; -import android.os.IBinder; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.SystemClock; -import android.preference.PreferenceManager; -import android.provider.ContactsContract; -import android.util.Log; -import android.util.LruCache; public class XmppConnectionService extends Service { - public DatabaseBackend databaseBackend; - private FileBackend fileBackend = new FileBackend(this); - - private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; public static String ACTION_CLEAR_NOTIFICATION = "clear_notification"; - - private MemorizingTrustManager mMemorizingTrustManager; - - private NotificationService mNotificationService = new NotificationService( - this); - - private MessageParser mMessageParser = new MessageParser(this); - private PresenceParser mPresenceParser = new PresenceParser(this); - private IqParser mIqParser = new IqParser(this); - private MessageGenerator mMessageGenerator = new MessageGenerator(this); - private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this); - - private List accounts; - private CopyOnWriteArrayList conversations = null; - private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager( - this); - private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( - this); - private AvatarService mAvatarService = new AvatarService(this); - - private OnConversationUpdate mOnConversationUpdate = null; - private Integer convChangedListenerCount = 0; - private OnAccountUpdate mOnAccountUpdate = null; - private Integer accountChangedListenerCount = 0; - private OnRosterUpdate mOnRosterUpdate = null; - private Integer rosterChangedListenerCount = 0; + private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; + private ContentObserver contactObserver = new ContentObserver(null) { + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + Intent intent = new Intent(getApplicationContext(), + XmppConnectionService.class); + intent.setAction(ACTION_MERGE_PHONE_CONTACTS); + startService(intent); + } + }; + private final IBinder mBinder = new XmppConnectionBinder(); + public DatabaseBackend databaseBackend; public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() { @Override @@ -139,32 +126,25 @@ public class XmppConnectionService extends Service { } } }; - - private SecureRandom mRandom; - - private ContentObserver contactObserver = new ContentObserver(null) { - @Override - public void onChange(boolean selfChange) { - super.onChange(selfChange); - Intent intent = new Intent(getApplicationContext(), - XmppConnectionService.class); - intent.setAction(ACTION_MERGE_PHONE_CONTACTS); - startService(intent); - } - }; - - private FileObserver fileObserver = new FileObserver( - FileBackend.getConversationsDirectory()) { - - @Override - public void onEvent(int event, String path) { - if (event == FileObserver.DELETE) { - markFileDeleted(path.split("\\.")[0]); - } - } - }; - - private final IBinder mBinder = new XmppConnectionBinder(); + private FileBackend fileBackend = new FileBackend(this); + private MemorizingTrustManager mMemorizingTrustManager; + private NotificationService mNotificationService = new NotificationService( + this); + private MessageParser mMessageParser = new MessageParser(this); + private PresenceParser mPresenceParser = new PresenceParser(this); + private IqParser mIqParser = new IqParser(this); + private MessageGenerator mMessageGenerator = new MessageGenerator(this); + private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this); + private List accounts; + private CopyOnWriteArrayList conversations = null; + private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager( + this); + private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( + this); + private AvatarService mAvatarService = new AvatarService(this); + private OnConversationUpdate mOnConversationUpdate = null; + private Integer convChangedListenerCount = 0; + private OnAccountUpdate mOnAccountUpdate = null; private OnStatusChanged statusListener = new OnStatusChanged() { @Override @@ -182,12 +162,12 @@ public class XmppConnectionService extends Service { } mJingleConnectionManager.cancelInTransmission(); List conversations = getConversations(); - for (Conversation conversation : conversations) { - if (conversation.getAccount() == account) { - conversation.startOtrIfNeeded(); - sendUnsendMessages(conversation); - } - } + for (Conversation conversation : conversations) { + if (conversation.getAccount() == account) { + conversation.startOtrIfNeeded(); + sendUnsendMessages(conversation); + } + } if (connection != null && connection.getFeatures().csi()) { if (checkListeners()) { Log.d(Config.LOGTAG, account.getJid().toBareJid() @@ -225,7 +205,20 @@ public class XmppConnectionService extends Service { getAccounts()); } }; + private Integer accountChangedListenerCount = 0; + private OnRosterUpdate mOnRosterUpdate = null; + private Integer rosterChangedListenerCount = 0; + private SecureRandom mRandom; + private FileObserver fileObserver = new FileObserver( + FileBackend.getConversationsDirectory()) { + @Override + public void onEvent(int event, String path) { + if (event == FileObserver.DELETE) { + markFileDeleted(path.split("\\.")[0]); + } + } + }; private OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() { @Override @@ -276,6 +269,8 @@ public class XmppConnectionService extends Service { } }; private LruCache mBitmapCache; + private OnRenameListener renameListener = null; + private IqGenerator mIqGenerator = new IqGenerator(this); public PgpEngine getPgpEngine() { if (pgpServiceConnection.isBound()) { @@ -300,7 +295,7 @@ public class XmppConnectionService extends Service { } public Message attachImageToConversation(final Conversation conversation, - final Uri uri, final UiCallback callback) { + final Uri uri, final UiCallback callback) { final Message message; if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { message = new Message(conversation, "", @@ -339,12 +334,6 @@ public class XmppConnectionService extends Service { return find(getConversations(), account, jid); } - public class XmppConnectionBinder extends Binder { - public XmppConnectionService getService() { - return XmppConnectionService.this; - } - } - @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null && intent.getAction() != null) { @@ -395,7 +384,7 @@ public class XmppConnectionService extends Service { new Thread(account.getXmppConnection()).start(); } else if ((account.getStatus() == Account.STATUS_CONNECTING) && ((SystemClock.elapsedRealtime() - account - .getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) { + .getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) { Log.d(Config.LOGTAG, account.getJid() + ": time out during connect reconnecting"); reconnectAccount(account, true); @@ -412,6 +401,10 @@ public class XmppConnectionService extends Service { } } } + PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); + if (!pm.isScreenOn()) { + removeStaleListeners(); + } if (wakeLock.isHeld()) { try { wakeLock.release(); @@ -536,9 +529,9 @@ public class XmppConnectionService extends Service { public XmppConnection createConnection(Account account) { SharedPreferences sharedPref = getPreferences(); - account.setResource(sharedPref.getString("resource", "mobile") - .toLowerCase(Locale.getDefault())); - XmppConnection connection = new XmppConnection(account, this); + account.setResource(sharedPref.getString("resource", "mobile") + .toLowerCase(Locale.getDefault())); + XmppConnection connection = new XmppConnection(account, this); connection.setOnMessagePacketReceivedListener(this.mMessageParser); connection.setOnStatusChangedListener(this.statusListener); connection.setOnPresencePacketReceivedListener(this.mPresenceParser); @@ -582,16 +575,10 @@ public class XmppConnectionService extends Service { } } else { if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession()&& (message.getCounterpart() != null)) { + if (!conv.hasValidOtrSession() && (message.getCounterpart() != null)) { conv.startOtrSession(this, message.getCounterpart().getResourcepart(), true); message.setStatus(Message.STATUS_WAITING); } else if (conv.hasValidOtrSession()) { - SessionID id = conv.getOtrSession().getSessionID(); - try { - message.setCounterpart(Jid.fromString(id.getAccountID() + "/" + id.getUserID())); - } catch (final InvalidJidException e) { - message.setCounterpart(null); - } if (conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { packet = mMessageGenerator.generateOtrChat(message); send = true; @@ -631,14 +618,7 @@ public class XmppConnectionService extends Service { message.setBody(decryptedBody); message.setEncryption(Message.ENCRYPTION_DECRYPTED); } else if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (conv.hasValidOtrSession()) { - SessionID id = conv.getOtrSession().getSessionID(); - try { - message.setCounterpart(Jid.fromString(id.getAccountID() + "/" + id.getUserID())); - } catch (final InvalidJidException e) { - message.setCounterpart(null); - } - } else if (!conv.hasValidOtrSession() + if (!conv.hasValidOtrSession() && message.getCounterpart() != null) { conv.startOtrSession(this, message.getCounterpart().getResourcepart(), false); } @@ -750,7 +730,7 @@ public class XmppConnectionService extends Service { @Override public void onIqPacketReceived(final Account account, - IqPacket packet) { + IqPacket packet) { Element query = packet.findChild("query"); if (query != null) { account.getRoster().markAllAsNotInRoster(); @@ -818,14 +798,14 @@ public class XmppConnectionService extends Service { } for (Bundle phoneContact : phoneContacts) { for (Account account : accounts) { - Jid jid; - try { - jid = Jid.fromString(phoneContact.getString("jid")); - } catch (final InvalidJidException e) { - // TODO: Warn if contact import fails here? - break; - } - final Contact contact = account.getRoster() + Jid jid; + try { + jid = Jid.fromString(phoneContact.getString("jid")); + } catch (final InvalidJidException e) { + // TODO: Warn if contact import fails here? + break; + } + final Contact contact = account.getRoster() .getContact(jid); String systemAccount = phoneContact .getInt("phoneid") @@ -893,7 +873,7 @@ public class XmppConnectionService extends Service { } public void populateWithOrderedConversations(List list, - boolean includeConferences) { + boolean includeConferences) { list.clear(); if (includeConferences) { list.addAll(getConversations()); @@ -944,8 +924,8 @@ public class XmppConnectionService extends Service { } public Conversation find(final List haystack, - final Account account, - final Jid jid) { + final Account account, + final Jid jid) { for (Conversation conversation : haystack) { if ((account == null || conversation.getAccount() == account) && (conversation.getContactJid().toBareJid().equals(jid.toBareJid()))) { @@ -956,7 +936,7 @@ public class XmppConnectionService extends Service { } public Conversation findOrCreateConversation(final Account account, final Jid jid, - final boolean muc) { + final boolean muc) { Conversation conversation = find(account, jid); if (conversation != null) { return conversation; @@ -1058,6 +1038,46 @@ public class XmppConnectionService extends Service { UIHelper.showErrorNotification(getApplicationContext(), getAccounts()); } + private void removeStaleListeners() { + boolean removedListener = false; + synchronized (this.convChangedListenerCount) { + if (this.mOnConversationUpdate != null) { + this.mOnConversationUpdate = null; + this.convChangedListenerCount = 0; + this.mNotificationService.setIsInForeground(false); + removedListener = true; + } + } + synchronized (this.accountChangedListenerCount) { + if (this.mOnAccountUpdate != null) { + this.mOnAccountUpdate = null; + this.accountChangedListenerCount = 0; + removedListener = true; + } + } + synchronized (this.rosterChangedListenerCount) { + if (this.mOnRosterUpdate != null) { + this.mOnRosterUpdate = null; + this.rosterChangedListenerCount = 0; + removedListener = true; + } + } + if (removedListener) { + final String msg = "removed stale listeners"; + Log.d(Config.LOGTAG, msg); + checkListeners(); + try { + OutputStream os = openFileOutput("stacktrace.txt", MODE_PRIVATE); + os.write(msg.getBytes()); + os.flush(); + os.close(); + } catch (final FileNotFoundException ignored) { + + } catch (final IOException ignored) { + } + } + } + public void setOnConversationListChangedListener( OnConversationUpdate listener) { if (!isScreenOn()) { @@ -1181,12 +1201,12 @@ public class XmppConnectionService extends Service { public void connectMultiModeConversations(Account account) { List conversations = getConversations(); - for (Conversation conversation : conversations) { - if ((conversation.getMode() == Conversation.MODE_MULTI) - && (conversation.getAccount() == account)) { - joinMuc(conversation); - } - } + for (Conversation conversation : conversations) { + if ((conversation.getMode() == Conversation.MODE_MULTI) + && (conversation.getAccount() == account)) { + joinMuc(conversation); + } + } } public void joinMuc(Conversation conversation) { @@ -1200,7 +1220,7 @@ public class XmppConnectionService extends Service { conversation.getMucOptions().setJoinNick(nick); PresencePacket packet = new PresencePacket(); final Jid joinJid = conversation.getMucOptions().getJoinJid(); - packet.setTo(conversation.getMucOptions().getJoinJid()); + packet.setTo(conversation.getMucOptions().getJoinJid()); Element x = new Element("x"); x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); if (conversation.getMucOptions().getPassword() != null) { @@ -1232,9 +1252,6 @@ public class XmppConnectionService extends Service { } } - private OnRenameListener renameListener = null; - private IqGenerator mIqGenerator = new IqGenerator(this); - public void setOnRenameListener(OnRenameListener listener) { this.renameListener = listener; } @@ -1324,19 +1341,19 @@ public class XmppConnectionService extends Service { || (account.getStatus() == Account.STATUS_DISABLED)) { if (!force) { List conversations = getConversations(); - for (Conversation conversation : conversations) { - if (conversation.getAccount() == account) { - if (conversation.getMode() == Conversation.MODE_MULTI) { - leaveMuc(conversation); - } else { - if (conversation.endOtrIfNeeded()) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() - + ": ended otr session with " - + conversation.getContactJid()); - } - } - } - } + for (Conversation conversation : conversations) { + if (conversation.getAccount() == account) { + if (conversation.getMode() == Conversation.MODE_MULTI) { + leaveMuc(conversation); + } else { + if (conversation.endOtrIfNeeded()) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + + ": ended otr session with " + + conversation.getContactJid()); + } + } + } + } } account.getXmppConnection().disconnect(force); } @@ -1381,28 +1398,28 @@ public class XmppConnectionService extends Service { account.getJid().toBareJid() + " otr session established with " + conversation.getContactJid() + "/" + otrSession.getSessionID().getUserID()); - for (Message msg : messages) { - if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING) - && (msg.getEncryption() == Message.ENCRYPTION_OTR)) { + for (Message msg : messages) { + if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING) + && (msg.getEncryption() == Message.ENCRYPTION_OTR)) { SessionID id = otrSession.getSessionID(); try { - msg.setCounterpart(Jid.fromString(id.getAccountID()+"/"+id.getUserID())); + msg.setCounterpart(Jid.fromString(id.getAccountID() + "/" + id.getUserID())); } catch (InvalidJidException e) { break; } - if (msg.getType() == Message.TYPE_TEXT) { - MessagePacket outPacket = mMessageGenerator - .generateOtrChat(msg, true); - if (outPacket != null) { - msg.setStatus(Message.STATUS_SEND); - databaseBackend.updateMessage(msg); - sendMessagePacket(account, outPacket); - } - } else if (msg.getType() == Message.TYPE_IMAGE) { - mJingleConnectionManager.createNewConnection(msg); - } - } - } + if (msg.getType() == Message.TYPE_TEXT) { + MessagePacket outPacket = mMessageGenerator + .generateOtrChat(msg, true); + if (outPacket != null) { + msg.setStatus(Message.STATUS_SEND); + databaseBackend.updateMessage(msg); + sendMessagePacket(account, outPacket); + } + } else if (msg.getType() == Message.TYPE_IMAGE) { + mJingleConnectionManager.createNewConnection(msg); + } + } + } updateConversationUi(); } @@ -1457,7 +1474,7 @@ public class XmppConnectionService extends Service { } public void publishAvatar(Account account, Uri image, - final UiCallback callback) { + final UiCallback callback) { final Bitmap.CompressFormat format = Config.AVATAR_FORMAT; final int size = Config.AVATAR_SIZE; final Avatar avatar = getFileBackend() @@ -1488,7 +1505,7 @@ public class XmppConnectionService extends Service { @Override public void onIqPacketReceived(Account account, - IqPacket result) { + IqPacket result) { if (result.getType() == IqPacket.TYPE_RESULT) { if (account.setAvatar(avatar.getFilename())) { databaseBackend.updateAccount(account); @@ -1518,7 +1535,7 @@ public class XmppConnectionService extends Service { } public void fetchAvatar(Account account, final Avatar avatar, - final UiCallback callback) { + final UiCallback callback) { IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar); sendIqPacket(account, packet, new OnIqPacketReceived() { @@ -1574,7 +1591,7 @@ public class XmppConnectionService extends Service { } public void checkForAvatar(Account account, - final UiCallback callback) { + final UiCallback callback) { IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); this.sendIqPacket(account, packet, new OnIqPacketReceived() { @@ -1669,7 +1686,7 @@ public class XmppConnectionService extends Service { } public boolean markMessage(final Account account, final Jid recipient, final String uuid, - final int status) { + final int status) { if (uuid == null) { return false; } else { @@ -1684,14 +1701,14 @@ public class XmppConnectionService extends Service { } public boolean markMessage(Conversation conversation, String uuid, - int status) { + int status) { if (uuid == null) { return false; } else { for (Message message : conversation.getMessages()) { if (uuid.equals(message.getUuid()) || (message.getStatus() >= Message.STATUS_SEND && uuid - .equals(message.getRemoteMsgId()))) { + .equals(message.getRemoteMsgId()))) { markMessage(message, status); return true; } @@ -1703,7 +1720,7 @@ public class XmppConnectionService extends Service { public void markMessage(Message message, int status) { if (status == Message.STATUS_SEND_FAILED && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message - .getStatus() == Message.STATUS_SEND_DISPLAYED)) { + .getStatus() == Message.STATUS_SEND_DISPLAYED)) { return; } message.setStatus(status); @@ -1875,7 +1892,7 @@ public class XmppConnectionService extends Service { } public void sendIqPacket(Account account, IqPacket packet, - OnIqPacketReceived callback) { + OnIqPacketReceived callback) { XmppConnection connection = account.getXmppConnection(); if (connection != null) { connection.sendIqPacket(packet, callback); @@ -1898,18 +1915,6 @@ public class XmppConnectionService extends Service { return this.mJingleConnectionManager; } - public interface OnConversationUpdate { - public void onConversationUpdate(); - } - - public interface OnAccountUpdate { - public void onAccountUpdate(); - } - - public interface OnRosterUpdate { - public void onRosterUpdate(); - } - public List findContacts(String jid) { ArrayList contacts = new ArrayList<>(); for (Account account : getAccounts()) { @@ -1931,6 +1936,41 @@ public class XmppConnectionService extends Service { return this.mHttpConnectionManager; } + public void resendFailedMessages(Message message) { + List messages = new ArrayList<>(); + Message current = message; + while (current.getStatus() == Message.STATUS_SEND_FAILED) { + messages.add(current); + if (current.mergeable(current.next())) { + current = current.next(); + } else { + break; + } + } + for (Message msg : messages) { + markMessage(msg, Message.STATUS_WAITING); + this.resendMessage(msg); + } + } + + public interface OnConversationUpdate { + public void onConversationUpdate(); + } + + public interface OnAccountUpdate { + public void onAccountUpdate(); + } + + public interface OnRosterUpdate { + public void onRosterUpdate(); + } + + public class XmppConnectionBinder extends Binder { + public XmppConnectionService getService() { + return XmppConnectionService.this; + } + } + private class DeletedDownloadable implements Downloadable { @Override @@ -1949,21 +1989,4 @@ public class XmppConnectionService extends Service { } } - - public void resendFailedMessages(Message message) { - List messages = new ArrayList<>(); - Message current = message; - while(current.getStatus() == Message.STATUS_SEND_FAILED) { - messages.add(current); - if (current.mergeable(current.next())) { - current = current.next(); - } else { - break; - } - } - for(Message msg: messages) { - markMessage(msg, Message.STATUS_WAITING); - this.resendMessage(msg); - } - } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index d2ba6f51..63d740c3 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -825,21 +825,16 @@ public class ConversationFragment extends Fragment { protected void sendOtrMessage(final Message message) { final ConversationActivity activity = (ConversationActivity) getActivity(); final XmppConnectionService xmppService = activity.xmppConnectionService; - if (conversation.hasValidOtrSession()) { - activity.xmppConnectionService.sendMessage(message); - messageSent(); - } else { - activity.selectPresence(message.getConversation(), - new OnPresenceSelected() { + activity.selectPresence(message.getConversation(), + new OnPresenceSelected() { - @Override - public void onPresenceSelected() { - message.setCounterpart(conversation.getNextCounterpart()); - xmppService.sendMessage(message); - messageSent(); - } - }); - } + @Override + public void onPresenceSelected() { + message.setCounterpart(conversation.getNextCounterpart()); + xmppService.sendMessage(message); + messageSent(); + } + }); } public void appendText(String text) { diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index e8a858c0..78d7956a 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -48,6 +48,8 @@ import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import net.java.otr4j.session.SessionID; + import java.io.FileNotFoundException; import java.lang.ref.WeakReference; import java.util.Hashtable; @@ -452,7 +454,17 @@ public abstract class XmppActivity extends Activity { public void selectPresence(final Conversation conversation, final OnPresenceSelected listener) { final Contact contact = conversation.getContact(); - if (!contact.showInRoster()) { + if (conversation.hasValidOtrSession()) { + SessionID id = conversation.getOtrSession().getSessionID(); + Jid jid; + try { + jid = Jid.fromString(id.getAccountID() + "/" + id.getUserID()); + } catch (InvalidJidException e) { + jid = null; + } + conversation.setNextCounterpart(jid); + listener.onPresenceSelected(); + } else if (!contact.showInRoster()) { showAddToRosterDialog(conversation); } else { Presences presences = contact.getPresences(); diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java index 88fa18ff..0ad57fe2 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java @@ -31,6 +31,8 @@ public class ExceptionHandler implements UncaughtExceptionHandler { OutputStream os = context.openFileOutput("stacktrace.txt", Context.MODE_PRIVATE); os.write(stacktrace.getBytes()); + os.flush(); + os.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/src/main/java/eu/siacs/conversations/xml/Element.java b/src/main/java/eu/siacs/conversations/xml/Element.java index 31edec52..02c3e695 100644 --- a/src/main/java/eu/siacs/conversations/xml/Element.java +++ b/src/main/java/eu/siacs/conversations/xml/Element.java @@ -105,8 +105,8 @@ public class Element { } } - public Jid getJid() { - final String jid = this.getAttribute("jid"); + public Jid getAttributeAsJid(String name) { + final String jid = this.getAttribute(name); if (jid != null && !jid.isEmpty()) { try { return Jid.fromString(jid); @@ -115,31 +115,7 @@ public class Element { } } return null; - } - - public Jid getTo() { - final String to = this.getAttribute("to"); - if (to != null && !to.isEmpty()) { - try { - return Jid.fromString(to); - } catch (final InvalidJidException e) { - return null; - } - } - return null; - } - - public Jid getFrom() { - final String from = this.getAttribute("from"); - if (from != null && !from.isEmpty()) { - try { - return Jid.fromString(from); - } catch (final InvalidJidException e) { - return null; - } - } - return null; - } + } public Hashtable getAttributes() { return this.attributes; diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java index 9a0306fc..281ea3ca 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java @@ -109,7 +109,7 @@ public class JingleCandidate { JingleCandidate parsedCandidate = new JingleCandidate( candidate.getAttribute("cid"), false); parsedCandidate.setHost(candidate.getAttribute("host")); - parsedCandidate.setJid(candidate.getJid()); + parsedCandidate.setJid(candidate.getAttributeAsJid("jid")); parsedCandidate.setType(candidate.getAttribute("type")); parsedCandidate.setPriority(Integer.parseInt(candidate .getAttribute("priority")));