Search in sources :

Example 1 with SignalServiceGroupContext

use of org.whispersystems.signalservice.api.messages.SignalServiceGroupContext in project Signal-Android by WhisperSystems.

the class GroupV1MessageProcessor method process.

@Nullable
public static Long process(@NonNull Context context, @NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, boolean outgoing) throws BadGroupIdException {
    SignalServiceGroupContext signalServiceGroupContext = message.getGroupContext().get();
    Optional<SignalServiceGroup> groupV1 = signalServiceGroupContext.getGroupV1();
    if (signalServiceGroupContext.getGroupV2().isPresent()) {
        throw new AssertionError("Cannot process GV2");
    }
    if (!groupV1.isPresent() || groupV1.get().getGroupId() == null) {
        Log.w(TAG, "Received group message with no id! Ignoring...");
        return null;
    }
    GroupDatabase database = SignalDatabase.groups();
    SignalServiceGroup group = groupV1.get();
    GroupId id = GroupId.v1(group.getGroupId());
    Optional<GroupRecord> record = database.getGroup(id);
    if (record.isPresent() && group.getType() == Type.UPDATE) {
        return handleGroupUpdate(context, content, group, record.get(), outgoing);
    } else if (!record.isPresent() && group.getType() == Type.UPDATE) {
        return handleGroupCreate(context, content, group, outgoing);
    } else if (record.isPresent() && group.getType() == Type.QUIT) {
        return handleGroupLeave(context, content, group, record.get(), outgoing);
    } else if (record.isPresent() && group.getType() == Type.REQUEST_INFO) {
        return handleGroupInfoRequest(context, content, record.get());
    } else {
        Log.w(TAG, "Received unknown type, ignoring...");
        return null;
    }
}
Also used : GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) SignalServiceGroup(org.whispersystems.signalservice.api.messages.SignalServiceGroup) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) Nullable(androidx.annotation.Nullable)

Example 2 with SignalServiceGroupContext

use of org.whispersystems.signalservice.api.messages.SignalServiceGroupContext in project Signal-Android by WhisperSystems.

the class PushProcessMessageJob method createParameters.

@WorkerThread
@NonNull
private static Parameters createParameters(@Nullable SignalServiceContent content, @Nullable ExceptionMetadata exceptionMetadata) {
    Context context = ApplicationDependencies.getApplication();
    String queueName = QUEUE_PREFIX;
    Parameters.Builder builder = new Parameters.Builder().setMaxAttempts(Parameters.UNLIMITED);
    if (content != null) {
        SignalServiceGroupContext signalServiceGroupContext = GroupUtil.getGroupContextIfPresent(content);
        if (signalServiceGroupContext != null) {
            try {
                GroupId groupId = GroupUtil.idFromGroupContext(signalServiceGroupContext);
                queueName = getQueueName(Recipient.externalPossiblyMigratedGroup(context, groupId).getId());
                if (groupId.isV2()) {
                    int localRevision = SignalDatabase.groups().getGroupV2Revision(groupId.requireV2());
                    if (signalServiceGroupContext.getGroupV2().get().getRevision() > localRevision || SignalDatabase.groups().getGroupV1ByExpectedV2(groupId.requireV2()).isPresent()) {
                        Log.i(TAG, "Adding network constraint to group-related job.");
                        builder.addConstraint(NetworkConstraint.KEY).setLifespan(TimeUnit.DAYS.toMillis(30));
                    }
                }
            } catch (BadGroupIdException e) {
                Log.w(TAG, "Bad groupId! Using default queue. ID: " + content.getTimestamp());
            }
        } else if (content.getSyncMessage().isPresent() && content.getSyncMessage().get().getSent().isPresent() && content.getSyncMessage().get().getSent().get().getDestination().isPresent()) {
            queueName = getQueueName(RecipientId.fromHighTrust(content.getSyncMessage().get().getSent().get().getDestination().get()));
        } else {
            queueName = getQueueName(RecipientId.fromHighTrust(content.getSender()));
        }
    } else if (exceptionMetadata != null) {
        Recipient recipient = exceptionMetadata.getGroupId() != null ? Recipient.externalPossiblyMigratedGroup(context, exceptionMetadata.getGroupId()) : Recipient.external(context, exceptionMetadata.getSender());
        queueName = getQueueName(recipient.getId());
    }
    builder.setQueue(queueName);
    return builder.build();
}
Also used : Context(android.content.Context) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) Recipient(org.thoughtcrime.securesms.recipients.Recipient) BadGroupIdException(org.thoughtcrime.securesms.groups.BadGroupIdException) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) GroupId(org.thoughtcrime.securesms.groups.GroupId) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 3 with SignalServiceGroupContext

use of org.whispersystems.signalservice.api.messages.SignalServiceGroupContext in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method handleExpirationUpdate.

@Nullable
private MessageId handleExpirationUpdate(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Optional<Long> smsMessageId, @NonNull Optional<GroupId> groupId, @NonNull Recipient senderRecipient, @NonNull Recipient threadRecipient, long receivedTime) throws StorageFailedException {
    log(content.getTimestamp(), "Expiration update.");
    if (groupId.isPresent() && groupId.get().isV2()) {
        warn(String.valueOf(content.getTimestamp()), "Expiration update received for GV2. Ignoring.");
        return null;
    }
    int expiresInSeconds = message.getExpiresInSeconds();
    Optional<SignalServiceGroupContext> groupContext = message.getGroupContext();
    if (threadRecipient.getExpiresInSeconds() == expiresInSeconds) {
        log(String.valueOf(content.getTimestamp()), "No change in message expiry for group. Ignoring.");
        return null;
    }
    try {
        MessageDatabase database = SignalDatabase.mms();
        IncomingMediaMessage mediaMessage = new IncomingMediaMessage(senderRecipient.getId(), content.getTimestamp(), content.getServerReceivedTimestamp(), receivedTime, -1, expiresInSeconds * 1000L, true, false, content.isNeedsReceipt(), Optional.absent(), groupContext, Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), content.getServerUuid());
        Optional<InsertResult> insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
        SignalDatabase.recipients().setExpireMessages(threadRecipient.getId(), expiresInSeconds);
        if (smsMessageId.isPresent()) {
            SignalDatabase.sms().deleteMessage(smsMessageId.get());
        }
        if (insertResult.isPresent()) {
            return new MessageId(insertResult.get().getMessageId(), true);
        }
    } catch (MmsException e) {
        throw new StorageFailedException(e, content.getSender().getIdentifier(), content.getSenderDevice());
    }
    return null;
}
Also used : InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) MmsException(org.thoughtcrime.securesms.mms.MmsException) IncomingMediaMessage(org.thoughtcrime.securesms.mms.IncomingMediaMessage) SuppressLint(android.annotation.SuppressLint) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) Nullable(androidx.annotation.Nullable)

Example 4 with SignalServiceGroupContext

use of org.whispersystems.signalservice.api.messages.SignalServiceGroupContext in project Signal-Android by WhisperSystems.

the class SignalServiceMessageSender method createMessageContent.

private Content createMessageContent(SignalServiceDataMessage message) throws IOException {
    Content.Builder container = Content.newBuilder();
    DataMessage.Builder builder = DataMessage.newBuilder();
    List<AttachmentPointer> pointers = createAttachmentPointers(message.getAttachments());
    if (!pointers.isEmpty()) {
        builder.addAllAttachments(pointers);
        for (AttachmentPointer pointer : pointers) {
            if (pointer.getAttachmentIdentifierCase() == AttachmentPointer.AttachmentIdentifierCase.CDNKEY || pointer.getCdnNumber() != 0) {
                builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.CDN_SELECTOR_ATTACHMENTS_VALUE, builder.getRequiredProtocolVersion()));
                break;
            }
        }
    }
    if (message.getBody().isPresent()) {
        builder.setBody(message.getBody().get());
    }
    if (message.getGroupContext().isPresent()) {
        SignalServiceGroupContext groupContext = message.getGroupContext().get();
        if (groupContext.getGroupV1().isPresent()) {
            builder.setGroup(createGroupContent(groupContext.getGroupV1().get()));
        }
        if (groupContext.getGroupV2().isPresent()) {
            builder.setGroupV2(createGroupContent(groupContext.getGroupV2().get()));
        }
    }
    if (message.isEndSession()) {
        builder.setFlags(DataMessage.Flags.END_SESSION_VALUE);
    }
    if (message.isExpirationUpdate()) {
        builder.setFlags(DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE);
    }
    if (message.isProfileKeyUpdate()) {
        builder.setFlags(DataMessage.Flags.PROFILE_KEY_UPDATE_VALUE);
    }
    if (message.getExpiresInSeconds() > 0) {
        builder.setExpireTimer(message.getExpiresInSeconds());
    }
    if (message.getProfileKey().isPresent()) {
        builder.setProfileKey(ByteString.copyFrom(message.getProfileKey().get()));
    }
    if (message.getQuote().isPresent()) {
        DataMessage.Quote.Builder quoteBuilder = DataMessage.Quote.newBuilder().setId(message.getQuote().get().getId()).setText(message.getQuote().get().getText()).setAuthorUuid(message.getQuote().get().getAuthor().getServiceId().toString());
        if (!message.getQuote().get().getMentions().isEmpty()) {
            for (SignalServiceDataMessage.Mention mention : message.getQuote().get().getMentions()) {
                quoteBuilder.addBodyRanges(DataMessage.BodyRange.newBuilder().setStart(mention.getStart()).setLength(mention.getLength()).setMentionUuid(mention.getAci().toString()));
            }
            builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion()));
        }
        for (SignalServiceDataMessage.Quote.QuotedAttachment attachment : message.getQuote().get().getAttachments()) {
            DataMessage.Quote.QuotedAttachment.Builder quotedAttachment = DataMessage.Quote.QuotedAttachment.newBuilder();
            quotedAttachment.setContentType(attachment.getContentType());
            if (attachment.getFileName() != null) {
                quotedAttachment.setFileName(attachment.getFileName());
            }
            if (attachment.getThumbnail() != null) {
                quotedAttachment.setThumbnail(createAttachmentPointer(attachment.getThumbnail().asStream()));
            }
            quoteBuilder.addAttachments(quotedAttachment);
        }
        builder.setQuote(quoteBuilder);
    }
    if (message.getSharedContacts().isPresent()) {
        builder.addAllContact(createSharedContactContent(message.getSharedContacts().get()));
    }
    if (message.getPreviews().isPresent()) {
        for (SignalServiceDataMessage.Preview preview : message.getPreviews().get()) {
            DataMessage.Preview.Builder previewBuilder = DataMessage.Preview.newBuilder();
            previewBuilder.setTitle(preview.getTitle());
            previewBuilder.setDescription(preview.getDescription());
            previewBuilder.setDate(preview.getDate());
            previewBuilder.setUrl(preview.getUrl());
            if (preview.getImage().isPresent()) {
                if (preview.getImage().get().isStream()) {
                    previewBuilder.setImage(createAttachmentPointer(preview.getImage().get().asStream()));
                } else {
                    previewBuilder.setImage(createAttachmentPointer(preview.getImage().get().asPointer()));
                }
            }
            builder.addPreview(previewBuilder.build());
        }
    }
    if (message.getMentions().isPresent()) {
        for (SignalServiceDataMessage.Mention mention : message.getMentions().get()) {
            builder.addBodyRanges(DataMessage.BodyRange.newBuilder().setStart(mention.getStart()).setLength(mention.getLength()).setMentionUuid(mention.getAci().toString()));
        }
        builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion()));
    }
    if (message.getSticker().isPresent()) {
        DataMessage.Sticker.Builder stickerBuilder = DataMessage.Sticker.newBuilder();
        stickerBuilder.setPackId(ByteString.copyFrom(message.getSticker().get().getPackId()));
        stickerBuilder.setPackKey(ByteString.copyFrom(message.getSticker().get().getPackKey()));
        stickerBuilder.setStickerId(message.getSticker().get().getStickerId());
        if (message.getSticker().get().getEmoji() != null) {
            stickerBuilder.setEmoji(message.getSticker().get().getEmoji());
        }
        if (message.getSticker().get().getAttachment().isStream()) {
            stickerBuilder.setData(createAttachmentPointer(message.getSticker().get().getAttachment().asStream()));
        } else {
            stickerBuilder.setData(createAttachmentPointer(message.getSticker().get().getAttachment().asPointer()));
        }
        builder.setSticker(stickerBuilder.build());
    }
    if (message.isViewOnce()) {
        builder.setIsViewOnce(message.isViewOnce());
        builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.VIEW_ONCE_VIDEO_VALUE, builder.getRequiredProtocolVersion()));
    }
    if (message.getReaction().isPresent()) {
        DataMessage.Reaction.Builder reactionBuilder = DataMessage.Reaction.newBuilder().setEmoji(message.getReaction().get().getEmoji()).setRemove(message.getReaction().get().isRemove()).setTargetSentTimestamp(message.getReaction().get().getTargetSentTimestamp()).setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getServiceId().toString());
        builder.setReaction(reactionBuilder.build());
        builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.REACTIONS_VALUE, builder.getRequiredProtocolVersion()));
    }
    if (message.getRemoteDelete().isPresent()) {
        DataMessage.Delete delete = DataMessage.Delete.newBuilder().setTargetSentTimestamp(message.getRemoteDelete().get().getTargetSentTimestamp()).build();
        builder.setDelete(delete);
    }
    if (message.getGroupCallUpdate().isPresent()) {
        builder.setGroupCallUpdate(DataMessage.GroupCallUpdate.newBuilder().setEraId(message.getGroupCallUpdate().get().getEraId()));
    }
    if (message.getPayment().isPresent()) {
        SignalServiceDataMessage.Payment payment = message.getPayment().get();
        if (payment.getPaymentNotification().isPresent()) {
            SignalServiceDataMessage.PaymentNotification paymentNotification = payment.getPaymentNotification().get();
            DataMessage.Payment.Notification.MobileCoin.Builder mobileCoinPayment = DataMessage.Payment.Notification.MobileCoin.newBuilder().setReceipt(ByteString.copyFrom(paymentNotification.getReceipt()));
            DataMessage.Payment.Notification.Builder paymentBuilder = DataMessage.Payment.Notification.newBuilder().setNote(paymentNotification.getNote()).setMobileCoin(mobileCoinPayment);
            builder.setPayment(DataMessage.Payment.newBuilder().setNotification(paymentBuilder));
            builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.PAYMENTS_VALUE, builder.getRequiredProtocolVersion()));
        }
    }
    if (message.getStoryContext().isPresent()) {
        SignalServiceDataMessage.StoryContext storyContext = message.getStoryContext().get();
        builder.setStoryContext(DataMessage.StoryContext.newBuilder().setAuthorUuid(storyContext.getAuthorAci().toString()).setSentTimestamp(storyContext.getSentTimestamp()));
    }
    builder.setTimestamp(message.getTimestamp());
    return enforceMaxContentSize(container.setDataMessage(builder).build());
}
Also used : DataMessage(org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) AttachmentPointer(org.whispersystems.signalservice.internal.push.SignalServiceProtos.AttachmentPointer) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) EnvelopeContent(org.whispersystems.signalservice.api.crypto.EnvelopeContent) PlaintextContent(org.whispersystems.libsignal.protocol.PlaintextContent) Content(org.whispersystems.signalservice.internal.push.SignalServiceProtos.Content)

Aggregations

SignalServiceGroupContext (org.whispersystems.signalservice.api.messages.SignalServiceGroupContext)4 Nullable (androidx.annotation.Nullable)2 SuppressLint (android.annotation.SuppressLint)1 Context (android.content.Context)1 NonNull (androidx.annotation.NonNull)1 WorkerThread (androidx.annotation.WorkerThread)1 GroupDatabase (org.thoughtcrime.securesms.database.GroupDatabase)1 GroupRecord (org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord)1 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)1 InsertResult (org.thoughtcrime.securesms.database.MessageDatabase.InsertResult)1 SyncMessageId (org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)1 MessageId (org.thoughtcrime.securesms.database.model.MessageId)1 BadGroupIdException (org.thoughtcrime.securesms.groups.BadGroupIdException)1 GroupId (org.thoughtcrime.securesms.groups.GroupId)1 NetworkConstraint (org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint)1 IncomingMediaMessage (org.thoughtcrime.securesms.mms.IncomingMediaMessage)1 MmsException (org.thoughtcrime.securesms.mms.MmsException)1 Recipient (org.thoughtcrime.securesms.recipients.Recipient)1 PlaintextContent (org.whispersystems.libsignal.protocol.PlaintextContent)1 EnvelopeContent (org.whispersystems.signalservice.api.crypto.EnvelopeContent)1