use of org.thoughtcrime.securesms.database.ThreadDatabase in project Signal-Android by WhisperSystems.
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();
}
}
use of org.thoughtcrime.securesms.database.ThreadDatabase in project Signal-Android by WhisperSystems.
the class GroupManagerV1 method updateGroupTimer.
@WorkerThread
static void updateGroupTimer(@NonNull Context context, @NonNull GroupId.V1 groupId, int expirationTime) {
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
ThreadDatabase threadDatabase = SignalDatabase.threads();
Recipient recipient = Recipient.externalGroupExact(context, groupId);
long threadId = threadDatabase.getOrCreateThreadIdFor(recipient);
recipientDatabase.setExpireMessages(recipient.getId(), expirationTime);
OutgoingExpirationUpdateMessage outgoingMessage = new OutgoingExpirationUpdateMessage(recipient, System.currentTimeMillis(), expirationTime * 1000L);
MessageSender.send(context, outgoingMessage, threadId, false, null, null);
}
use of org.thoughtcrime.securesms.database.ThreadDatabase in project Signal-Android by WhisperSystems.
the class ConversationListFragment method onItemSwiped.
@SuppressLint("StaticFieldLeak")
protected void onItemSwiped(long threadId, int unreadCount) {
archiveDecoration.onArchiveStarted();
itemAnimator.enable();
new SnackbarAsyncTask<Long>(getViewLifecycleOwner().getLifecycle(), requireView(), getResources().getQuantityString(R.plurals.ConversationListFragment_conversations_archived, 1, 1), getString(R.string.ConversationListFragment_undo), getResources().getColor(R.color.amber_500), Snackbar.LENGTH_LONG, false) {
private final ThreadDatabase threadDatabase = SignalDatabase.threads();
private List<Long> pinnedThreadIds;
@Override
protected void executeAction(@Nullable Long parameter) {
Context context = requireActivity();
pinnedThreadIds = threadDatabase.getPinnedThreadIds();
threadDatabase.archiveConversation(threadId);
if (unreadCount > 0) {
List<MarkedMessageInfo> messageIds = threadDatabase.setRead(threadId, false);
ApplicationDependencies.getMessageNotifier().updateNotification(context);
MarkReadReceiver.process(context, messageIds);
}
}
@Override
protected void reverseAction(@Nullable Long parameter) {
Context context = requireActivity();
threadDatabase.unarchiveConversation(threadId);
threadDatabase.restorePins(pinnedThreadIds);
if (unreadCount > 0) {
threadDatabase.incrementUnread(threadId, unreadCount);
ApplicationDependencies.getMessageNotifier().updateNotification(context);
}
}
}.executeOnExecutor(SignalExecutors.BOUNDED, threadId);
}
use of org.thoughtcrime.securesms.database.ThreadDatabase in project Signal-Android by WhisperSystems.
the class ConversationListFragment method handlePin.
private void handlePin(@NonNull Collection<Conversation> conversations) {
final Set<Long> toPin = new LinkedHashSet<>(Stream.of(conversations).filterNot(conversation -> conversation.getThreadRecord().isPinned()).map(conversation -> conversation.getThreadRecord().getThreadId()).toList());
if (toPin.size() + viewModel.getPinnedCount() > MAXIMUM_PINNED_CONVERSATIONS) {
Snackbar.make(fab, getString(R.string.conversation_list__you_can_only_pin_up_to_d_chats, MAXIMUM_PINNED_CONVERSATIONS), Snackbar.LENGTH_LONG).setTextColor(Color.WHITE).show();
endActionModeIfActive();
return;
}
SimpleTask.run(SignalExecutors.BOUNDED, () -> {
ThreadDatabase db = SignalDatabase.threads();
db.pinConversations(toPin);
return null;
}, unused -> {
endActionModeIfActive();
});
}
use of org.thoughtcrime.securesms.database.ThreadDatabase in project Signal-Android by WhisperSystems.
the class MarkReadHelper method onViewsRevealed.
public void onViewsRevealed(long timestamp) {
if (timestamp <= latestTimestamp || lifecycleOwner.getLifecycle().getCurrentState() != Lifecycle.State.RESUMED) {
return;
}
latestTimestamp = timestamp;
debouncer.publish(() -> {
EXECUTOR.execute(() -> {
ThreadDatabase threadDatabase = SignalDatabase.threads();
List<MessageDatabase.MarkedMessageInfo> infos = threadDatabase.setReadSince(threadId, false, timestamp);
Log.d(TAG, "Marking " + infos.size() + " messages as read.");
ApplicationDependencies.getMessageNotifier().updateNotification(context);
MarkReadReceiver.process(context, infos);
});
});
}
Aggregations