Search in sources :

Example 16 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class ReactionSendJob method deliver.

@NonNull
private List<Recipient> deliver(@NonNull Recipient conversationRecipient, @NonNull List<Recipient> destinations, @NonNull Recipient targetAuthor, long targetSentTimestamp) throws IOException, UntrustedIdentityException {
    SignalServiceDataMessage.Builder dataMessageBuilder = SignalServiceDataMessage.newBuilder().withTimestamp(System.currentTimeMillis()).withReaction(buildReaction(context, reaction, remove, targetAuthor, targetSentTimestamp));
    if (conversationRecipient.isGroup()) {
        GroupUtil.setDataMessageGroupContext(context, dataMessageBuilder, conversationRecipient.requireGroupId().requirePush());
    }
    SignalServiceDataMessage dataMessage = dataMessageBuilder.build();
    List<Recipient> nonSelfDestinations = destinations.stream().filter(r -> !r.isSelf()).collect(Collectors.toList());
    boolean includesSelf = nonSelfDestinations.size() != destinations.size();
    List<SendMessageResult> results = GroupSendUtil.sendResendableDataMessage(context, conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(), nonSelfDestinations, false, ContentHint.RESENDABLE, messageId, dataMessage);
    if (includesSelf) {
        results.add(ApplicationDependencies.getSignalServiceMessageSender().sendSyncMessage(dataMessage));
    }
    return GroupSendJobHelper.getCompletedSends(destinations, results);
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) WorkerThread(androidx.annotation.WorkerThread) NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupSendUtil(org.thoughtcrime.securesms.messages.GroupSendUtil) ReactionDatabase(org.thoughtcrime.securesms.database.ReactionDatabase) MessageId(org.thoughtcrime.securesms.database.model.MessageId) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) Collectors(java.util.stream.Collectors) TimeUnit(java.util.concurrent.TimeUnit) Log(org.signal.core.util.logging.Log) List(java.util.List) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) GroupId(org.thoughtcrime.securesms.groups.GroupId) Job(org.thoughtcrime.securesms.jobmanager.Job) GroupUtil(org.thoughtcrime.securesms.util.GroupUtil) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Collections(java.util.Collections) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) GroupId(org.thoughtcrime.securesms.groups.GroupId) NonNull(androidx.annotation.NonNull)

Example 17 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class PushGroupSendJob method onPushSend.

@Override
public void onPushSend() throws IOException, MmsException, NoSuchMessageException, RetryLaterException {
    SignalLocalMetrics.GroupMessageSend.onJobStarted(messageId);
    MessageDatabase database = SignalDatabase.mms();
    OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
    long threadId = database.getMessageRecord(messageId).getThreadId();
    Set<NetworkFailure> existingNetworkFailures = message.getNetworkFailures();
    Set<IdentityKeyMismatch> existingIdentityMismatches = message.getIdentityKeyMismatches();
    ApplicationDependencies.getJobManager().cancelAllInQueue(TypingSendJob.getQueue(threadId));
    if (database.isSent(messageId)) {
        log(TAG, String.valueOf(message.getSentTimeMillis()), "Message " + messageId + " was already sent. Ignoring.");
        return;
    }
    Recipient groupRecipient = message.getRecipient().resolve();
    if (!groupRecipient.isPushGroup()) {
        throw new MmsException("Message recipient isn't a group!");
    }
    if (groupRecipient.isPushV1Group()) {
        throw new MmsException("No GV1 messages can be sent anymore!");
    }
    try {
        log(TAG, String.valueOf(message.getSentTimeMillis()), "Sending message: " + messageId + ", Recipient: " + message.getRecipient().getId() + ", Thread: " + threadId + ", Attachments: " + buildAttachmentString(message.getAttachments()));
        if (!groupRecipient.resolve().isProfileSharing() && !database.isGroupQuitMessage(messageId)) {
            RecipientUtil.shareProfileIfFirstSecureMessage(context, groupRecipient);
        }
        List<Recipient> target;
        if (filterRecipient != null)
            target = Collections.singletonList(Recipient.resolved(filterRecipient));
        else if (!existingNetworkFailures.isEmpty())
            target = Stream.of(existingNetworkFailures).map(nf -> nf.getRecipientId(context)).distinct().map(Recipient::resolved).toList();
        else
            target = Stream.of(getGroupMessageRecipients(groupRecipient.requireGroupId(), messageId)).distinctBy(Recipient::getId).toList();
        RecipientAccessList accessList = new RecipientAccessList(target);
        List<SendMessageResult> results = deliver(message, groupRecipient, target);
        Log.i(TAG, JobLogger.format(this, "Finished send."));
        List<NetworkFailure> networkFailures = Stream.of(results).filter(SendMessageResult::isNetworkFailure).map(result -> new NetworkFailure(accessList.requireIdByAddress(result.getAddress()))).toList();
        List<IdentityKeyMismatch> identityMismatches = Stream.of(results).filter(result -> result.getIdentityFailure() != null).map(result -> new IdentityKeyMismatch(accessList.requireIdByAddress(result.getAddress()), result.getIdentityFailure().getIdentityKey())).toList();
        ProofRequiredException proofRequired = Stream.of(results).filter(r -> r.getProofRequiredFailure() != null).findLast().map(SendMessageResult::getProofRequiredFailure).orElse(null);
        List<SendMessageResult> successes = Stream.of(results).filter(result -> result.getSuccess() != null).toList();
        List<Pair<RecipientId, Boolean>> successUnidentifiedStatus = Stream.of(successes).map(result -> new Pair<>(accessList.requireIdByAddress(result.getAddress()), result.getSuccess().isUnidentified())).toList();
        Set<RecipientId> successIds = Stream.of(successUnidentifiedStatus).map(Pair::first).collect(Collectors.toSet());
        List<NetworkFailure> resolvedNetworkFailures = Stream.of(existingNetworkFailures).filter(failure -> successIds.contains(failure.getRecipientId(context))).toList();
        List<IdentityKeyMismatch> resolvedIdentityFailures = Stream.of(existingIdentityMismatches).filter(failure -> successIds.contains(failure.getRecipientId(context))).toList();
        List<RecipientId> unregisteredRecipients = Stream.of(results).filter(SendMessageResult::isUnregisteredFailure).map(result -> RecipientId.from(result.getAddress())).toList();
        if (networkFailures.size() > 0 || identityMismatches.size() > 0 || proofRequired != null || unregisteredRecipients.size() > 0) {
            Log.w(TAG, String.format(Locale.US, "Failed to send to some recipients. Network: %d, Identity: %d, ProofRequired: %s, Unregistered: %d", networkFailures.size(), identityMismatches.size(), proofRequired != null, unregisteredRecipients.size()));
        }
        RecipientDatabase recipientDatabase = SignalDatabase.recipients();
        for (RecipientId unregistered : unregisteredRecipients) {
            recipientDatabase.markUnregistered(unregistered);
        }
        existingNetworkFailures.removeAll(resolvedNetworkFailures);
        existingNetworkFailures.addAll(networkFailures);
        database.setNetworkFailures(messageId, existingNetworkFailures);
        existingIdentityMismatches.removeAll(resolvedIdentityFailures);
        existingIdentityMismatches.addAll(identityMismatches);
        database.setMismatchedIdentities(messageId, existingIdentityMismatches);
        SignalDatabase.groupReceipts().setUnidentified(successUnidentifiedStatus, messageId);
        if (proofRequired != null) {
            handleProofRequiredException(proofRequired, groupRecipient, threadId, messageId, true);
        }
        if (existingNetworkFailures.isEmpty() && networkFailures.isEmpty() && identityMismatches.isEmpty() && existingIdentityMismatches.isEmpty()) {
            database.markAsSent(messageId, true);
            markAttachmentsUploaded(messageId, message);
            if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) {
                database.markExpireStarted(messageId);
                ApplicationDependencies.getExpiringMessageManager().scheduleDeletion(messageId, true, message.getExpiresIn());
            }
            if (message.isViewOnce()) {
                SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(messageId);
            }
        } else if (!identityMismatches.isEmpty()) {
            Log.w(TAG, "Failing because there were " + identityMismatches.size() + " identity mismatches.");
            database.markAsSentFailed(messageId);
            notifyMediaMessageDeliveryFailed(context, messageId);
            Set<RecipientId> mismatchRecipientIds = Stream.of(identityMismatches).map(mismatch -> mismatch.getRecipientId(context)).collect(Collectors.toSet());
            RetrieveProfileJob.enqueue(mismatchRecipientIds);
        } else if (!networkFailures.isEmpty()) {
            Log.w(TAG, "Retrying because there were " + networkFailures.size() + " network failures.");
            throw new RetryLaterException();
        }
    } catch (UntrustedIdentityException | UndeliverableMessageException e) {
        warn(TAG, String.valueOf(message.getSentTimeMillis()), e);
        database.markAsSentFailed(messageId);
        notifyMediaMessageDeliveryFailed(context, messageId);
    }
    SignalLocalMetrics.GroupMessageSend.onJobFinished(messageId);
}
Also used : ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) Quote(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Quote) MessageGroupContext(org.thoughtcrime.securesms.mms.MessageGroupContext) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Locale(java.util.Locale) Recipient(org.thoughtcrime.securesms.recipients.Recipient) OutgoingGroupUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingGroupUpdateMessage) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Set(java.util.Set) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) ByteString(com.google.protobuf.ByteString) Log(org.signal.core.util.logging.Log) GroupContextV2(org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2) List(java.util.List) Nullable(androidx.annotation.Nullable) SignalServiceGroupV2(org.whispersystems.signalservice.api.messages.SignalServiceGroupV2) GroupId(org.thoughtcrime.securesms.groups.GroupId) Job(org.thoughtcrime.securesms.jobmanager.Job) SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) GroupUtil(org.thoughtcrime.securesms.util.GroupUtil) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Preview(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview) Context(android.content.Context) RecipientAccessList(org.thoughtcrime.securesms.util.RecipientAccessList) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) Stream(com.annimon.stream.Stream) JobLogger(org.thoughtcrime.securesms.jobmanager.JobLogger) SignalLocalMetrics(org.thoughtcrime.securesms.util.SignalLocalMetrics) WorkerThread(androidx.annotation.WorkerThread) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) Pair(org.whispersystems.libsignal.util.Pair) GroupSendUtil(org.thoughtcrime.securesms.messages.GroupSendUtil) GroupReceiptInfo(org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Collectors(com.annimon.stream.Collectors) GroupReceiptDatabase(org.thoughtcrime.securesms.database.GroupReceiptDatabase) IdentityKeyMismatch(org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch) MmsException(org.thoughtcrime.securesms.mms.MmsException) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) ProofRequiredException(org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) NetworkFailure(org.thoughtcrime.securesms.database.documents.NetworkFailure) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Set(java.util.Set) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) MmsException(org.thoughtcrime.securesms.mms.MmsException) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) Pair(org.whispersystems.libsignal.util.Pair) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ProofRequiredException(org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException) NetworkFailure(org.thoughtcrime.securesms.database.documents.NetworkFailure) IdentityKeyMismatch(org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) RecipientAccessList(org.thoughtcrime.securesms.util.RecipientAccessList)

Example 18 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class PushTextSendJob method deliver.

private boolean deliver(SmsMessageRecord message) throws UntrustedIdentityException, InsecureFallbackApprovalException, UndeliverableMessageException, IOException {
    try {
        rotateSenderCertificateIfNecessary();
        Recipient messageRecipient = message.getIndividualRecipient().resolve();
        if (messageRecipient.isUnregistered()) {
            throw new UndeliverableMessageException(messageRecipient.getId() + " not registered!");
        }
        SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
        SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, messageRecipient);
        Optional<byte[]> profileKey = getProfileKey(messageRecipient);
        Optional<UnidentifiedAccessPair> unidentifiedAccess = UnidentifiedAccessUtil.getAccessFor(context, messageRecipient);
        log(TAG, String.valueOf(message.getDateSent()), "Have access key to use: " + unidentifiedAccess.isPresent());
        SignalServiceDataMessage textSecureMessage = SignalServiceDataMessage.newBuilder().withTimestamp(message.getDateSent()).withBody(message.getBody()).withExpiration((int) (message.getExpiresIn() / 1000)).withProfileKey(profileKey.orNull()).asEndSessionMessage(message.isEndSession()).build();
        if (Util.equals(SignalStore.account().getAci(), address.getServiceId())) {
            Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
            SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId);
            SendMessageResult result = messageSender.sendSyncMessage(textSecureMessage);
            SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false));
            return syncAccess.isPresent();
        } else {
            SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId);
            SendMessageResult result = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.RESENDABLE, textSecureMessage, new MetricEventListener(messageId));
            SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false));
            return result.getSuccess().isUnidentified();
        }
    } catch (UnregisteredUserException e) {
        warn(TAG, "Failure", e);
        throw new InsecureFallbackApprovalException(e);
    } catch (ServerRejectedException e) {
        throw new UndeliverableMessageException(e);
    }
}
Also used : UnregisteredUserException(org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) Recipient(org.thoughtcrime.securesms.recipients.Recipient) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) InsecureFallbackApprovalException(org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)

Example 19 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class ReactionsBottomSheetDialogFragment method onViewCreated.

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    recipientPagerView = view.findViewById(R.id.reactions_bottom_view_recipient_pager);
    disposables.bindTo(getViewLifecycleOwner());
    setUpRecipientsRecyclerView();
    setUpTabMediator(savedInstanceState);
    MessageId messageId = new MessageId(requireArguments().getLong(ARGS_MESSAGE_ID), requireArguments().getBoolean(ARGS_IS_MMS));
    setUpViewModel(messageId);
}
Also used : MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 20 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class MessageSender method sendMediaBroadcast.

public static void sendMediaBroadcast(@NonNull Context context, @NonNull List<OutgoingSecureMediaMessage> messages, @NonNull Collection<PreUploadResult> preUploadResults) {
    Log.i(TAG, "Sending media broadcast to " + Stream.of(messages).map(m -> m.getRecipient().getId()).toList());
    Preconditions.checkArgument(messages.size() > 0, "No messages!");
    Preconditions.checkArgument(Stream.of(messages).allMatch(m -> m.getAttachments().isEmpty()), "Messages can't have attachments! They should be pre-uploaded.");
    JobManager jobManager = ApplicationDependencies.getJobManager();
    AttachmentDatabase attachmentDatabase = SignalDatabase.attachments();
    MessageDatabase mmsDatabase = SignalDatabase.mms();
    ThreadDatabase threadDatabase = SignalDatabase.threads();
    List<AttachmentId> preUploadAttachmentIds = Stream.of(preUploadResults).map(PreUploadResult::getAttachmentId).toList();
    List<String> preUploadJobIds = Stream.of(preUploadResults).map(PreUploadResult::getJobIds).flatMap(Stream::of).toList();
    List<Long> messageIds = new ArrayList<>(messages.size());
    List<String> messageDependsOnIds = new ArrayList<>(preUploadJobIds);
    mmsDatabase.beginTransaction();
    try {
        OutgoingSecureMediaMessage primaryMessage = messages.get(0);
        long primaryThreadId = threadDatabase.getOrCreateThreadIdFor(primaryMessage.getRecipient(), primaryMessage.getDistributionType());
        long primaryMessageId = mmsDatabase.insertMessageOutbox(applyUniversalExpireTimerIfNecessary(context, primaryMessage.getRecipient(), primaryMessage, primaryThreadId), primaryThreadId, false, null);
        attachmentDatabase.updateMessageId(preUploadAttachmentIds, primaryMessageId);
        messageIds.add(primaryMessageId);
        if (messages.size() > 0) {
            List<OutgoingSecureMediaMessage> secondaryMessages = messages.subList(1, messages.size());
            List<List<AttachmentId>> attachmentCopies = new ArrayList<>();
            List<DatabaseAttachment> preUploadAttachments = Stream.of(preUploadAttachmentIds).map(attachmentDatabase::getAttachment).toList();
            for (int i = 0; i < preUploadAttachmentIds.size(); i++) {
                attachmentCopies.add(new ArrayList<>(messages.size()));
            }
            for (OutgoingSecureMediaMessage secondaryMessage : secondaryMessages) {
                long allocatedThreadId = threadDatabase.getOrCreateThreadIdFor(secondaryMessage.getRecipient(), secondaryMessage.getDistributionType());
                long messageId = mmsDatabase.insertMessageOutbox(applyUniversalExpireTimerIfNecessary(context, secondaryMessage.getRecipient(), secondaryMessage, allocatedThreadId), allocatedThreadId, false, null);
                List<AttachmentId> attachmentIds = new ArrayList<>(preUploadAttachmentIds.size());
                for (int i = 0; i < preUploadAttachments.size(); i++) {
                    AttachmentId attachmentId = attachmentDatabase.insertAttachmentForPreUpload(preUploadAttachments.get(i)).getAttachmentId();
                    attachmentCopies.get(i).add(attachmentId);
                    attachmentIds.add(attachmentId);
                }
                attachmentDatabase.updateMessageId(attachmentIds, messageId);
                messageIds.add(messageId);
            }
            for (int i = 0; i < attachmentCopies.size(); i++) {
                Job copyJob = new AttachmentCopyJob(preUploadAttachmentIds.get(i), attachmentCopies.get(i));
                jobManager.add(copyJob, preUploadJobIds);
                messageDependsOnIds.add(copyJob.getId());
            }
        }
        for (int i = 0; i < messageIds.size(); i++) {
            long messageId = messageIds.get(i);
            OutgoingSecureMediaMessage message = messages.get(i);
            Recipient recipient = message.getRecipient();
            if (isLocalSelfSend(context, recipient, false)) {
                sendLocalMediaSelf(context, messageId);
            } else if (isGroupPushSend(recipient)) {
                jobManager.add(new PushGroupSendJob(messageId, recipient.getId(), null, true), messageDependsOnIds, recipient.getId().toQueueKey());
            } else {
                jobManager.add(new PushMediaSendJob(messageId, recipient, true), messageDependsOnIds, recipient.getId().toQueueKey());
            }
        }
        onMessageSent();
        mmsDatabase.setTransactionSuccessful();
    } catch (MmsException e) {
        Log.w(TAG, "Failed to send messages.", e);
    } finally {
        mmsDatabase.endTransaction();
    }
}
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) PushGroupSendJob(org.thoughtcrime.securesms.jobs.PushGroupSendJob) ArrayList(java.util.ArrayList) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) MmsException(org.thoughtcrime.securesms.mms.MmsException) AttachmentCopyJob(org.thoughtcrime.securesms.jobs.AttachmentCopyJob) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) PushMediaSendJob(org.thoughtcrime.securesms.jobs.PushMediaSendJob) AttachmentMarkUploadedJob(org.thoughtcrime.securesms.jobs.AttachmentMarkUploadedJob) ReactionSendJob(org.thoughtcrime.securesms.jobs.ReactionSendJob) PushMediaSendJob(org.thoughtcrime.securesms.jobs.PushMediaSendJob) Job(org.thoughtcrime.securesms.jobmanager.Job) ResumableUploadSpecJob(org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob) PushGroupSendJob(org.thoughtcrime.securesms.jobs.PushGroupSendJob) AttachmentCompressionJob(org.thoughtcrime.securesms.jobs.AttachmentCompressionJob) ProfileKeySendJob(org.thoughtcrime.securesms.jobs.ProfileKeySendJob) RemoteDeleteSendJob(org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob) MmsSendJob(org.thoughtcrime.securesms.jobs.MmsSendJob) AttachmentUploadJob(org.thoughtcrime.securesms.jobs.AttachmentUploadJob) PushTextSendJob(org.thoughtcrime.securesms.jobs.PushTextSendJob) AttachmentCopyJob(org.thoughtcrime.securesms.jobs.AttachmentCopyJob) SmsSendJob(org.thoughtcrime.securesms.jobs.SmsSendJob) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage)

Aggregations

MessageId (org.thoughtcrime.securesms.database.model.MessageId)90 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)40 NonNull (androidx.annotation.NonNull)30 Recipient (org.thoughtcrime.securesms.recipients.Recipient)30 Nullable (androidx.annotation.Nullable)28 LinkedList (java.util.LinkedList)24 List (java.util.List)24 SyncMessageId (org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)24 Context (android.content.Context)22 IOException (java.io.IOException)22 Log (org.signal.core.util.logging.Log)22 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)22 SignalServiceDataMessage (org.whispersystems.signalservice.api.messages.SignalServiceDataMessage)22 ContentValues (android.content.ContentValues)20 Collections (java.util.Collections)20 Attachment (org.thoughtcrime.securesms.attachments.Attachment)20 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)20 Cursor (android.database.Cursor)18 ArrayList (java.util.ArrayList)18 TextSecurePreferences (org.thoughtcrime.securesms.util.TextSecurePreferences)18