aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java305
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/PgpEngine.java107
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Account.java14
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Conversation.java2
-rw-r--r--src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java2
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java6
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java17
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java91
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java4
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java2
-rw-r--r--src/main/res/values/strings.xml1
11 files changed, 211 insertions, 340 deletions
diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java
index ed67dc65..2bc270c1 100644
--- a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java
+++ b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java
@@ -1,162 +1,181 @@
package eu.siacs.conversations.crypto;
import android.app.PendingIntent;
+import android.content.Intent;
+
+import org.openintents.openpgp.util.OpenPgpApi;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayDeque;
+import java.util.List;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.services.XmppConnectionService;
-import eu.siacs.conversations.ui.UiCallback;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
public class PgpDecryptionService {
- private final XmppConnectionService xmppConnectionService;
- private final ConcurrentHashMap<String, List<Message>> messages = new ConcurrentHashMap<>();
- private final ConcurrentHashMap<String, Boolean> decryptingMessages = new ConcurrentHashMap<>();
- private Boolean keychainLocked = false;
- private final Object keychainLockedLock = new Object();
-
- public PgpDecryptionService(XmppConnectionService xmppConnectionService) {
- this.xmppConnectionService = xmppConnectionService;
- }
-
- public void add(Message message) {
- if (isRunning()) {
- decryptDirectly(message);
- } else {
- store(message);
- }
- }
-
- public void addAll(List<Message> messagesList) {
- if (!messagesList.isEmpty()) {
- String conversationUuid = messagesList.get(0).getConversation().getUuid();
- if (!messages.containsKey(conversationUuid)) {
- List<Message> list = Collections.synchronizedList(new LinkedList<Message>());
- messages.put(conversationUuid, list);
- }
- synchronized (messages.get(conversationUuid)) {
- messages.get(conversationUuid).addAll(messagesList);
- }
- decryptAllMessages();
- }
- }
-
- public void onKeychainUnlocked() {
- synchronized (keychainLockedLock) {
- keychainLocked = false;
- }
- decryptAllMessages();
- }
-
- public void onKeychainLocked() {
- synchronized (keychainLockedLock) {
- keychainLocked = true;
- }
- xmppConnectionService.updateConversationUi();
- }
+ private final XmppConnectionService mXmppConnectionService;
+ private OpenPgpApi openPgpApi = null;
- public void onOpenPgpServiceBound() {
- decryptAllMessages();
- }
-
- public boolean isRunning() {
- synchronized (keychainLockedLock) {
- return !keychainLocked;
- }
- }
+ protected final ArrayDeque<Message> messages = new ArrayDeque();
+ Message currentMessage;
+ private PendingIntent pendingIntent;
- private void store(Message message) {
- if (messages.containsKey(message.getConversation().getUuid())) {
- messages.get(message.getConversation().getUuid()).add(message);
- } else {
- List<Message> messageList = Collections.synchronizedList(new LinkedList<Message>());
- messageList.add(message);
- messages.put(message.getConversation().getUuid(), messageList);
- }
- }
- private void decryptAllMessages() {
- for (String uuid : messages.keySet()) {
- decryptMessages(uuid);
- }
- }
+ public PgpDecryptionService(XmppConnectionService service) {
+ this.mXmppConnectionService = service;
+ }
- private void decryptMessages(final String uuid) {
- synchronized (decryptingMessages) {
- Boolean decrypting = decryptingMessages.get(uuid);
- if ((decrypting != null && !decrypting) || decrypting == null) {
- decryptingMessages.put(uuid, true);
- decryptMessage(uuid);
- }
- }
+ public synchronized void decrypt(final Message message) {
+ messages.add(message);
+ continueDecryption();
}
- private void decryptMessage(final String uuid) {
- Message message = null;
- synchronized (messages.get(uuid)) {
- while (!messages.get(uuid).isEmpty()) {
- if (messages.get(uuid).get(0).getEncryption() == Message.ENCRYPTION_PGP) {
- if (isRunning()) {
- message = messages.get(uuid).remove(0);
- }
- break;
- } else {
- messages.get(uuid).remove(0);
- }
- }
- if (message != null && xmppConnectionService.getPgpEngine() != null) {
- xmppConnectionService.getPgpEngine().decrypt(message, new UiCallback<Message>() {
-
- @Override
- public void userInputRequried(PendingIntent pi, Message message) {
- messages.get(uuid).add(0, message);
- decryptingMessages.put(uuid, false);
- }
-
- @Override
- public void success(Message message) {
- xmppConnectionService.updateConversationUi();
- decryptMessage(uuid);
- }
-
- @Override
- public void error(int error, Message message) {
- message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
- xmppConnectionService.updateConversationUi();
- decryptMessage(uuid);
- }
- });
- } else {
- decryptingMessages.put(uuid, false);
- }
+ public synchronized void decrypt(final List<Message> list) {
+ for(Message message : list) {
+ if (message.getEncryption() == Message.ENCRYPTION_PGP) {
+ messages.add(message);
+ }
+ }
+ continueDecryption();
+ }
+
+ protected synchronized void decryptNext() {
+ if (pendingIntent == null
+ && getOpenPgpApi() != null
+ && (currentMessage = messages.poll()) != null) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ executeApi(currentMessage);
+ decryptNext();
+ }
+ }).start();
}
}
- private void decryptDirectly(final Message message) {
- if (message.getEncryption() == Message.ENCRYPTION_PGP && xmppConnectionService.getPgpEngine() != null) {
- xmppConnectionService.getPgpEngine().decrypt(message, new UiCallback<Message>() {
-
- @Override
- public void userInputRequried(PendingIntent pi, Message message) {
- store(message);
- }
-
- @Override
- public void success(Message message) {
- xmppConnectionService.updateConversationUi();
- xmppConnectionService.getNotificationService().updateNotification(false);
- }
-
- @Override
- public void error(int error, Message message) {
- message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
- xmppConnectionService.updateConversationUi();
- }
- });
- }
- }
+ public synchronized void continueDecryption(boolean resetPending) {
+ if (resetPending) {
+ this.pendingIntent = null;
+ }
+ continueDecryption();
+ }
+
+ public synchronized void continueDecryption() {
+ if (currentMessage == null) {
+ decryptNext();
+ }
+ }
+
+ private synchronized OpenPgpApi getOpenPgpApi() {
+ if (openPgpApi == null) {
+ this.openPgpApi = mXmppConnectionService.getOpenPgpApi();
+ }
+ return this.openPgpApi;
+ }
+
+ private void executeApi(Message message) {
+ Intent params = new Intent();
+ params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
+ if (message.getType() == Message.TYPE_TEXT) {
+ InputStream is = new ByteArrayInputStream(message.getBody().getBytes());
+ final OutputStream os = new ByteArrayOutputStream();
+ Intent result = getOpenPgpApi().executeApi(params, is, os);
+ switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
+ case OpenPgpApi.RESULT_CODE_SUCCESS:
+ try {
+ os.flush();
+ message.setBody(os.toString());
+ message.setEncryption(Message.ENCRYPTION_DECRYPTED);
+ final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager();
+ if (message.trusted()
+ && message.treatAsDownloadable() != Message.Decision.NEVER
+ && manager.getAutoAcceptFileSize() > 0) {
+ manager.createNewDownloadConnection(message);
+ }
+ } catch (IOException e) {
+ message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
+ }
+ mXmppConnectionService.updateMessage(message);
+ break;
+ case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
+ messages.addFirst(message);
+ currentMessage = null;
+ storePendingIntent((PendingIntent) result.getParcelableExtra(OpenPgpApi.RESULT_INTENT));
+ break;
+ case OpenPgpApi.RESULT_CODE_ERROR:
+ message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
+ mXmppConnectionService.updateMessage(message);
+ break;
+ }
+ } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
+ try {
+ final DownloadableFile inputFile = mXmppConnectionService.getFileBackend().getFile(message, false);
+ final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true);
+ outputFile.getParentFile().mkdirs();
+ outputFile.createNewFile();
+ InputStream is = new FileInputStream(inputFile);
+ OutputStream os = new FileOutputStream(outputFile);
+ Intent result = getOpenPgpApi().executeApi(params, is, os);
+ switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
+ case OpenPgpApi.RESULT_CODE_SUCCESS:
+ URL url = message.getFileParams().url;
+ mXmppConnectionService.getFileBackend().updateFileParams(message,url);
+ message.setEncryption(Message.ENCRYPTION_DECRYPTED);
+ inputFile.delete();
+ mXmppConnectionService.getFileBackend().updateMediaScanner(outputFile);
+ mXmppConnectionService.updateMessage(message);
+ break;
+ case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
+ messages.addFirst(message);
+ currentMessage = null;
+ storePendingIntent((PendingIntent) result.getParcelableExtra(OpenPgpApi.RESULT_INTENT));
+ break;
+ case OpenPgpApi.RESULT_CODE_ERROR:
+ message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
+ mXmppConnectionService.updateMessage(message);
+ break;
+ }
+ } catch (final IOException e) {
+ message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
+ mXmppConnectionService.updateMessage(message);
+ }
+ }
+ }
+
+ private void storePendingIntent(PendingIntent pendingIntent) {
+ this.pendingIntent = pendingIntent;
+ mXmppConnectionService.updateConversationUi();
+ }
+
+ public synchronized boolean hasPendingIntent(Conversation conversation) {
+ if (pendingIntent == null) {
+ return false;
+ } else {
+ for(Message message : messages) {
+ if (message.getConversation() == conversation) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ public PendingIntent getPendingIntent() {
+ return pendingIntent;
+ }
+
+ public boolean isConnected() {
+ return getOpenPgpApi() != null;
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java
index b7d5ac8c..fe3ac04b 100644
--- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java
+++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java
@@ -38,96 +38,6 @@ public class PgpEngine {
this.mXmppConnectionService = service;
}
- public void decrypt(final Message message, final UiCallback<Message> callback) {
- Intent params = new Intent();
- params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
- final String uuid = message.getUuid();
- if (message.getType() == Message.TYPE_TEXT) {
- InputStream is = new ByteArrayInputStream(message.getBody().getBytes());
- final OutputStream os = new ByteArrayOutputStream();
- api.executeApiAsync(params, is, os, new IOpenPgpCallback() {
-
- @Override
- public void onReturn(Intent result) {
- notifyPgpDecryptionService(message.getConversation().getAccount(), OpenPgpApi.ACTION_DECRYPT_VERIFY, result);
- switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
- case OpenPgpApi.RESULT_CODE_SUCCESS:
- try {
- os.flush();
- if (message.getEncryption() == Message.ENCRYPTION_PGP
- && message.getUuid().equals(uuid)) {
- message.setBody(os.toString());
- message.setEncryption(Message.ENCRYPTION_DECRYPTED);
- final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager();
- if (message.trusted()
- && message.treatAsDownloadable() != Message.Decision.NEVER
- && manager.getAutoAcceptFileSize() > 0) {
- manager.createNewDownloadConnection(message);
- }
- mXmppConnectionService.updateMessage(message);
- callback.success(message);
- }
- } catch (IOException e) {
- callback.error(R.string.openpgp_error, message);
- return;
- }
-
- return;
- case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
- callback.userInputRequried((PendingIntent) result
- .getParcelableExtra(OpenPgpApi.RESULT_INTENT),
- message);
- return;
- case OpenPgpApi.RESULT_CODE_ERROR:
- callback.error(R.string.openpgp_error, message);
- }
- }
- });
- } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
- try {
- final DownloadableFile inputFile = this.mXmppConnectionService
- .getFileBackend().getFile(message, false);
- final DownloadableFile outputFile = this.mXmppConnectionService
- .getFileBackend().getFile(message, true);
- outputFile.getParentFile().mkdirs();
- outputFile.createNewFile();
- InputStream is = new FileInputStream(inputFile);
- OutputStream os = new FileOutputStream(outputFile);
- api.executeApiAsync(params, is, os, new IOpenPgpCallback() {
-
- @Override
- public void onReturn(Intent result) {
- notifyPgpDecryptionService(message.getConversation().getAccount(), OpenPgpApi.ACTION_DECRYPT_VERIFY, result);
- switch (result.getIntExtra(OpenPgpApi.RESULT_CODE,
- OpenPgpApi.RESULT_CODE_ERROR)) {
- case OpenPgpApi.RESULT_CODE_SUCCESS:
- URL url = message.getFileParams().url;
- mXmppConnectionService.getFileBackend().updateFileParams(message,url);
- message.setEncryption(Message.ENCRYPTION_DECRYPTED);
- PgpEngine.this.mXmppConnectionService
- .updateMessage(message);
- inputFile.delete();
- mXmppConnectionService.getFileBackend().updateMediaScanner(outputFile);
- callback.success(message);
- return;
- case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
- callback.userInputRequried(
- (PendingIntent) result
- .getParcelableExtra(OpenPgpApi.RESULT_INTENT),
- message);
- return;
- case OpenPgpApi.RESULT_CODE_ERROR:
- callback.error(R.string.openpgp_error, message);
- }
- }
- });
- } catch (final IOException e) {
- callback.error(R.string.error_decrypting_file, message);
- }
-
- }
- }
-
public void encrypt(final Message message, final UiCallback<Message> callback) {
Intent params = new Intent();
params.setAction(OpenPgpApi.ACTION_ENCRYPT);
@@ -156,7 +66,6 @@ public class PgpEngine {
@Override
public void onReturn(Intent result) {
- notifyPgpDecryptionService(message.getConversation().getAccount(), OpenPgpApi.ACTION_ENCRYPT, result);
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE,
OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
@@ -202,7 +111,6 @@ public class PgpEngine {
@Override
public void onReturn(Intent result) {
- notifyPgpDecryptionService(message.getConversation().getAccount(), OpenPgpApi.ACTION_ENCRYPT, result);
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE,
OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
@@ -257,7 +165,6 @@ public class PgpEngine {
InputStream is = new ByteArrayInputStream(pgpSig.toString().getBytes());
ByteArrayOutputStream os = new ByteArrayOutputStream();
Intent result = api.executeApi(params, is, os);
- notifyPgpDecryptionService(account, OpenPgpApi.ACTION_DECRYPT_VERIFY, result);
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE,
OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
@@ -315,7 +222,6 @@ public class PgpEngine {
@Override
public void onReturn(Intent result) {
- notifyPgpDecryptionService(account, OpenPgpApi.ACTION_SIGN, result);
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
StringBuilder signatureBuilder = new StringBuilder();
@@ -397,17 +303,4 @@ public class PgpEngine {
return (PendingIntent) result
.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
}
-
- private void notifyPgpDecryptionService(Account account, String action, final Intent result) {
- switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0)) {
- case OpenPgpApi.RESULT_CODE_SUCCESS:
- if (OpenPgpApi.ACTION_SIGN.equals(action)) {
- account.getPgpDecryptionService().onKeychainUnlocked();
- }
- break;
- case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
- account.getPgpDecryptionService().onKeychainLocked();
- break;
- }
- }
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java
index 3e79fccd..62c78cb6 100644
--- a/src/main/java/eu/siacs/conversations/entities/Account.java
+++ b/src/main/java/eu/siacs/conversations/entities/Account.java
@@ -6,6 +6,7 @@ import android.os.SystemClock;
import android.util.Pair;
import eu.siacs.conversations.crypto.PgpDecryptionService;
+
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
import net.java.otr4j.crypto.OtrCryptoException;
@@ -20,7 +21,6 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
-import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.OtrService;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@@ -83,6 +83,14 @@ public class Account extends AbstractEntity {
return getRoster().getContact(jid);
}
+ public boolean hasPendingPgpIntent(Conversation conversation) {
+ return pgpDecryptionService != null && pgpDecryptionService.hasPendingIntent(conversation);
+ }
+
+ public boolean isPgpDecryptionServiceConnected() {
+ return pgpDecryptionService != null && pgpDecryptionService.isConnected();
+ }
+
public enum State {
DISABLED,
OFFLINE,
@@ -398,10 +406,10 @@ public class Account extends AbstractEntity {
public void initAccountServices(final XmppConnectionService context) {
this.mOtrService = new OtrService(context, this);
this.axolotlService = new AxolotlService(this, context);
+ this.pgpDecryptionService = new PgpDecryptionService(context);
if (xmppConnection != null) {
xmppConnection.addOnAdvancedStreamFeaturesAvailableListener(axolotlService);
}
- this.pgpDecryptionService = new PgpDecryptionService(context);
}
public OtrService getOtrService() {
@@ -409,7 +417,7 @@ public class Account extends AbstractEntity {
}
public PgpDecryptionService getPgpDecryptionService() {
- return pgpDecryptionService;
+ return this.pgpDecryptionService;
}
public XmppConnection getXmppConnection() {
diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java
index 37a57f7b..182e86dd 100644
--- a/src/main/java/eu/siacs/conversations/entities/Conversation.java
+++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java
@@ -932,7 +932,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
synchronized (this.messages) {
this.messages.addAll(index, messages);
}
- account.getPgpDecryptionService().addAll(messages);
+ account.getPgpDecryptionService().decrypt(messages);
}
public void sort() {
diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java
index a28bb679..04dacbdb 100644
--- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java
+++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java
@@ -127,7 +127,7 @@ public class HttpDownloadConnection implements Transferable {
message.setTransferable(null);
mHttpConnectionManager.finishConnection(this);
if (message.getEncryption() == Message.ENCRYPTION_PGP) {
- message.getConversation().getAccount().getPgpDecryptionService().add(message);
+ message.getConversation().getAccount().getPgpDecryptionService().decrypt(message);
}
mXmppConnectionService.updateConversationUi();
if (acceptedAutomatically) {
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index 2883b9a5..86f96c37 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -7,7 +7,6 @@ import android.util.Pair;
import net.java.otr4j.session.Session;
import net.java.otr4j.session.SessionStatus;
-import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -32,7 +31,6 @@ import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.services.MessageArchiveService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
-import eu.siacs.conversations.utils.Xmlns;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
import eu.siacs.conversations.xmpp.chatstate.ChatState;
@@ -484,7 +482,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
sendMessageReceipts(account, packet);
}
if (replacedMessage.getEncryption() == Message.ENCRYPTION_PGP) {
- conversation.getAccount().getPgpDecryptionService().add(replacedMessage);
+ conversation.getAccount().getPgpDecryptionService().decrypt(replacedMessage);
}
return;
} else {
@@ -508,7 +506,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
}
if (message.getEncryption() == Message.ENCRYPTION_PGP) {
- conversation.getAccount().getPgpDecryptionService().add(message);
+ conversation.getAccount().getPgpDecryptionService().decrypt(message);
}
if (query == null || query.getWith() == null) { //either no mam or catchup
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 083c108a..541bf4b9 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -49,7 +49,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@@ -62,6 +61,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import de.duenndns.ssl.MemorizingTrustManager;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
+import eu.siacs.conversations.crypto.PgpDecryptionService;
import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage;
@@ -383,6 +383,16 @@ public class XmppConnectionService extends Service {
}
+ public OpenPgpApi getOpenPgpApi() {
+ if (!Config.supportOpenPgp()) {
+ return null;
+ } else if (pgpServiceConnection != null && pgpServiceConnection.isBound()) {
+ return new OpenPgpApi(this, pgpServiceConnection.getService());
+ } else {
+ return null;
+ }
+ }
+
public FileBackend getFileBackend() {
return this.fileBackend;
}
@@ -754,8 +764,9 @@ public class XmppConnectionService extends Service {
@Override
public void onBound(IOpenPgpService2 service) {
for (Account account : accounts) {
- if (account.getPgpDecryptionService() != null) {
- account.getPgpDecryptionService().onOpenPgpServiceBound();
+ final PgpDecryptionService pgp = account.getPgpDecryptionService();
+ if(pgp != null) {
+ pgp.continueDecryption(true);
}
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index 53a36525..b996b71a 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -9,12 +9,9 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
-import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
-import android.support.annotation.Nullable;
import android.text.InputType;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
@@ -214,49 +211,25 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
return -1;
}
-
- private final int KEYCHAIN_UNLOCK_NOT_REQUIRED = 0;
- private final int KEYCHAIN_UNLOCK_REQUIRED = 1;
- private final int KEYCHAIN_UNLOCK_PENDING = 2;
- private int keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
protected OnClickListener clickToDecryptListener = new OnClickListener() {
@Override
public void onClick(View v) {
- if (keychainUnlock == KEYCHAIN_UNLOCK_REQUIRED
- && activity.hasPgp() && !conversation.getAccount().getPgpDecryptionService().isRunning()) {
- keychainUnlock = KEYCHAIN_UNLOCK_PENDING;
- updateSnackBar(conversation);
- Message message = getLastPgpDecryptableMessage();
- if (message != null) {
- activity.xmppConnectionService.getPgpEngine().decrypt(message, new UiCallback<Message>() {
- @Override
- public void success(Message object) {
- conversation.getAccount().getPgpDecryptionService().onKeychainUnlocked();
- keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
- }
-
- @Override
- public void error(int errorCode, Message object) {
- keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
- }
-
- @Override
- public void userInputRequried(PendingIntent pi, Message object) {
- try {
- activity.startIntentSenderForResult(pi.getIntentSender(),
- ConversationActivity.REQUEST_DECRYPT_PGP, null, 0, 0, 0);
- } catch (SendIntentException e) {
- keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
- updatePgpMessages();
- }
- }
- });
+ PendingIntent pendingIntent = conversation.getAccount().getPgpDecryptionService().getPendingIntent();
+ if (pendingIntent != null) {
+ try {
+ activity.startIntentSenderForResult(pendingIntent.getIntentSender(),
+ ConversationActivity.REQUEST_DECRYPT_PGP,
+ null,
+ 0,
+ 0,
+ 0);
+ } catch (SendIntentException e) {
+ Toast.makeText(activity,R.string.unable_to_connect_to_keychain, Toast.LENGTH_SHORT).show();
+ conversation.getAccount().getPgpDecryptionService().continueDecryption(true);
}
- } else {
- keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
- updatePgpMessages();
}
+ updateSnackBar(conversation);
}
};
protected OnClickListener clickToVerify = new OnClickListener() {
@@ -722,7 +695,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
message.setEncryption(Message.ENCRYPTION_PGP);
activity.updateConversationList();
updateMessages();
- conversation.getAccount().getPgpDecryptionService().add(message);
+ conversation.getAccount().getPgpDecryptionService().decrypt(message);
}
protected void privateMessageWith(final Jid counterpart) {
@@ -789,7 +762,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
this.conversation.trim();
}
- this.keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
this.conversation = conversation;
boolean canWrite = this.conversation.getMode() == Conversation.MODE_SINGLE || this.conversation.getMucOptions().participating();
this.mEditMessage.setEnabled(canWrite);
@@ -909,7 +881,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
default:
break;
}
- } else if (keychainUnlock == KEYCHAIN_UNLOCK_REQUIRED) {
+ } else if (account.hasPendingPgpIntent(conversation)) {
showSnackbar(R.string.openpgp_messages_found, R.string.decrypt, clickToDecryptListener);
} else if (mode == Conversation.MODE_SINGLE
&& conversation.smpRequested()) {
@@ -932,7 +904,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
final ConversationActivity activity = (ConversationActivity) getActivity();
if (this.conversation != null) {
conversation.populateWithMessages(ConversationFragment.this.messageList);
- updatePgpMessages();
updateSnackBar(conversation);
updateStatusMessages();
this.messageListAdapter.notifyDataSetChanged();
@@ -945,29 +916,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
}
- public void updatePgpMessages() {
- if (keychainUnlock != KEYCHAIN_UNLOCK_PENDING) {
- if (getLastPgpDecryptableMessage() != null
- && !conversation.getAccount().getPgpDecryptionService().isRunning()) {
- keychainUnlock = KEYCHAIN_UNLOCK_REQUIRED;
- } else {
- keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
- }
- }
- }
-
- @Nullable
- private Message getLastPgpDecryptableMessage() {
- for (final Message message : this.messageList) {
- if (message.getEncryption() == Message.ENCRYPTION_PGP
- && (message.getStatus() == Message.STATUS_RECEIVED || message.getStatus() >= Message.STATUS_SEND)
- && message.getTransferable() == null) {
- return message;
- }
- }
- return null;
- }
-
private void messageSent() {
mEditMessage.setText("");
updateChatMsgHint();
@@ -1424,9 +1372,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
final Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == ConversationActivity.REQUEST_DECRYPT_PGP) {
- activity.getSelectedConversation().getAccount().getPgpDecryptionService().onKeychainUnlocked();
- keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
- updatePgpMessages();
+ activity.getSelectedConversation().getAccount().getPgpDecryptionService().continueDecryption(true);
} else if (requestCode == ConversationActivity.REQUEST_TRUST_KEYS_TEXT) {
final String body = mEditMessage.getText().toString();
Message message = new Message(conversation, body, conversation.getNextEncryption());
@@ -1435,11 +1381,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
int choice = data.getIntExtra("choice", ConversationActivity.ATTACHMENT_CHOICE_INVALID);
activity.selectPresenceToAttachFile(choice, conversation.getNextEncryption());
}
- } else {
- if (requestCode == ConversationActivity.REQUEST_DECRYPT_PGP) {
- keychainUnlock = KEYCHAIN_UNLOCK_NOT_REQUIRED;
- updatePgpMessages();
- }
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index e174401d..56517e3b 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -631,8 +631,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
displayOpenableMessage(viewHolder, message);
}
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
- if (activity.hasPgp()) {
- if (account.getPgpDecryptionService().isRunning()) {
+ if (account.isPgpDecryptionServiceConnected()) {
+ if (!account.hasPendingPgpIntent(conversation)) {
displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting), darkBackground);
} else {
displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), darkBackground);
diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
index c9ee6bdc..dbcb4b6d 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
@@ -110,7 +110,7 @@ public class JingleConnection implements Transferable {
if (message.getEncryption() != Message.ENCRYPTION_PGP) {
mXmppConnectionService.getFileBackend().updateMediaScanner(file);
} else {
- account.getPgpDecryptionService().add(message);
+ account.getPgpDecryptionService().decrypt(message);
}
}
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 945d6fb9..328004af 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -662,4 +662,5 @@
<string name="pref_theme_dark">Dark theme</string>
<string name="pref_use_green_background">Green Background</string>
<string name="pref_use_green_background_summary">Use green background for received messages</string>
+ <string name="unable_to_connect_to_keychain">Unable to connect to OpenKeychain</string>
</resources>