]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java
Improve JSON-RPC subscribeReceive method with subscription id
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / MultiAccountManagerImpl.java
index df74cf42418cf83078e96784a0899bcd10a63b0a..83f0bb269e9da4a9e5512a33053e9fdc7b7e55b7 100644 (file)
@@ -6,12 +6,16 @@ import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeoutException;
 import java.util.function.Consumer;
-import java.util.stream.Collectors;
 
 public class MultiAccountManagerImpl implements MultiAccountManager {
 
@@ -20,6 +24,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
     private final Set<Consumer<Manager>> onManagerAddedHandlers = new HashSet<>();
     private final Set<Consumer<Manager>> onManagerRemovedHandlers = new HashSet<>();
     private final Set<Manager> managers = new HashSet<>();
+    private final Map<URI, ProvisioningManager> provisioningManagers = new HashMap<>();
     private final File dataPath;
     private final ServiceEnvironment serviceEnvironment;
     private final String userAgent;
@@ -31,6 +36,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
             final String userAgent
     ) {
         this.managers.addAll(managers);
+        managers.forEach(m -> m.addClosedListener(() -> this.removeManager(m)));
         this.dataPath = dataPath;
         this.serviceEnvironment = serviceEnvironment;
         this.userAgent = userAgent;
@@ -39,7 +45,14 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
     @Override
     public List<String> getAccountNumbers() {
         synchronized (managers) {
-            return managers.stream().map(Manager::getSelfNumber).collect(Collectors.toList());
+            return managers.stream().map(Manager::getSelfNumber).toList();
+        }
+    }
+
+    @Override
+    public List<Manager> getManagers() {
+        synchronized (managers) {
+            return new ArrayList<>(managers);
         }
     }
 
@@ -49,6 +62,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
                 return;
             }
             managers.add(m);
+            m.addClosedListener(() -> this.removeManager(m));
         }
         synchronized (onManagerAddedHandlers) {
             for (final var handler : onManagerAddedHandlers) {
@@ -64,6 +78,19 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
         }
     }
 
+    void removeManager(final Manager m) {
+        synchronized (managers) {
+            if (!managers.remove(m)) {
+                return;
+            }
+        }
+        synchronized (onManagerRemovedHandlers) {
+            for (final var handler : onManagerRemovedHandlers) {
+                handler.accept(m);
+            }
+        }
+    }
+
     @Override
     public void addOnManagerRemovedHandler(final Consumer<Manager> handler) {
         synchronized (onManagerRemovedHandlers) {
@@ -79,7 +106,19 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
     }
 
     @Override
-    public ProvisioningManager getNewProvisioningManager() {
+    public URI getNewProvisioningDeviceLinkUri() throws TimeoutException, IOException {
+        final var provisioningManager = getNewProvisioningManager();
+        final var deviceLinkUri = provisioningManager.getDeviceLinkUri();
+        provisioningManagers.put(deviceLinkUri, provisioningManager);
+        return deviceLinkUri;
+    }
+
+    @Override
+    public ProvisioningManager getProvisioningManagerFor(final URI deviceLinkUri) {
+        return provisioningManagers.remove(deviceLinkUri);
+    }
+
+    private ProvisioningManager getNewProvisioningManager() {
         return ProvisioningManager.init(dataPath, serviceEnvironment, userAgent, this::addManager);
     }
 
@@ -91,7 +130,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
     @Override
     public void close() {
         synchronized (managers) {
-            for (var m : managers) {
+            for (var m : new ArrayList<>(managers)) {
                 try {
                     m.close();
                 } catch (IOException e) {