kopia lustrzana https://github.com/ryukoposting/Signal-Android
Remove the rest of MmsSmsTable.
rodzic
6cd6073bc7
commit
fecfd7cd78
|
@ -72,7 +72,7 @@ class MessageContentProcessor__handleStoryMessageTest : MessageContentProcessorT
|
||||||
|
|
||||||
runTestWithContent(contentProto = storyContent)
|
runTestWithContent(contentProto = storyContent)
|
||||||
|
|
||||||
val replyId = SignalDatabase.mmsSms.getConversation(senderThreadId, 0, 1).use {
|
val replyId = SignalDatabase.messages.getConversation(senderThreadId, 0, 1).use {
|
||||||
it.moveToFirst()
|
it.moveToFirst()
|
||||||
it.requireLong(MessageTable.ID)
|
it.requireLong(MessageTable.ID)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import org.thoughtcrime.securesms.conversation.ConversationData.MessageRequestDa
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory;
|
import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory;
|
||||||
import org.thoughtcrime.securesms.database.CallTable;
|
import org.thoughtcrime.securesms.database.CallTable;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||||
|
@ -94,7 +93,6 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
||||||
@Override
|
@Override
|
||||||
public @NonNull List<ConversationMessage> load(int start, int length, @NonNull CancellationSignal cancellationSignal) {
|
public @NonNull List<ConversationMessage> load(int start, int length, @NonNull CancellationSignal cancellationSignal) {
|
||||||
Stopwatch stopwatch = new Stopwatch("load(" + start + ", " + length + "), thread " + threadId);
|
Stopwatch stopwatch = new Stopwatch("load(" + start + ", " + length + "), thread " + threadId);
|
||||||
MmsSmsTable db = SignalDatabase.mmsSms();
|
|
||||||
List<MessageRecord> records = new ArrayList<>(length);
|
List<MessageRecord> records = new ArrayList<>(length);
|
||||||
MentionHelper mentionHelper = new MentionHelper();
|
MentionHelper mentionHelper = new MentionHelper();
|
||||||
QuotedHelper quotedHelper = new QuotedHelper();
|
QuotedHelper quotedHelper = new QuotedHelper();
|
||||||
|
@ -104,7 +102,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
||||||
CallHelper callHelper = new CallHelper();
|
CallHelper callHelper = new CallHelper();
|
||||||
Set<ServiceId> referencedIds = new HashSet<>();
|
Set<ServiceId> referencedIds = new HashSet<>();
|
||||||
|
|
||||||
try (MessageTable.Reader reader = MessageTable.mmsReaderFor(db.getConversation(threadId, start, length))) {
|
try (MessageTable.Reader reader = MessageTable.mmsReaderFor(SignalDatabase.messages().getConversation(threadId, start, length))) {
|
||||||
MessageRecord record;
|
MessageRecord record;
|
||||||
while ((record = reader.getNext()) != null && !cancellationSignal.isCanceled()) {
|
while ((record = reader.getNext()) != null && !cancellationSignal.isCanceled()) {
|
||||||
records.add(record);
|
records.add(record);
|
||||||
|
@ -144,7 +142,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
||||||
records = reactionHelper.buildUpdatedModels(records);
|
records = reactionHelper.buildUpdatedModels(records);
|
||||||
stopwatch.split("reaction-models");
|
stopwatch.split("reaction-models");
|
||||||
|
|
||||||
attachmentHelper.fetchAttachments(context);
|
attachmentHelper.fetchAttachments();
|
||||||
stopwatch.split("attachments");
|
stopwatch.split("attachments");
|
||||||
|
|
||||||
records = attachmentHelper.buildUpdatedModels(context, records);
|
records = attachmentHelper.buildUpdatedModels(context, records);
|
||||||
|
@ -274,22 +272,28 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AttachmentHelper {
|
public static class AttachmentHelper {
|
||||||
|
|
||||||
private Collection<Long> messageIds = new LinkedList<>();
|
private Collection<Long> messageIds = new LinkedList<>();
|
||||||
private Map<Long, List<DatabaseAttachment>> messageIdToAttachments = new HashMap<>();
|
private Map<Long, List<DatabaseAttachment>> messageIdToAttachments = new HashMap<>();
|
||||||
|
|
||||||
void add(MessageRecord record) {
|
public void add(MessageRecord record) {
|
||||||
if (record.isMms()) {
|
if (record.isMms()) {
|
||||||
messageIds.add(record.getId());
|
messageIds.add(record.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchAttachments(Context context) {
|
public void addAll(List<MessageRecord> records) {
|
||||||
|
for (MessageRecord record : records) {
|
||||||
|
add(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchAttachments() {
|
||||||
messageIdToAttachments = SignalDatabase.attachments().getAttachmentsForMessages(messageIds);
|
messageIdToAttachments = SignalDatabase.attachments().getAttachmentsForMessages(messageIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull List<MessageRecord> buildUpdatedModels(@NonNull Context context, @NonNull List<MessageRecord> records) {
|
public @NonNull List<MessageRecord> buildUpdatedModels(@NonNull Context context, @NonNull List<MessageRecord> records) {
|
||||||
return records.stream()
|
return records.stream()
|
||||||
.map(record -> {
|
.map(record -> {
|
||||||
if (record instanceof MediaMmsMessageRecord) {
|
if (record instanceof MediaMmsMessageRecord) {
|
||||||
|
|
|
@ -179,6 +179,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.database.ThreadTable;
|
import org.thoughtcrime.securesms.database.ThreadTable;
|
||||||
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
||||||
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
||||||
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.Mention;
|
import org.thoughtcrime.securesms.database.model.Mention;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
|
@ -4185,11 +4186,15 @@ public class ConversationParentFragment extends Fragment
|
||||||
|
|
||||||
Context context = ApplicationDependencies.getApplication();
|
Context context = ApplicationDependencies.getApplication();
|
||||||
|
|
||||||
MessageRecord messageRecord = SignalDatabase.mmsSms().getMessageFor(quoteId.getId(), quoteId.getAuthor());
|
MessageRecord messageRecord = SignalDatabase.messages().getMessageFor(quoteId.getId(), quoteId.getAuthor());
|
||||||
if (messageRecord == null) {
|
if (messageRecord == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (messageRecord instanceof MediaMmsMessageRecord) {
|
||||||
|
messageRecord = ((MediaMmsMessageRecord) messageRecord).withAttachments(context, SignalDatabase.attachments().getAttachmentsForMessage(messageRecord.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
return ConversationMessageFactory.createWithUnresolvedData(context, messageRecord);
|
return ConversationMessageFactory.createWithUnresolvedData(context, messageRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,14 +54,21 @@ class MessageQuotesRepository {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val replyRecords: List<MessageRecord> = SignalDatabase.mmsSms.getAllMessagesThatQuote(rootMessageId)
|
var replyRecords: List<MessageRecord> = SignalDatabase.messages.getAllMessagesThatQuote(rootMessageId)
|
||||||
|
|
||||||
val replies: List<ConversationMessage> = ConversationDataSource.ReactionHelper()
|
val reactionHelper = ConversationDataSource.ReactionHelper()
|
||||||
.apply {
|
val attachmentHelper = ConversationDataSource.AttachmentHelper()
|
||||||
addAll(replyRecords)
|
|
||||||
fetchReactions()
|
reactionHelper.addAll(replyRecords)
|
||||||
}
|
attachmentHelper.addAll(replyRecords)
|
||||||
.buildUpdatedModels(replyRecords)
|
|
||||||
|
reactionHelper.fetchReactions()
|
||||||
|
attachmentHelper.fetchAttachments()
|
||||||
|
|
||||||
|
replyRecords = reactionHelper.buildUpdatedModels(replyRecords)
|
||||||
|
replyRecords = attachmentHelper.buildUpdatedModels(ApplicationDependencies.getApplication(), replyRecords)
|
||||||
|
|
||||||
|
val replies: List<ConversationMessage> = replyRecords
|
||||||
.map { replyRecord ->
|
.map { replyRecord ->
|
||||||
val replyQuote: Quote? = replyRecord.getQuote()
|
val replyQuote: Quote? = replyRecord.getQuote()
|
||||||
if (replyQuote != null && replyQuote.id == originalRecord!!.dateSent) {
|
if (replyQuote != null && replyQuote.id == originalRecord!!.dateSent) {
|
||||||
|
@ -76,13 +83,23 @@ class MessageQuotesRepository {
|
||||||
originalRecord = SignalDatabase.payments.updateMessageWithPayment(originalRecord)
|
originalRecord = SignalDatabase.payments.updateMessageWithPayment(originalRecord)
|
||||||
}
|
}
|
||||||
|
|
||||||
val originalMessage: List<ConversationMessage> = ConversationDataSource.ReactionHelper()
|
originalRecord = ConversationDataSource.ReactionHelper()
|
||||||
.apply {
|
.apply {
|
||||||
add(originalRecord)
|
add(originalRecord)
|
||||||
fetchReactions()
|
fetchReactions()
|
||||||
}
|
}
|
||||||
.buildUpdatedModels(listOf(originalRecord))
|
.buildUpdatedModels(listOf(originalRecord))
|
||||||
.map { ConversationMessageFactory.createWithUnresolvedData(application, it, it.getDisplayBody(application), false) }
|
.get(0)
|
||||||
|
|
||||||
|
originalRecord = ConversationDataSource.AttachmentHelper()
|
||||||
|
.apply {
|
||||||
|
add(originalRecord)
|
||||||
|
fetchAttachments()
|
||||||
|
}
|
||||||
|
.buildUpdatedModels(ApplicationDependencies.getApplication(), listOf(originalRecord))
|
||||||
|
.get(0)
|
||||||
|
|
||||||
|
val originalMessage: ConversationMessage = ConversationMessageFactory.createWithUnresolvedData(application, originalRecord, originalRecord.getDisplayBody(application), false)
|
||||||
|
|
||||||
return replies + originalMessage
|
return replies + originalMessage
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ import org.thoughtcrime.securesms.mms.MmsException;
|
||||||
import org.thoughtcrime.securesms.mms.OutgoingMessage;
|
import org.thoughtcrime.securesms.mms.OutgoingMessage;
|
||||||
import org.thoughtcrime.securesms.mms.QuoteModel;
|
import org.thoughtcrime.securesms.mms.QuoteModel;
|
||||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
|
import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo;
|
import org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo;
|
||||||
|
@ -3267,7 +3268,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
db.beginTransaction();
|
db.beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
try (MessageTable.Reader reader = MessageTable.mmsReaderFor(SignalDatabase.mmsSms().getConversation(threadId, 0, 2))) {
|
try (MessageTable.Reader reader = MessageTable.mmsReaderFor(getConversation(threadId, 0, 2))) {
|
||||||
MessageRecord latestMessage = reader.getNext();
|
MessageRecord latestMessage = reader.getNext();
|
||||||
if (latestMessage != null && latestMessage.isGroupV2()) {
|
if (latestMessage != null && latestMessage.isGroupV2()) {
|
||||||
Optional<ByteString> changeEditor = message.getChangeEditor();
|
Optional<ByteString> changeEditor = message.getChangeEditor();
|
||||||
|
@ -3694,6 +3695,41 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<MessageRecord> getAllMessagesThatQuote(@NonNull MessageId id) {
|
||||||
|
MessageRecord targetMessage;
|
||||||
|
try {
|
||||||
|
targetMessage = getMessageRecord(id.getId());
|
||||||
|
} catch (NoSuchMessageException e) {
|
||||||
|
throw new IllegalArgumentException("Invalid message ID!");
|
||||||
|
}
|
||||||
|
|
||||||
|
RecipientId author = targetMessage.isOutgoing() ? Recipient.self().getId() : targetMessage.getRecipient().getId();
|
||||||
|
String query = QUOTE_ID + " = " + targetMessage.getDateSent() + " AND " + QUOTE_AUTHOR + " = " + author.serialize();
|
||||||
|
String order = DATE_RECEIVED + " DESC";
|
||||||
|
|
||||||
|
List<MessageRecord> records = new ArrayList<>();
|
||||||
|
|
||||||
|
try (Reader reader = new MmsReader(getReadableDatabase().query(TABLE_NAME, MMS_PROJECTION, query, null, null, null, order))) {
|
||||||
|
MessageRecord record;
|
||||||
|
while ((record = reader.getNext()) != null) {
|
||||||
|
records.add(record);
|
||||||
|
records.addAll(getAllMessagesThatQuote(new MessageId(record.getId())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(records, (lhs, rhs) -> {
|
||||||
|
if (lhs.getDateReceived() > rhs.getDateReceived()) {
|
||||||
|
return -1;
|
||||||
|
} else if (lhs.getDateReceived() < rhs.getDateReceived()) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) {
|
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) {
|
||||||
String[] projection = new String[]{ DATE_SENT, RECIPIENT_ID, REMOTE_DELETED};
|
String[] projection = new String[]{ DATE_SENT, RECIPIENT_ID, REMOTE_DELETED};
|
||||||
String order = DATE_RECEIVED + " DESC";
|
String order = DATE_RECEIVED + " DESC";
|
||||||
|
@ -3748,7 +3784,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the position of the message with the provided timestamp in the query results you'd
|
* Retrieves the position of the message with the provided timestamp in the query results you'd
|
||||||
* get from calling {@link MmsSmsTable#getConversation(long)}.
|
* get from calling {@link #getConversation(long)}.
|
||||||
*
|
*
|
||||||
* Note: This could give back incorrect results in the situation where multiple messages have the
|
* Note: This could give back incorrect results in the situation where multiple messages have the
|
||||||
* same received timestamp. However, because this was designed to determine where to scroll to,
|
* same received timestamp. However, because this was designed to determine where to scroll to,
|
||||||
|
@ -4275,6 +4311,85 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
return new TimestampReadResult(expiring, threads);
|
return new TimestampReadResult(expiring, threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a message by timestamp+author.
|
||||||
|
* Does *not* include attachments.
|
||||||
|
*/
|
||||||
|
public @Nullable MessageRecord getMessageFor(long timestamp, RecipientId authorId) {
|
||||||
|
Recipient author = Recipient.resolved(authorId);
|
||||||
|
|
||||||
|
String query = DATE_SENT + " = ?";
|
||||||
|
String[] args = SqlUtil.buildArgs(timestamp);
|
||||||
|
|
||||||
|
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, MMS_PROJECTION, query, args, null, null, null)) {
|
||||||
|
MessageTable.Reader reader = MessageTable.mmsReaderFor(cursor);
|
||||||
|
|
||||||
|
MessageRecord messageRecord;
|
||||||
|
|
||||||
|
while ((messageRecord = reader.getNext()) != null) {
|
||||||
|
if ((author.isSelf() && messageRecord.isOutgoing()) ||
|
||||||
|
(!author.isSelf() && messageRecord.getIndividualRecipient().getId().equals(authorId)))
|
||||||
|
{
|
||||||
|
return messageRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cursor containing all of the messages in a given thread, in the proper order.
|
||||||
|
* This does *not* have attachments in it.
|
||||||
|
*/
|
||||||
|
public Cursor getConversation(long threadId) {
|
||||||
|
return getConversation(threadId, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cursor containing all of the messages in a given thread, in the proper order, respecting offset/limit.
|
||||||
|
* This does *not* have attachments in it.
|
||||||
|
*/
|
||||||
|
public Cursor getConversation(long threadId, long offset, long limit) {
|
||||||
|
String selection = THREAD_ID + " = ? AND " + STORY_TYPE + " = ? AND " + PARENT_STORY_ID + " <= ?";
|
||||||
|
String[] args = SqlUtil.buildArgs(threadId, 0, 0);
|
||||||
|
String order = DATE_RECEIVED + " DESC";
|
||||||
|
String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null;
|
||||||
|
|
||||||
|
return getReadableDatabase().query(TABLE_NAME, MMS_PROJECTION, selection, args, null, null, order, limitStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cursor getMessagesForNotificationState(Collection<DefaultMessageNotifier.StickyThread> stickyThreads) {
|
||||||
|
StringBuilder stickyQuery = new StringBuilder();
|
||||||
|
for (DefaultMessageNotifier.StickyThread stickyThread : stickyThreads) {
|
||||||
|
if (stickyQuery.length() > 0) {
|
||||||
|
stickyQuery.append(" OR ");
|
||||||
|
}
|
||||||
|
stickyQuery.append("(")
|
||||||
|
.append(MessageTable.THREAD_ID + " = ")
|
||||||
|
.append(stickyThread.getConversationId().getThreadId())
|
||||||
|
.append(" AND ")
|
||||||
|
.append(MessageTable.DATE_RECEIVED)
|
||||||
|
.append(" >= ")
|
||||||
|
.append(stickyThread.getEarliestTimestamp())
|
||||||
|
.append(getStickyWherePartForParentStoryId(stickyThread.getConversationId().getGroupStoryId()))
|
||||||
|
.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
String order = MessageTable.DATE_RECEIVED + " ASC";
|
||||||
|
String selection = MessageTable.NOTIFIED + " = 0 AND " + MessageTable.STORY_TYPE + " = 0 AND (" + MessageTable.READ + " = 0 OR " + MessageTable.REACTIONS_UNREAD + " = 1" + (stickyQuery.length() > 0 ? " OR (" + stickyQuery + ")" : "") + ")";
|
||||||
|
|
||||||
|
return getReadableDatabase().query(TABLE_NAME, MMS_PROJECTION, selection, null, null, null, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NonNull String getStickyWherePartForParentStoryId(@Nullable Long parentStoryId) {
|
||||||
|
if (parentStoryId == null) {
|
||||||
|
return " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return " AND " + MessageTable.PARENT_STORY_ID + " = " + parentStoryId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remapRecipient(@NonNull RecipientId fromId, @NonNull RecipientId toId) {
|
public void remapRecipient(@NonNull RecipientId fromId, @NonNull RecipientId toId) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
|
|
@ -1,253 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2011 Whisper Systems
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.thoughtcrime.securesms.database;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import net.zetetic.database.sqlcipher.SQLiteQueryBuilder;
|
|
||||||
|
|
||||||
import org.signal.core.util.SqlUtil;
|
|
||||||
import org.signal.core.util.logging.Log;
|
|
||||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
|
||||||
import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier;
|
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MmsSmsTable extends DatabaseTable {
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static final String TAG = Log.tag(MmsSmsTable.class);
|
|
||||||
|
|
||||||
private static final String[] PROJECTION = { MessageTable.TABLE_NAME + "." + MessageTable.ID + " AS " + MessageTable.ID,
|
|
||||||
MessageTable.BODY,
|
|
||||||
MessageTable.TYPE,
|
|
||||||
MessageTable.THREAD_ID,
|
|
||||||
MessageTable.RECIPIENT_ID,
|
|
||||||
MessageTable.RECIPIENT_DEVICE_ID,
|
|
||||||
MessageTable.DATE_SENT,
|
|
||||||
MessageTable.DATE_RECEIVED,
|
|
||||||
MessageTable.DATE_SERVER,
|
|
||||||
MessageTable.MMS_MESSAGE_TYPE,
|
|
||||||
MessageTable.UNIDENTIFIED,
|
|
||||||
MessageTable.MMS_CONTENT_LOCATION,
|
|
||||||
MessageTable.MMS_TRANSACTION_ID,
|
|
||||||
MessageTable.MMS_MESSAGE_SIZE,
|
|
||||||
MessageTable.MMS_EXPIRY,
|
|
||||||
MessageTable.MMS_STATUS,
|
|
||||||
MessageTable.DELIVERY_RECEIPT_COUNT,
|
|
||||||
MessageTable.READ_RECEIPT_COUNT,
|
|
||||||
MessageTable.MISMATCHED_IDENTITIES,
|
|
||||||
MessageTable.NETWORK_FAILURES,
|
|
||||||
MessageTable.SMS_SUBSCRIPTION_ID,
|
|
||||||
MessageTable.EXPIRES_IN,
|
|
||||||
MessageTable.EXPIRE_STARTED,
|
|
||||||
MessageTable.NOTIFIED,
|
|
||||||
MessageTable.QUOTE_ID,
|
|
||||||
MessageTable.QUOTE_AUTHOR,
|
|
||||||
MessageTable.QUOTE_BODY,
|
|
||||||
MessageTable.QUOTE_MISSING,
|
|
||||||
MessageTable.QUOTE_TYPE,
|
|
||||||
MessageTable.QUOTE_MENTIONS,
|
|
||||||
MessageTable.SHARED_CONTACTS,
|
|
||||||
MessageTable.LINK_PREVIEWS,
|
|
||||||
MessageTable.VIEW_ONCE,
|
|
||||||
MessageTable.READ,
|
|
||||||
MessageTable.REACTIONS_UNREAD,
|
|
||||||
MessageTable.REACTIONS_LAST_SEEN,
|
|
||||||
MessageTable.REMOTE_DELETED,
|
|
||||||
MessageTable.MENTIONS_SELF,
|
|
||||||
MessageTable.NOTIFIED_TIMESTAMP,
|
|
||||||
MessageTable.VIEWED_RECEIPT_COUNT,
|
|
||||||
MessageTable.RECEIPT_TIMESTAMP,
|
|
||||||
MessageTable.MESSAGE_RANGES,
|
|
||||||
MessageTable.STORY_TYPE,
|
|
||||||
MessageTable.PARENT_STORY_ID};
|
|
||||||
|
|
||||||
public MmsSmsTable(Context context, SignalDatabase databaseHelper) {
|
|
||||||
super(context, databaseHelper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable MessageRecord getMessageFor(long timestamp, RecipientId authorId) {
|
|
||||||
Recipient author = Recipient.resolved(authorId);
|
|
||||||
|
|
||||||
try (Cursor cursor = queryTables(PROJECTION, MessageTable.DATE_SENT + " = " + timestamp, null, null, true)) {
|
|
||||||
MessageTable.Reader reader = MessageTable.mmsReaderFor(cursor);
|
|
||||||
|
|
||||||
MessageRecord messageRecord;
|
|
||||||
|
|
||||||
while ((messageRecord = reader.getNext()) != null) {
|
|
||||||
if ((author.isSelf() && messageRecord.isOutgoing()) ||
|
|
||||||
(!author.isSelf() && messageRecord.getIndividualRecipient().getId().equals(authorId)))
|
|
||||||
{
|
|
||||||
return messageRecord;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cursor getConversation(long threadId, long offset, long limit) {
|
|
||||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
|
||||||
String order = MessageTable.DATE_RECEIVED + " DESC";
|
|
||||||
String selection = MessageTable.THREAD_ID + " = " + threadId + " AND " + MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
|
||||||
String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null;
|
|
||||||
String query = buildQuery(PROJECTION, selection, order, limitStr, false);
|
|
||||||
|
|
||||||
return db.rawQuery(query, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cursor getConversation(long threadId) {
|
|
||||||
return getConversation(threadId, 0, 0);
|
|
||||||
}
|
|
||||||
public Cursor getMessagesForNotificationState(Collection<DefaultMessageNotifier.StickyThread> stickyThreads) {
|
|
||||||
StringBuilder stickyQuery = new StringBuilder();
|
|
||||||
for (DefaultMessageNotifier.StickyThread stickyThread : stickyThreads) {
|
|
||||||
if (stickyQuery.length() > 0) {
|
|
||||||
stickyQuery.append(" OR ");
|
|
||||||
}
|
|
||||||
stickyQuery.append("(")
|
|
||||||
.append(MessageTable.THREAD_ID + " = ")
|
|
||||||
.append(stickyThread.getConversationId().getThreadId())
|
|
||||||
.append(" AND ")
|
|
||||||
.append(MessageTable.DATE_RECEIVED)
|
|
||||||
.append(" >= ")
|
|
||||||
.append(stickyThread.getEarliestTimestamp())
|
|
||||||
.append(getStickyWherePartForParentStoryId(stickyThread.getConversationId().getGroupStoryId()))
|
|
||||||
.append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
String order = MessageTable.DATE_RECEIVED + " ASC";
|
|
||||||
String selection = MessageTable.NOTIFIED + " = 0 AND " + MessageTable.STORY_TYPE + " = 0 AND (" + MessageTable.READ + " = 0 OR " + MessageTable.REACTIONS_UNREAD + " = 1" + (stickyQuery.length() > 0 ? " OR (" + stickyQuery + ")" : "") + ")";
|
|
||||||
|
|
||||||
return queryTables(PROJECTION, selection, order, null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MessageRecord> getAllMessagesThatQuote(@NonNull MessageId id) {
|
|
||||||
MessageRecord targetMessage;
|
|
||||||
try {
|
|
||||||
targetMessage = SignalDatabase.messages().getMessageRecord(id.getId());
|
|
||||||
} catch (NoSuchMessageException e) {
|
|
||||||
throw new IllegalArgumentException("Invalid message ID!");
|
|
||||||
}
|
|
||||||
|
|
||||||
RecipientId author = targetMessage.isOutgoing() ? Recipient.self().getId() : targetMessage.getRecipient().getId();
|
|
||||||
String query = MessageTable.QUOTE_ID + " = " + targetMessage.getDateSent() + " AND " + MessageTable.QUOTE_AUTHOR + " = " + author.serialize();
|
|
||||||
String order = MessageTable.DATE_RECEIVED + " DESC";
|
|
||||||
|
|
||||||
List<MessageRecord> records = new ArrayList<>();
|
|
||||||
|
|
||||||
try (MessageTable.Reader reader = new MessageTable.MmsReader(queryTables(PROJECTION, query, order, null, true))) {
|
|
||||||
MessageRecord record;
|
|
||||||
while ((record = reader.getNext()) != null) {
|
|
||||||
records.add(record);
|
|
||||||
records.addAll(getAllMessagesThatQuote(new MessageId(record.getId())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(records, (lhs, rhs) -> {
|
|
||||||
if (lhs.getDateReceived() > rhs.getDateReceived()) {
|
|
||||||
return -1;
|
|
||||||
} else if (lhs.getDateReceived() < rhs.getDateReceived()) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return records;
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NonNull String getStickyWherePartForParentStoryId(@Nullable Long parentStoryId) {
|
|
||||||
if (parentStoryId == null) {
|
|
||||||
return " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
|
||||||
}
|
|
||||||
|
|
||||||
return " AND " + MessageTable.PARENT_STORY_ID + " = " + parentStoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @NonNull String buildQuery(String[] projection, String selection, String order, String limit, boolean includeAttachments) {
|
|
||||||
String attachmentJsonJoin;
|
|
||||||
if (includeAttachments) {
|
|
||||||
attachmentJsonJoin = "json_group_array(json_object(" + "'" + AttachmentTable.ROW_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.ROW_ID + ", " +
|
|
||||||
"'" + AttachmentTable.UNIQUE_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.UNIQUE_ID + ", " +
|
|
||||||
"'" + AttachmentTable.MMS_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.MMS_ID + "," +
|
|
||||||
"'" + AttachmentTable.SIZE + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.SIZE + ", " +
|
|
||||||
"'" + AttachmentTable.FILE_NAME + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.FILE_NAME + ", " +
|
|
||||||
"'" + AttachmentTable.DATA + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.DATA + ", " +
|
|
||||||
"'" + AttachmentTable.CONTENT_TYPE + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.CONTENT_TYPE + ", " +
|
|
||||||
"'" + AttachmentTable.CDN_NUMBER + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.CDN_NUMBER + ", " +
|
|
||||||
"'" + AttachmentTable.CONTENT_LOCATION + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.CONTENT_LOCATION + ", " +
|
|
||||||
"'" + AttachmentTable.FAST_PREFLIGHT_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.FAST_PREFLIGHT_ID + ", " +
|
|
||||||
"'" + AttachmentTable.VOICE_NOTE + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.VOICE_NOTE + ", " +
|
|
||||||
"'" + AttachmentTable.BORDERLESS + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.BORDERLESS + ", " +
|
|
||||||
"'" + AttachmentTable.VIDEO_GIF + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.VIDEO_GIF + ", " +
|
|
||||||
"'" + AttachmentTable.WIDTH + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.WIDTH + ", " +
|
|
||||||
"'" + AttachmentTable.HEIGHT + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.HEIGHT + ", " +
|
|
||||||
"'" + AttachmentTable.QUOTE + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.QUOTE + ", " +
|
|
||||||
"'" + AttachmentTable.CONTENT_DISPOSITION + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.CONTENT_DISPOSITION + ", " +
|
|
||||||
"'" + AttachmentTable.NAME + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.NAME + ", " +
|
|
||||||
"'" + AttachmentTable.TRANSFER_STATE + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.TRANSFER_STATE + ", " +
|
|
||||||
"'" + AttachmentTable.CAPTION + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.CAPTION + ", " +
|
|
||||||
"'" + AttachmentTable.STICKER_PACK_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.STICKER_PACK_ID + ", " +
|
|
||||||
"'" + AttachmentTable.STICKER_PACK_KEY + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.STICKER_PACK_KEY + ", " +
|
|
||||||
"'" + AttachmentTable.STICKER_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.STICKER_ID + ", " +
|
|
||||||
"'" + AttachmentTable.STICKER_EMOJI + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.STICKER_EMOJI + ", " +
|
|
||||||
"'" + AttachmentTable.VISUAL_HASH + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.VISUAL_HASH + ", " +
|
|
||||||
"'" + AttachmentTable.TRANSFORM_PROPERTIES + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.TRANSFORM_PROPERTIES + ", " +
|
|
||||||
"'" + AttachmentTable.DISPLAY_ORDER + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.DISPLAY_ORDER + ", " +
|
|
||||||
"'" + AttachmentTable.UPLOAD_TIMESTAMP + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.UPLOAD_TIMESTAMP + "))";
|
|
||||||
} else {
|
|
||||||
attachmentJsonJoin = "NULL";
|
|
||||||
}
|
|
||||||
|
|
||||||
projection = SqlUtil.appendArg(projection, attachmentJsonJoin + " AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS);
|
|
||||||
|
|
||||||
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
|
|
||||||
|
|
||||||
if (includeAttachments) {
|
|
||||||
mmsQueryBuilder.setDistinct(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeAttachments) {
|
|
||||||
mmsQueryBuilder.setTables(MessageTable.TABLE_NAME + " LEFT OUTER JOIN " + AttachmentTable.TABLE_NAME +
|
|
||||||
" ON " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.MMS_ID + " = " + MessageTable.TABLE_NAME + "." + MessageTable.ID);
|
|
||||||
} else {
|
|
||||||
mmsQueryBuilder.setTables(MessageTable.TABLE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
String mmsGroupBy = includeAttachments ? MessageTable.TABLE_NAME + "." + MessageTable.ID : null;
|
|
||||||
|
|
||||||
return mmsQueryBuilder.buildQuery(projection, selection, null, mmsGroupBy, null, order, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cursor queryTables(String[] projection, String selection, String order, String limit, boolean includeAttachments) {
|
|
||||||
String query = buildQuery(projection, selection, order, limit, includeAttachments);
|
|
||||||
|
|
||||||
return databaseHelper.getSignalReadableDatabase().rawQuery(query, null);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -42,7 +42,6 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
|
||||||
val attachmentTable: AttachmentTable = AttachmentTable(context, this, attachmentSecret)
|
val attachmentTable: AttachmentTable = AttachmentTable(context, this, attachmentSecret)
|
||||||
val mediaTable: MediaTable = MediaTable(context, this)
|
val mediaTable: MediaTable = MediaTable(context, this)
|
||||||
val threadTable: ThreadTable = ThreadTable(context, this)
|
val threadTable: ThreadTable = ThreadTable(context, this)
|
||||||
val mmsSmsTable: MmsSmsTable = MmsSmsTable(context, this)
|
|
||||||
val identityTable: IdentityTable = IdentityTable(context, this)
|
val identityTable: IdentityTable = IdentityTable(context, this)
|
||||||
val draftTable: DraftTable = DraftTable(context, this)
|
val draftTable: DraftTable = DraftTable(context, this)
|
||||||
val pushTable: PushTable = PushTable(context, this)
|
val pushTable: PushTable = PushTable(context, this)
|
||||||
|
@ -431,11 +430,6 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
|
||||||
val messageSearch: SearchTable
|
val messageSearch: SearchTable
|
||||||
get() = instance!!.searchTable
|
get() = instance!!.searchTable
|
||||||
|
|
||||||
@get:JvmStatic
|
|
||||||
@get:JvmName("mmsSms")
|
|
||||||
val mmsSms: MmsSmsTable
|
|
||||||
get() = instance!!.mmsSmsTable
|
|
||||||
|
|
||||||
@get:JvmStatic
|
@get:JvmStatic
|
||||||
@get:JvmName("notificationProfiles")
|
@get:JvmName("notificationProfiles")
|
||||||
val notificationProfiles: NotificationProfileDatabase
|
val notificationProfiles: NotificationProfileDatabase
|
||||||
|
|
|
@ -35,7 +35,6 @@ import org.thoughtcrime.securesms.database.SignalDatabase.Companion.groupReceipt
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.mentions
|
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.mentions
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.messageLog
|
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.messageLog
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.messages
|
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.messages
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.mmsSms
|
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.recipients
|
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.recipients
|
||||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
|
@ -339,7 +338,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||||
}
|
}
|
||||||
|
|
||||||
val finalTrimBeforeDate = if (length != NO_TRIM_MESSAGE_COUNT_SET && length > 0) {
|
val finalTrimBeforeDate = if (length != NO_TRIM_MESSAGE_COUNT_SET && length > 0) {
|
||||||
mmsSms.getConversation(threadId).use { cursor ->
|
messages.getConversation(threadId).use { cursor ->
|
||||||
if (cursor.count > length) {
|
if (cursor.count > length) {
|
||||||
cursor.moveToPosition(length - 1)
|
cursor.moveToPosition(length - 1)
|
||||||
max(trimBeforeDate, cursor.requireLong(MessageTable.DATE_RECEIVED))
|
max(trimBeforeDate, cursor.requireLong(MessageTable.DATE_RECEIVED))
|
||||||
|
|
|
@ -11,7 +11,6 @@ import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.mms.OutgoingMessage;
|
import org.thoughtcrime.securesms.mms.OutgoingMessage;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.invites;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.jobmanager.migrations;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class PushProcessEarlyMessagesJob private constructor(parameters: Parameters) :
|
||||||
|
|
||||||
override fun onRun() {
|
override fun onRun() {
|
||||||
val earlyIds: List<ServiceMessageId> = ApplicationDependencies.getEarlyMessageCache().allReferencedIds
|
val earlyIds: List<ServiceMessageId> = ApplicationDependencies.getEarlyMessageCache().allReferencedIds
|
||||||
.filter { SignalDatabase.mmsSms.getMessageFor(it.sentTimestamp, it.sender) != null }
|
.filter { SignalDatabase.messages.getMessageFor(it.sentTimestamp, it.sender) != null }
|
||||||
.sortedBy { it.sentTimestamp }
|
.sortedBy { it.sentTimestamp }
|
||||||
|
|
||||||
if (earlyIds.isNotEmpty()) {
|
if (earlyIds.isNotEmpty()) {
|
||||||
|
|
|
@ -15,7 +15,6 @@ import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.components.FullScreenDialogFragment;
|
import org.thoughtcrime.securesms.components.FullScreenDialogFragment;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer;
|
import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackController;
|
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackController;
|
||||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionPlayerHolder;
|
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionPlayerHolder;
|
||||||
|
|
|
@ -10,7 +10,6 @@ import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
||||||
import org.thoughtcrime.securesms.database.GroupTable;
|
import org.thoughtcrime.securesms.database.GroupTable;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
|
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.groups.GroupChangeBusyException;
|
import org.thoughtcrime.securesms.groups.GroupChangeBusyException;
|
||||||
|
|
|
@ -41,7 +41,6 @@ import org.thoughtcrime.securesms.database.GroupReceiptTable.GroupReceiptInfo;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable.InsertResult;
|
import org.thoughtcrime.securesms.database.MessageTable.InsertResult;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
|
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
||||||
import org.thoughtcrime.securesms.database.PaymentTable;
|
import org.thoughtcrime.securesms.database.PaymentTable;
|
||||||
import org.thoughtcrime.securesms.database.PaymentMetaDataUtil;
|
import org.thoughtcrime.securesms.database.PaymentMetaDataUtil;
|
||||||
|
@ -971,7 +970,7 @@ public final class MessageContentProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipient targetAuthor = Recipient.externalPush(reaction.getTargetAuthor());
|
Recipient targetAuthor = Recipient.externalPush(reaction.getTargetAuthor());
|
||||||
MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());
|
MessageRecord targetMessage = SignalDatabase.messages().getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());
|
||||||
|
|
||||||
if (targetMessage == null) {
|
if (targetMessage == null) {
|
||||||
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find matching message! Putting it in the early message cache. timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
|
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find matching message! Putting it in the early message cache. timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
|
||||||
|
@ -1025,7 +1024,7 @@ public final class MessageContentProcessor {
|
||||||
|
|
||||||
SignalServiceDataMessage.RemoteDelete delete = message.getRemoteDelete().get();
|
SignalServiceDataMessage.RemoteDelete delete = message.getRemoteDelete().get();
|
||||||
|
|
||||||
MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(delete.getTargetSentTimestamp(), senderRecipient.getId());
|
MessageRecord targetMessage = SignalDatabase.messages().getMessageFor(delete.getTargetSentTimestamp(), senderRecipient.getId());
|
||||||
|
|
||||||
if (targetMessage != null && RemoteDeleteUtil.isValidReceive(targetMessage, senderRecipient, content.getServerReceivedTimestamp())) {
|
if (targetMessage != null && RemoteDeleteUtil.isValidReceive(targetMessage, senderRecipient, content.getServerReceivedTimestamp())) {
|
||||||
MessageTable db = targetMessage.isMms() ? SignalDatabase.messages() : SignalDatabase.messages();
|
MessageTable db = targetMessage.isMms() ? SignalDatabase.messages() : SignalDatabase.messages();
|
||||||
|
@ -1442,7 +1441,7 @@ public final class MessageContentProcessor {
|
||||||
List<MessageRecord> records = Stream.of(viewedMessages)
|
List<MessageRecord> records = Stream.of(viewedMessages)
|
||||||
.map(message -> {
|
.map(message -> {
|
||||||
RecipientId author = Recipient.externalPush(message.getSender()).getId();
|
RecipientId author = Recipient.externalPush(message.getSender()).getId();
|
||||||
return SignalDatabase.mmsSms().getMessageFor(message.getTimestamp(), author);
|
return SignalDatabase.messages().getMessageFor(message.getTimestamp(), author);
|
||||||
})
|
})
|
||||||
.filter(message -> message != null && message.isMms())
|
.filter(message -> message != null && message.isMms())
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -1475,7 +1474,7 @@ public final class MessageContentProcessor {
|
||||||
|
|
||||||
RecipientId author = Recipient.externalPush(openMessage.getSender()).getId();
|
RecipientId author = Recipient.externalPush(openMessage.getSender()).getId();
|
||||||
long timestamp = openMessage.getTimestamp();
|
long timestamp = openMessage.getTimestamp();
|
||||||
MessageRecord record = SignalDatabase.mmsSms().getMessageFor(timestamp, author);
|
MessageRecord record = SignalDatabase.messages().getMessageFor(timestamp, author);
|
||||||
|
|
||||||
if (record != null && record.isMms()) {
|
if (record != null && record.isMms()) {
|
||||||
SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(record.getId());
|
SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(record.getId());
|
||||||
|
@ -2351,9 +2350,7 @@ public final class MessageContentProcessor {
|
||||||
return threadId;
|
return threadId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleGroupRecipientUpdate(@NonNull SentTranscriptMessage message, long envelopeTimestamp)
|
private void handleGroupRecipientUpdate(@NonNull SentTranscriptMessage message, long envelopeTimestamp) {
|
||||||
throws BadGroupIdException
|
|
||||||
{
|
|
||||||
log(envelopeTimestamp, "Group recipient update.");
|
log(envelopeTimestamp, "Group recipient update.");
|
||||||
|
|
||||||
Recipient recipient = getSyncMessageDestination(message);
|
Recipient recipient = getSyncMessageDestination(message);
|
||||||
|
@ -2363,8 +2360,7 @@ public final class MessageContentProcessor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MmsSmsTable database = SignalDatabase.mmsSms();
|
MessageRecord record = SignalDatabase.messages().getMessageFor(message.getTimestamp(), Recipient.self().getId());
|
||||||
MessageRecord record = database.getMessageFor(message.getTimestamp(), Recipient.self().getId());
|
|
||||||
|
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
warn("Got recipient update for non-existing message! Skipping.");
|
warn("Got recipient update for non-existing message! Skipping.");
|
||||||
|
@ -2911,7 +2907,7 @@ public final class MessageContentProcessor {
|
||||||
MessageId relatedMessage = messageLogEntry.getRelatedMessages().get(0);
|
MessageId relatedMessage = messageLogEntry.getRelatedMessages().get(0);
|
||||||
return SignalDatabase.messages().getMessageRecordOrNull(relatedMessage.getId());
|
return SignalDatabase.messages().getMessageRecordOrNull(relatedMessage.getId());
|
||||||
} else {
|
} else {
|
||||||
return SignalDatabase.mmsSms().getMessageFor(sentTimestamp, Recipient.self().getId());
|
return SignalDatabase.messages().getMessageFor(sentTimestamp, Recipient.self().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2951,7 +2947,7 @@ public final class MessageContentProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
RecipientId author = Recipient.externalPush(quote.get().getAuthor()).getId();
|
RecipientId author = Recipient.externalPush(quote.get().getAuthor()).getId();
|
||||||
MessageRecord message = SignalDatabase.mmsSms().getMessageFor(quote.get().getId(), author);
|
MessageRecord message = SignalDatabase.messages().getMessageFor(quote.get().getId(), author);
|
||||||
|
|
||||||
if (message != null && !message.isRemoteDelete()) {
|
if (message != null && !message.isRemoteDelete()) {
|
||||||
log("Found matching message record...");
|
log("Found matching message record...");
|
||||||
|
@ -2962,6 +2958,10 @@ public final class MessageContentProcessor {
|
||||||
if (message.isMms()) {
|
if (message.isMms()) {
|
||||||
MmsMessageRecord mmsMessage = (MmsMessageRecord) message;
|
MmsMessageRecord mmsMessage = (MmsMessageRecord) message;
|
||||||
|
|
||||||
|
if (mmsMessage instanceof MediaMmsMessageRecord) {
|
||||||
|
mmsMessage = ((MediaMmsMessageRecord) mmsMessage).withAttachments(context, SignalDatabase.attachments().getAttachmentsForMessage(mmsMessage.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
mentions.addAll(SignalDatabase.mentions().getMentionsForMessage(mmsMessage.getId()));
|
mentions.addAll(SignalDatabase.mentions().getMentionsForMessage(mmsMessage.getId()));
|
||||||
|
|
||||||
if (mmsMessage.isViewOnce()) {
|
if (mmsMessage.isViewOnce()) {
|
||||||
|
|
|
@ -7,9 +7,11 @@ import org.thoughtcrime.securesms.database.MessageTable
|
||||||
import org.thoughtcrime.securesms.database.NoSuchMessageException
|
import org.thoughtcrime.securesms.database.NoSuchMessageException
|
||||||
import org.thoughtcrime.securesms.database.RecipientTable
|
import org.thoughtcrime.securesms.database.RecipientTable
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MessageId
|
import org.thoughtcrime.securesms.database.model.MessageId
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.ReactionRecord
|
import org.thoughtcrime.securesms.database.model.ReactionRecord
|
||||||
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
|
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.util.isStoryReaction
|
import org.thoughtcrime.securesms.util.isStoryReaction
|
||||||
|
@ -25,7 +27,7 @@ object NotificationStateProvider {
|
||||||
fun constructNotificationState(stickyThreads: Map<ConversationId, DefaultMessageNotifier.StickyThread>, notificationProfile: NotificationProfile?): NotificationState {
|
fun constructNotificationState(stickyThreads: Map<ConversationId, DefaultMessageNotifier.StickyThread>, notificationProfile: NotificationProfile?): NotificationState {
|
||||||
val messages: MutableList<NotificationMessage> = mutableListOf()
|
val messages: MutableList<NotificationMessage> = mutableListOf()
|
||||||
|
|
||||||
SignalDatabase.mmsSms.getMessagesForNotificationState(stickyThreads.values).use { unreadMessages ->
|
SignalDatabase.messages.getMessagesForNotificationState(stickyThreads.values).use { unreadMessages ->
|
||||||
if (unreadMessages.count == 0) {
|
if (unreadMessages.count == 0) {
|
||||||
return NotificationState.EMPTY
|
return NotificationState.EMPTY
|
||||||
}
|
}
|
||||||
|
@ -50,6 +52,13 @@ object NotificationStateProvider {
|
||||||
SignalDatabase.messages.hasGroupReplyOrReactionInStory(it)
|
SignalDatabase.messages.hasGroupReplyOrReactionInStory(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (record is MediaMmsMessageRecord) {
|
||||||
|
val attachments = SignalDatabase.attachments.getAttachmentsForMessage(record.id)
|
||||||
|
if (attachments.isNotEmpty()) {
|
||||||
|
record = record.withAttachments(ApplicationDependencies.getApplication(), attachments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
messages += NotificationMessage(
|
messages += NotificationMessage(
|
||||||
messageRecord = record,
|
messageRecord = record,
|
||||||
reactions = if (hasUnreadReactions) SignalDatabase.reactions.getReactions(MessageId(record.id)) else emptyList(),
|
reactions = if (hasUnreadReactions) SignalDatabase.reactions.getReactions(MessageId(record.id)) else emptyList(),
|
||||||
|
|
|
@ -36,7 +36,6 @@ import org.thoughtcrime.securesms.contactshare.Contact;
|
||||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
|
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
||||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
|
@ -61,7 +60,6 @@ import org.thoughtcrime.securesms.jobs.IndividualSendJob;
|
||||||
import org.thoughtcrime.securesms.jobs.ReactionSendJob;
|
import org.thoughtcrime.securesms.jobs.ReactionSendJob;
|
||||||
import org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob;
|
import org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob;
|
||||||
import org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob;
|
import org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob;
|
||||||
import org.thoughtcrime.securesms.jobs.SmsSendJob;
|
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||||
import org.thoughtcrime.securesms.mediasend.Media;
|
import org.thoughtcrime.securesms.mediasend.Media;
|
||||||
|
|
|
@ -18,6 +18,7 @@ import com.bumptech.glide.load.resource.SimpleResource
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost
|
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost
|
||||||
|
@ -112,7 +113,13 @@ data class StoryTextPostModel(
|
||||||
override fun handles(source: StoryTextPostModel, options: Options): Boolean = true
|
override fun handles(source: StoryTextPostModel, options: Options): Boolean = true
|
||||||
|
|
||||||
override fun decode(source: StoryTextPostModel, width: Int, height: Int, options: Options): Resource<Bitmap> {
|
override fun decode(source: StoryTextPostModel, width: Int, height: Int, options: Options): Resource<Bitmap> {
|
||||||
val message = SignalDatabase.mmsSms.getMessageFor(source.storySentAtMillis, source.storyAuthor)
|
val message = SignalDatabase.messages.getMessageFor(source.storySentAtMillis, source.storyAuthor).run {
|
||||||
|
if (this is MediaMmsMessageRecord) {
|
||||||
|
this.withAttachments(ApplicationDependencies.getApplication(), SignalDatabase.attachments.getAttachmentsForMessage(this.id))
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
val view = StoryTextPostView(ContextThemeWrapper(ApplicationDependencies.getApplication(), R.style.TextSecure_DarkNoActionBar))
|
val view = StoryTextPostView(ContextThemeWrapper(ApplicationDependencies.getApplication(), R.style.TextSecure_DarkNoActionBar))
|
||||||
val typeface = TypefaceCache.get(
|
val typeface = TypefaceCache.get(
|
||||||
ApplicationDependencies.getApplication(),
|
ApplicationDependencies.getApplication(),
|
||||||
|
|
|
@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.testing.TestDatabaseUtil
|
||||||
@Config(manifest = Config.NONE, application = Application::class)
|
@Config(manifest = Config.NONE, application = Application::class)
|
||||||
class MmsSmsDatabaseTest {
|
class MmsSmsDatabaseTest {
|
||||||
|
|
||||||
private lateinit var mmsSmsTable: MmsSmsTable
|
|
||||||
private lateinit var messageTable: MessageTable
|
private lateinit var messageTable: MessageTable
|
||||||
private lateinit var db: SQLiteDatabase
|
private lateinit var db: SQLiteDatabase
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ class MmsSmsDatabaseTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
db = sqlCipher.writableDatabase
|
db = sqlCipher.writableDatabase
|
||||||
mmsSmsTable = MmsSmsTable(ApplicationProvider.getApplicationContext(), sqlCipher)
|
|
||||||
messageTable = MessageTable(ApplicationProvider.getApplicationContext(), sqlCipher)
|
messageTable = MessageTable(ApplicationProvider.getApplicationContext(), sqlCipher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.jobmanager.migrations;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
||||||
import org.thoughtcrime.securesms.jobs.SendReadReceiptJob;
|
import org.thoughtcrime.securesms.jobs.SendReadReceiptJob;
|
||||||
|
|
Ładowanie…
Reference in New Issue