use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.
the class ResendMessageJob method onRun.
@Override
protected void onRun() throws Exception {
if (SignalStore.internalValues().delayResends()) {
Log.w(TAG, "Delaying resend by 10 sec because of an internal preference.");
ThreadUtil.sleep(10000);
}
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
Recipient recipient = Recipient.resolved(recipientId);
if (recipient.isUnregistered()) {
Log.w(TAG, recipient.getId() + " is unregistered!");
return;
}
SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, recipient);
Optional<UnidentifiedAccessPair> access = UnidentifiedAccessUtil.getAccessFor(context, recipient);
Content contentToSend = content;
if (distributionId != null) {
Optional<GroupRecord> groupRecord = SignalDatabase.groups().getGroupByDistributionId(distributionId);
if (!groupRecord.isPresent()) {
Log.w(TAG, "Could not find a matching group for the distributionId! Skipping message send.");
return;
} else if (!groupRecord.get().getMembers().contains(recipientId)) {
Log.w(TAG, "The target user is no longer in the group! Skipping message send.");
return;
}
SenderKeyDistributionMessage senderKeyDistributionMessage = messageSender.getOrCreateNewGroupSession(distributionId);
ByteString distributionBytes = ByteString.copyFrom(senderKeyDistributionMessage.serialize());
contentToSend = contentToSend.toBuilder().setSenderKeyDistributionMessage(distributionBytes).build();
}
SendMessageResult result = messageSender.resendContent(address, access, sentTimestamp, contentToSend, contentHint, Optional.fromNullable(groupId).transform(GroupId::getDecodedId));
if (result.isSuccess() && distributionId != null) {
List<SignalProtocolAddress> addresses = result.getSuccess().getDevices().stream().map(device -> recipient.requireServiceId().toProtocolAddress(device)).collect(Collectors.toList());
ApplicationDependencies.getProtocolStore().aci().markSenderKeySharedWith(distributionId, addresses);
}
}
use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.
the class ChunkedDataFetcher method fetchChunks.
private void fetchChunks(@NonNull String url, long contentLength, Optional<Pair<InputStream, Long>> firstChunk, CompositeRequestController compositeController, Callback callback) {
List<ByteRange> requestPattern;
try {
if (firstChunk.isPresent()) {
requestPattern = Stream.of(getRequestPattern(contentLength - firstChunk.get().second())).map(b -> new ByteRange(b.start + firstChunk.get().second(), b.end + firstChunk.get().second(), b.ignoreFirst)).toList();
} else {
requestPattern = getRequestPattern(contentLength);
}
} catch (IOException e) {
callback.onFailure(e);
compositeController.cancel();
return;
}
SignalExecutors.UNBOUNDED.execute(() -> {
List<CallRequestController> controllers = Stream.of(requestPattern).map(range -> makeChunkRequest(client, url, range)).toList();
List<InputStream> streams = new ArrayList<>(controllers.size() + (firstChunk.isPresent() ? 1 : 0));
if (firstChunk.isPresent()) {
streams.add(firstChunk.get().first());
}
Stream.of(controllers).forEach(compositeController::addController);
for (CallRequestController controller : controllers) {
Optional<InputStream> stream = controller.getStream();
if (!stream.isPresent()) {
Log.w(TAG, "Stream was canceled.");
callback.onFailure(new IOException("Failure"));
compositeController.cancel();
return;
}
streams.add(stream.get());
}
try {
callback.onSuccess(new InputStreamList(streams));
} catch (IOException e) {
callback.onFailure(e);
compositeController.cancel();
}
});
}
use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.
the class MessageSender method sendLocalMediaSelf.
private static void sendLocalMediaSelf(Context context, long messageId) {
try {
ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager();
MessageDatabase mmsDatabase = SignalDatabase.mms();
MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms();
OutgoingMediaMessage message = mmsDatabase.getOutgoingMessage(messageId);
SyncMessageId syncId = new SyncMessageId(Recipient.self().getId(), message.getSentTimeMillis());
List<Attachment> attachments = new LinkedList<>();
attachments.addAll(message.getAttachments());
attachments.addAll(Stream.of(message.getLinkPreviews()).map(LinkPreview::getThumbnail).filter(Optional::isPresent).map(Optional::get).toList());
attachments.addAll(Stream.of(message.getSharedContacts()).map(Contact::getAvatar).withoutNulls().map(Contact.Avatar::getAttachment).withoutNulls().toList());
List<AttachmentCompressionJob> compressionJobs = Stream.of(attachments).map(a -> AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, false, -1)).toList();
List<AttachmentMarkUploadedJob> fakeUploadJobs = Stream.of(attachments).map(a -> new AttachmentMarkUploadedJob(messageId, ((DatabaseAttachment) a).getAttachmentId())).toList();
ApplicationDependencies.getJobManager().startChain(compressionJobs).then(fakeUploadJobs).enqueue();
mmsDatabase.markAsSent(messageId, true);
mmsDatabase.markUnidentified(messageId, true);
mmsSmsDatabase.incrementDeliveryReceiptCount(syncId, System.currentTimeMillis());
mmsSmsDatabase.incrementReadReceiptCount(syncId, System.currentTimeMillis());
mmsSmsDatabase.incrementViewedReceiptCount(syncId, System.currentTimeMillis());
if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) {
mmsDatabase.markExpireStarted(messageId);
expirationManager.scheduleDeletion(messageId, true, message.getExpiresIn());
}
} catch (NoSuchMessageException | MmsException e) {
Log.w(TAG, "Failed to update self-sent message.", e);
}
}
use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.
the class ContactRecordProcessor method getMatching.
@Override
@NonNull
Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord remote, @NonNull StorageKeyGenerator keyGenerator) {
SignalServiceAddress address = remote.getAddress();
Optional<RecipientId> byUuid = recipientDatabase.getByServiceId(address.getServiceId());
Optional<RecipientId> byE164 = address.getNumber().isPresent() ? recipientDatabase.getByE164(address.getNumber().get()) : Optional.absent();
return byUuid.or(byE164).transform(recipientDatabase::getRecordForSync).transform(settings -> {
if (settings.getStorageId() != null) {
return StorageSyncModels.localToRemoteRecord(settings);
} else {
Log.w(TAG, "Newly discovering a registered user via storage service. Saving a storageId for them.");
recipientDatabase.updateStorageId(settings.getId(), keyGenerator.generate());
RecipientRecord updatedSettings = Objects.requireNonNull(recipientDatabase.getRecordForSync(settings.getId()));
return StorageSyncModels.localToRemoteRecord(updatedSettings);
}
}).transform(r -> r.getContact().get());
}
use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.
the class IdentityUtil method getRemoteIdentityKey.
public static ListenableFuture<Optional<IdentityRecord>> getRemoteIdentityKey(final Context context, final Recipient recipient) {
final SettableFuture<Optional<IdentityRecord>> future = new SettableFuture<>();
final RecipientId recipientId = recipient.getId();
SimpleTask.run(SignalExecutors.BOUNDED, () -> ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipientId), future::set);
return future;
}
Aggregations