aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/crypto/PgpDecryptionService.java
diff options
context:
space:
mode:
authorlookshe <github@lookshe.org>2016-03-06 19:42:55 +0100
committerlookshe <github@lookshe.org>2016-03-06 19:42:55 +0100
commit3c400703e082a1b180b35d891b8fb3460c7d5b87 (patch)
tree28738dd90fc41b4ab71897f38d324828778ad2e3 /src/main/java/de/thedevstack/conversationsplus/crypto/PgpDecryptionService.java
parent72114d732427266024cdd6e27cd8d1aa60afae2f (diff)
parentf28d77dc42f6bac5a026e0b1c78562dee8de45ac (diff)
Merge branch 'trz/rebase' into trz/rename
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/crypto/PgpDecryptionService.java')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/crypto/PgpDecryptionService.java162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/PgpDecryptionService.java b/src/main/java/de/thedevstack/conversationsplus/crypto/PgpDecryptionService.java
new file mode 100644
index 00000000..b833f6e4
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/crypto/PgpDecryptionService.java
@@ -0,0 +1,162 @@
+package de.thedevstack.conversationsplus.crypto;
+
+import android.app.PendingIntent;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.services.XmppConnectionService;
+import de.thedevstack.conversationsplus.ui.UiCallback;
+
+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();
+ }
+
+ public void onOpenPgpServiceBound() {
+ decryptAllMessages();
+ }
+
+ public boolean isRunning() {
+ synchronized (keychainLockedLock) {
+ return !keychainLocked;
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+ }
+
+ 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);
+ }
+ }
+ }
+
+ 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();
+ }
+ });
+ }
+ }
+}