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 | 154 |
1 files changed, 113 insertions, 41 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index f5c54adf5..a9a2f2117 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -52,16 +52,17 @@ import de.duenndns.ssl.MemorizingTrustManager; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; +import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Transferable; -import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; +import eu.siacs.conversations.entities.Transferable; +import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.generator.IqGenerator; import eu.siacs.conversations.generator.MessageGenerator; import eu.siacs.conversations.generator.PresenceGenerator; @@ -85,6 +86,7 @@ import eu.siacs.conversations.xmpp.OnContactStatusChanged; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.OnMessageAcknowledged; import eu.siacs.conversations.xmpp.OnMessagePacketReceived; +import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnPresencePacketReceived; import eu.siacs.conversations.xmpp.OnStatusChanged; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; @@ -273,11 +275,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } syncDirtyContacts(account); - scheduleWakeUpCall(Config.PING_MAX_INTERVAL,account.getUuid().hashCode()); + account.getAxolotlService().publishOwnDeviceIdIfNeeded(); + account.getAxolotlService().publishBundlesIfNeeded(); + + scheduleWakeUpCall(Config.PING_MAX_INTERVAL, account.getUuid().hashCode()); } else if (account.getStatus() == Account.State.OFFLINE) { - resetSendingToWaiting(account); if (!account.isOptionSet(Account.OPTION_DISABLED)) { - int timeToReconnect = mRandom.nextInt(50) + 10; + int timeToReconnect = mRandom.nextInt(20) + 10; scheduleWakeUpCall(timeToReconnect,account.getUuid().hashCode()); } } else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) { @@ -304,6 +308,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private int rosterChangedListenerCount = 0; private OnMucRosterUpdate mOnMucRosterUpdate = null; private int mucRosterChangedListenerCount = 0; + private OnKeyStatusUpdated mOnKeyStatusUpdated = null; + private int keyStatusUpdatedListenerCount = 0; private SecureRandom mRandom; private OpenPgpServiceConnection pgpServiceConnection; private PgpEngine mPgpEngine = null; @@ -342,7 +348,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void attachLocationToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) { - int encryption = conversation.getNextEncryption(forceEncryption()); + int encryption = conversation.getNextEncryption(); if (encryption == Message.ENCRYPTION_PGP) { encryption = Message.ENCRYPTION_DECRYPTED; } @@ -361,12 +367,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final Uri uri, final UiCallback<Message> callback) { final Message message; - if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { - message = new Message(conversation, "", - Message.ENCRYPTION_DECRYPTED); + if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { + message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED); } else { - message = new Message(conversation, "", - conversation.getNextEncryption(forceEncryption())); + message = new Message(conversation, "", conversation.getNextEncryption()); } message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_FILE); @@ -399,15 +403,17 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - public void attachImageToConversation(final Conversation conversation, - final Uri uri, final UiCallback<Message> callback) { + public void attachImageToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) { + if (getFileBackend().useImageAsIs(uri)) { + Log.d(Config.LOGTAG,"using image as is"); + attachFileToConversation(conversation, uri, callback); + return; + } final Message message; - if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { - message = new Message(conversation, "", - Message.ENCRYPTION_DECRYPTED); + if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { + message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED); } else { - message = new Message(conversation, "", - conversation.getNextEncryption(forceEncryption())); + message = new Message(conversation, "",conversation.getNextEncryption()); } message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_IMAGE); @@ -417,7 +423,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void run() { try { getFileBackend().copyImageToPrivateStorage(message, uri); - if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { + if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { getPgpEngine().encrypt(message, callback); } else { callback.success(message); @@ -591,9 +597,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); this.accounts = databaseBackend.getAccounts(); - for (final Account account : this.accounts) { - account.initAccountServices(this); - } restoreFromDatabase(); getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver); @@ -674,22 +677,22 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - private void sendFileMessage(final Message message) { + private void sendFileMessage(final Message message, final boolean delay) { Log.d(Config.LOGTAG, "send file message"); final Account account = message.getConversation().getAccount(); final XmppConnection connection = account.getXmppConnection(); if (connection != null && connection.getFeatures().httpUpload()) { - mHttpConnectionManager.createNewUploadConnection(message); + mHttpConnectionManager.createNewUploadConnection(message, delay); } else { mJingleConnectionManager.createNewConnection(message); } } public void sendMessage(final Message message) { - sendMessage(message, false); + sendMessage(message, false, false); } - private void sendMessage(final Message message, final boolean resend) { + private void sendMessage(final Message message, final boolean resend, final boolean delay) { final Account account = message.getConversation().getAccount(); final Conversation conversation = message.getConversation(); account.deactivateGracePeriod(); @@ -699,7 +702,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (!resend && message.getEncryption() != Message.ENCRYPTION_OTR) { message.getConversation().endOtrIfNeeded(); - message.getConversation().findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() { + message.getConversation().findUnsentMessagesWithEncryption(Message.ENCRYPTION_OTR, + new Conversation.OnMessageFound() { @Override public void onMessageFound(Message message) { markMessage(message,Message.STATUS_SEND_FAILED); @@ -712,24 +716,24 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa case Message.ENCRYPTION_NONE: if (message.needsUploading()) { if (account.httpUploadAvailable() || message.fixCounterpart()) { - this.sendFileMessage(message); + this.sendFileMessage(message,delay); } else { break; } } else { - packet = mMessageGenerator.generateChat(message,resend); + packet = mMessageGenerator.generateChat(message); } break; case Message.ENCRYPTION_PGP: case Message.ENCRYPTION_DECRYPTED: if (message.needsUploading()) { if (account.httpUploadAvailable() || message.fixCounterpart()) { - this.sendFileMessage(message); + this.sendFileMessage(message,delay); } else { break; } } else { - packet = mMessageGenerator.generatePgpChat(message,resend); + packet = mMessageGenerator.generatePgpChat(message); } break; case Message.ENCRYPTION_OTR: @@ -743,7 +747,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (message.needsUploading()) { mJingleConnectionManager.createNewConnection(message); } else { - packet = mMessageGenerator.generateOtrChat(message,resend); + packet = mMessageGenerator.generateOtrChat(message); } } else if (otrSession == null) { if (message.fixCounterpart()) { @@ -753,6 +757,24 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } break; + case Message.ENCRYPTION_AXOLOTL: + message.setAxolotlFingerprint(account.getAxolotlService().getOwnPublicKey().getFingerprint().replaceAll("\\s", "")); + if (message.needsUploading()) { + if (account.httpUploadAvailable() || message.fixCounterpart()) { + this.sendFileMessage(message,delay); + } else { + break; + } + } else { + XmppAxolotlMessage axolotlMessage = account.getAxolotlService().fetchAxolotlMessageFromCache(message); + if (axolotlMessage == null) { + account.getAxolotlService().preparePayloadMessage(message, delay); + } else { + packet = mMessageGenerator.generateAxolotlChat(message, axolotlMessage); + } + } + break; + } if (packet != null) { if (account.getXmppConnection().getFeatures().sm() || conversation.getMode() == Conversation.MODE_MULTI) { @@ -780,6 +802,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa conversation.startOtrSession(message.getCounterpart().getResourcepart(), false); } break; + case Message.ENCRYPTION_AXOLOTL: + message.setAxolotlFingerprint(account.getAxolotlService().getOwnPublicKey().getFingerprint().replaceAll("\\s", "")); + break; } } @@ -799,6 +824,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa updateConversationUi(); } if (packet != null) { + if (delay) { + mMessageGenerator.addDelay(packet,message.getTimeSent()); + } if (conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { if (this.sendChatStates()) { packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); @@ -813,13 +841,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onMessageFound(Message message) { - resendMessage(message); + resendMessage(message, true); } }); } - public void resendMessage(final Message message) { - sendMessage(message, true); + public void resendMessage(final Message message, final boolean delay) { + sendMessage(message, true, delay); } public void fetchRosterFromServer(final Account account) { @@ -830,7 +858,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } else { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetching roster"); } - iqPacket.query(Xmlns.ROSTER).setAttribute("ver",account.getRosterVersion()); + iqPacket.query(Xmlns.ROSTER).setAttribute("ver", account.getRosterVersion()); sendIqPacket(account,iqPacket,mIqParser); } @@ -943,6 +971,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Log.d(Config.LOGTAG,"restoring roster"); for(Account account : accounts) { databaseBackend.readRoster(account.getRoster()); + account.initAccountServices(XmppConnectionService.this); } getBitmapCache().evictAll(); Looper.prepare(); @@ -974,6 +1003,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onMessageFound(Message message) { if (!getFileBackend().isFileAvailable(message)) { message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); + final int s = message.getStatus(); + if(s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) { + markMessage(message,Message.STATUS_SEND_FAILED); + } } } }); @@ -985,7 +1018,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (message != null) { if (!getFileBackend().isFileAvailable(message)) { message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); - updateConversationUi(); + final int s = message.getStatus(); + if(s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) { + markMessage(message,Message.STATUS_SEND_FAILED); + } else { + updateConversationUi(); + } } return; } @@ -1342,6 +1380,31 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + public void setOnKeyStatusUpdatedListener(final OnKeyStatusUpdated listener) { + synchronized (this) { + if (checkListeners()) { + switchToForeground(); + } + this.mOnKeyStatusUpdated = listener; + if (this.keyStatusUpdatedListenerCount < 2) { + this.keyStatusUpdatedListenerCount++; + } + } + } + + public void removeOnNewKeysAvailableListener() { + synchronized (this) { + this.keyStatusUpdatedListenerCount--; + if (this.keyStatusUpdatedListenerCount <= 0) { + this.keyStatusUpdatedListenerCount = 0; + this.mOnKeyStatusUpdated = null; + if (checkListeners()) { + switchToBackground(); + } + } + } + } + public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) { synchronized (this) { if (checkListeners()) { @@ -1372,7 +1435,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa && this.mOnConversationUpdate == null && this.mOnRosterUpdate == null && this.mOnUpdateBlocklist == null - && this.mOnShowErrorToast == null); + && this.mOnShowErrorToast == null + && this.mOnKeyStatusUpdated == null); } private void switchToForeground() { @@ -1784,7 +1848,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa account.getJid().toBareJid() + " otr session established with " + conversation.getJid() + "/" + otrSession.getSessionID().getUserID()); - conversation.findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() { + conversation.findUnsentMessagesWithEncryption(Message.ENCRYPTION_OTR, new Conversation.OnMessageFound() { @Override public void onMessageFound(Message message) { @@ -1797,8 +1861,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (message.needsUploading()) { mJingleConnectionManager.createNewConnection(message); } else { - MessagePacket outPacket = mMessageGenerator.generateOtrChat(message, true); + MessagePacket outPacket = mMessageGenerator.generateOtrChat(message); if (outPacket != null) { + mMessageGenerator.addDelay(outPacket, message.getTimeSent()); message.setStatus(Message.STATUS_SEND); databaseBackend.updateMessage(message); sendMessagePacket(account, outPacket); @@ -2260,6 +2325,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + public void keyStatusUpdated() { + if(mOnKeyStatusUpdated != null) { + mOnKeyStatusUpdated.onKeyStatusUpdated(); + } + } + public Account findAccountByJid(final Jid accountJid) { for (Account account : this.accounts) { if (account.getJid().toBareJid().equals(accountJid.toBareJid())) { @@ -2470,8 +2541,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } for (final Message msg : messages) { + msg.setTime(System.currentTimeMillis()); markMessage(msg, Message.STATUS_WAITING); - this.resendMessage(msg); + this.resendMessage(msg,false); } } |