Search in sources :

Example 11 with SyncMessageId

use of org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId in project Signal-Android by WhisperSystems.

the class MarkReadReceiver method process.

public static void process(@NonNull Context context, @NonNull List<MarkedMessageInfo> markedReadMessages) {
    if (markedReadMessages.isEmpty())
        return;
    List<SyncMessageId> syncMessageIds = Stream.of(markedReadMessages).map(MarkedMessageInfo::getSyncMessageId).toList();
    List<ExpirationInfo> mmsExpirationInfo = Stream.of(markedReadMessages).map(MarkedMessageInfo::getExpirationInfo).filter(ExpirationInfo::isMms).filter(info -> info.getExpiresIn() > 0 && info.getExpireStarted() <= 0).toList();
    List<ExpirationInfo> smsExpirationInfo = Stream.of(markedReadMessages).map(MarkedMessageInfo::getExpirationInfo).filterNot(ExpirationInfo::isMms).filter(info -> info.getExpiresIn() > 0 && info.getExpireStarted() <= 0).toList();
    scheduleDeletion(context, smsExpirationInfo, mmsExpirationInfo);
    MultiDeviceReadUpdateJob.enqueue(syncMessageIds);
    Map<Long, List<MarkedMessageInfo>> threadToInfo = Stream.of(markedReadMessages).collect(Collectors.groupingBy(MarkedMessageInfo::getThreadId));
    Stream.of(threadToInfo).forEach(threadToInfoEntry -> {
        Map<RecipientId, List<MarkedMessageInfo>> recipientIdToInfo = Stream.of(threadToInfoEntry.getValue()).map(info -> info).collect(Collectors.groupingBy(info -> info.getSyncMessageId().getRecipientId()));
        Stream.of(recipientIdToInfo).forEach(entry -> {
            long threadId = threadToInfoEntry.getKey();
            RecipientId recipientId = entry.getKey();
            List<MarkedMessageInfo> infos = entry.getValue();
            SendReadReceiptJob.enqueue(threadId, recipientId, infos);
        });
    });
}
Also used : MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Collectors(com.annimon.stream.Collectors) Stream(com.annimon.stream.Stream) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) NonNull(androidx.annotation.NonNull) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) SendReadReceiptJob(org.thoughtcrime.securesms.jobs.SendReadReceiptJob) ExpirationInfo(org.thoughtcrime.securesms.database.MessageDatabase.ExpirationInfo) Intent(android.content.Intent) BroadcastReceiver(android.content.BroadcastReceiver) Log(org.signal.core.util.logging.Log) SuppressLint(android.annotation.SuppressLint) List(java.util.List) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) MultiDeviceReadUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob) Map(java.util.Map) ExpiringMessageManager(org.thoughtcrime.securesms.service.ExpiringMessageManager) LinkedList(java.util.LinkedList) SignalExecutors(org.signal.core.util.concurrent.SignalExecutors) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ExpirationInfo(org.thoughtcrime.securesms.database.MessageDatabase.ExpirationInfo) List(java.util.List) LinkedList(java.util.LinkedList) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo)

Example 12 with SyncMessageId

use of org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId in project Signal-Android by WhisperSystems.

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 13 with SyncMessageId

use of org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId in project Signal-Android by WhisperSystems.

the class MessageSender method sendLocalTextSelf.

private static void sendLocalTextSelf(Context context, long messageId) {
    try {
        ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager();
        MessageDatabase smsDatabase = SignalDatabase.sms();
        MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms();
        SmsMessageRecord message = smsDatabase.getSmsMessage(messageId);
        SyncMessageId syncId = new SyncMessageId(Recipient.self().getId(), message.getDateSent());
        smsDatabase.markAsSent(messageId, true);
        smsDatabase.markUnidentified(messageId, true);
        mmsSmsDatabase.incrementDeliveryReceiptCount(syncId, System.currentTimeMillis());
        mmsSmsDatabase.incrementReadReceiptCount(syncId, System.currentTimeMillis());
        if (message.getExpiresIn() > 0) {
            smsDatabase.markExpireStarted(messageId);
            expirationManager.scheduleDeletion(message.getId(), message.isMms(), message.getExpiresIn());
        }
    } catch (NoSuchMessageException e) {
        Log.w(TAG, "Failed to update self-sent message.", e);
    }
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) SmsMessageRecord(org.thoughtcrime.securesms.database.model.SmsMessageRecord) MmsSmsDatabase(org.thoughtcrime.securesms.database.MmsSmsDatabase) ExpiringMessageManager(org.thoughtcrime.securesms.service.ExpiringMessageManager) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)

Example 14 with SyncMessageId

use of org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId in project Signal-Android by WhisperSystems.

the class PushMediaSendJob method onPushSend.

@Override
public void onPushSend() throws IOException, MmsException, NoSuchMessageException, UndeliverableMessageException, RetryLaterException {
    ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager();
    MessageDatabase database = SignalDatabase.mms();
    OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
    long threadId = database.getMessageRecord(messageId).getThreadId();
    if (database.isSent(messageId)) {
        warn(TAG, String.valueOf(message.getSentTimeMillis()), "Message " + messageId + " was already sent. Ignoring.");
        return;
    }
    try {
        log(TAG, String.valueOf(message.getSentTimeMillis()), "Sending message: " + messageId + ", Recipient: " + message.getRecipient().getId() + ", Thread: " + threadId + ", Attachments: " + buildAttachmentString(message.getAttachments()));
        RecipientUtil.shareProfileIfFirstSecureMessage(context, message.getRecipient());
        Recipient recipient = message.getRecipient().fresh();
        byte[] profileKey = recipient.getProfileKey();
        UnidentifiedAccessMode accessMode = recipient.getUnidentifiedAccessMode();
        boolean unidentified = deliver(message);
        database.markAsSent(messageId, true);
        markAttachmentsUploaded(messageId, message);
        database.markUnidentified(messageId, unidentified);
        if (recipient.isSelf()) {
            SyncMessageId id = new SyncMessageId(recipient.getId(), message.getSentTimeMillis());
            SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
            SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis());
            SignalDatabase.mmsSms().incrementViewedReceiptCount(id, System.currentTimeMillis());
        }
        if (unidentified && accessMode == UnidentifiedAccessMode.UNKNOWN && profileKey == null) {
            log(TAG, String.valueOf(message.getSentTimeMillis()), "Marking recipient as UD-unrestricted following a UD send.");
            SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.UNRESTRICTED);
        } else if (unidentified && accessMode == UnidentifiedAccessMode.UNKNOWN) {
            log(TAG, String.valueOf(message.getSentTimeMillis()), "Marking recipient as UD-enabled following a UD send.");
            SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.ENABLED);
        } else if (!unidentified && accessMode != UnidentifiedAccessMode.DISABLED) {
            log(TAG, String.valueOf(message.getSentTimeMillis()), "Marking recipient as UD-disabled following a non-UD send.");
            SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.DISABLED);
        }
        if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) {
            database.markExpireStarted(messageId);
            expirationManager.scheduleDeletion(messageId, true, message.getExpiresIn());
        }
        if (message.isViewOnce()) {
            SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(messageId);
        }
        log(TAG, String.valueOf(message.getSentTimeMillis()), "Sent message: " + messageId);
    } catch (InsecureFallbackApprovalException ifae) {
        warn(TAG, "Failure", ifae);
        database.markAsPendingInsecureSmsFallback(messageId);
        notifyMediaMessageDeliveryFailed(context, messageId);
        ApplicationDependencies.getJobManager().add(new DirectoryRefreshJob(false));
    } catch (UntrustedIdentityException uie) {
        warn(TAG, "Failure", uie);
        RecipientId recipientId = Recipient.external(context, uie.getIdentifier()).getId();
        database.addMismatchedIdentity(messageId, recipientId, uie.getIdentityKey());
        database.markAsSentFailed(messageId);
        RetrieveProfileJob.enqueue(recipientId);
    } catch (ProofRequiredException e) {
        handleProofRequiredException(e, SignalDatabase.threads().getRecipientForThreadId(threadId), threadId, messageId, true);
    }
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ExpiringMessageManager(org.thoughtcrime.securesms.service.ExpiringMessageManager) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ProofRequiredException(org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException) UnidentifiedAccessMode(org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode) InsecureFallbackApprovalException(org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)

Example 15 with SyncMessageId

use of org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId in project Signal-Android by WhisperSystems.

the class MultiDeviceReadUpdateJob method enqueue.

/**
 * Enqueues all the necessary jobs for read receipts, ensuring that they're all within the
 * maximum size.
 */
public static void enqueue(@NonNull List<SyncMessageId> messageIds) {
    JobManager jobManager = ApplicationDependencies.getJobManager();
    List<List<SyncMessageId>> messageIdChunks = Util.chunk(messageIds, SendReadReceiptJob.MAX_TIMESTAMPS);
    if (messageIdChunks.size() > 1) {
        Log.w(TAG, "Large receipt count! Had to break into multiple chunks. Total count: " + messageIds.size());
    }
    for (List<SyncMessageId> chunk : messageIdChunks) {
        jobManager.add(new MultiDeviceReadUpdateJob(chunk));
    }
}
Also used : LinkedList(java.util.LinkedList) List(java.util.List) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)

Aggregations

SyncMessageId (org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)26 LinkedList (java.util.LinkedList)16 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)16 List (java.util.List)14 Recipient (org.thoughtcrime.securesms.recipients.Recipient)14 OutgoingMediaMessage (org.thoughtcrime.securesms.mms.OutgoingMediaMessage)12 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)12 NonNull (androidx.annotation.NonNull)10 JobManager (org.thoughtcrime.securesms.jobmanager.JobManager)10 OutgoingSecureMediaMessage (org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage)10 ExpiringMessageManager (org.thoughtcrime.securesms.service.ExpiringMessageManager)10 Context (android.content.Context)8 Stream (com.annimon.stream.Stream)8 ArrayList (java.util.ArrayList)8 Log (org.signal.core.util.logging.Log)8 SignalDatabase (org.thoughtcrime.securesms.database.SignalDatabase)8 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)8 Attachment (org.thoughtcrime.securesms.attachments.Attachment)7 DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)7 MmsSmsDatabase (org.thoughtcrime.securesms.database.MmsSmsDatabase)7