1 package org
.asamk
.signal
.manager
;
3 import org
.asamk
.signal
.manager
.config
.ServiceConfig
;
4 import org
.asamk
.signal
.manager
.config
.ServiceEnvironmentConfig
;
5 import org
.signal
.libsignal
.metadata
.certificate
.CertificateValidator
;
6 import org
.signal
.libsignal
.zkgroup
.profiles
.ClientZkProfileOperations
;
7 import org
.whispersystems
.signalservice
.api
.KeyBackupService
;
8 import org
.whispersystems
.signalservice
.api
.SignalServiceAccountManager
;
9 import org
.whispersystems
.signalservice
.api
.SignalServiceDataStore
;
10 import org
.whispersystems
.signalservice
.api
.SignalServiceMessageReceiver
;
11 import org
.whispersystems
.signalservice
.api
.SignalServiceMessageSender
;
12 import org
.whispersystems
.signalservice
.api
.SignalSessionLock
;
13 import org
.whispersystems
.signalservice
.api
.SignalWebSocket
;
14 import org
.whispersystems
.signalservice
.api
.crypto
.SignalServiceCipher
;
15 import org
.whispersystems
.signalservice
.api
.groupsv2
.ClientZkOperations
;
16 import org
.whispersystems
.signalservice
.api
.groupsv2
.GroupsV2Api
;
17 import org
.whispersystems
.signalservice
.api
.groupsv2
.GroupsV2Operations
;
18 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
19 import org
.whispersystems
.signalservice
.api
.services
.ProfileService
;
20 import org
.whispersystems
.signalservice
.api
.util
.CredentialsProvider
;
21 import org
.whispersystems
.signalservice
.api
.util
.UptimeSleepTimer
;
22 import org
.whispersystems
.signalservice
.api
.websocket
.WebSocketFactory
;
23 import org
.whispersystems
.signalservice
.internal
.websocket
.WebSocketConnection
;
25 import java
.util
.Collection
;
26 import java
.util
.Optional
;
27 import java
.util
.concurrent
.ExecutorService
;
28 import java
.util
.function
.Supplier
;
30 import static org
.asamk
.signal
.manager
.config
.ServiceConfig
.capabilities
;
32 public class SignalDependencies
{
34 private final Object LOCK
= new Object();
36 private final ServiceEnvironmentConfig serviceEnvironmentConfig
;
37 private final String userAgent
;
38 private final CredentialsProvider credentialsProvider
;
39 private final SignalServiceDataStore dataStore
;
40 private final ExecutorService executor
;
41 private final SignalSessionLock sessionLock
;
43 private boolean allowStories
= true;
45 private SignalServiceAccountManager accountManager
;
46 private GroupsV2Api groupsV2Api
;
47 private GroupsV2Operations groupsV2Operations
;
48 private ClientZkOperations clientZkOperations
;
50 private SignalWebSocket signalWebSocket
;
51 private SignalServiceMessageReceiver messageReceiver
;
52 private SignalServiceMessageSender messageSender
;
54 private KeyBackupService keyBackupService
;
55 private ProfileService profileService
;
56 private SignalServiceCipher cipher
;
59 final ServiceEnvironmentConfig serviceEnvironmentConfig
,
60 final String userAgent
,
61 final CredentialsProvider credentialsProvider
,
62 final SignalServiceDataStore dataStore
,
63 final ExecutorService executor
,
64 final SignalSessionLock sessionLock
66 this.serviceEnvironmentConfig
= serviceEnvironmentConfig
;
67 this.userAgent
= userAgent
;
68 this.credentialsProvider
= credentialsProvider
;
69 this.dataStore
= dataStore
;
70 this.executor
= executor
;
71 this.sessionLock
= sessionLock
;
74 public void resetAfterAddressChange() {
75 this.messageSender
= null;
77 getSignalWebSocket().forceNewWebSockets();
81 * This method needs to be called before the first websocket is created
83 public void setAllowStories(final boolean allowStories
) {
84 this.allowStories
= allowStories
;
87 public ServiceEnvironmentConfig
getServiceEnvironmentConfig() {
88 return serviceEnvironmentConfig
;
91 public SignalSessionLock
getSessionLock() {
95 public SignalServiceAccountManager
getAccountManager() {
96 return getOrCreate(() -> accountManager
,
97 () -> accountManager
= new SignalServiceAccountManager(serviceEnvironmentConfig
.getSignalServiceConfiguration(),
100 getGroupsV2Operations(),
101 ServiceConfig
.AUTOMATIC_NETWORK_RETRY
));
104 public SignalServiceAccountManager
createUnauthenticatedAccountManager(String number
, String password
) {
105 return new SignalServiceAccountManager(getServiceEnvironmentConfig().getSignalServiceConfiguration(),
109 SignalServiceAddress
.DEFAULT_DEVICE_ID
,
112 ServiceConfig
.AUTOMATIC_NETWORK_RETRY
,
113 ServiceConfig
.GROUP_MAX_SIZE
);
116 public GroupsV2Api
getGroupsV2Api() {
117 return getOrCreate(() -> groupsV2Api
, () -> groupsV2Api
= getAccountManager().getGroupsV2Api());
120 public GroupsV2Operations
getGroupsV2Operations() {
121 return getOrCreate(() -> groupsV2Operations
,
122 () -> groupsV2Operations
= capabilities
.getGv2()
123 ?
new GroupsV2Operations(ClientZkOperations
.create(serviceEnvironmentConfig
.getSignalServiceConfiguration()),
124 ServiceConfig
.GROUP_MAX_SIZE
)
128 private ClientZkOperations
getClientZkOperations() {
129 return getOrCreate(() -> clientZkOperations
,
130 () -> clientZkOperations
= capabilities
.getGv2()
131 ? ClientZkOperations
.create(serviceEnvironmentConfig
.getSignalServiceConfiguration())
135 private ClientZkProfileOperations
getClientZkProfileOperations() {
136 final var clientZkOperations
= getClientZkOperations();
137 return clientZkOperations
== null ?
null : clientZkOperations
.getProfileOperations();
140 public SignalWebSocket
getSignalWebSocket() {
141 return getOrCreate(() -> signalWebSocket
, () -> {
142 final var timer
= new UptimeSleepTimer();
143 final var healthMonitor
= new SignalWebSocketHealthMonitor(timer
);
144 final var webSocketFactory
= new WebSocketFactory() {
146 public WebSocketConnection
createWebSocket() {
147 return new WebSocketConnection("normal",
148 serviceEnvironmentConfig
.getSignalServiceConfiguration(),
149 Optional
.of(credentialsProvider
),
156 public WebSocketConnection
createUnidentifiedWebSocket() {
157 return new WebSocketConnection("unidentified",
158 serviceEnvironmentConfig
.getSignalServiceConfiguration(),
165 signalWebSocket
= new SignalWebSocket(webSocketFactory
);
166 healthMonitor
.monitor(signalWebSocket
);
170 public SignalServiceMessageReceiver
getMessageReceiver() {
171 return getOrCreate(() -> messageReceiver
,
172 () -> messageReceiver
= new SignalServiceMessageReceiver(serviceEnvironmentConfig
.getSignalServiceConfiguration(),
175 getClientZkProfileOperations(),
176 ServiceConfig
.AUTOMATIC_NETWORK_RETRY
));
179 public SignalServiceMessageSender
getMessageSender() {
180 return getOrCreate(() -> messageSender
,
181 () -> messageSender
= new SignalServiceMessageSender(serviceEnvironmentConfig
.getSignalServiceConfiguration(),
186 getSignalWebSocket(),
188 getClientZkProfileOperations(),
190 ServiceConfig
.MAX_ENVELOPE_SIZE
,
191 ServiceConfig
.AUTOMATIC_NETWORK_RETRY
));
194 public KeyBackupService
getKeyBackupService() {
195 return getOrCreate(() -> keyBackupService
,
196 () -> keyBackupService
= getAccountManager().getKeyBackupService(ServiceConfig
.getIasKeyStore(),
197 serviceEnvironmentConfig
.getKeyBackupConfig().getEnclaveName(),
198 serviceEnvironmentConfig
.getKeyBackupConfig().getServiceId(),
199 serviceEnvironmentConfig
.getKeyBackupConfig().getMrenclave(),
203 public Collection
<KeyBackupService
> getFallbackKeyBackupServices() {
204 return serviceEnvironmentConfig
.getFallbackKeyBackupConfigs()
206 .map(config
-> getAccountManager().getKeyBackupService(ServiceConfig
.getIasKeyStore(),
207 config
.getEnclaveName(),
208 config
.getServiceId(),
209 config
.getMrenclave(),
214 public ProfileService
getProfileService() {
215 return getOrCreate(() -> profileService
,
216 () -> profileService
= new ProfileService(getClientZkProfileOperations(),
217 getMessageReceiver(),
218 getSignalWebSocket()));
221 public SignalServiceCipher
getCipher() {
222 return getOrCreate(() -> cipher
, () -> {
223 final var certificateValidator
= new CertificateValidator(serviceEnvironmentConfig
.getUnidentifiedSenderTrustRoot());
224 final var address
= new SignalServiceAddress(credentialsProvider
.getAci(), credentialsProvider
.getE164());
225 final var deviceId
= credentialsProvider
.getDeviceId();
226 cipher
= new SignalServiceCipher(address
, deviceId
, dataStore
.aci(), sessionLock
, certificateValidator
);
230 private <T
> T
getOrCreate(Supplier
<T
> supplier
, Callable creator
) {
231 var value
= supplier
.get();
236 synchronized (LOCK
) {
237 value
= supplier
.get();
242 return supplier
.get();
246 private interface Callable
{