From: AsamK Date: Fri, 12 Nov 2021 15:07:35 +0000 (+0100) Subject: Implement unregister command for jsonrpc and dbus daemon X-Git-Tag: v0.10.0~50 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/c73c58723cc001327ed3f28cb8b98578a5437b93?ds=sidebyside Implement unregister command for jsonrpc and dbus daemon --- diff --git a/graalvm-config-dir/resource-config.json b/graalvm-config-dir/resource-config.json index 5aabcdf9..a15c69c3 100644 --- a/graalvm-config-dir/resource-config.json +++ b/graalvm-config-dir/resource-config.json @@ -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" }, diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index 656cba49..2ffb5337 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -248,6 +248,8 @@ public interface Manager extends Closeable { boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient); + void addClosedListener(Runnable listener); + @Override void close() throws IOException; diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index 756c0a94..28a46161 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -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 weakHandlers = new HashSet<>(); private final Set messageHandlers = new HashSet<>(); + private final List 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; diff --git a/lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java index 26f8b961..8fd1d5aa 100644 --- a/lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java @@ -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 handler) { synchronized (onManagerRemovedHandlers) { diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 7e25bfc4..8ce71745 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -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; diff --git a/src/main/java/org/asamk/signal/Main.java b/src/main/java/org/asamk/signal/Main.java index fb9d92b6..eaa85c12 100644 --- a/src/main/java/org/asamk/signal/Main.java +++ b/src/main/java/org/asamk/signal/Main.java @@ -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) { diff --git a/src/main/java/org/asamk/signal/commands/DaemonCommand.java b/src/main/java/org/asamk/signal/commands/DaemonCommand.java index 605182ae..726cf268 100644 --- a/src/main/java/org/asamk/signal/commands/DaemonCommand.java +++ b/src/main/java/org/asamk/signal/commands/DaemonCommand.java @@ -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 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() diff --git a/src/main/java/org/asamk/signal/commands/UnregisterCommand.java b/src/main/java/org/asamk/signal/commands/UnregisterCommand.java index 68a20375..d7b9c9e5 100644 --- a/src/main/java/org/asamk/signal/commands/UnregisterCommand.java +++ b/src/main/java/org/asamk/signal/commands/UnregisterCommand.java @@ -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() { diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index cc346f7a..b61ca135 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -68,6 +68,7 @@ public class DbusManagerImpl implements Manager { private final Set weakHandlers = new HashSet<>(); private final Set messageHandlers = new HashSet<>(); + private final List closedListeners = new ArrayList<>(); private DBusSigHandler dbusMsgHandler; private DBusSigHandler dbusRcptHandler; private DBusSigHandler 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( diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 2983b293..8f6d0aa4 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -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 { diff --git a/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java b/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java index c4e9775a..12a56775 100644 --- a/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java +++ b/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java @@ -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(); }