Give the service direct knowledge of linked device status.
This commit is contained in:
parent
75421b1af8
commit
c1c9ca7c4c
5 changed files with 27 additions and 25 deletions
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.crypto.storage;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
import org.whispersystems.libsignal.IdentityKeyPair;
|
||||
import org.whispersystems.libsignal.InvalidKeyIdException;
|
||||
|
@ -14,7 +15,7 @@ import org.whispersystems.libsignal.state.PreKeyStore;
|
|||
import org.whispersystems.libsignal.state.SessionRecord;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
||||
import org.whispersystems.signalservice.api.SignalServiceProtocolStore;
|
||||
import org.whispersystems.signalservice.api.SignalServiceDataStore;
|
||||
import org.whispersystems.signalservice.api.SignalServiceSessionStore;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
|
||||
|
@ -23,8 +24,9 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SignalProtocolStoreImpl implements SignalServiceProtocolStore {
|
||||
public class SignalProtocolStoreImpl implements SignalServiceDataStore {
|
||||
|
||||
private final Context context;
|
||||
private final PreKeyStore preKeyStore;
|
||||
private final SignedPreKeyStore signedPreKeyStore;
|
||||
private final IdentityKeyStore identityKeyStore;
|
||||
|
@ -32,6 +34,7 @@ public class SignalProtocolStoreImpl implements SignalServiceProtocolStore {
|
|||
private final SignalSenderKeyStore senderKeyStore;
|
||||
|
||||
public SignalProtocolStoreImpl(Context context) {
|
||||
this.context = context;
|
||||
this.preKeyStore = new TextSecurePreKeyStore(context);
|
||||
this.signedPreKeyStore = new TextSecurePreKeyStore(context);
|
||||
this.identityKeyStore = new TextSecureIdentityKeyStore(context);
|
||||
|
@ -173,4 +176,9 @@ public class SignalProtocolStoreImpl implements SignalServiceProtocolStore {
|
|||
public void clearSenderKeySharedWith(Collection<SignalProtocolAddress> addresses) {
|
||||
senderKeyStore.clearSenderKeySharedWith(addresses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultiDevice() {
|
||||
return TextSecurePreferences.isMultiDevice(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,8 +181,6 @@ public class ApplicationDependencies {
|
|||
synchronized (LOCK) {
|
||||
if (messageSender == null) {
|
||||
messageSender = provider.provideSignalServiceMessageSender(getSignalWebSocket());
|
||||
} else {
|
||||
messageSender.update(TextSecurePreferences.isMultiDevice(application));
|
||||
}
|
||||
return messageSender;
|
||||
}
|
||||
|
|
|
@ -105,7 +105,6 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
new SignalProtocolStoreImpl(context),
|
||||
ReentrantSessionLock.INSTANCE,
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
TextSecurePreferences.isMultiDevice(context),
|
||||
signalWebSocket,
|
||||
Optional.of(new SecurityEventListener(context)),
|
||||
provideClientZkOperations().getProfileOperations(),
|
||||
|
|
|
@ -6,5 +6,9 @@ import org.whispersystems.libsignal.state.SignalProtocolStore;
|
|||
* And extension of the normal protocol store interface that has additional methods that are needed
|
||||
* in the service layer, but not the protocol layer.
|
||||
*/
|
||||
public interface SignalServiceProtocolStore extends SignalProtocolStore, SignalServiceSessionStore, SignalServiceSenderKeyStore {
|
||||
public interface SignalServiceDataStore extends SignalProtocolStore, SignalServiceSessionStore, SignalServiceSenderKeyStore {
|
||||
/**
|
||||
* @return True if the active account has linked devices, otherwise false.
|
||||
*/
|
||||
boolean isMultiDevice();
|
||||
}
|
|
@ -145,25 +145,23 @@ public class SignalServiceMessageSender {
|
|||
|
||||
private static final int RETRY_COUNT = 4;
|
||||
|
||||
private final PushServiceSocket socket;
|
||||
private final SignalServiceProtocolStore store;
|
||||
private final SignalSessionLock sessionLock;
|
||||
private final SignalServiceAddress localAddress;
|
||||
private final Optional<EventListener> eventListener;
|
||||
private final PushServiceSocket socket;
|
||||
private final SignalServiceDataStore store;
|
||||
private final SignalSessionLock sessionLock;
|
||||
private final SignalServiceAddress localAddress;
|
||||
private final Optional<EventListener> eventListener;
|
||||
|
||||
private final AttachmentService attachmentService;
|
||||
private final MessagingService messagingService;
|
||||
private final AtomicBoolean isMultiDevice;
|
||||
|
||||
private final ExecutorService executor;
|
||||
private final long maxEnvelopeSize;
|
||||
|
||||
public SignalServiceMessageSender(SignalServiceConfiguration urls,
|
||||
CredentialsProvider credentialsProvider,
|
||||
SignalServiceProtocolStore store,
|
||||
SignalServiceDataStore store,
|
||||
SignalSessionLock sessionLock,
|
||||
String signalAgent,
|
||||
boolean isMultiDevice,
|
||||
SignalWebSocket signalWebSocket,
|
||||
Optional<EventListener> eventListener,
|
||||
ClientZkProfileOperations clientZkProfileOperations,
|
||||
|
@ -177,7 +175,6 @@ public class SignalServiceMessageSender {
|
|||
this.localAddress = new SignalServiceAddress(credentialsProvider.getUuid(), credentialsProvider.getE164());
|
||||
this.attachmentService = new AttachmentService(signalWebSocket);
|
||||
this.messagingService = new MessagingService(signalWebSocket);
|
||||
this.isMultiDevice = new AtomicBoolean(isMultiDevice);
|
||||
this.eventListener = eventListener;
|
||||
this.executor = executor != null ? executor : Executors.newSingleThreadExecutor();
|
||||
this.maxEnvelopeSize = maxEnvelopeSize;
|
||||
|
@ -403,7 +400,7 @@ public class SignalServiceMessageSender {
|
|||
Optional<byte[]> groupId = message.getGroupId();
|
||||
List<SendMessageResult> results = sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, contentHint, groupId.orNull(), false);
|
||||
|
||||
if (isMultiDevice.get()) {
|
||||
if (store.isMultiDevice()) {
|
||||
Content syncMessage = createMultiDeviceSentTranscriptContent(content, Optional.absent(), message.getTimestamp(), results, isRecipientUpdate);
|
||||
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.absent());
|
||||
|
||||
|
@ -443,7 +440,7 @@ public class SignalServiceMessageSender {
|
|||
}
|
||||
}
|
||||
|
||||
if (needsSyncInResults || isMultiDevice.get()) {
|
||||
if (needsSyncInResults || store.isMultiDevice()) {
|
||||
Optional<SignalServiceAddress> recipient = Optional.absent();
|
||||
if (!message.getGroupContext().isPresent() && recipients.size() == 1) {
|
||||
recipient = Optional.of(recipients.get(0));
|
||||
|
@ -512,10 +509,6 @@ public class SignalServiceMessageSender {
|
|||
socket.cancelInFlightRequests();
|
||||
}
|
||||
|
||||
public void update(boolean isMultiDevice) {
|
||||
this.isMultiDevice.set(isMultiDevice);
|
||||
}
|
||||
|
||||
public SignalServiceAttachmentPointer uploadAttachment(SignalServiceAttachmentStream attachment) throws IOException {
|
||||
byte[] attachmentKey = attachment.getResumableUploadSpec().transform(ResumableUploadSpec::getSecretKey).or(() -> Util.getSecretBytes(64));
|
||||
byte[] attachmentIV = attachment.getResumableUploadSpec().transform(ResumableUploadSpec::getIV).or(() -> Util.getSecretBytes(16));
|
||||
|
@ -1608,7 +1601,7 @@ public class SignalServiceMessageSender {
|
|||
if (!unidentifiedAccess.isPresent()) {
|
||||
try {
|
||||
SendMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.send(messages, Optional.absent()).blockingGet()).getResultOrThrow();
|
||||
return SendMessageResult.success(recipient, messages.getDevices(), false, response.getNeedsSync() || isMultiDevice.get(), System.currentTimeMillis() - startTime, content.getContent());
|
||||
return SendMessageResult.success(recipient, messages.getDevices(), false, response.getNeedsSync() || store.isMultiDevice(), System.currentTimeMillis() - startTime, content.getContent());
|
||||
} catch (WebSocketUnavailableException e) {
|
||||
Log.i(TAG, "[sendMessage] Pipe unavailable, falling back... (" + e.getClass().getSimpleName() + ": " + e.getMessage() + ")");
|
||||
} catch (IOException e) {
|
||||
|
@ -1618,7 +1611,7 @@ public class SignalServiceMessageSender {
|
|||
} else if (unidentifiedAccess.isPresent()) {
|
||||
try {
|
||||
SendMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.send(messages, unidentifiedAccess).blockingGet()).getResultOrThrow();
|
||||
return SendMessageResult.success(recipient, messages.getDevices(), true, response.getNeedsSync() || isMultiDevice.get(), System.currentTimeMillis() - startTime, content.getContent());
|
||||
return SendMessageResult.success(recipient, messages.getDevices(), true, response.getNeedsSync() || store.isMultiDevice(), System.currentTimeMillis() - startTime, content.getContent());
|
||||
} catch (WebSocketUnavailableException e) {
|
||||
Log.i(TAG, "[sendMessage] Unidentified pipe unavailable, falling back... (" + e.getClass().getSimpleName() + ": " + e.getMessage() + ")");
|
||||
} catch (IOException e) {
|
||||
|
@ -1633,7 +1626,7 @@ public class SignalServiceMessageSender {
|
|||
|
||||
SendMessageResponse response = socket.sendMessage(messages, unidentifiedAccess);
|
||||
|
||||
return SendMessageResult.success(recipient, messages.getDevices(), unidentifiedAccess.isPresent(), response.getNeedsSync() || isMultiDevice.get(), System.currentTimeMillis() - startTime, content.getContent());
|
||||
return SendMessageResult.success(recipient, messages.getDevices(), unidentifiedAccess.isPresent(), response.getNeedsSync() || store.isMultiDevice(), System.currentTimeMillis() - startTime, content.getContent());
|
||||
|
||||
} catch (InvalidKeyException ike) {
|
||||
Log.w(TAG, ike);
|
||||
|
@ -1843,7 +1836,7 @@ public class SignalServiceMessageSender {
|
|||
List<SendMessageResult> success = recipients.keySet()
|
||||
.stream()
|
||||
.filter(r -> !unregistered.contains(r.getUuid().get()))
|
||||
.map(a -> SendMessageResult.success(a, recipients.get(a), true, isMultiDevice.get(), -1, Optional.of(content)))
|
||||
.map(a -> SendMessageResult.success(a, recipients.get(a), true, store.isMultiDevice(), -1, Optional.of(content)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<SendMessageResult> results = new ArrayList<>(success.size() + failures.size());
|
||||
|
|
Loading…
Add table
Reference in a new issue