Search in sources :

Example 6 with Optional

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);
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress) Recipient(org.thoughtcrime.securesms.recipients.Recipient) DistributionId(org.whispersystems.signalservice.api.push.DistributionId) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) SenderKeyDistributionMessage(org.whispersystems.libsignal.protocol.SenderKeyDistributionMessage) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) UnidentifiedAccessUtil(org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil) ThreadUtil(org.signal.core.util.ThreadUtil) Collectors(java.util.stream.Collectors) Optional(org.whispersystems.libsignal.util.guava.Optional) ByteString(com.google.protobuf.ByteString) TimeUnit(java.util.concurrent.TimeUnit) Log(org.signal.core.util.logging.Log) List(java.util.List) Nullable(androidx.annotation.Nullable) GroupId(org.thoughtcrime.securesms.groups.GroupId) Content(org.whispersystems.signalservice.internal.push.SignalServiceProtos.Content) Job(org.thoughtcrime.securesms.jobmanager.Job) ByteString(com.google.protobuf.ByteString) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) Recipient(org.thoughtcrime.securesms.recipients.Recipient) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) Content(org.whispersystems.signalservice.internal.push.SignalServiceProtos.Content) SenderKeyDistributionMessage(org.whispersystems.libsignal.protocol.SenderKeyDistributionMessage) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress)

Example 7 with Optional

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();
        }
    });
}
Also used : Request(okhttp3.Request) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) NonNull(androidx.annotation.NonNull) TextUtils(android.text.TextUtils) ContentLengthInputStream(com.bumptech.glide.util.ContentLengthInputStream) IOException(java.io.IOException) CacheControl(okhttp3.CacheControl) Optional(org.whispersystems.libsignal.util.guava.Optional) ArrayList(java.util.ArrayList) SecureRandom(java.security.SecureRandom) Log(org.signal.core.util.logging.Log) Pair(org.whispersystems.libsignal.util.Pair) FilterInputStream(java.io.FilterInputStream) List(java.util.List) OkHttpClient(okhttp3.OkHttpClient) Response(okhttp3.Response) Call(okhttp3.Call) LinkedList(java.util.LinkedList) SignalExecutors(org.signal.core.util.concurrent.SignalExecutors) InputStream(java.io.InputStream) ContentLengthInputStream(com.bumptech.glide.util.ContentLengthInputStream) FilterInputStream(java.io.FilterInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException)

Example 8 with Optional

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);
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) Arrays(java.util.Arrays) LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) NonNull(androidx.annotation.NonNull) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) AttachmentMarkUploadedJob(org.thoughtcrime.securesms.jobs.AttachmentMarkUploadedJob) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SmsDatabase(org.thoughtcrime.securesms.database.SmsDatabase) Preconditions(org.whispersystems.libsignal.util.guava.Preconditions) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ParcelUtil(org.thoughtcrime.securesms.util.ParcelUtil) ReactionSendJob(org.thoughtcrime.securesms.jobs.ReactionSendJob) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) PushMediaSendJob(org.thoughtcrime.securesms.jobs.PushMediaSendJob) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Collection(java.util.Collection) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) Log(org.signal.core.util.logging.Log) List(java.util.List) Nullable(androidx.annotation.Nullable) Job(org.thoughtcrime.securesms.jobmanager.Job) ResumableUploadSpecJob(org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) PushGroupSendJob(org.thoughtcrime.securesms.jobs.PushGroupSendJob) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) AttachmentCompressionJob(org.thoughtcrime.securesms.jobs.AttachmentCompressionJob) Context(android.content.Context) MmsSmsDatabase(org.thoughtcrime.securesms.database.MmsSmsDatabase) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) ProfileKeySendJob(org.thoughtcrime.securesms.jobs.ProfileKeySendJob) Stream(com.annimon.stream.Stream) DirectoryHelper(org.thoughtcrime.securesms.contacts.sync.DirectoryHelper) SignalLocalMetrics(org.thoughtcrime.securesms.util.SignalLocalMetrics) WorkerThread(androidx.annotation.WorkerThread) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) Parcel(android.os.Parcel) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) ArrayList(java.util.ArrayList) RemoteDeleteSendJob(org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) MmsSendJob(org.thoughtcrime.securesms.jobs.MmsSendJob) AttachmentUploadJob(org.thoughtcrime.securesms.jobs.AttachmentUploadJob) PushTextSendJob(org.thoughtcrime.securesms.jobs.PushTextSendJob) EventBus(org.greenrobot.eventbus.EventBus) AttachmentCopyJob(org.thoughtcrime.securesms.jobs.AttachmentCopyJob) LinkedList(java.util.LinkedList) Parcelable(android.os.Parcelable) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Contact(org.thoughtcrime.securesms.contactshare.Contact) MmsException(org.thoughtcrime.securesms.mms.MmsException) IOException(java.io.IOException) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) SmsSendJob(org.thoughtcrime.securesms.jobs.SmsSendJob) ExpiringMessageManager(org.thoughtcrime.securesms.service.ExpiringMessageManager) SmsMessageRecord(org.thoughtcrime.securesms.database.model.SmsMessageRecord) Collections(java.util.Collections) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Optional(org.whispersystems.libsignal.util.guava.Optional) LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) AttachmentMarkUploadedJob(org.thoughtcrime.securesms.jobs.AttachmentMarkUploadedJob) ExpiringMessageManager(org.thoughtcrime.securesms.service.ExpiringMessageManager) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Attachment(org.thoughtcrime.securesms.attachments.Attachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) LinkedList(java.util.LinkedList) Contact(org.thoughtcrime.securesms.contactshare.Contact) MmsException(org.thoughtcrime.securesms.mms.MmsException) MmsSmsDatabase(org.thoughtcrime.securesms.database.MmsSmsDatabase) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) AttachmentCompressionJob(org.thoughtcrime.securesms.jobs.AttachmentCompressionJob)

Example 9 with Optional

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());
}
Also used : Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Arrays(java.util.Arrays) ACI(org.whispersystems.signalservice.api.push.ACI) NonNull(androidx.annotation.NonNull) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) IdentityState(org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState) Optional(org.whispersystems.libsignal.util.guava.Optional) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) Nullable(androidx.annotation.Nullable) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalContactRecord(org.whispersystems.signalservice.api.storage.SignalContactRecord) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) RecipientRecord(org.thoughtcrime.securesms.database.model.RecipientRecord) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) RecipientRecord(org.thoughtcrime.securesms.database.model.RecipientRecord) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) NonNull(androidx.annotation.NonNull)

Example 10 with Optional

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;
}
Also used : SettableFuture(org.thoughtcrime.securesms.util.concurrent.SettableFuture) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Optional(org.whispersystems.libsignal.util.guava.Optional)

Aggregations

Optional (org.whispersystems.libsignal.util.guava.Optional)61 Recipient (org.thoughtcrime.securesms.recipients.Recipient)33 NonNull (androidx.annotation.NonNull)32 List (java.util.List)32 Log (org.signal.core.util.logging.Log)28 SignalServiceAddress (org.whispersystems.signalservice.api.push.SignalServiceAddress)27 LinkedList (java.util.LinkedList)25 IOException (java.io.IOException)24 ArrayList (java.util.ArrayList)24 TimeUnit (java.util.concurrent.TimeUnit)24 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)24 Nullable (androidx.annotation.Nullable)22 SignalDatabase (org.thoughtcrime.securesms.database.SignalDatabase)22 Context (android.content.Context)21 Collections (java.util.Collections)20 Locale (java.util.Locale)18 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)18 SignalStore (org.thoughtcrime.securesms.keyvalue.SignalStore)18 RecipientUtil (org.thoughtcrime.securesms.recipients.RecipientUtil)18 Stream (com.annimon.stream.Stream)16