]> nmode's Git Repositories - signal-cli/commitdiff
Implement unregister command for jsonrpc and dbus daemon
authorAsamK <asamk@gmx.de>
Fri, 12 Nov 2021 15:07:35 +0000 (16:07 +0100)
committerAsamK <asamk@gmx.de>
Fri, 12 Nov 2021 15:07:35 +0000 (16:07 +0100)
graalvm-config-dir/resource-config.json
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java
src/main/java/org/asamk/Signal.java
src/main/java/org/asamk/signal/Main.java
src/main/java/org/asamk/signal/commands/DaemonCommand.java
src/main/java/org/asamk/signal/commands/UnregisterCommand.java
src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java
src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java
src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java

index 5aabcdf957152966897c13f804ec3e6ff6d6ff5c..a15c69c3238ffbc2f6bcf8ac41026b2046fe257b 100644 (file)
@@ -13,6 +13,9 @@
     {
       "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AT\\E"
     }, 
+    {
+      "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ\\E"
+    }, 
     {
       "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BB\\E"
     }, 
index 656cba49abdc2cb64938323c082cf10a0d4565be..2ffb5337e8ae9b10d4c50109ab03deb6141f1fb0 100644 (file)
@@ -248,6 +248,8 @@ public interface Manager extends Closeable {
 
     boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient);
 
+    void addClosedListener(Runnable listener);
+
     @Override
     void close() throws IOException;
 
index 756c0a9474894ff8ca770c6b7b8b62f727f74fe9..28a461619e16386f4af43e90b6e78e7c4014a1f6 100644 (file)
@@ -95,6 +95,7 @@ import java.net.URISyntaxException;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.security.SignatureException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -142,6 +143,7 @@ public class ManagerImpl implements Manager {
     private Thread receiveThread;
     private final Set<ReceiveMessageHandler> weakHandlers = new HashSet<>();
     private final Set<ReceiveMessageHandler> messageHandlers = new HashSet<>();
+    private final List<Runnable> closedListeners = new ArrayList<>();
     private boolean isReceivingSynchronous;
 
     ManagerImpl(
@@ -385,6 +387,7 @@ public class ManagerImpl implements Manager {
         dependencies.getAccountManager().setGcmId(Optional.absent());
 
         account.setRegistered(false);
+        close();
     }
 
     @Override
@@ -399,6 +402,7 @@ public class ManagerImpl implements Manager {
         dependencies.getAccountManager().deleteAccount();
 
         account.setRegistered(false);
+        close();
     }
 
     @Override
@@ -1325,6 +1329,13 @@ public class ManagerImpl implements Manager {
         return identityHelper.trustIdentityAllKeys(recipientId);
     }
 
+    @Override
+    public void addClosedListener(final Runnable listener) {
+        synchronized (closedListeners) {
+            closedListeners.add(listener);
+        }
+    }
+
     private void handleIdentityFailure(
             final RecipientId recipientId,
             final org.whispersystems.signalservice.api.messages.SendMessageResult.IdentityFailure identityFailure
@@ -1390,10 +1401,6 @@ public class ManagerImpl implements Manager {
 
     @Override
     public void close() throws IOException {
-        close(true);
-    }
-
-    private void close(boolean closeAccount) throws IOException {
         Thread thread;
         synchronized (messageHandlers) {
             weakHandlers.clear();
@@ -1408,7 +1415,12 @@ public class ManagerImpl implements Manager {
 
         dependencies.getSignalWebSocket().disconnect();
 
-        if (closeAccount && account != null) {
+        synchronized (closedListeners) {
+            closedListeners.forEach(Runnable::run);
+            closedListeners.clear();
+        }
+
+        if (account != null) {
             account.close();
         }
         account = null;
index 26f8b961b089b80c34e71179a1f9d8be37ccdd17..8fd1d5aaf7ab72f4e52e024beb8960ee5b26b861 100644 (file)
@@ -36,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;
@@ -54,6 +55,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
                 return;
             }
             managers.add(m);
+            m.addClosedListener(() -> this.removeManager(m));
         }
         synchronized (onManagerAddedHandlers) {
             for (final var handler : onManagerAddedHandlers) {
@@ -69,6 +71,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) {
index 7e25bfc489b676a2cc0bc7e49ae6d3e31daf4e1b..8ce717455b9171c2bb8df6c2b8b4d96e0a1dba1d 100644 (file)
@@ -171,6 +171,10 @@ public interface Signal extends DBusInterface {
 
     void submitRateLimitChallenge(String challenge, String captchaString) throws Error.Failure;
 
+    void unregister() throws Error.Failure;
+
+    void deleteAccount() throws Error.Failure;
+
     class MessageReceivedV2 extends DBusSignal {
 
         private final long timestamp;
index fb9d92b6ad9ce6b35529077e96ea1f8a20a12b88..eaa85c128eff4357c2dbc8a1e6eaf36f7d085d7a 100644 (file)
@@ -100,7 +100,7 @@ public class Main {
         }
         SLF4JBridgeHandler.removeHandlersForRootLogger();
         SLF4JBridgeHandler.install();
-        java.util.logging.Logger.getLogger("").setLevel(java.util.logging.Level.FINEST);
+        // java.util.logging.Logger.getLogger("").setLevel(java.util.logging.Level.FINEST);
     }
 
     private static int getStatusForError(final CommandException e) {
index 605182ae04a999bd52f453d243a2bcb87d306202..726cf26800d87bb9ef3651c65bf3f0dc8b18651e 100644 (file)
@@ -132,6 +132,12 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
             runDbusSingleAccount(m, false, receiveMode != ReceiveMode.ON_START);
         }
 
+        m.addClosedListener(() -> {
+            synchronized (this) {
+                notifyAll();
+            }
+        });
+
         synchronized (this) {
             try {
                 wait();
@@ -230,7 +236,6 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
     }
 
     private void runSocket(final ServerSocketChannel serverChannel, Consumer<SocketChannel> socketHandler) {
-        final var mainThread = Thread.currentThread();
         new Thread(() -> {
             while (true) {
                 final SocketChannel channel;
@@ -241,7 +246,9 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
                     logger.info("Accepted new client: " + clientString);
                 } catch (IOException e) {
                     logger.error("Failed to accept new socket connection", e);
-                    mainThread.notifyAll();
+                    synchronized (this) {
+                        notifyAll();
+                    }
                     break;
                 }
                 new Thread(() -> {
@@ -292,6 +299,17 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
                     }
                 }
             });
+            c.addOnManagerRemovedHandler(m -> {
+                final var path = DbusConfig.getObjectPath(m.getSelfNumber());
+                try {
+                    final var object = connection.getExportedObject(null, path);
+                    if (object instanceof DbusSignalImpl dbusSignal) {
+                        dbusSignal.close();
+                    }
+                } catch (DBusException ignored) {
+                }
+                connection.unExportObject(path);
+            });
 
             final var initThreads = c.getAccountNumbers()
                     .stream()
index 68a203752bd4edc56bfac19f778b586dabe4b927..d7b9c9e53630e6194842e11dde3abc0610d58401 100644 (file)
@@ -11,7 +11,7 @@ import org.asamk.signal.manager.Manager;
 
 import java.io.IOException;
 
-public class UnregisterCommand implements LocalCommand {
+public class UnregisterCommand implements JsonRpcLocalCommand {
 
     @Override
     public String getName() {
index cc346f7af7ff7ab4b8fd434dfb7c1297b0c0eeb4..b61ca1358f93de03ada08e9b2d54fa6982c49a8e 100644 (file)
@@ -68,6 +68,7 @@ public class DbusManagerImpl implements Manager {
 
     private final Set<ReceiveMessageHandler> weakHandlers = new HashSet<>();
     private final Set<ReceiveMessageHandler> messageHandlers = new HashSet<>();
+    private final List<Runnable> closedListeners = new ArrayList<>();
     private DBusSigHandler<Signal.MessageReceivedV2> dbusMsgHandler;
     private DBusSigHandler<Signal.ReceiptReceivedV2> dbusRcptHandler;
     private DBusSigHandler<Signal.SyncMessageReceivedV2> dbusSyncHandler;
@@ -583,6 +584,13 @@ public class DbusManagerImpl implements Manager {
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public void addClosedListener(final Runnable listener) {
+        synchronized (closedListeners) {
+            closedListeners.add(listener);
+        }
+    }
+
     @Override
     public void close() throws IOException {
         synchronized (this) {
@@ -595,6 +603,10 @@ public class DbusManagerImpl implements Manager {
             weakHandlers.clear();
             messageHandlers.clear();
         }
+        synchronized (closedListeners) {
+            closedListeners.forEach(Runnable::run);
+            closedListeners.clear();
+        }
     }
 
     private SendMessageResults handleMessage(
index 2983b2931f292eb7502e4529e683359c0021c029..8f6d0aa4575d9c146bf97b78286aa532cd3cb8b1 100644 (file)
@@ -138,6 +138,24 @@ public class DbusSignalImpl implements Signal {
 
     }
 
+    @Override
+    public void unregister() throws Error.Failure {
+        try {
+            m.unregister();
+        } catch (IOException e) {
+            throw new Error.Failure("Failed to unregister: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void deleteAccount() throws Error.Failure {
+        try {
+            m.deleteAccount();
+        } catch (IOException e) {
+            throw new Error.Failure("Failed to delete account: " + e.getMessage());
+        }
+    }
+
     @Override
     public void addDevice(String uri) {
         try {
index c4e9775aefb52f273e378286d830427a15fbf8c0..12a56775f31f0307527af46b9112886ef156afb4 100644 (file)
@@ -64,6 +64,8 @@ public class SignalJsonRpcDispatcherHandler {
 
         if (!noReceiveOnStart) {
             c.getAccountNumbers().stream().map(c::getManager).filter(Objects::nonNull).forEach(this::subscribeReceive);
+            c.addOnManagerAddedHandler(this::subscribeReceive);
+            c.addOnManagerRemovedHandler(this::unsubscribeReceive);
         }
 
         handleConnection();
@@ -76,6 +78,9 @@ public class SignalJsonRpcDispatcherHandler {
             subscribeReceive(m);
         }
 
+        final var currentThread = Thread.currentThread();
+        m.addClosedListener(currentThread::interrupt);
+
         handleConnection();
     }