]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
Add MultiAccountManager
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / ManagerImpl.java
index 57ac0aa78beb4446f9faf5e78fb0b2866e9c452e..69ae926992fe0764b55fb461935ceb3acf9a6b49 100644 (file)
@@ -17,6 +17,7 @@
 package org.asamk.signal.manager;
 
 import org.asamk.signal.manager.actions.HandleAction;
+import org.asamk.signal.manager.api.Configuration;
 import org.asamk.signal.manager.api.Device;
 import org.asamk.signal.manager.api.Group;
 import org.asamk.signal.manager.api.Identity;
@@ -107,6 +108,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static org.asamk.signal.manager.config.ServiceConfig.capabilities;
 
@@ -138,6 +140,7 @@ public class ManagerImpl implements Manager {
     private boolean ignoreAttachments = false;
 
     private Thread receiveThread;
+    private final Set<ReceiveMessageHandler> weakHandlers = new HashSet<>();
     private final Set<ReceiveMessageHandler> messageHandlers = new HashSet<>();
     private boolean isReceivingSynchronous;
 
@@ -322,29 +325,35 @@ public class ManagerImpl implements Manager {
                         account.isDiscoverableByPhoneNumber());
     }
 
+    @Override
+    public Configuration getConfiguration() {
+        final var configurationStore = account.getConfigurationStore();
+        return new Configuration(java.util.Optional.ofNullable(configurationStore.getReadReceipts()),
+                java.util.Optional.ofNullable(configurationStore.getUnidentifiedDeliveryIndicators()),
+                java.util.Optional.ofNullable(configurationStore.getTypingIndicators()),
+                java.util.Optional.ofNullable(configurationStore.getLinkPreviews()));
+    }
+
     @Override
     public void updateConfiguration(
-            final Boolean readReceipts,
-            final Boolean unidentifiedDeliveryIndicators,
-            final Boolean typingIndicators,
-            final Boolean linkPreviews
+            Configuration configuration
     ) throws IOException, NotMasterDeviceException {
         if (!account.isMasterDevice()) {
             throw new NotMasterDeviceException();
         }
 
         final var configurationStore = account.getConfigurationStore();
-        if (readReceipts != null) {
-            configurationStore.setReadReceipts(readReceipts);
+        if (configuration.readReceipts().isPresent()) {
+            configurationStore.setReadReceipts(configuration.readReceipts().get());
         }
-        if (unidentifiedDeliveryIndicators != null) {
-            configurationStore.setUnidentifiedDeliveryIndicators(unidentifiedDeliveryIndicators);
+        if (configuration.unidentifiedDeliveryIndicators().isPresent()) {
+            configurationStore.setUnidentifiedDeliveryIndicators(configuration.unidentifiedDeliveryIndicators().get());
         }
-        if (typingIndicators != null) {
-            configurationStore.setTypingIndicators(typingIndicators);
+        if (configuration.typingIndicators().isPresent()) {
+            configurationStore.setTypingIndicators(configuration.typingIndicators().get());
         }
-        if (linkPreviews != null) {
-            configurationStore.setLinkPreviews(linkPreviews);
+        if (configuration.linkPreviews().isPresent()) {
+            configurationStore.setLinkPreviews(configuration.linkPreviews().get());
         }
         syncHelper.sendConfigurationMessage();
     }
@@ -394,6 +403,8 @@ public class ManagerImpl implements Manager {
 
     @Override
     public void submitRateLimitRecaptchaChallenge(String challenge, String captcha) throws IOException {
+        captcha = captcha == null ? null : captcha.replace("signalcaptcha://", "");
+
         dependencies.getAccountManager().submitRateLimitRecaptchaChallenge(challenge, captcha);
     }
 
@@ -897,14 +908,17 @@ public class ManagerImpl implements Manager {
     }
 
     @Override
-    public void addReceiveHandler(final ReceiveMessageHandler handler) {
+    public void addReceiveHandler(final ReceiveMessageHandler handler, final boolean isWeakListener) {
         if (isReceivingSynchronous) {
             throw new IllegalStateException("Already receiving message synchronously.");
         }
         synchronized (messageHandlers) {
-            messageHandlers.add(handler);
-
-            startReceiveThreadIfRequired();
+            if (isWeakListener) {
+                weakHandlers.add(handler);
+            } else {
+                messageHandlers.add(handler);
+                startReceiveThreadIfRequired();
+            }
         }
     }
 
@@ -913,17 +927,18 @@ public class ManagerImpl implements Manager {
             return;
         }
         receiveThread = new Thread(() -> {
+            logger.debug("Starting receiving messages");
             while (!Thread.interrupted()) {
                 try {
                     receiveMessagesInternal(1L, TimeUnit.HOURS, false, (envelope, e) -> {
                         synchronized (messageHandlers) {
-                            for (ReceiveMessageHandler h : messageHandlers) {
+                            Stream.concat(messageHandlers.stream(), weakHandlers.stream()).forEach(h -> {
                                 try {
                                     h.handleMessage(envelope, e);
                                 } catch (Exception ex) {
                                     logger.warn("Message handler failed, ignoring", ex);
                                 }
-                            }
+                            });
                         }
                     });
                     break;
@@ -931,12 +946,14 @@ public class ManagerImpl implements Manager {
                     logger.warn("Receiving messages failed, retrying", e);
                 }
             }
+            logger.debug("Finished receiving messages");
             hasCaughtUpWithOldMessages = false;
             synchronized (messageHandlers) {
                 receiveThread = null;
 
                 // Check if in the meantime another handler has been registered
                 if (!messageHandlers.isEmpty()) {
+                    logger.debug("Another handler has been registered, starting receive thread again");
                     startReceiveThreadIfRequired();
                 }
             }
@@ -949,12 +966,13 @@ public class ManagerImpl implements Manager {
     public void removeReceiveHandler(final ReceiveMessageHandler handler) {
         final Thread thread;
         synchronized (messageHandlers) {
-            thread = receiveThread;
-            receiveThread = null;
+            weakHandlers.remove(handler);
             messageHandlers.remove(handler);
-            if (!messageHandlers.isEmpty() || isReceivingSynchronous) {
+            if (!messageHandlers.isEmpty() || receiveThread == null || isReceivingSynchronous) {
                 return;
             }
+            thread = receiveThread;
+            receiveThread = null;
         }
 
         stopReceiveThread(thread);
@@ -1107,6 +1125,7 @@ public class ManagerImpl implements Manager {
         }
         handleQueuedActions(queuedActions);
         queuedActions.clear();
+        dependencies.getSignalWebSocket().disconnect();
     }
 
     @Override
@@ -1369,6 +1388,7 @@ public class ManagerImpl implements Manager {
     private void close(boolean closeAccount) throws IOException {
         Thread thread;
         synchronized (messageHandlers) {
+            weakHandlers.clear();
             messageHandlers.clear();
             thread = receiveThread;
             receiveThread = null;