Search in sources :

Example 11 with Optional

use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.

the class MessagingService method send.

public Single<ServiceResponse<SendMessageResponse>> send(OutgoingPushMessageList list, Optional<UnidentifiedAccess> unidentifiedAccess) {
    List<String> headers = new LinkedList<String>() {

        {
            add("content-type:application/json");
        }
    };
    WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder().setId(new SecureRandom().nextLong()).setVerb("PUT").setPath(String.format("/v1/messages/%s", list.getDestination())).addAllHeaders(headers).setBody(ByteString.copyFrom(JsonUtil.toJson(list).getBytes())).build();
    ResponseMapper<SendMessageResponse> responseMapper = DefaultResponseMapper.extend(SendMessageResponse.class).withResponseMapper((status, body, getHeader, unidentified) -> {
        SendMessageResponse sendMessageResponse = Util.isEmpty(body) ? new SendMessageResponse(false, unidentified) : JsonUtil.fromJsonResponse(body, SendMessageResponse.class);
        sendMessageResponse.setSentUnidentfied(unidentified);
        return ServiceResponse.forResult(sendMessageResponse, status, body);
    }).withCustomError(404, (status, body, getHeader) -> new UnregisteredUserException(list.getDestination(), new NotFoundException("not found"))).build();
    return signalWebSocket.request(requestMessage, unidentifiedAccess).map(responseMapper::map).onErrorReturn(ServiceResponse::forUnknownError);
}
Also used : Single(io.reactivex.rxjava3.core.Single) SignalWebSocket(org.whispersystems.signalservice.api.SignalWebSocket) Util(org.whispersystems.signalservice.internal.util.Util) SecureRandom(java.security.SecureRandom) UnidentifiedAccess(org.whispersystems.signalservice.api.crypto.UnidentifiedAccess) NotFoundException(org.whispersystems.signalservice.api.push.exceptions.NotFoundException) GroupMismatchedDevicesException(org.whispersystems.signalservice.internal.push.exceptions.GroupMismatchedDevicesException) Locale(java.util.Locale) GroupStaleDevicesException(org.whispersystems.signalservice.internal.push.exceptions.GroupStaleDevicesException) LinkedList(java.util.LinkedList) GroupMismatchedDevices(org.whispersystems.signalservice.internal.push.GroupMismatchedDevices) DefaultResponseMapper(org.whispersystems.signalservice.internal.websocket.DefaultResponseMapper) SendMessageResponse(org.whispersystems.signalservice.internal.push.SendMessageResponse) InvalidUnidentifiedAccessHeaderException(org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException) WebSocketRequestMessage(org.whispersystems.signalservice.internal.websocket.WebSocketProtos.WebSocketRequestMessage) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) JsonUtil(org.whispersystems.signalservice.internal.util.JsonUtil) OutgoingPushMessageList(org.whispersystems.signalservice.internal.push.OutgoingPushMessageList) Optional(org.whispersystems.libsignal.util.guava.Optional) UnregisteredUserException(org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException) ByteString(com.google.protobuf.ByteString) List(java.util.List) GroupStaleDevices(org.whispersystems.signalservice.internal.push.GroupStaleDevices) Base64(org.whispersystems.util.Base64) SendGroupMessageResponse(org.whispersystems.signalservice.internal.push.SendGroupMessageResponse) ResponseMapper(org.whispersystems.signalservice.internal.websocket.ResponseMapper) ServiceResponseProcessor(org.whispersystems.signalservice.internal.ServiceResponseProcessor) SendMessageResponse(org.whispersystems.signalservice.internal.push.SendMessageResponse) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) UnregisteredUserException(org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException) WebSocketRequestMessage(org.whispersystems.signalservice.internal.websocket.WebSocketProtos.WebSocketRequestMessage) SecureRandom(java.security.SecureRandom) NotFoundException(org.whispersystems.signalservice.api.push.exceptions.NotFoundException) ByteString(com.google.protobuf.ByteString) LinkedList(java.util.LinkedList)

Example 12 with Optional

use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.

the class SignalServiceCipher method decrypt.

private Plaintext decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) throws InvalidMetadataMessageException, InvalidMetadataVersionException, ProtocolDuplicateMessageException, ProtocolUntrustedIdentityException, ProtocolLegacyMessageException, ProtocolInvalidKeyException, ProtocolInvalidVersionException, ProtocolInvalidMessageException, ProtocolInvalidKeyIdException, ProtocolNoSessionException, SelfSendException, InvalidMessageStructureException {
    try {
        byte[] paddedMessage;
        SignalServiceMetadata metadata;
        if (!envelope.hasSourceUuid() && !envelope.isUnidentifiedSender()) {
            throw new InvalidMessageStructureException("Non-UD envelope is missing a UUID!");
        }
        if (envelope.isPreKeySignalMessage()) {
            SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSourceUuid().get(), envelope.getSourceDevice());
            SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, sourceAddress));
            paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext));
            metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent());
            signalProtocolStore.clearSenderKeySharedWith(Collections.singleton(sourceAddress));
        } else if (envelope.isSignalMessage()) {
            SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSourceUuid().get(), envelope.getSourceDevice());
            SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, sourceAddress));
            paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext));
            metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent());
        } else if (envelope.isPlaintextContent()) {
            paddedMessage = new PlaintextContent(ciphertext).getBody();
            metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent());
        } else if (envelope.isUnidentifiedSender()) {
            SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getServiceId().uuid(), localAddress.getNumber().orNull(), localDeviceId));
            DecryptionResult result = sealedSessionCipher.decrypt(certificateValidator, ciphertext, envelope.getServerReceivedTimestamp());
            SignalServiceAddress resultAddress = new SignalServiceAddress(ACI.parseOrThrow(result.getSenderUuid()), result.getSenderE164());
            Optional<byte[]> groupId = result.getGroupId();
            boolean needsReceipt = true;
            if (envelope.hasSourceUuid()) {
                Log.w(TAG, "[" + envelope.getTimestamp() + "] Received a UD-encrypted message sent over an identified channel. Marking as needsReceipt=false");
                needsReceipt = false;
            }
            if (result.getCiphertextMessageType() == CiphertextMessage.PREKEY_TYPE) {
                signalProtocolStore.clearSenderKeySharedWith(Collections.singleton(new SignalProtocolAddress(result.getSenderUuid(), result.getDeviceId())));
            }
            paddedMessage = result.getPaddedMessage();
            metadata = new SignalServiceMetadata(resultAddress, result.getDeviceId(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), needsReceipt, envelope.getServerGuid(), groupId);
        } else {
            throw new InvalidMetadataMessageException("Unknown type: " + envelope.getType());
        }
        PushTransportDetails transportDetails = new PushTransportDetails();
        byte[] data = transportDetails.getStrippedPaddingMessageBody(paddedMessage);
        return new Plaintext(metadata, data);
    } catch (DuplicateMessageException e) {
        throw new ProtocolDuplicateMessageException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (LegacyMessageException e) {
        throw new ProtocolLegacyMessageException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidMessageException e) {
        throw new ProtocolInvalidMessageException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidKeyIdException e) {
        throw new ProtocolInvalidKeyIdException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidKeyException e) {
        throw new ProtocolInvalidKeyException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (UntrustedIdentityException e) {
        throw new ProtocolUntrustedIdentityException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidVersionException e) {
        throw new ProtocolInvalidVersionException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (NoSessionException e) {
        throw new ProtocolNoSessionException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    }
}
Also used : SealedSessionCipher(org.signal.libsignal.metadata.SealedSessionCipher) ProtocolInvalidMessageException(org.signal.libsignal.metadata.ProtocolInvalidMessageException) InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) ProtocolInvalidMessageException(org.signal.libsignal.metadata.ProtocolInvalidMessageException) UntrustedIdentityException(org.whispersystems.libsignal.UntrustedIdentityException) ProtocolUntrustedIdentityException(org.signal.libsignal.metadata.ProtocolUntrustedIdentityException) ProtocolUntrustedIdentityException(org.signal.libsignal.metadata.ProtocolUntrustedIdentityException) ProtocolInvalidVersionException(org.signal.libsignal.metadata.ProtocolInvalidVersionException) InvalidVersionException(org.whispersystems.libsignal.InvalidVersionException) InvalidMessageStructureException(org.whispersystems.signalservice.api.InvalidMessageStructureException) ProtocolInvalidVersionException(org.signal.libsignal.metadata.ProtocolInvalidVersionException) PlaintextContent(org.whispersystems.libsignal.protocol.PlaintextContent) ProtocolInvalidKeyIdException(org.signal.libsignal.metadata.ProtocolInvalidKeyIdException) NoSessionException(org.whispersystems.libsignal.NoSessionException) ProtocolNoSessionException(org.signal.libsignal.metadata.ProtocolNoSessionException) ProtocolDuplicateMessageException(org.signal.libsignal.metadata.ProtocolDuplicateMessageException) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) PushTransportDetails(org.whispersystems.signalservice.internal.push.PushTransportDetails) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) ProtocolLegacyMessageException(org.signal.libsignal.metadata.ProtocolLegacyMessageException) SessionCipher(org.whispersystems.libsignal.SessionCipher) SealedSessionCipher(org.signal.libsignal.metadata.SealedSessionCipher) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress) ProtocolNoSessionException(org.signal.libsignal.metadata.ProtocolNoSessionException) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) SignalMessage(org.whispersystems.libsignal.protocol.SignalMessage) Optional(org.whispersystems.libsignal.util.guava.Optional) SignalServiceMetadata(org.whispersystems.signalservice.api.messages.SignalServiceMetadata) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ProtocolInvalidKeyException(org.signal.libsignal.metadata.ProtocolInvalidKeyException) InvalidMetadataMessageException(org.signal.libsignal.metadata.InvalidMetadataMessageException) ProtocolInvalidKeyException(org.signal.libsignal.metadata.ProtocolInvalidKeyException) DuplicateMessageException(org.whispersystems.libsignal.DuplicateMessageException) ProtocolDuplicateMessageException(org.signal.libsignal.metadata.ProtocolDuplicateMessageException) DecryptionResult(org.signal.libsignal.metadata.SealedSessionCipher.DecryptionResult) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) ProtocolInvalidKeyIdException(org.signal.libsignal.metadata.ProtocolInvalidKeyIdException) LegacyMessageException(org.whispersystems.libsignal.LegacyMessageException) ProtocolLegacyMessageException(org.signal.libsignal.metadata.ProtocolLegacyMessageException)

Example 13 with Optional

use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.

the class SignalServiceContent method createFromProto.

/**
 * Takes internal protobuf serialization format and processes it into a {@link SignalServiceContent}.
 */
public static SignalServiceContent createFromProto(SignalServiceContentProto serviceContentProto) throws ProtocolInvalidMessageException, ProtocolInvalidKeyException, UnsupportedDataMessageException, InvalidMessageStructureException {
    SignalServiceMetadata metadata = SignalServiceMetadataProtobufSerializer.fromProtobuf(serviceContentProto.getMetadata());
    SignalServiceAddress localAddress = SignalServiceAddressProtobufSerializer.fromProtobuf(serviceContentProto.getLocalAddress());
    if (serviceContentProto.getDataCase() == SignalServiceContentProto.DataCase.LEGACYDATAMESSAGE) {
        SignalServiceProtos.DataMessage message = serviceContentProto.getLegacyDataMessage();
        return new SignalServiceContent(createSignalServiceMessage(metadata, message), Optional.absent(), metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), metadata.isNeedsReceipt(), metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
    } else if (serviceContentProto.getDataCase() == SignalServiceContentProto.DataCase.CONTENT) {
        SignalServiceProtos.Content message = serviceContentProto.getContent();
        Optional<SenderKeyDistributionMessage> senderKeyDistributionMessage = Optional.absent();
        if (message.hasSenderKeyDistributionMessage()) {
            try {
                senderKeyDistributionMessage = Optional.of(new SenderKeyDistributionMessage(message.getSenderKeyDistributionMessage().toByteArray()));
            } catch (LegacyMessageException | InvalidMessageException e) {
                Log.w(TAG, "Failed to parse SenderKeyDistributionMessage!", e);
            }
        }
        if (message.hasDataMessage()) {
            return new SignalServiceContent(createSignalServiceMessage(metadata, message.getDataMessage()), senderKeyDistributionMessage, metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), metadata.isNeedsReceipt(), metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
        } else if (message.hasSyncMessage() && localAddress.matches(metadata.getSender())) {
            return new SignalServiceContent(createSynchronizeMessage(metadata, message.getSyncMessage()), senderKeyDistributionMessage, metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), metadata.isNeedsReceipt(), metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
        } else if (message.hasCallMessage()) {
            return new SignalServiceContent(createCallMessage(message.getCallMessage()), senderKeyDistributionMessage, metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), metadata.isNeedsReceipt(), metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
        } else if (message.hasReceiptMessage()) {
            return new SignalServiceContent(createReceiptMessage(metadata, message.getReceiptMessage()), senderKeyDistributionMessage, metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), metadata.isNeedsReceipt(), metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
        } else if (message.hasTypingMessage()) {
            return new SignalServiceContent(createTypingMessage(metadata, message.getTypingMessage()), senderKeyDistributionMessage, metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), false, metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
        } else if (message.hasDecryptionErrorMessage()) {
            return new SignalServiceContent(createDecryptionErrorMessage(metadata, message.getDecryptionErrorMessage()), senderKeyDistributionMessage, metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), metadata.isNeedsReceipt(), metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
        } else if (senderKeyDistributionMessage.isPresent()) {
            return new SignalServiceContent(senderKeyDistributionMessage.get(), metadata.getSender(), metadata.getSenderDevice(), metadata.getTimestamp(), metadata.getServerReceivedTimestamp(), metadata.getServerDeliveredTimestamp(), false, metadata.getServerGuid(), metadata.getGroupId(), serviceContentProto);
        }
    }
    return null;
}
Also used : SignalServiceProtos(org.whispersystems.signalservice.internal.push.SignalServiceProtos) Optional(org.whispersystems.libsignal.util.guava.Optional) SenderKeyDistributionMessage(org.whispersystems.libsignal.protocol.SenderKeyDistributionMessage) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress)

Example 14 with Optional

use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.

the class TypingSendJob method onRun.

@Override
public void onRun() throws Exception {
    if (!Recipient.self().isRegistered()) {
        throw new NotPushRegisteredException();
    }
    if (!TextSecurePreferences.isTypingIndicatorsEnabled(context)) {
        return;
    }
    Log.d(TAG, "Sending typing " + (typing ? "started" : "stopped") + " for thread " + threadId);
    Recipient recipient = SignalDatabase.threads().getRecipientForThreadId(threadId);
    if (recipient == null) {
        Log.w(TAG, "Tried to send a typing indicator to a non-existent thread.");
        return;
    }
    if (recipient.isBlocked()) {
        Log.w(TAG, "Not sending typing indicators to blocked recipients.");
        return;
    }
    if (recipient.isSelf()) {
        Log.w(TAG, "Not sending typing indicators to self.");
        return;
    }
    if (recipient.isPushV1Group() || recipient.isMmsGroup()) {
        Log.w(TAG, "Not sending typing indicators to unsupported groups.");
        return;
    }
    if (!recipient.isRegistered() || recipient.isForceSmsSelection()) {
        Log.w(TAG, "Not sending typing indicators to non-Signal recipients.");
        return;
    }
    List<Recipient> recipients = Collections.singletonList(recipient);
    Optional<byte[]> groupId = Optional.absent();
    if (recipient.isGroup()) {
        recipients = SignalDatabase.groups().getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
        groupId = Optional.of(recipient.requireGroupId().getDecodedId());
    }
    recipients = RecipientUtil.getEligibleForSending(Stream.of(recipients).map(Recipient::resolve).filter(r -> !r.isBlocked()).toList());
    SignalServiceTypingMessage typingMessage = new SignalServiceTypingMessage(typing ? Action.STARTED : Action.STOPPED, System.currentTimeMillis(), groupId);
    try {
        GroupSendUtil.sendTypingMessage(context, recipient.getGroupId().transform(GroupId::requireV2).orNull(), recipients, typingMessage, this::isCanceled);
    } catch (CancelationException e) {
        Log.w(TAG, "Canceled during send!");
    }
}
Also used : SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) SignalServiceTypingMessage(org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage) Stream(com.annimon.stream.Stream) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) Optional(org.whispersystems.libsignal.util.guava.Optional) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) TimeUnit(java.util.concurrent.TimeUnit) Log(org.signal.core.util.logging.Log) List(java.util.List) GroupId(org.thoughtcrime.securesms.groups.GroupId) Job(org.thoughtcrime.securesms.jobmanager.Job) Action(org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage.Action) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupSendUtil(org.thoughtcrime.securesms.messages.GroupSendUtil) Collections(java.util.Collections) CancelationException(org.whispersystems.signalservice.api.CancelationException) SignalServiceTypingMessage(org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage) CancelationException(org.whispersystems.signalservice.api.CancelationException) NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupId(org.thoughtcrime.securesms.groups.GroupId)

Example 15 with Optional

use of org.whispersystems.libsignal.util.guava.Optional in project Signal-Android by signalapp.

the class MessageContentProcessor method getValidatedQuote.

private Optional<QuoteModel> getValidatedQuote(Optional<SignalServiceDataMessage.Quote> quote) {
    if (!quote.isPresent())
        return Optional.absent();
    if (quote.get().getId() <= 0) {
        warn("Received quote without an ID! Ignoring...");
        return Optional.absent();
    }
    if (quote.get().getAuthor() == null) {
        warn("Received quote without an author! Ignoring...");
        return Optional.absent();
    }
    RecipientId author = Recipient.externalPush(quote.get().getAuthor()).getId();
    MessageRecord message = SignalDatabase.mmsSms().getMessageFor(quote.get().getId(), author);
    if (message != null && !message.isRemoteDelete()) {
        log("Found matching message record...");
        List<Attachment> attachments = new LinkedList<>();
        List<Mention> mentions = new LinkedList<>();
        if (message.isMms()) {
            MmsMessageRecord mmsMessage = (MmsMessageRecord) message;
            mentions.addAll(SignalDatabase.mentions().getMentionsForMessage(mmsMessage.getId()));
            if (mmsMessage.isViewOnce()) {
                attachments.add(new TombstoneAttachment(MediaUtil.VIEW_ONCE, true));
            } else {
                attachments = mmsMessage.getSlideDeck().asAttachments();
                if (attachments.isEmpty()) {
                    attachments.addAll(Stream.of(mmsMessage.getLinkPreviews()).filter(lp -> lp.getThumbnail().isPresent()).map(lp -> lp.getThumbnail().get()).toList());
                }
            }
        }
        return Optional.of(new QuoteModel(quote.get().getId(), author, message.getBody(), false, attachments, mentions));
    } else if (message != null) {
        warn("Found the target for the quote, but it's flagged as remotely deleted.");
    }
    warn("Didn't find matching message record...");
    return Optional.of(new QuoteModel(quote.get().getId(), author, quote.get().getText(), true, PointerAttachment.forPointers(quote.get().getAttachments()), getMentions(quote.get().getMentions())));
}
Also used : LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) StickerPackOperationMessage(org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage) NonNull(androidx.annotation.NonNull) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) PaymentTransactionCheckJob(org.thoughtcrime.securesms.jobs.PaymentTransactionCheckJob) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) LinkPreviewUtil(org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil) SecureRandom(java.security.SecureRandom) SignalServiceContent(org.whispersystems.signalservice.api.messages.SignalServiceContent) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) RequestGroupInfoJob(org.thoughtcrime.securesms.jobs.RequestGroupInfoJob) Map(java.util.Map) GroupChangeBusyException(org.thoughtcrime.securesms.groups.GroupChangeBusyException) ThreadRecord(org.thoughtcrime.securesms.database.model.ThreadRecord) OutgoingTextMessage(org.thoughtcrime.securesms.sms.OutgoingTextMessage) MultiDeviceGroupUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) Nullable(androidx.annotation.Nullable) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) StickerPackDownloadJob(org.thoughtcrime.securesms.jobs.StickerPackDownloadJob) SignalServiceGroupV2(org.whispersystems.signalservice.api.messages.SignalServiceGroupV2) MessageLogEntry(org.thoughtcrime.securesms.database.model.MessageLogEntry) CallId(org.signal.ringrtc.CallId) GroupUtil(org.thoughtcrime.securesms.util.GroupUtil) PendingRetryReceiptModel(org.thoughtcrime.securesms.database.model.PendingRetryReceiptModel) RefreshOwnProfileJob(org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob) Attachment(org.thoughtcrime.securesms.attachments.Attachment) MultiDeviceBlockedUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) MediaUtil(org.thoughtcrime.securesms.util.MediaUtil) MmsSmsDatabase(org.thoughtcrime.securesms.database.MmsSmsDatabase) StickerDatabase(org.thoughtcrime.securesms.database.StickerDatabase) GroupsV1MigrationUtil(org.thoughtcrime.securesms.groups.GroupsV1MigrationUtil) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) SignalServiceTypingMessage(org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage) ProfileKeySendJob(org.thoughtcrime.securesms.jobs.ProfileKeySendJob) Stream(com.annimon.stream.Stream) PaymentMetaDataUtil(org.thoughtcrime.securesms.database.PaymentMetaDataUtil) Util(org.thoughtcrime.securesms.util.Util) RefreshAttributesJob(org.thoughtcrime.securesms.jobs.RefreshAttributesJob) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) RetrieveProfileJob(org.thoughtcrime.securesms.jobs.RetrieveProfileJob) ArrayList(java.util.ArrayList) PaymentDatabase(org.thoughtcrime.securesms.database.PaymentDatabase) BlockedListMessage(org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage) ContactModelMapper(org.thoughtcrime.securesms.contactshare.ContactModelMapper) MultiDeviceConfigurationUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob) NullMessageSendJob(org.thoughtcrime.securesms.jobs.NullMessageSendJob) IncomingEncryptedMessage(org.thoughtcrime.securesms.sms.IncomingEncryptedMessage) OutgoingEndSessionMessage(org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage) HangupMessage(org.whispersystems.signalservice.api.messages.calls.HangupMessage) EmojiUtil(org.thoughtcrime.securesms.components.emoji.EmojiUtil) ECPublicKey(org.whispersystems.libsignal.ecc.ECPublicKey) SignalServiceGroup(org.whispersystems.signalservice.api.messages.SignalServiceGroup) SignalServiceCallMessage(org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage) ReadMessage(org.whispersystems.signalservice.api.messages.multidevice.ReadMessage) IncomingEndSessionMessage(org.thoughtcrime.securesms.sms.IncomingEndSessionMessage) ViewOnceOpenMessage(org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage) MessageRequestResponseMessage(org.whispersystems.signalservice.api.messages.multidevice.MessageRequestResponseMessage) OutgoingEncryptedMessage(org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage) KeysMessage(org.whispersystems.signalservice.api.messages.multidevice.KeysMessage) DistributionId(org.whispersystems.signalservice.api.push.DistributionId) GroupReceiptInfo(org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo) RequestMessage(org.whispersystems.signalservice.api.messages.multidevice.RequestMessage) IdentityUtil(org.thoughtcrime.securesms.util.IdentityUtil) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Collectors(com.annimon.stream.Collectors) GroupReceiptDatabase(org.thoughtcrime.securesms.database.GroupReceiptDatabase) Contact(org.thoughtcrime.securesms.contactshare.Contact) TextUtils(android.text.TextUtils) Hex(org.thoughtcrime.securesms.util.Hex) IOException(java.io.IOException) Optional(org.whispersystems.libsignal.util.guava.Optional) StickerLocator(org.thoughtcrime.securesms.stickers.StickerLocator) GroupV1MessageProcessor(org.thoughtcrime.securesms.groups.GroupV1MessageProcessor) TrimThreadJob(org.thoughtcrime.securesms.jobs.TrimThreadJob) IncomingMediaMessage(org.thoughtcrime.securesms.mms.IncomingMediaMessage) Money(org.whispersystems.signalservice.api.payments.Money) SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) VerifiedMessage(org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage) MessageNotifier(org.thoughtcrime.securesms.notifications.MessageNotifier) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SlideDeck(org.thoughtcrime.securesms.mms.SlideDeck) AttachmentDownloadJob(org.thoughtcrime.securesms.jobs.AttachmentDownloadJob) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) MultiDeviceStickerPackSyncJob(org.thoughtcrime.securesms.jobs.MultiDeviceStickerPackSyncJob) WebRtcData(org.thoughtcrime.securesms.service.webrtc.WebRtcData) SentTranscriptMessage(org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage) Mention(org.thoughtcrime.securesms.database.model.Mention) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) AutomaticSessionResetJob(org.thoughtcrime.securesms.jobs.AutomaticSessionResetJob) SecurityEvent(org.thoughtcrime.securesms.crypto.SecurityEvent) StorageSyncHelper(org.thoughtcrime.securesms.storage.StorageSyncHelper) Locale(java.util.Locale) ResendMessageJob(org.thoughtcrime.securesms.jobs.ResendMessageJob) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress) Recipient(org.thoughtcrime.securesms.recipients.Recipient) BusyMessage(org.whispersystems.signalservice.api.messages.calls.BusyMessage) StickerSlide(org.thoughtcrime.securesms.mms.StickerSlide) MultiDeviceContactSyncJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactSyncJob) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) PaymentLedgerUpdateJob(org.thoughtcrime.securesms.jobs.PaymentLedgerUpdateJob) Collection(java.util.Collection) ProfileKeyUtil(org.thoughtcrime.securesms.crypto.ProfileKeyUtil) SendDeliveryReceiptJob(org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) UUID(java.util.UUID) SenderKeyDistributionSendJob(org.thoughtcrime.securesms.jobs.SenderKeyDistributionSendJob) OutgoingExpirationUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) FeatureFlags(org.thoughtcrime.securesms.util.FeatureFlags) List(java.util.List) MarkReadReceiver(org.thoughtcrime.securesms.notifications.MarkReadReceiver) ViewedMessage(org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage) GroupNotAMemberException(org.thoughtcrime.securesms.groups.GroupNotAMemberException) GroupId(org.thoughtcrime.securesms.groups.GroupId) SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) ContactsMessage(org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage) GroupV2UpdateSelfProfileKeyJob(org.thoughtcrime.securesms.jobs.GroupV2UpdateSelfProfileKeyJob) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) SignalServiceReceiptMessage(org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage) InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) PushProcessMessageJob(org.thoughtcrime.securesms.jobs.PushProcessMessageJob) AnswerMessage(org.whispersystems.signalservice.api.messages.calls.AnswerMessage) MultiDevicePniIdentityUpdateJob(org.thoughtcrime.securesms.jobs.MultiDevicePniIdentityUpdateJob) Context(android.content.Context) ConfigurationMessage(org.whispersystems.signalservice.api.messages.multidevice.ConfigurationMessage) RemotePeer(org.thoughtcrime.securesms.ringrtc.RemotePeer) BadGroupIdException(org.thoughtcrime.securesms.groups.BadGroupIdException) HashMap(java.util.HashMap) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) OfferMessage(org.whispersystems.signalservice.api.messages.calls.OfferMessage) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) OpaqueMessage(org.whispersystems.signalservice.api.messages.calls.OpaqueMessage) GroupManager(org.thoughtcrime.securesms.groups.GroupManager) SuppressLint(android.annotation.SuppressLint) GroupCallPeekJob(org.thoughtcrime.securesms.jobs.GroupCallPeekJob) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel) Build(android.os.Build) LinkedList(java.util.LinkedList) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) MultiDeviceKeysUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceKeysUpdateJob) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) DecryptionErrorMessage(org.whispersystems.libsignal.protocol.DecryptionErrorMessage) StickerRecord(org.thoughtcrime.securesms.database.model.StickerRecord) MmsException(org.thoughtcrime.securesms.mms.MmsException) RemoteDeleteUtil(org.thoughtcrime.securesms.util.RemoteDeleteUtil) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) OutgoingPaymentMessage(org.whispersystems.signalservice.api.messages.multidevice.OutgoingPaymentMessage) TimeUnit(java.util.concurrent.TimeUnit) IceUpdateMessage(org.whispersystems.signalservice.api.messages.calls.IceUpdateMessage) RateLimitUtil(org.thoughtcrime.securesms.ratelimit.RateLimitUtil) SignalServiceSyncMessage(org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage) SessionRecord(org.whispersystems.libsignal.state.SessionRecord) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) Mention(org.thoughtcrime.securesms.database.model.Mention) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) LinkedList(java.util.LinkedList) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel)

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