]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java
Add --bus-name option to use different D-Bus bus name
[signal-cli] / src / main / java / org / asamk / signal / dbus / DbusMultiAccountManagerImpl.java
1 package org.asamk.signal.dbus;
2
3 import org.asamk.Signal;
4 import org.asamk.SignalControl;
5 import org.asamk.signal.manager.Manager;
6 import org.asamk.signal.manager.MultiAccountManager;
7 import org.asamk.signal.manager.ProvisioningManager;
8 import org.asamk.signal.manager.RegistrationManager;
9 import org.freedesktop.dbus.DBusPath;
10 import org.freedesktop.dbus.connections.impl.DBusConnection;
11 import org.freedesktop.dbus.exceptions.DBusException;
12 import org.freedesktop.dbus.interfaces.DBusInterface;
13
14 import java.io.IOException;
15 import java.net.URI;
16 import java.net.URISyntaxException;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Set;
20 import java.util.concurrent.TimeoutException;
21 import java.util.function.Consumer;
22
23 /**
24 * This class implements the MultiAccountManager interface using the DBus Signal interface, where possible.
25 * It's used for the signal-cli dbus client mode (--dbus, --dbus-system)
26 */
27 public class DbusMultiAccountManagerImpl implements MultiAccountManager {
28
29 private final SignalControl signalControl;
30 private final DBusConnection connection;
31 // TODO add listeners for added/removed accounts
32 private final Set<Consumer<Manager>> onManagerAddedHandlers = new HashSet<>();
33 private final Set<Consumer<Manager>> onManagerRemovedHandlers = new HashSet<>();
34 private final String busname;
35
36 public DbusMultiAccountManagerImpl(
37 final SignalControl signalControl, DBusConnection connection, final String busname
38 ) {
39 this.signalControl = signalControl;
40 this.connection = connection;
41 this.busname = busname;
42 }
43
44 @Override
45 public List<String> getAccountNumbers() {
46 return signalControl.listAccounts()
47 .stream()
48 .map(a -> getRemoteObject(a, Signal.class).getSelfNumber())
49 .toList();
50 }
51
52 @Override
53 public List<Manager> getManagers() {
54 return signalControl.listAccounts()
55 .stream()
56 .map(a -> (Manager) new DbusManagerImpl(getRemoteObject(a, Signal.class), connection, busname))
57 .toList();
58 }
59
60 @Override
61 public void addOnManagerAddedHandler(final Consumer<Manager> handler) {
62 synchronized (onManagerAddedHandlers) {
63 onManagerAddedHandlers.add(handler);
64 }
65 }
66
67 @Override
68 public void addOnManagerRemovedHandler(final Consumer<Manager> handler) {
69 synchronized (onManagerRemovedHandlers) {
70 onManagerRemovedHandlers.add(handler);
71 }
72 }
73
74 @Override
75 public Manager getManager(final String phoneNumber) {
76 return new DbusManagerImpl(getRemoteObject(signalControl.getAccount(phoneNumber), Signal.class),
77 connection,
78 busname);
79 }
80
81 @Override
82 public URI getNewProvisioningDeviceLinkUri() throws TimeoutException, IOException {
83 try {
84 return new URI(signalControl.startLink());
85 } catch (URISyntaxException e) {
86 throw new IOException(e);
87 }
88 }
89
90 @Override
91 public ProvisioningManager getProvisioningManagerFor(final URI deviceLinkUri) {
92 return new DbusProvisioningManagerImpl(signalControl, connection, deviceLinkUri);
93 }
94
95 @Override
96 public RegistrationManager getNewRegistrationManager(final String account) throws IOException {
97 return new DbusRegistrationManagerImpl(account, signalControl, connection);
98 }
99
100 @Override
101 public void close() {
102 }
103
104 private <T extends DBusInterface> T getRemoteObject(final DBusPath path, final Class<T> type) {
105 try {
106 return connection.getRemoteObject(busname, path.getPath(), type);
107 } catch (DBusException e) {
108 throw new AssertionError(e);
109 }
110 }
111 }