Search in sources :

Example 21 with MarkedMessageInfo

use of org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo in project Signal-Android by signalapp.

the class SendReadReceiptJob method enqueue.

/**
 * Enqueues all the necessary jobs for read receipts, ensuring that they're all within the
 * maximum size.
 */
public static void enqueue(long threadId, @NonNull RecipientId recipientId, List<MarkedMessageInfo> markedMessageInfos) {
    if (recipientId.equals(Recipient.self().getId())) {
        return;
    }
    JobManager jobManager = ApplicationDependencies.getJobManager();
    List<List<MarkedMessageInfo>> messageIdChunks = ListUtil.chunk(markedMessageInfos, MAX_TIMESTAMPS);
    if (messageIdChunks.size() > 1) {
        Log.w(TAG, "Large receipt count! Had to break into multiple chunks. Total count: " + markedMessageInfos.size());
    }
    for (List<MarkedMessageInfo> chunk : messageIdChunks) {
        List<Long> sentTimestamps = chunk.stream().map(info -> info.getSyncMessageId().getTimetamp()).collect(Collectors.toList());
        List<MessageId> messageIds = chunk.stream().map(MarkedMessageInfo::getMessageId).collect(Collectors.toList());
        jobManager.add(new SendReadReceiptJob(threadId, recipientId, sentTimestamps, messageIds));
    }
}
Also used : MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) Util(org.thoughtcrime.securesms.util.Util) 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) NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) ListUtil(org.signal.core.util.ListUtil) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) ArrayList(java.util.ArrayList) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) MessageId(org.thoughtcrime.securesms.database.model.MessageId) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) UnidentifiedAccessUtil(org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) 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) Application(android.app.Application) Job(org.thoughtcrime.securesms.jobmanager.Job) SignalServiceReceiptMessage(org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage) VisibleForTesting(androidx.annotation.VisibleForTesting) Collections(java.util.Collections) ArrayList(java.util.ArrayList) List(java.util.List) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo) MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 22 with MarkedMessageInfo

use of org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo in project Signal-Android by signalapp.

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) ArrayList(java.util.ArrayList) 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) ConversationId(org.thoughtcrime.securesms.notifications.v2.ConversationId) LinkedList(java.util.LinkedList) SignalExecutors(org.signal.core.util.concurrent.SignalExecutors) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ExpirationInfo(org.thoughtcrime.securesms.database.MessageDatabase.ExpirationInfo) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo)

Example 23 with MarkedMessageInfo

use of org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo in project Signal-Android by signalapp.

the class RemoteReplyReceiver method onReceive.

@SuppressLint("StaticFieldLeak")
@Override
public void onReceive(final Context context, Intent intent) {
    if (!REPLY_ACTION.equals(intent.getAction()))
        return;
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput == null)
        return;
    final RecipientId recipientId = intent.getParcelableExtra(RECIPIENT_EXTRA);
    final ReplyMethod replyMethod = (ReplyMethod) intent.getSerializableExtra(REPLY_METHOD);
    final CharSequence responseText = remoteInput.getCharSequence(MessageNotifierV2.EXTRA_REMOTE_REPLY);
    final long groupStoryId = intent.getLongExtra(GROUP_STORY_ID_EXTRA, Long.MIN_VALUE);
    if (recipientId == null)
        throw new AssertionError("No recipientId specified");
    if (replyMethod == null)
        throw new AssertionError("No reply method specified");
    if (responseText != null) {
        SignalExecutors.BOUNDED.execute(() -> {
            long threadId;
            Recipient recipient = Recipient.resolved(recipientId);
            int subscriptionId = recipient.getDefaultSubscriptionId().orElse(-1);
            long expiresIn = TimeUnit.SECONDS.toMillis(recipient.getExpiresInSeconds());
            ParentStoryId parentStoryId = groupStoryId != Long.MIN_VALUE ? ParentStoryId.deserialize(groupStoryId) : null;
            switch(replyMethod) {
                case GroupMessage:
                    {
                        OutgoingMediaMessage reply = new OutgoingMediaMessage(recipient, responseText.toString(), new LinkedList<>(), System.currentTimeMillis(), subscriptionId, expiresIn, false, 0, StoryType.NONE, parentStoryId, false, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptySet(), Collections.emptySet(), null);
                        threadId = MessageSender.send(context, reply, -1, false, null, null);
                        break;
                    }
                case SecureMessage:
                    {
                        OutgoingEncryptedMessage reply = new OutgoingEncryptedMessage(recipient, responseText.toString(), expiresIn);
                        threadId = MessageSender.send(context, reply, -1, false, null, null);
                        break;
                    }
                case UnsecuredSmsMessage:
                    {
                        OutgoingTextMessage reply = new OutgoingTextMessage(recipient, responseText.toString(), expiresIn, subscriptionId);
                        threadId = MessageSender.send(context, reply, -1, true, null, null);
                        break;
                    }
                default:
                    throw new AssertionError("Unknown Reply method");
            }
            ApplicationDependencies.getMessageNotifier().addStickyThread(new ConversationId(threadId, groupStoryId != Long.MIN_VALUE ? groupStoryId : null), intent.getLongExtra(EARLIEST_TIMESTAMP, System.currentTimeMillis()));
            List<MarkedMessageInfo> messageIds = SignalDatabase.threads().setRead(threadId, true);
            ApplicationDependencies.getMessageNotifier().updateNotification(context);
            MarkReadReceiver.process(context, messageIds);
        });
    }
}
Also used : OutgoingTextMessage(org.thoughtcrime.securesms.sms.OutgoingTextMessage) ConversationId(org.thoughtcrime.securesms.notifications.v2.ConversationId) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Bundle(android.os.Bundle) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ParentStoryId(org.thoughtcrime.securesms.database.model.ParentStoryId) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) SuppressLint(android.annotation.SuppressLint) LinkedList(java.util.LinkedList) OutgoingEncryptedMessage(org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage) MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo) SuppressLint(android.annotation.SuppressLint)

Example 24 with MarkedMessageInfo

use of org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo in project mollyim-android by mollyim.

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 25 with MarkedMessageInfo

use of org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo in project mollyim-android by mollyim.

the class ConversationListFragment method handleMarkAllRead.

private void handleMarkAllRead() {
    Context context = requireContext();
    SignalExecutors.BOUNDED.execute(() -> {
        List<MarkedMessageInfo> messageIds = SignalDatabase.threads().setAllThreadsRead();
        ApplicationDependencies.getMessageNotifier().updateNotification(context);
        MarkReadReceiver.process(context, messageIds);
    });
}
Also used : Context(android.content.Context) MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo)

Aggregations

MarkedMessageInfo (org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo)26 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)12 LinkedList (java.util.LinkedList)11 Context (android.content.Context)9 NonNull (androidx.annotation.NonNull)9 List (java.util.List)9 Log (org.signal.core.util.logging.Log)9 SignalDatabase (org.thoughtcrime.securesms.database.SignalDatabase)9 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)9 Recipient (org.thoughtcrime.securesms.recipients.Recipient)9 SuppressLint (android.annotation.SuppressLint)8 Application (android.app.Application)6 ContentValues (android.content.ContentValues)6 IOException (java.io.IOException)6 Collections (java.util.Collections)6 Map (java.util.Map)6 TimeUnit (java.util.concurrent.TimeUnit)6 Collectors (java.util.stream.Collectors)6 UnidentifiedAccessUtil (org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil)6 MessageId (org.thoughtcrime.securesms.database.model.MessageId)6