Migrate most of MmsSmsTable.
This commit is contained in:
parent
f149c0adb9
commit
6cd6073bc7
33 changed files with 884 additions and 1069 deletions
|
@ -24,7 +24,7 @@ class MessageContentProcessor__handleTextMessageTest : MessageContentProcessorTe
|
|||
|
||||
// THEN
|
||||
val record = SignalDatabase.messages.getMessageRecord(1)
|
||||
val threadSize = SignalDatabase.mmsSms.getConversationCount(record.threadId)
|
||||
val threadSize = SignalDatabase.messages.getMessageCountForThread(record.threadId)
|
||||
assertEquals(1, threadSize)
|
||||
|
||||
assertTrue(record.isSecure)
|
||||
|
|
|
@ -80,9 +80,9 @@ class VoiceNoteMediaItemFactory {
|
|||
@Nullable static MediaItem buildMediaItem(@NonNull Context context,
|
||||
@NonNull MessageRecord messageRecord)
|
||||
{
|
||||
int startingPosition = SignalDatabase.mmsSms()
|
||||
.getMessagePositionInConversation(messageRecord.getThreadId(),
|
||||
messageRecord.getDateReceived());
|
||||
int startingPosition = SignalDatabase.messages()
|
||||
.getMessagePositionInConversation(messageRecord.getThreadId(),
|
||||
messageRecord.getDateReceived());
|
||||
|
||||
Recipient threadRecipient = Objects.requireNonNull(SignalDatabase.threads()
|
||||
.getRecipientForThreadId(messageRecord.getThreadId()));
|
||||
|
|
|
@ -267,8 +267,7 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.Playbac
|
|||
@WorkerThread
|
||||
private @NonNull List<MediaItem> loadMediaItemsForConsecutivePlayback(long messageId) {
|
||||
try {
|
||||
List<MessageRecord> recordsAfter = SignalDatabase.mmsSms()
|
||||
.getMessagesAfterVoiceNoteInclusive(messageId, LIMIT);
|
||||
List<MessageRecord> recordsAfter = SignalDatabase.messages().getMessagesAfterVoiceNoteInclusive(messageId, LIMIT);
|
||||
|
||||
return buildFilteredMessageRecordList(recordsAfter).stream()
|
||||
.map(record -> VoiceNoteMediaItemFactory
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
|||
import org.thoughtcrime.securesms.conversation.ConversationData.MessageRequestData;
|
||||
import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory;
|
||||
import org.thoughtcrime.securesms.database.CallTable;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||
|
@ -87,7 +88,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
|||
}
|
||||
}
|
||||
|
||||
return SignalDatabase.mmsSms().getConversationCount(threadId);
|
||||
return SignalDatabase.messages().getMessageCountForThread(threadId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,7 +104,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
|||
CallHelper callHelper = new CallHelper();
|
||||
Set<ServiceId> referencedIds = new HashSet<>();
|
||||
|
||||
try (MmsSmsTable.Reader reader = MmsSmsTable.readerFor(db.getConversation(threadId, start, length))) {
|
||||
try (MessageTable.Reader reader = MessageTable.mmsReaderFor(db.getConversation(threadId, start, length))) {
|
||||
MessageRecord record;
|
||||
while ((record = reader.getNext()) != null && !cancellationSignal.isCanceled()) {
|
||||
records.add(record);
|
||||
|
@ -194,7 +195,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
|||
List<Mention> mentions = SignalDatabase.mentions().getMentionsForMessage(messageId.getId());
|
||||
stopwatch.split("mentions");
|
||||
|
||||
boolean isQuoted = SignalDatabase.mmsSms().isQuoted(record);
|
||||
boolean isQuoted = SignalDatabase.messages().isQuoted(record);
|
||||
stopwatch.split("is-quoted");
|
||||
|
||||
List<ReactionRecord> reactions = SignalDatabase.reactions().getReactions(messageId);
|
||||
|
@ -265,7 +266,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
|
|||
}
|
||||
|
||||
void fetchQuotedState() {
|
||||
hasBeenQuotedIds = SignalDatabase.mmsSms().isQuoted(records);
|
||||
hasBeenQuotedIds = SignalDatabase.messages().isQuoted(records);
|
||||
}
|
||||
|
||||
boolean isQuoted(long id) {
|
||||
|
|
|
@ -1309,7 +1309,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
@SuppressWarnings("CodeBlock2Expr")
|
||||
public void jumpToMessage(@NonNull RecipientId author, long timestamp, @Nullable Runnable onMessageNotFound) {
|
||||
SimpleTask.run(getLifecycle(), () -> {
|
||||
return SignalDatabase.mmsSms().getMessagePositionInConversation(threadId, timestamp, author);
|
||||
return SignalDatabase.messages().getMessagePositionInConversation(threadId, timestamp, author);
|
||||
}, p -> moveToPosition(p + (isTypingIndicatorShowing() ? 1 : 0), onMessageNotFound));
|
||||
}
|
||||
|
||||
|
@ -1453,7 +1453,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
@Override
|
||||
public void jumpToMessage(@NonNull MessageRecord messageRecord) {
|
||||
SimpleTask.run(getLifecycle(), () -> {
|
||||
return SignalDatabase.mmsSms().getMessagePositionInConversation(threadId,
|
||||
return SignalDatabase.messages().getMessagePositionInConversation(threadId,
|
||||
messageRecord.getDateReceived(),
|
||||
messageRecord.isOutgoing() ? Recipient.self().getId() : messageRecord.getRecipient().getId());
|
||||
}, p -> moveToPosition(p + (isTypingIndicatorShowing() ? 1 : 0), () -> {
|
||||
|
@ -1738,9 +1738,9 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
}
|
||||
|
||||
SimpleTask.run(getLifecycle(), () -> {
|
||||
return SignalDatabase.mmsSms().getQuotedMessagePosition(threadId,
|
||||
messageRecord.getQuote().getId(),
|
||||
messageRecord.getQuote().getAuthor());
|
||||
return SignalDatabase.messages().getQuotedMessagePosition(threadId,
|
||||
messageRecord.getQuote().getId(),
|
||||
messageRecord.getQuote().getAuthor());
|
||||
}, p -> moveToPosition(p + (isTypingIndicatorShowing() ? 1 : 0), () -> {
|
||||
Toast.makeText(getContext(), R.string.ConversationFragment_quoted_message_no_longer_available, Toast.LENGTH_SHORT).show();
|
||||
}));
|
||||
|
|
|
@ -186,7 +186,7 @@ public class ConversationMessage {
|
|||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull ConversationMessage createWithUnresolvedData(@NonNull Context context, @NonNull MessageRecord messageRecord, @NonNull CharSequence body) {
|
||||
boolean hasBeenQuoted = SignalDatabase.mmsSms().isQuoted(messageRecord);
|
||||
boolean hasBeenQuoted = SignalDatabase.messages().isQuoted(messageRecord);
|
||||
|
||||
if (messageRecord.isMms()) {
|
||||
List<Mention> mentions = SignalDatabase.mentions().getMentionsForMessage(messageRecord.getId());
|
||||
|
|
|
@ -3889,7 +3889,7 @@ public class ConversationParentFragment extends Fragment
|
|||
|
||||
SimpleTask.run(() -> {
|
||||
//noinspection CodeBlock2Expr
|
||||
return SignalDatabase.mmsSms().checkMessageExists(reactionDelegate.getMessageRecord());
|
||||
return SignalDatabase.messages().checkMessageExists(reactionDelegate.getMessageRecord());
|
||||
}, messageExists -> {
|
||||
if (!messageExists) {
|
||||
reactionDelegate.hide();
|
||||
|
|
|
@ -59,7 +59,7 @@ class ConversationRepository {
|
|||
@WorkerThread
|
||||
public @NonNull ConversationData getConversationData(long threadId, @NonNull Recipient conversationRecipient, int jumpToPosition) {
|
||||
ThreadTable.ConversationMetadata metadata = SignalDatabase.threads().getConversationMetadata(threadId);
|
||||
int threadSize = SignalDatabase.mmsSms().getConversationCount(threadId);
|
||||
int threadSize = SignalDatabase.messages().getMessageCountForThread(threadId);
|
||||
long lastSeen = metadata.getLastSeen();
|
||||
int lastSeenPosition = 0;
|
||||
long lastScrolled = metadata.getLastScrolled();
|
||||
|
@ -69,7 +69,7 @@ class ConversationRepository {
|
|||
boolean showUniversalExpireTimerUpdate = false;
|
||||
|
||||
if (lastSeen > 0) {
|
||||
lastSeenPosition = SignalDatabase.mmsSms().getMessagePositionOnOrAfterTimestamp(threadId, lastSeen);
|
||||
lastSeenPosition = SignalDatabase.messages().getMessagePositionOnOrAfterTimestamp(threadId, lastSeen);
|
||||
}
|
||||
|
||||
if (lastSeenPosition <= 0) {
|
||||
|
@ -77,7 +77,7 @@ class ConversationRepository {
|
|||
}
|
||||
|
||||
if (lastSeen == 0 && lastScrolled > 0) {
|
||||
lastScrolledPosition = SignalDatabase.mmsSms().getMessagePositionOnOrAfterTimestamp(threadId, lastScrolled);
|
||||
lastScrolledPosition = SignalDatabase.messages().getMessagePositionOnOrAfterTimestamp(threadId, lastScrolled);
|
||||
}
|
||||
|
||||
if (!isMessageRequestAccepted) {
|
||||
|
@ -105,7 +105,7 @@ class ConversationRepository {
|
|||
conversationRecipient.getExpiresInSeconds() == 0 &&
|
||||
!conversationRecipient.isGroup() &&
|
||||
conversationRecipient.isRegistered() &&
|
||||
(threadId == -1 || !SignalDatabase.mmsSms().hasMeaningfulMessage(threadId)))
|
||||
(threadId == -1 || !SignalDatabase.messages().hasMeaningfulMessage(threadId)))
|
||||
{
|
||||
showUniversalExpireTimerUpdate = true;
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ class ConversationRepository {
|
|||
|
||||
long threadId = SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId());
|
||||
|
||||
boolean hasUnexportedInsecureMessages = threadId != -1 && SignalDatabase.mmsSms().getUnexportedInsecureMessagesCount(threadId) > 0;
|
||||
boolean hasUnexportedInsecureMessages = threadId != -1 && SignalDatabase.messages().getUnexportedInsecureMessagesCount(threadId) > 0;
|
||||
|
||||
Log.i(TAG, "Returning registered state...");
|
||||
return new ConversationSecurityInfo(recipient.getId(),
|
||||
|
@ -190,7 +190,7 @@ class ConversationRepository {
|
|||
|
||||
return Observable.<Integer> create(emitter -> {
|
||||
|
||||
DatabaseObserver.Observer listener = () -> emitter.onNext(SignalDatabase.mmsSms().getIncomingMeaningfulMessageCountSince(threadId, afterTime));
|
||||
DatabaseObserver.Observer listener = () -> emitter.onNext(SignalDatabase.messages().getIncomingMeaningfulMessageCountSince(threadId, afterTime));
|
||||
|
||||
ApplicationDependencies.getDatabaseObserver().registerConversationObserver(threadId, listener);
|
||||
emitter.setCancellable(() -> ApplicationDependencies.getDatabaseObserver().unregisterObserver(listener));
|
||||
|
|
|
@ -27,7 +27,7 @@ class MessageQuotesRepository {
|
|||
*/
|
||||
fun getMessagesInQuoteChain(application: Application, messageId: MessageId): Observable<List<ConversationMessage>> {
|
||||
return Observable.create { emitter ->
|
||||
val threadId: Long = SignalDatabase.mmsSms.getThreadId(messageId)
|
||||
val threadId: Long = SignalDatabase.messages.getThreadIdForMessage(messageId.id)
|
||||
if (threadId < 0) {
|
||||
Log.w(TAG, "Could not find a threadId for $messageId!")
|
||||
emitter.onNext(emptyList())
|
||||
|
@ -46,7 +46,7 @@ class MessageQuotesRepository {
|
|||
|
||||
@WorkerThread
|
||||
private fun getMessagesInQuoteChainSync(application: Application, messageId: MessageId): List<ConversationMessage> {
|
||||
val rootMessageId: MessageId = SignalDatabase.mmsSms.getRootOfQuoteChain(messageId)
|
||||
val rootMessageId: MessageId = SignalDatabase.messages.getRootOfQuoteChain(messageId)
|
||||
|
||||
var originalRecord: MessageRecord? = SignalDatabase.messages.getMessageRecordOrNull(rootMessageId.id)
|
||||
|
||||
|
|
|
@ -616,7 +616,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
@Override
|
||||
public void onMessageClicked(@NonNull MessageResult message) {
|
||||
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
|
||||
int startingPosition = SignalDatabase.mmsSms().getMessagePositionInConversation(message.getThreadId(), message.getReceivedTimestampMs());
|
||||
int startingPosition = SignalDatabase.messages().getMessagePositionInConversation(message.getThreadId(), message.getReceivedTimestampMs());
|
||||
return Math.max(0, startingPosition);
|
||||
}, startingPosition -> {
|
||||
hideKeyboard();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,51 +16,26 @@
|
|||
*/
|
||||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import net.zetetic.database.sqlcipher.SQLiteQueryBuilder;
|
||||
|
||||
import org.signal.core.util.CursorUtil;
|
||||
import org.signal.core.util.SqlUtil;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.thoughtcrime.securesms.database.MessageTable.MessageUpdate;
|
||||
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.database.model.DisplayRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MessageExportStatus;
|
||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExportState;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MmsSmsTable extends DatabaseTable {
|
||||
|
||||
|
@ -112,61 +87,15 @@ public class MmsSmsTable extends DatabaseTable {
|
|||
MessageTable.STORY_TYPE,
|
||||
MessageTable.PARENT_STORY_ID};
|
||||
|
||||
private static final String SNIPPET_QUERY = "SELECT " + MessageTable.ID + ", " + MessageTable.TYPE + ", " + MessageTable.DATE_RECEIVED + " FROM " + MessageTable.TABLE_NAME + " " +
|
||||
"WHERE " + MessageTable.THREAD_ID + " = ? AND " + MessageTable.TYPE + " & " + MessageTypes.GROUP_V2_LEAVE_BITS + " != " + MessageTypes.GROUP_V2_LEAVE_BITS + " AND " + MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0 " +
|
||||
"ORDER BY " + MessageTable.DATE_RECEIVED + " DESC " +
|
||||
"LIMIT 1";
|
||||
|
||||
public MmsSmsTable(Context context, SignalDatabase databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The user that added you to the group, otherwise null.
|
||||
*/
|
||||
public @Nullable RecipientId getGroupAddedBy(long threadId) {
|
||||
long lastQuitChecked = System.currentTimeMillis();
|
||||
Pair<RecipientId, Long> pair;
|
||||
|
||||
do {
|
||||
pair = getGroupAddedBy(threadId, lastQuitChecked);
|
||||
if (pair.first() != null) {
|
||||
return pair.first();
|
||||
} else {
|
||||
lastQuitChecked = pair.second();
|
||||
}
|
||||
|
||||
} while (pair.second() != -1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private @NonNull Pair<RecipientId, Long> getGroupAddedBy(long threadId, long lastQuitChecked) {
|
||||
long latestQuit = SignalDatabase.messages().getLatestGroupQuitTimestamp(threadId, lastQuitChecked);
|
||||
RecipientId id = SignalDatabase.messages().getOldestGroupUpdateSender(threadId, latestQuit);
|
||||
|
||||
return new Pair<>(id, latestQuit);
|
||||
}
|
||||
|
||||
public int getMessagePositionOnOrAfterTimestamp(long threadId, long timestamp) {
|
||||
String[] projection = new String[] { "COUNT(*)" };
|
||||
String selection = MessageTable.THREAD_ID + " = " + threadId + " AND " +
|
||||
MessageTable.DATE_RECEIVED + " >= " + timestamp + " AND " +
|
||||
MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
||||
|
||||
try (Cursor cursor = queryTables(projection, selection, null, null, false)) {
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return cursor.getInt(0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)) {
|
||||
MmsSmsTable.Reader reader = readerFor(cursor);
|
||||
MessageTable.Reader reader = MessageTable.mmsReaderFor(cursor);
|
||||
|
||||
MessageRecord messageRecord;
|
||||
|
||||
|
@ -182,16 +111,6 @@ public class MmsSmsTable extends DatabaseTable {
|
|||
return null;
|
||||
}
|
||||
|
||||
public @NonNull List<MessageRecord> getMessagesAfterVoiceNoteInclusive(long messageId, long limit) throws NoSuchMessageException {
|
||||
MessageRecord origin = SignalDatabase.messages().getMessageRecord(messageId);
|
||||
List<MessageRecord> mms = SignalDatabase.messages().getMessagesInThreadAfterInclusive(origin.getThreadId(), origin.getDateReceived(), limit);
|
||||
|
||||
Collections.sort(mms, Comparator.comparingLong(DisplayRecord::getDateReceived));
|
||||
|
||||
return Stream.of(mms).limit(limit).toList();
|
||||
}
|
||||
|
||||
|
||||
public Cursor getConversation(long threadId, long offset, long limit) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String order = MessageTable.DATE_RECEIVED + " DESC";
|
||||
|
@ -205,35 +124,6 @@ public class MmsSmsTable extends DatabaseTable {
|
|||
public Cursor getConversation(long threadId) {
|
||||
return getConversation(threadId, 0, 0);
|
||||
}
|
||||
|
||||
public @NonNull MessageRecord getConversationSnippet(long threadId) throws NoSuchMessageException {
|
||||
try (Cursor cursor = getConversationSnippetCursor(threadId)) {
|
||||
if (cursor.moveToFirst()) {
|
||||
long id = CursorUtil.requireLong(cursor, MessageTable.ID);
|
||||
return SignalDatabase.messages().getMessageRecord(id);
|
||||
} else {
|
||||
throw new NoSuchMessageException("no message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@NonNull Cursor getConversationSnippetCursor(long threadId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
return db.rawQuery(SNIPPET_QUERY, SqlUtil.buildArgs(threadId));
|
||||
}
|
||||
|
||||
public long getConversationSnippetType(long threadId) throws NoSuchMessageException {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
try (Cursor cursor = db.rawQuery(SNIPPET_QUERY, SqlUtil.buildArgs(threadId))) {
|
||||
if (cursor.moveToFirst()) {
|
||||
return CursorUtil.requireLong(cursor, MessageTable.TYPE);
|
||||
} else {
|
||||
throw new NoSuchMessageException("no message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Cursor getMessagesForNotificationState(Collection<DefaultMessageNotifier.StickyThread> stickyThreads) {
|
||||
StringBuilder stickyQuery = new StringBuilder();
|
||||
for (DefaultMessageNotifier.StickyThread stickyThread : stickyThreads) {
|
||||
|
@ -257,86 +147,6 @@ public class MmsSmsTable extends DatabaseTable {
|
|||
return queryTables(PROJECTION, selection, order, null, true);
|
||||
}
|
||||
|
||||
public Set<Long> isQuoted(@NonNull Collection<MessageRecord> records) {
|
||||
if (records.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
Map<QuoteDescriptor, MessageRecord> byQuoteDescriptor = new HashMap<>(records.size());
|
||||
List<String[]> args = new ArrayList<>(records.size());
|
||||
|
||||
for (MessageRecord record : records) {
|
||||
long timestamp = record.getDateSent();
|
||||
RecipientId author = record.isOutgoing() ? Recipient.self().getId() : record.getRecipient().getId();
|
||||
|
||||
byQuoteDescriptor.put(new QuoteDescriptor(timestamp, author), record);
|
||||
args.add(SqlUtil.buildArgs(timestamp, author));
|
||||
}
|
||||
|
||||
|
||||
String[] projection = new String[] { MessageTable.QUOTE_ID, MessageTable.QUOTE_AUTHOR };
|
||||
List<SqlUtil.Query> queries = SqlUtil.buildCustomCollectionQuery(MessageTable.QUOTE_ID + " = ? AND " + MessageTable.QUOTE_AUTHOR + " = ?", args);
|
||||
Set<Long> quotedIds = new HashSet<>();
|
||||
|
||||
for (SqlUtil.Query query : queries) {
|
||||
try (Cursor cursor = getReadableDatabase().query(MessageTable.TABLE_NAME, projection, query.getWhere(), query.getWhereArgs(), null, null, null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
long timestamp = CursorUtil.requireLong(cursor, MessageTable.QUOTE_ID);
|
||||
RecipientId author = RecipientId.from(CursorUtil.requireString(cursor, MessageTable.QUOTE_AUTHOR));
|
||||
QuoteDescriptor quoteLocator = new QuoteDescriptor(timestamp, author);
|
||||
|
||||
quotedIds.add(byQuoteDescriptor.get(quoteLocator).getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return quotedIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the message has been quoted by another message.
|
||||
*/
|
||||
public boolean isQuoted(@NonNull MessageRecord messageRecord) {
|
||||
RecipientId author = messageRecord.isOutgoing() ? Recipient.self().getId() : messageRecord.getRecipient().getId();
|
||||
long timestamp = messageRecord.getDateSent();
|
||||
|
||||
String where = MessageTable.QUOTE_ID + " = ? AND " + MessageTable.QUOTE_AUTHOR + " = ?";
|
||||
String[] whereArgs = SqlUtil.buildArgs(timestamp, author);
|
||||
|
||||
try (Cursor cursor = getReadableDatabase().query(MessageTable.TABLE_NAME, new String[]{ "1" }, where, whereArgs, null, null, null, "1")) {
|
||||
return cursor.moveToFirst();
|
||||
}
|
||||
}
|
||||
|
||||
public MessageId getRootOfQuoteChain(@NonNull MessageId id) {
|
||||
MmsMessageRecord targetMessage;
|
||||
try {
|
||||
targetMessage = (MmsMessageRecord) SignalDatabase.messages().getMessageRecord(id.getId());
|
||||
} catch (NoSuchMessageException e) {
|
||||
throw new IllegalArgumentException("Invalid message ID!");
|
||||
}
|
||||
|
||||
if (targetMessage.getQuote() == null) {
|
||||
return id;
|
||||
}
|
||||
|
||||
String query;
|
||||
if (targetMessage.getQuote().getAuthor().equals(Recipient.self().getId())) {
|
||||
query = MessageTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND (" + MessageTable.TYPE + " & " + MessageTypes.BASE_TYPE_MASK + ") = " + MessageTypes.BASE_SENT_TYPE;
|
||||
} else {
|
||||
query = MessageTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND " + MessageTable.RECIPIENT_ID + " = '" + targetMessage.getQuote().getAuthor().serialize() + "'";
|
||||
}
|
||||
|
||||
try (Reader reader = new Reader(queryTables(PROJECTION, query, null, "1", false))) {
|
||||
MessageRecord record;
|
||||
if ((record = reader.getNext()) != null) {
|
||||
return getRootOfQuoteChain(new MessageId(record.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<MessageRecord> getAllMessagesThatQuote(@NonNull MessageId id) {
|
||||
MessageRecord targetMessage;
|
||||
try {
|
||||
|
@ -351,7 +161,7 @@ public class MmsSmsTable extends DatabaseTable {
|
|||
|
||||
List<MessageRecord> records = new ArrayList<>();
|
||||
|
||||
try (Reader reader = new Reader(queryTables(PROJECTION, query, order, null, true))) {
|
||||
try (MessageTable.Reader reader = new MessageTable.MmsReader(queryTables(PROJECTION, query, order, null, true))) {
|
||||
MessageRecord record;
|
||||
while ((record = reader.getNext()) != null) {
|
||||
records.add(record);
|
||||
|
@ -380,508 +190,6 @@ public class MmsSmsTable extends DatabaseTable {
|
|||
return " AND " + MessageTable.PARENT_STORY_ID + " = " + parentStoryId;
|
||||
}
|
||||
|
||||
public int getUnreadCount(long threadId) {
|
||||
String selection = MessageTable.READ + " = 0 AND " + MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.THREAD_ID + " = " + threadId + " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
||||
|
||||
try (Cursor cursor = queryTables(PROJECTION, selection, null, null, false)) {
|
||||
return cursor != null ? cursor.getCount() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkMessageExists(@NonNull MessageRecord messageRecord) {
|
||||
try (Cursor cursor = SignalDatabase.messages().getMessageCursor(messageRecord.getId())) {
|
||||
return cursor != null && cursor.getCount() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSecureConversationCount(long threadId) {
|
||||
if (threadId == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SignalDatabase.messages().getSecureMessageCount(threadId);
|
||||
}
|
||||
|
||||
public int getOutgoingSecureConversationCount(long threadId) {
|
||||
if (threadId == -1L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SignalDatabase.messages().getOutgoingSecureMessageCount(threadId);
|
||||
}
|
||||
|
||||
public int getConversationCount(long threadId) {
|
||||
return SignalDatabase.messages().getMessageCountForThread(threadId);
|
||||
}
|
||||
|
||||
public int getConversationCount(long threadId, long beforeTime) {
|
||||
return SignalDatabase.messages().getMessageCountForThread(threadId, beforeTime);
|
||||
}
|
||||
|
||||
public int getInsecureSentCount(long threadId) {
|
||||
return SignalDatabase.messages().getInsecureMessagesSentForThread(threadId);
|
||||
}
|
||||
|
||||
public int getInsecureMessageCountForInsights() {
|
||||
return SignalDatabase.messages().getInsecureMessageCountForInsights();
|
||||
}
|
||||
|
||||
public int getUnexportedInsecureMessagesCount() {
|
||||
return getUnexportedInsecureMessagesCount(-1);
|
||||
}
|
||||
|
||||
public int getUnexportedInsecureMessagesCount(long threadId) {
|
||||
return SignalDatabase.messages().getUnexportedInsecureMessagesCount(threadId);
|
||||
}
|
||||
|
||||
public int getIncomingMeaningfulMessageCountSince(long threadId, long afterTime) {
|
||||
return SignalDatabase.messages().getIncomingMeaningfulMessageCountSince(threadId, afterTime);
|
||||
}
|
||||
|
||||
public int getMessageCountBeforeDate(long date) {
|
||||
String selection = MessageTable.DATE_RECEIVED + " < " + date;
|
||||
|
||||
try (Cursor cursor = queryTables(new String[] { "COUNT(*)" }, selection, null, null, false)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getSecureMessageCountForInsights() {
|
||||
return SignalDatabase.messages().getSecureMessageCountForInsights();
|
||||
}
|
||||
|
||||
public boolean hasMeaningfulMessage(long threadId) {
|
||||
if (threadId == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return SignalDatabase.messages().hasMeaningfulMessage(threadId);
|
||||
}
|
||||
|
||||
public long getThreadId(MessageId messageId) {
|
||||
return SignalDatabase.messages().getThreadIdForMessage(messageId.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is currently only used in an old migration and shouldn't be used by anyone else, just because it flat-out isn't correct.
|
||||
*/
|
||||
@Deprecated
|
||||
public long getThreadForMessageId(long messageId) {
|
||||
long id = SignalDatabase.messages().getThreadIdForMessage(messageId);
|
||||
|
||||
if (id == -1) return SignalDatabase.messages().getThreadIdForMessage(messageId);
|
||||
else return id;
|
||||
}
|
||||
|
||||
public Collection<SyncMessageId> incrementDeliveryReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp) {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, MessageTable.ReceiptType.DELIVERY);
|
||||
}
|
||||
|
||||
public boolean incrementDeliveryReceiptCount(SyncMessageId syncMessageId, long timestamp) {
|
||||
return incrementReceiptCount(syncMessageId, timestamp, MessageTable.ReceiptType.DELIVERY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A list of ID's that were not updated.
|
||||
*/
|
||||
public @NonNull Collection<SyncMessageId> incrementReadReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp) {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, MessageTable.ReceiptType.READ);
|
||||
}
|
||||
|
||||
public boolean incrementReadReceiptCount(SyncMessageId syncMessageId, long timestamp) {
|
||||
return incrementReceiptCount(syncMessageId, timestamp, MessageTable.ReceiptType.READ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A list of ID's that were not updated.
|
||||
*/
|
||||
public @NonNull Collection<SyncMessageId> incrementViewedReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp) {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, MessageTable.ReceiptType.VIEWED);
|
||||
}
|
||||
|
||||
public @NonNull Collection<SyncMessageId> incrementViewedNonStoryReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp) {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, MessageTable.ReceiptType.VIEWED, MessageTable.MessageQualifier.NORMAL);
|
||||
}
|
||||
|
||||
public boolean incrementViewedReceiptCount(SyncMessageId syncMessageId, long timestamp) {
|
||||
return incrementReceiptCount(syncMessageId, timestamp, MessageTable.ReceiptType.VIEWED);
|
||||
}
|
||||
|
||||
public @NonNull Collection<SyncMessageId> incrementViewedStoryReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
Set<MessageUpdate> messageUpdates = new HashSet<>();
|
||||
Collection<SyncMessageId> unhandled = new HashSet<>();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (SyncMessageId id : syncMessageIds) {
|
||||
Set<MessageUpdate> updates = incrementReceiptCountInternal(id, timestamp, MessageTable.ReceiptType.VIEWED, MessageTable.MessageQualifier.STORY);
|
||||
|
||||
if (updates.size() > 0) {
|
||||
messageUpdates.addAll(updates);
|
||||
} else {
|
||||
unhandled.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
||||
for (MessageUpdate update : messageUpdates) {
|
||||
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(update.getMessageId());
|
||||
ApplicationDependencies.getDatabaseObserver().notifyVerboseConversationListeners(Collections.singleton(update.getThreadId()));
|
||||
}
|
||||
|
||||
if (messageUpdates.size() > 0) {
|
||||
notifyConversationListListeners();
|
||||
}
|
||||
}
|
||||
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a single receipt update in a transaction and triggers the proper updates.
|
||||
*
|
||||
* @return Whether or not some thread was updated.
|
||||
*/
|
||||
private boolean incrementReceiptCount(SyncMessageId syncMessageId, long timestamp, @NonNull MessageTable.ReceiptType receiptType) {
|
||||
return incrementReceiptCount(syncMessageId, timestamp, receiptType, MessageTable.MessageQualifier.ALL);
|
||||
}
|
||||
|
||||
private boolean incrementReceiptCount(SyncMessageId syncMessageId, long timestamp, @NonNull MessageTable.ReceiptType receiptType, @NonNull MessageTable.MessageQualifier messageQualifier) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
ThreadTable threadTable = SignalDatabase.threads();
|
||||
Set<MessageUpdate> messageUpdates = new HashSet<>();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
messageUpdates = incrementReceiptCountInternal(syncMessageId, timestamp, receiptType, messageQualifier);
|
||||
|
||||
for (MessageUpdate messageUpdate : messageUpdates) {
|
||||
threadTable.update(messageUpdate.getThreadId(), false);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
||||
for (MessageUpdate threadUpdate : messageUpdates) {
|
||||
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(threadUpdate.getMessageId());
|
||||
}
|
||||
}
|
||||
|
||||
return messageUpdates.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps multiple receipt updates in a transaction and triggers the proper updates.
|
||||
*
|
||||
* @return All of the messages that didn't result in updates.
|
||||
*/
|
||||
private @NonNull Collection<SyncMessageId> incrementReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp, @NonNull MessageTable.ReceiptType receiptType) {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, receiptType, MessageTable.MessageQualifier.ALL);
|
||||
}
|
||||
|
||||
private @NonNull Collection<SyncMessageId> incrementReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp, @NonNull MessageTable.ReceiptType receiptType, @NonNull MessageTable.MessageQualifier messageQualifier) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
ThreadTable threadTable = SignalDatabase.threads();
|
||||
Set<MessageUpdate> messageUpdates = new HashSet<>();
|
||||
Collection<SyncMessageId> unhandled = new HashSet<>();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (SyncMessageId id : syncMessageIds) {
|
||||
Set<MessageUpdate> updates = incrementReceiptCountInternal(id, timestamp, receiptType, messageQualifier);
|
||||
|
||||
if (updates.size() > 0) {
|
||||
messageUpdates.addAll(updates);
|
||||
} else {
|
||||
unhandled.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
for (MessageUpdate update : messageUpdates) {
|
||||
threadTable.updateSilently(update.getThreadId(), false);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
||||
for (MessageUpdate update : messageUpdates) {
|
||||
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(update.getMessageId());
|
||||
ApplicationDependencies.getDatabaseObserver().notifyVerboseConversationListeners(Collections.singleton(update.getThreadId()));
|
||||
}
|
||||
|
||||
if (messageUpdates.size() > 0) {
|
||||
notifyConversationListListeners();
|
||||
}
|
||||
}
|
||||
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Doesn't do any transactions or updates, so we can re-use the method safely.
|
||||
*/
|
||||
private @NonNull Set<MessageUpdate> incrementReceiptCountInternal(SyncMessageId syncMessageId, long timestamp, MessageTable.ReceiptType receiptType, @NonNull MessageTable.MessageQualifier messageQualifier) {
|
||||
return SignalDatabase.messages().incrementReceiptCount(syncMessageId, timestamp, receiptType, messageQualifier);
|
||||
}
|
||||
|
||||
public void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds) {
|
||||
SignalDatabase.messages().updateViewedStories(syncMessageIds);
|
||||
}
|
||||
|
||||
private @NonNull MessageExportState getMessageExportState(@NonNull MessageId messageId) throws NoSuchMessageException {
|
||||
String table = MessageTable.TABLE_NAME;
|
||||
String[] projection = SqlUtil.buildArgs(MessageTable.EXPORT_STATE);
|
||||
String[] args = SqlUtil.buildArgs(messageId.getId());
|
||||
|
||||
try (Cursor cursor = getReadableDatabase().query(table, projection, ID_WHERE, args, null, null, null, null)) {
|
||||
if (cursor.moveToFirst()) {
|
||||
byte[] bytes = CursorUtil.requireBlob(cursor, MessageTable.EXPORT_STATE);
|
||||
if (bytes == null) {
|
||||
return MessageExportState.getDefaultInstance();
|
||||
} else {
|
||||
try {
|
||||
return MessageExportState.parseFrom(bytes);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
return MessageExportState.getDefaultInstance();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new NoSuchMessageException("The requested message does not exist.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMessageExportState(@NonNull MessageId messageId, @NonNull Function<MessageExportState, MessageExportState> transform) throws NoSuchMessageException {
|
||||
SQLiteDatabase database = getWritableDatabase();
|
||||
|
||||
database.beginTransaction();
|
||||
try {
|
||||
MessageExportState oldState = getMessageExportState(messageId);
|
||||
MessageExportState newState = transform.apply(oldState);
|
||||
|
||||
setMessageExportState(messageId, newState);
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
} finally {
|
||||
database.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public void markMessageExported(@NonNull MessageId messageId) {
|
||||
String table = MessageTable.TABLE_NAME;
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
|
||||
contentValues.put(MessageTable.EXPORTED, MessageExportStatus.EXPORTED.getCode());
|
||||
|
||||
getWritableDatabase().update(table, contentValues, ID_WHERE, SqlUtil.buildArgs(messageId.getId()));
|
||||
}
|
||||
|
||||
public void markMessageExportFailed(@NonNull MessageId messageId) {
|
||||
String table = MessageTable.TABLE_NAME;
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
|
||||
contentValues.put(MessageTable.EXPORTED, MessageExportStatus.ERROR.getCode());
|
||||
|
||||
getWritableDatabase().update(table, contentValues, ID_WHERE, SqlUtil.buildArgs(messageId.getId()));
|
||||
}
|
||||
|
||||
private void setMessageExportState(@NonNull MessageId messageId, @NonNull MessageExportState messageExportState) {
|
||||
String table = MessageTable.TABLE_NAME;
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
|
||||
contentValues.put(MessageTable.EXPORT_STATE, messageExportState.toByteArray());
|
||||
|
||||
getWritableDatabase().update(table, contentValues, ID_WHERE, SqlUtil.buildArgs(messageId.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Unhandled ids
|
||||
*/
|
||||
public Collection<SyncMessageId> setTimestampReadFromSyncMessage(@NonNull List<ReadMessage> readMessages, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
|
||||
List<Pair<Long, Long>> expiringMessages = new LinkedList<>();
|
||||
Set<Long> updatedThreads = new HashSet<>();
|
||||
Collection<SyncMessageId> unhandled = new LinkedList<>();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (ReadMessage readMessage : readMessages) {
|
||||
RecipientId authorId = Recipient.externalPush(readMessage.getSender()).getId();
|
||||
TimestampReadResult result = SignalDatabase.messages().setTimestampReadFromSyncMessage(new SyncMessageId(authorId, readMessage.getTimestamp()),
|
||||
proposedExpireStarted,
|
||||
threadToLatestRead);
|
||||
|
||||
expiringMessages.addAll(result.expiring);
|
||||
updatedThreads.addAll(result.threads);
|
||||
|
||||
if (result.threads.isEmpty()) {
|
||||
unhandled.add(new SyncMessageId(authorId, readMessage.getTimestamp()));
|
||||
}
|
||||
}
|
||||
|
||||
for (long threadId : updatedThreads) {
|
||||
SignalDatabase.threads().updateReadState(threadId);
|
||||
SignalDatabase.threads().setLastSeen(threadId);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
for (Pair<Long, Long> expiringMessage : expiringMessages) {
|
||||
ApplicationDependencies.getExpiringMessageManager()
|
||||
.scheduleDeletion(expiringMessage.first(), true, proposedExpireStarted, expiringMessage.second());
|
||||
}
|
||||
|
||||
for (long threadId : updatedThreads) {
|
||||
notifyConversationListeners(threadId);
|
||||
}
|
||||
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) {
|
||||
String order = MessageTable.DATE_RECEIVED + " DESC";
|
||||
String selection = MessageTable.THREAD_ID + " = " + threadId + " AND " + MessageTable.STORY_TYPE + " = 0" + " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
||||
|
||||
try (Cursor cursor = queryTables(new String[]{ MessageTable.DATE_SENT, MessageTable.RECIPIENT_ID, MessageTable.REMOTE_DELETED}, selection, order, null, false)) {
|
||||
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();
|
||||
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
boolean quoteIdMatches = cursor.getLong(0) == quoteId;
|
||||
boolean recipientIdMatches = recipientId.equals(RecipientId.from(CursorUtil.requireLong(cursor, MessageTable.RECIPIENT_ID)));
|
||||
|
||||
if (quoteIdMatches && (recipientIdMatches || isOwnNumber)) {
|
||||
if (CursorUtil.requireBoolean(cursor, MessageTable.REMOTE_DELETED)) {
|
||||
return -1;
|
||||
} else {
|
||||
return cursor.getPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getMessagePositionInConversation(long threadId, long receivedTimestamp, @NonNull RecipientId recipientId) {
|
||||
String order = MessageTable.DATE_RECEIVED + " DESC";
|
||||
String selection = MessageTable.THREAD_ID + " = " + threadId + " AND " + MessageTable.STORY_TYPE + " = 0" + " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
||||
|
||||
try (Cursor cursor = queryTables(new String[]{ MessageTable.DATE_RECEIVED, MessageTable.RECIPIENT_ID, MessageTable.REMOTE_DELETED}, selection, order, null, false)) {
|
||||
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();
|
||||
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
boolean timestampMatches = cursor.getLong(0) == receivedTimestamp;
|
||||
boolean recipientIdMatches = recipientId.equals(RecipientId.from(cursor.getLong(1)));
|
||||
|
||||
if (timestampMatches && (recipientIdMatches || isOwnNumber)) {
|
||||
if (CursorUtil.requireBoolean(cursor, MessageTable.REMOTE_DELETED)) {
|
||||
return -1;
|
||||
} else {
|
||||
return cursor.getPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
boolean hasReceivedAnyCallsSince(long threadId, long timestamp) {
|
||||
return SignalDatabase.messages().hasReceivedAnyCallsSince(threadId, timestamp);
|
||||
}
|
||||
|
||||
|
||||
public int getMessagePositionInConversation(long threadId, long receivedTimestamp) {
|
||||
return getMessagePositionInConversation(threadId, 0, receivedTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the position of the message with the provided timestamp in the query results you'd
|
||||
* get from calling {@link #getConversation(long)}.
|
||||
*
|
||||
* 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,
|
||||
* you'll still wind up in about the right spot.
|
||||
*
|
||||
* @param groupStoryId Ignored if passed value is <= 0
|
||||
*/
|
||||
public int getMessagePositionInConversation(long threadId, long groupStoryId, long receivedTimestamp) {
|
||||
final String order;
|
||||
final String selection;
|
||||
|
||||
if (groupStoryId > 0) {
|
||||
order = MessageTable.DATE_RECEIVED + " ASC";
|
||||
selection = MessageTable.THREAD_ID + " = " + threadId + " AND " +
|
||||
MessageTable.DATE_RECEIVED + " < " + receivedTimestamp + " AND " +
|
||||
MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " = " + groupStoryId;
|
||||
} else {
|
||||
order = MessageTable.DATE_RECEIVED + " DESC";
|
||||
selection = MessageTable.THREAD_ID + " = " + threadId + " AND " +
|
||||
MessageTable.DATE_RECEIVED + " > " + receivedTimestamp + " AND " +
|
||||
MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0";
|
||||
}
|
||||
|
||||
try (Cursor cursor = queryTables(new String[]{ "COUNT(*)" }, selection, order, null, false)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getInt(0);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public long getTimestampForFirstMessageAfterDate(long date) {
|
||||
String order = MessageTable.DATE_RECEIVED + " ASC";
|
||||
String selection = MessageTable.DATE_RECEIVED + " > " + date;
|
||||
|
||||
try (Cursor cursor = queryTables(new String[] { MessageTable.DATE_RECEIVED }, selection, order, "1", false)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getLong(0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setNotifiedTimestamp(long timestamp, @NonNull List<Long> messageIds) {
|
||||
SignalDatabase.messages().setNotifiedTimestamp(timestamp, messageIds);
|
||||
}
|
||||
|
||||
public int deleteMessagesInThreadBeforeDate(long threadId, long trimBeforeDate) {
|
||||
Log.d(TAG, "deleteMessagesInThreadBeforeData(" + threadId + ", " + trimBeforeDate + ")");
|
||||
int deletes = SignalDatabase.messages().deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate);
|
||||
deletes += SignalDatabase.messages().deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate);
|
||||
return deletes;
|
||||
}
|
||||
|
||||
public void deleteAbandonedMessages() {
|
||||
Log.d(TAG, "deleteAbandonedMessages()");
|
||||
SignalDatabase.messages().deleteAbandonedMessages();
|
||||
SignalDatabase.messages().deleteAbandonedMessages();
|
||||
}
|
||||
|
||||
public @NonNull List<MessageTable.ReportSpamData> getReportSpamMessageServerData(long threadId, long timestamp, int limit) {
|
||||
List<MessageTable.ReportSpamData> data = new ArrayList<>();
|
||||
data.addAll(SignalDatabase.messages().getReportSpamMessageServerGuids(threadId, timestamp));
|
||||
data.addAll(SignalDatabase.messages().getReportSpamMessageServerGuids(threadId, timestamp));
|
||||
return data.stream()
|
||||
.sorted((l, r) -> -Long.compare(l.getDateReceived(), r.getDateReceived()))
|
||||
.limit(limit)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static @NonNull String buildQuery(String[] projection, String selection, String order, String limit, boolean includeAttachments) {
|
||||
String attachmentJsonJoin;
|
||||
if (includeAttachments) {
|
||||
|
@ -942,75 +250,4 @@ public class MmsSmsTable extends DatabaseTable {
|
|||
|
||||
return databaseHelper.getSignalReadableDatabase().rawQuery(query, null);
|
||||
}
|
||||
|
||||
public static Reader readerFor(@NonNull Cursor cursor) {
|
||||
return new Reader(cursor);
|
||||
}
|
||||
|
||||
public static class Reader implements Closeable {
|
||||
|
||||
private final Cursor cursor;
|
||||
private MessageTable.MmsReader mmsReader;
|
||||
|
||||
public Reader(Cursor cursor) {
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
private MessageTable.MmsReader getMmsReader() {
|
||||
if (mmsReader == null) {
|
||||
mmsReader = MessageTable.mmsReaderFor(cursor);
|
||||
}
|
||||
|
||||
return mmsReader;
|
||||
}
|
||||
|
||||
public MessageRecord getNext() {
|
||||
if (cursor == null || !cursor.moveToNext())
|
||||
return null;
|
||||
|
||||
return getCurrent();
|
||||
}
|
||||
|
||||
public MessageRecord getCurrent() {
|
||||
return getMmsReader().getCurrent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
static final class TimestampReadResult {
|
||||
final List<Pair<Long, Long>> expiring;
|
||||
final List<Long> threads;
|
||||
|
||||
TimestampReadResult(@NonNull List<Pair<Long, Long>> expiring, @NonNull List<Long> threads) {
|
||||
this.expiring = expiring;
|
||||
this.threads = threads;
|
||||
}
|
||||
}
|
||||
|
||||
private static class QuoteDescriptor {
|
||||
private final long timestamp;
|
||||
private final RecipientId author;
|
||||
|
||||
private QuoteDescriptor(long timestamp, RecipientId author) {
|
||||
this.author = author;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final QuoteDescriptor that = (QuoteDescriptor) o;
|
||||
return timestamp == that.timestamp && author.equals(that.author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(author, timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
}
|
||||
|
||||
val deletes = writableDatabase.withinTransaction {
|
||||
mmsSms.deleteAbandonedMessages()
|
||||
messages.deleteAbandonedMessages()
|
||||
attachments.trimAllAbandonedAttachments()
|
||||
groupReceipts.deleteAbandonedRows()
|
||||
mentions.deleteAbandonedMentions()
|
||||
|
@ -318,7 +318,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
|
||||
val deletes = writableDatabase.withinTransaction {
|
||||
trimThreadInternal(threadId, length, trimBeforeDate)
|
||||
mmsSms.deleteAbandonedMessages()
|
||||
messages.deleteAbandonedMessages()
|
||||
attachments.trimAllAbandonedAttachments()
|
||||
groupReceipts.deleteAbandonedRows()
|
||||
mentions.deleteAbandonedMentions()
|
||||
|
@ -354,7 +354,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
if (finalTrimBeforeDate != NO_TRIM_BEFORE_DATE_SET) {
|
||||
Log.i(TAG, "Trimming thread: $threadId before: $finalTrimBeforeDate")
|
||||
|
||||
val deletes = mmsSms.deleteMessagesInThreadBeforeDate(threadId, finalTrimBeforeDate)
|
||||
val deletes = messages.deleteMessagesInThreadBeforeDate(threadId, finalTrimBeforeDate)
|
||||
if (deletes > 0) {
|
||||
Log.i(TAG, "Trimming deleted $deletes messages thread: $threadId")
|
||||
setLastScrolled(threadId, 0)
|
||||
|
@ -389,7 +389,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
}
|
||||
|
||||
fun hasReceivedAnyCallsSince(threadId: Long, timestamp: Long): Boolean {
|
||||
return mmsSms.hasReceivedAnyCallsSince(threadId, timestamp)
|
||||
return messages.hasReceivedAnyCallsSince(threadId, timestamp)
|
||||
}
|
||||
|
||||
fun setEntireThreadRead(threadId: Long): List<MarkedMessageInfo> {
|
||||
|
@ -441,7 +441,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
|
||||
messages.setReactionsSeen(threadId, sinceTimestamp)
|
||||
|
||||
val unreadCount = mmsSms.getUnreadCount(threadId)
|
||||
val unreadCount = messages.getUnreadCount(threadId)
|
||||
val unreadMentionsCount = messages.getUnreadMentionCount(threadId)
|
||||
|
||||
val contentValues = contentValuesOf(
|
||||
|
@ -1180,7 +1180,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
|
||||
fun updateReadState(threadId: Long) {
|
||||
val previous = getThreadRecord(threadId)
|
||||
val unreadCount = mmsSms.getUnreadCount(threadId)
|
||||
val unreadCount = messages.getUnreadCount(threadId)
|
||||
val unreadMentionsCount = messages.getUnreadMentionCount(threadId)
|
||||
|
||||
writableDatabase
|
||||
|
@ -1268,7 +1268,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
if (forcedUnread) {
|
||||
values.put(READ, ReadStatus.FORCED_UNREAD.serialize())
|
||||
} else if (threadId != null) {
|
||||
val unreadCount = mmsSms.getUnreadCount(threadId)
|
||||
val unreadCount = messages.getUnreadCount(threadId)
|
||||
val unreadMentionsCount = messages.getUnreadMentionCount(threadId)
|
||||
|
||||
values.put(READ, if (unreadCount == 0) ReadStatus.READ.serialize() else ReadStatus.UNREAD.serialize())
|
||||
|
@ -1315,7 +1315,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
}
|
||||
|
||||
private fun update(threadId: Long, unarchive: Boolean, allowDeletion: Boolean, notifyListeners: Boolean): Boolean {
|
||||
val meaningfulMessages = mmsSms.hasMeaningfulMessage(threadId)
|
||||
val meaningfulMessages = messages.hasMeaningfulMessage(threadId)
|
||||
|
||||
val isPinned = getPinnedThreadIds().contains(threadId)
|
||||
val shouldDelete = allowDeletion && !isPinned && !messages.containsStories(threadId)
|
||||
|
@ -1331,7 +1331,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
}
|
||||
|
||||
val record: MessageRecord = try {
|
||||
mmsSms.getConversationSnippet(threadId)
|
||||
messages.getConversationSnippet(threadId)
|
||||
} catch (e: NoSuchMessageException) {
|
||||
Log.w(TAG, "Failed to get a conversation snippet for thread $threadId")
|
||||
|
||||
|
@ -1400,7 +1400,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
}
|
||||
|
||||
val type: Long = try {
|
||||
mmsSms.getConversationSnippetType(threadId)
|
||||
messages.getConversationSnippetType(threadId)
|
||||
} catch (e: NoSuchMessageException) {
|
||||
Log.w(TAG, "Unable to find snippet message for thread $threadId")
|
||||
return
|
||||
|
@ -1552,7 +1552,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
Log.w(TAG, "Falling back to unknown message request state for GV2 message")
|
||||
return Extra.forMessageRequest(individualRecipientId)
|
||||
} else {
|
||||
val recipientId = mmsSms.getGroupAddedBy(record.threadId)
|
||||
val recipientId = messages.getGroupAddedBy(record.threadId)
|
||||
if (recipientId != null) {
|
||||
return Extra.forGroupMessageRequest(recipientId, individualRecipientId)
|
||||
}
|
||||
|
|
|
@ -103,66 +103,66 @@ class SignalSmsExportService : SmsExportService() {
|
|||
}
|
||||
|
||||
override fun onMessageExportStarted(exportableMessage: ExportableMessage) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().setProgress(MessageExportState.Progress.STARTED).build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMessageExportSucceeded(exportableMessage: ExportableMessage) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().setProgress(MessageExportState.Progress.COMPLETED).build()
|
||||
}
|
||||
|
||||
SignalDatabase.mmsSms.markMessageExported(exportableMessage.getMessageId())
|
||||
SignalDatabase.messages.markMessageExported(exportableMessage.getMessageId())
|
||||
}
|
||||
|
||||
override fun onMessageExportFailed(exportableMessage: ExportableMessage) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().setProgress(MessageExportState.Progress.INIT).build()
|
||||
}
|
||||
|
||||
SignalDatabase.mmsSms.markMessageExportFailed(exportableMessage.getMessageId())
|
||||
SignalDatabase.messages.markMessageExportFailed(exportableMessage.getMessageId())
|
||||
}
|
||||
|
||||
override fun onMessageIdCreated(exportableMessage: ExportableMessage, messageId: Long) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().setMessageId(messageId).build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachmentPartExportStarted(exportableMessage: ExportableMessage, part: ExportableMessage.Mms.Part) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().addStartedAttachments(part.contentId).build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachmentPartExportSucceeded(exportableMessage: ExportableMessage, part: ExportableMessage.Mms.Part) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().addCompletedAttachments(part.contentId).build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachmentPartExportFailed(exportableMessage: ExportableMessage, part: ExportableMessage.Mms.Part) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
val startedAttachments = it.startedAttachmentsList - part.contentId
|
||||
it.toBuilder().clearStartedAttachments().addAllStartedAttachments(startedAttachments).build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRecipientExportStarted(exportableMessage: ExportableMessage, recipient: String) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().addStartedRecipients(recipient).build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRecipientExportSucceeded(exportableMessage: ExportableMessage, recipient: String) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
it.toBuilder().addCompletedRecipients(recipient).build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRecipientExportFailed(exportableMessage: ExportableMessage, recipient: String) {
|
||||
SignalDatabase.mmsSms.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
SignalDatabase.messages.updateMessageExportState(exportableMessage.getMessageId()) {
|
||||
val startedAttachments = it.startedRecipientsList - recipient
|
||||
it.toBuilder().clearStartedRecipients().addAllStartedRecipients(startedAttachments).build()
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.annimon.stream.Stream;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
|
@ -34,9 +35,9 @@ public class InsightsRepository implements InsightsDashboardViewModel.Repository
|
|||
@Override
|
||||
public void getInsightsData(@NonNull Consumer<InsightsData> insightsDataConsumer) {
|
||||
SimpleTask.run(() -> {
|
||||
MmsSmsTable mmsSmsDatabase = SignalDatabase.mmsSms();
|
||||
int insecure = mmsSmsDatabase.getInsecureMessageCountForInsights();
|
||||
int secure = mmsSmsDatabase.getSecureMessageCountForInsights();
|
||||
MessageTable messageTable = SignalDatabase.messages();
|
||||
int insecure = messageTable.getInsecureMessageCountForInsights();
|
||||
int secure = messageTable.getSecureMessageCountForInsights();
|
||||
|
||||
if (insecure + secure == 0) {
|
||||
return new InsightsData(false, 0);
|
||||
|
|
|
@ -52,7 +52,7 @@ public final class InviteReminderModel {
|
|||
Long threadId = threadTable.getThreadIdFor(recipient.getId());
|
||||
|
||||
if (threadId != null) {
|
||||
int conversationCount = SignalDatabase.mmsSms().getInsecureSentCount(threadId);
|
||||
int conversationCount = SignalDatabase.messages().getInsecureMessageSentCount(threadId);
|
||||
|
||||
if (conversationCount >= SECOND_INVITE_REMINDER_MESSAGE_THRESHOLD && !resolved.hasSeenSecondInviteReminder()) {
|
||||
return new SecondInviteReminderInfo(context, resolved, repository, repository.getPercentOfInsecureMessages(conversationCount));
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.invites;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
|
@ -29,9 +30,9 @@ public final class InviteReminderRepository implements InviteReminderModel.Repos
|
|||
|
||||
@Override
|
||||
public int getPercentOfInsecureMessages(int insecureCount) {
|
||||
MmsSmsTable mmsSmsDatabase = SignalDatabase.mmsSms();
|
||||
int insecure = mmsSmsDatabase.getInsecureMessageCountForInsights();
|
||||
int secure = mmsSmsDatabase.getSecureMessageCountForInsights();
|
||||
MessageTable messageTable = SignalDatabase.messages();
|
||||
int insecure = messageTable.getInsecureMessageCountForInsights();
|
||||
int secure = messageTable.getSecureMessageCountForInsights();
|
||||
|
||||
if (insecure + secure == 0) return 0;
|
||||
return Math.round(100f * (insecureCount / (float) (insecure + secure)));
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.jobmanager.migrations;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
||||
|
@ -11,22 +12,22 @@ import java.util.TreeSet;
|
|||
|
||||
public class SendReadReceiptsJobMigration extends JobMigration {
|
||||
|
||||
private final MmsSmsTable mmsSmsDatabase;
|
||||
private final MessageTable messageTable;
|
||||
|
||||
public SendReadReceiptsJobMigration(@NonNull MmsSmsTable mmsSmsDatabase) {
|
||||
public SendReadReceiptsJobMigration(@NonNull MessageTable messageTable) {
|
||||
super(5);
|
||||
this.mmsSmsDatabase = mmsSmsDatabase;
|
||||
this.messageTable = messageTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull JobData migrate(@NonNull JobData jobData) {
|
||||
if ("SendReadReceiptJob".equals(jobData.getFactoryKey())) {
|
||||
return migrateSendReadReceiptJob(mmsSmsDatabase, jobData);
|
||||
return migrateSendReadReceiptJob(messageTable, jobData);
|
||||
}
|
||||
return jobData;
|
||||
}
|
||||
|
||||
private static @NonNull JobData migrateSendReadReceiptJob(@NonNull MmsSmsTable mmsSmsDatabase, @NonNull JobData jobData) {
|
||||
private static @NonNull JobData migrateSendReadReceiptJob(@NonNull MessageTable messageTable, @NonNull JobData jobData) {
|
||||
Data data = jobData.getData();
|
||||
|
||||
if (!data.hasLong("thread")) {
|
||||
|
@ -34,7 +35,7 @@ public class SendReadReceiptsJobMigration extends JobMigration {
|
|||
SortedSet<Long> threadIds = new TreeSet<>();
|
||||
|
||||
for (long id : messageIds) {
|
||||
long threadForMessageId = mmsSmsDatabase.getThreadForMessageId(id);
|
||||
long threadForMessageId = messageTable.getThreadIdForMessage(id);
|
||||
if (id != -1) {
|
||||
threadIds.add(threadForMessageId);
|
||||
}
|
||||
|
|
|
@ -156,9 +156,9 @@ public class IndividualSendJob extends PushSendJob {
|
|||
|
||||
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());
|
||||
SignalDatabase.messages().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementViewedReceiptCount(id, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
if (unidentified && accessMode == UnidentifiedAccessMode.UNKNOWN && profileKey == null) {
|
||||
|
|
|
@ -287,7 +287,7 @@ public final class JobManagerFactories {
|
|||
return Arrays.asList(new RecipientIdJobMigration(application),
|
||||
new RecipientIdFollowUpJobMigration(),
|
||||
new RecipientIdFollowUpJobMigration2(),
|
||||
new SendReadReceiptsJobMigration(SignalDatabase.mmsSms()),
|
||||
new SendReadReceiptsJobMigration(SignalDatabase.messages()),
|
||||
new PushProcessMessageQueueJobMigration(application),
|
||||
new RetrieveProfileJobMigration(),
|
||||
new PushDecryptMessageJobEnvelopeMigration(application),
|
||||
|
|
|
@ -69,7 +69,7 @@ public class ReportSpamJob extends BaseJob {
|
|||
}
|
||||
|
||||
int count = 0;
|
||||
List<ReportSpamData> reportSpamData = SignalDatabase.mmsSms().getReportSpamMessageServerData(threadId, timestamp, MAX_MESSAGE_COUNT);
|
||||
List<ReportSpamData> reportSpamData = SignalDatabase.messages().getReportSpamMessageServerData(threadId, timestamp, MAX_MESSAGE_COUNT);
|
||||
SignalServiceAccountManager signalServiceAccountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
for (ReportSpamData data : reportSpamData) {
|
||||
Optional<ServiceId> serviceId = Recipient.resolved(data.getRecipientId()).getServiceId();
|
||||
|
|
|
@ -95,7 +95,7 @@ class MediaPreviewRepository {
|
|||
stopwatch.split("get message record")
|
||||
|
||||
val threadId: Long = messageRecord.threadId
|
||||
val messagePosition: Int = SignalDatabase.mmsSms.getMessagePositionInConversation(threadId, messageRecord.dateReceived)
|
||||
val messagePosition: Int = SignalDatabase.messages.getMessagePositionInConversation(threadId, messageRecord.dateReceived)
|
||||
stopwatch.split("get message position")
|
||||
|
||||
val recipientId: RecipientId = SignalDatabase.threads.getRecipientForThreadId(threadId)?.id ?: throw IllegalStateException("Could not find recipient for thread ID $threadId")
|
||||
|
|
|
@ -66,12 +66,10 @@ public class IncomingMessageProcessor {
|
|||
public class Processor implements Closeable {
|
||||
|
||||
private final Context context;
|
||||
private final MmsSmsTable mmsSmsDatabase;
|
||||
private final JobManager jobManager;
|
||||
|
||||
private Processor(@NonNull Context context) {
|
||||
this.context = context;
|
||||
this.mmsSmsDatabase = SignalDatabase.mmsSms();
|
||||
this.jobManager = ApplicationDependencies.getJobManager();
|
||||
}
|
||||
|
||||
|
@ -160,7 +158,7 @@ public class IncomingMessageProcessor {
|
|||
Recipient sender = Recipient.externalPush(envelope.getSourceAddress());
|
||||
Log.i(TAG, "Received server receipt. Sender: " + sender.getId() + ", Device: " + envelope.getSourceDevice() + ", Timestamp: " + envelope.getTimestamp());
|
||||
|
||||
mmsSmsDatabase.incrementDeliveryReceiptCount(new SyncMessageId(sender.getId(), envelope.getTimestamp()), System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementDeliveryReceiptCount(new SyncMessageId(sender.getId(), envelope.getTimestamp()), System.currentTimeMillis());
|
||||
SignalDatabase.messageLog().deleteEntryForRecipient(envelope.getTimestamp(), sender.getId(), envelope.getSourceDevice());
|
||||
}
|
||||
|
||||
|
|
|
@ -1410,7 +1410,7 @@ public final class MessageContentProcessor {
|
|||
|
||||
Map<Long, Long> threadToLatestRead = new HashMap<>();
|
||||
|
||||
Collection<SyncMessageId> unhandled = SignalDatabase.mmsSms().setTimestampReadFromSyncMessage(readMessages, envelopeTimestamp, threadToLatestRead);
|
||||
Collection<SyncMessageId> unhandled = SignalDatabase.messages().setTimestampReadFromSyncMessage(readMessages, envelopeTimestamp, threadToLatestRead);
|
||||
|
||||
List<MessageTable.MarkedMessageInfo> markedMessages = SignalDatabase.threads().setReadSince(threadToLatestRead, false);
|
||||
|
||||
|
@ -2111,8 +2111,8 @@ public final class MessageContentProcessor {
|
|||
|
||||
if (recipient.isSelf()) {
|
||||
SyncMessageId id = new SyncMessageId(recipient.getId(), message.getTimestamp());
|
||||
SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
|
@ -2224,8 +2224,8 @@ public final class MessageContentProcessor {
|
|||
|
||||
if (recipient.isSelf()) {
|
||||
SyncMessageId id = new SyncMessageId(recipient.getId(), message.getTimestamp());
|
||||
SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
|
@ -2333,8 +2333,8 @@ public final class MessageContentProcessor {
|
|||
|
||||
if (recipients.isSelf()) {
|
||||
SyncMessageId id = new SyncMessageId(recipients.getId(), message.getTimestamp());
|
||||
SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
|
@ -2502,8 +2502,8 @@ public final class MessageContentProcessor {
|
|||
|
||||
if (recipient.isSelf()) {
|
||||
SyncMessageId id = new SyncMessageId(recipient.getId(), message.getTimestamp());
|
||||
SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
|
||||
SignalDatabase.messages().incrementReadReceiptCount(id, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
return threadId;
|
||||
|
@ -2659,17 +2659,17 @@ public final class MessageContentProcessor {
|
|||
|
||||
final Collection<SyncMessageId> unhandled;
|
||||
if (readReceipts && storyViewedReceipts) {
|
||||
unhandled = SignalDatabase.mmsSms().incrementViewedReceiptCounts(ids, content.getTimestamp());
|
||||
unhandled = SignalDatabase.messages().incrementViewedReceiptCounts(ids, content.getTimestamp());
|
||||
} else if (readReceipts) {
|
||||
unhandled = SignalDatabase.mmsSms().incrementViewedNonStoryReceiptCounts(ids, content.getTimestamp());
|
||||
unhandled = SignalDatabase.messages().incrementViewedNonStoryReceiptCounts(ids, content.getTimestamp());
|
||||
} else {
|
||||
unhandled = SignalDatabase.mmsSms().incrementViewedStoryReceiptCounts(ids, content.getTimestamp());
|
||||
unhandled = SignalDatabase.messages().incrementViewedStoryReceiptCounts(ids, content.getTimestamp());
|
||||
}
|
||||
|
||||
Set<SyncMessageId> handled = new HashSet<>(ids);
|
||||
handled.removeAll(unhandled);
|
||||
|
||||
SignalDatabase.mmsSms().updateViewedStories(handled);
|
||||
SignalDatabase.messages().updateViewedStories(handled);
|
||||
|
||||
if (unhandled.size() > 0) {
|
||||
RecipientId selfId = Recipient.self().getId();
|
||||
|
@ -2698,7 +2698,7 @@ public final class MessageContentProcessor {
|
|||
.map(t -> new SyncMessageId(senderRecipient.getId(), t))
|
||||
.toList();
|
||||
|
||||
Collection<SyncMessageId> unhandled = SignalDatabase.mmsSms().incrementDeliveryReceiptCounts(ids, System.currentTimeMillis());
|
||||
Collection<SyncMessageId> unhandled = SignalDatabase.messages().incrementDeliveryReceiptCounts(ids, System.currentTimeMillis());
|
||||
|
||||
for (SyncMessageId id : unhandled) {
|
||||
warn(String.valueOf(content.getTimestamp()), "[handleDeliveryReceipt] Could not find matching message! timestamp: " + id.getTimetamp() + " author: " + id.getRecipientId());
|
||||
|
@ -2729,7 +2729,7 @@ public final class MessageContentProcessor {
|
|||
.map(t -> new SyncMessageId(senderRecipient.getId(), t))
|
||||
.toList();
|
||||
|
||||
Collection<SyncMessageId> unhandled = SignalDatabase.mmsSms().incrementReadReceiptCounts(ids, content.getTimestamp());
|
||||
Collection<SyncMessageId> unhandled = SignalDatabase.messages().incrementReadReceiptCounts(ids, content.getTimestamp());
|
||||
|
||||
if (unhandled.size() > 0) {
|
||||
RecipientId selfId = Recipient.self().getId();
|
||||
|
|
|
@ -212,7 +212,7 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier {
|
|||
updateBadge(context, state.messageCount)
|
||||
|
||||
val messageIds: List<Long> = state.notificationItems.map { it.id }
|
||||
SignalDatabase.mmsSms.setNotifiedTimestamp(System.currentTimeMillis(), messageIds)
|
||||
SignalDatabase.messages.setNotifiedTimestamp(System.currentTimeMillis(), messageIds)
|
||||
|
||||
Log.i(TAG, "threads: ${state.threadCount} messages: ${state.messageCount}")
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ class MessageNotification(threadRecipient: Recipient, record: MessageRecord) : N
|
|||
|
||||
override fun getStartingPosition(context: Context): Int {
|
||||
return if (thread.groupStoryId != null) {
|
||||
SignalDatabase.mmsSms.getMessagePositionInConversation(thread.threadId, thread.groupStoryId, record.dateReceived)
|
||||
SignalDatabase.messages.getMessagePositionInConversation(thread.threadId, thread.groupStoryId, record.dateReceived)
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
|
@ -328,7 +328,7 @@ class ReactionNotification(threadRecipient: Recipient, record: MessageRecord, va
|
|||
}
|
||||
|
||||
override fun getStartingPosition(context: Context): Int {
|
||||
return SignalDatabase.mmsSms.getMessagePositionInConversation(thread.threadId, thread.groupStoryId ?: 0L, record.dateReceived)
|
||||
return SignalDatabase.messages.getMessagePositionInConversation(thread.threadId, thread.groupStoryId ?: 0L, record.dateReceived)
|
||||
}
|
||||
|
||||
override fun getLargeIconUri(): Uri? = null
|
||||
|
|
|
@ -4,7 +4,6 @@ import androidx.annotation.WorkerThread
|
|||
import org.signal.core.util.CursorUtil
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.database.MessageTable
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable
|
||||
import org.thoughtcrime.securesms.database.NoSuchMessageException
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
|
@ -31,7 +30,7 @@ object NotificationStateProvider {
|
|||
return NotificationState.EMPTY
|
||||
}
|
||||
|
||||
MmsSmsTable.readerFor(unreadMessages).use { reader ->
|
||||
MessageTable.mmsReaderFor(unreadMessages).use { reader ->
|
||||
var record: MessageRecord? = reader.next
|
||||
while (record != null) {
|
||||
val threadRecipient: Recipient? = SignalDatabase.threads.getRecipientForThreadId(record.threadId)
|
||||
|
|
|
@ -257,7 +257,7 @@ public class RecipientUtil {
|
|||
@WorkerThread
|
||||
public static boolean isPreMessageRequestThread(@Nullable Long threadId) {
|
||||
long beforeTime = SignalStore.misc().getMessageRequestEnableTime();
|
||||
return threadId != null && SignalDatabase.mmsSms().getConversationCount(threadId, beforeTime) > 0;
|
||||
return threadId != null && SignalDatabase.messages().getMessageCountForThread(threadId, beforeTime) > 0;
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
@ -272,7 +272,7 @@ public class RecipientUtil {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean firstMessage = SignalDatabase.mmsSms().getOutgoingSecureConversationCount(threadId) == 0;
|
||||
boolean firstMessage = SignalDatabase.messages().getOutgoingSecureMessageCount(threadId) == 0;
|
||||
|
||||
if (firstMessage) {
|
||||
SignalDatabase.recipients().setProfileSharing(recipient.getId(), true);
|
||||
|
@ -317,7 +317,7 @@ public class RecipientUtil {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (threadId == -1 || !SignalDatabase.mmsSms().hasMeaningfulMessage(threadId)) {
|
||||
if (threadId == -1 || !SignalDatabase.messages().hasMeaningfulMessage(threadId)) {
|
||||
SignalDatabase.recipients().setExpireMessages(recipient.getId(), defaultTimer);
|
||||
OutgoingMessage outgoingMessage = OutgoingMessage.expirationUpdateMessage(recipient, System.currentTimeMillis(), defaultTimer * 1000L);
|
||||
MessageSender.send(context, outgoingMessage, SignalDatabase.threads().getOrCreateThreadIdFor(recipient), false, null, null);
|
||||
|
@ -349,7 +349,7 @@ public class RecipientUtil {
|
|||
|
||||
@WorkerThread
|
||||
public static boolean hasSentMessageInThread(@Nullable Long threadId) {
|
||||
return threadId != null && SignalDatabase.mmsSms().getOutgoingSecureConversationCount(threadId) != 0;
|
||||
return threadId != null && SignalDatabase.messages().getOutgoingSecureMessageCount(threadId) != 0;
|
||||
}
|
||||
|
||||
public static boolean isSmsOnly(long threadId, @NonNull Recipient threadRecipient) {
|
||||
|
@ -363,7 +363,7 @@ public class RecipientUtil {
|
|||
return true;
|
||||
}
|
||||
|
||||
return SignalDatabase.mmsSms().getSecureConversationCount(threadId) == 0 &&
|
||||
return SignalDatabase.messages().getSecureMessageCount(threadId) == 0 &&
|
||||
!SignalDatabase.threads().hasReceivedAnyCallsSince(threadId, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadTable;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
|
@ -20,14 +20,14 @@ public class TrimThreadsByDateManager extends TimedEventManager<TrimThreadsByDat
|
|||
|
||||
private static final String TAG = Log.tag(TrimThreadsByDateManager.class);
|
||||
|
||||
private final ThreadTable threadTable;
|
||||
private final MmsSmsTable mmsSmsDatabase;
|
||||
private final ThreadTable threadTable;
|
||||
private final MessageTable messageTable;
|
||||
|
||||
public TrimThreadsByDateManager(@NonNull Application application) {
|
||||
super(application, "TrimThreadsByDateManager");
|
||||
|
||||
threadTable = SignalDatabase.threads();
|
||||
mmsSmsDatabase = SignalDatabase.mmsSms();
|
||||
threadTable = SignalDatabase.threads();
|
||||
messageTable = SignalDatabase.messages();
|
||||
|
||||
scheduleIfNecessary();
|
||||
}
|
||||
|
@ -41,12 +41,12 @@ public class TrimThreadsByDateManager extends TimedEventManager<TrimThreadsByDat
|
|||
|
||||
long trimBeforeDate = System.currentTimeMillis() - keepMessagesDuration.getDuration();
|
||||
|
||||
if (mmsSmsDatabase.getMessageCountBeforeDate(trimBeforeDate) > 0) {
|
||||
if (messageTable.getMessageCountBeforeDate(trimBeforeDate) > 0) {
|
||||
Log.i(TAG, "Messages exist before date, trim immediately");
|
||||
return new TrimEvent(0);
|
||||
}
|
||||
|
||||
long timestamp = mmsSmsDatabase.getTimestampForFirstMessageAfterDate(trimBeforeDate);
|
||||
long timestamp = messageTable.getTimestampForFirstMessageAfterDate(trimBeforeDate);
|
||||
|
||||
if (timestamp == 0) {
|
||||
return null;
|
||||
|
|
|
@ -598,10 +598,9 @@ public class MessageSender {
|
|||
private static void sendLocalMediaSelf(Context context, long messageId) {
|
||||
try {
|
||||
ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager();
|
||||
MessageTable mmsDatabase = SignalDatabase.messages();
|
||||
MmsSmsTable mmsSmsDatabase = SignalDatabase.mmsSms();
|
||||
OutgoingMessage message = mmsDatabase.getOutgoingMessage(messageId);
|
||||
SyncMessageId syncId = new SyncMessageId(Recipient.self().getId(), message.getSentTimeMillis());
|
||||
MessageTable mmsDatabase = SignalDatabase.messages();
|
||||
OutgoingMessage message = mmsDatabase.getOutgoingMessage(messageId);
|
||||
SyncMessageId syncId = new SyncMessageId(Recipient.self().getId(), message.getSentTimeMillis());
|
||||
List<Attachment> attachments = new LinkedList<>();
|
||||
|
||||
|
||||
|
@ -633,9 +632,9 @@ public class MessageSender {
|
|||
mmsDatabase.markAsSent(messageId, true);
|
||||
mmsDatabase.markUnidentified(messageId, true);
|
||||
|
||||
mmsSmsDatabase.incrementDeliveryReceiptCount(syncId, System.currentTimeMillis());
|
||||
mmsSmsDatabase.incrementReadReceiptCount(syncId, System.currentTimeMillis());
|
||||
mmsSmsDatabase.incrementViewedReceiptCount(syncId, System.currentTimeMillis());
|
||||
mmsDatabase.incrementDeliveryReceiptCount(syncId, System.currentTimeMillis());
|
||||
mmsDatabase.incrementReadReceiptCount(syncId, System.currentTimeMillis());
|
||||
mmsDatabase.incrementViewedReceiptCount(syncId, System.currentTimeMillis());
|
||||
|
||||
if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) {
|
||||
mmsDatabase.markExpireStarted(messageId);
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.testing.TestDatabaseUtil
|
|||
class MmsSmsDatabaseTest {
|
||||
|
||||
private lateinit var mmsSmsTable: MmsSmsTable
|
||||
private lateinit var messageTable: MessageTable
|
||||
private lateinit var db: SQLiteDatabase
|
||||
|
||||
@Before
|
||||
|
@ -28,6 +29,7 @@ class MmsSmsDatabaseTest {
|
|||
|
||||
db = sqlCipher.writableDatabase
|
||||
mmsSmsTable = MmsSmsTable(ApplicationProvider.getApplicationContext(), sqlCipher)
|
||||
messageTable = MessageTable(ApplicationProvider.getApplicationContext(), sqlCipher)
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -38,7 +40,7 @@ class MmsSmsDatabaseTest {
|
|||
@Test
|
||||
fun `getConversationSnippet when single normal SMS, return SMS message id and transport as false`() {
|
||||
TestSms.insert(db)
|
||||
mmsSmsTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
messageTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
cursor.moveToFirst()
|
||||
assertEquals(1, CursorUtil.requireLong(cursor, MessageTable.ID))
|
||||
}
|
||||
|
@ -47,7 +49,7 @@ class MmsSmsDatabaseTest {
|
|||
@Test
|
||||
fun `getConversationSnippet when single normal MMS, return MMS message id and transport as true`() {
|
||||
TestMms.insert(db)
|
||||
mmsSmsTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
messageTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
cursor.moveToFirst()
|
||||
assertEquals(1, CursorUtil.requireLong(cursor, MessageTable.ID))
|
||||
}
|
||||
|
@ -58,13 +60,13 @@ class MmsSmsDatabaseTest {
|
|||
val timestamp = System.currentTimeMillis()
|
||||
|
||||
TestMms.insert(db, receivedTimestampMillis = timestamp + 2)
|
||||
mmsSmsTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
messageTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
cursor.moveToFirst()
|
||||
assertEquals(1, CursorUtil.requireLong(cursor, MessageTable.ID))
|
||||
}
|
||||
|
||||
TestSms.insert(db, receivedTimestampMillis = timestamp + 3, type = MessageTypes.BASE_SENDING_TYPE or MessageTypes.SECURE_MESSAGE_BIT or MessageTypes.PUSH_MESSAGE_BIT or MessageTypes.GROUP_V2_LEAVE_BITS)
|
||||
mmsSmsTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
messageTable.getConversationSnippetCursor(1).use { cursor ->
|
||||
cursor.moveToFirst()
|
||||
assertEquals(1, CursorUtil.requireLong(cursor, MessageTable.ID))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.jobmanager.migrations;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
||||
|
@ -17,7 +18,7 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
public class SendReadReceiptsJobMigrationTest {
|
||||
|
||||
private final MmsSmsTable mockDatabase = mock(MmsSmsTable.class);
|
||||
private final MessageTable mockDatabase = mock(MessageTable.class);
|
||||
private final SendReadReceiptsJobMigration testSubject = new SendReadReceiptsJobMigration(mockDatabase);
|
||||
|
||||
@Test
|
||||
|
@ -30,7 +31,7 @@ public class SendReadReceiptsJobMigrationTest {
|
|||
.putString("recipient", RecipientId.from(2).serialize())
|
||||
.putLongArray("message_ids", new long[]{1, 2, 3, 4, 5})
|
||||
.putLong("timestamp", 292837649).build());
|
||||
when(mockDatabase.getThreadForMessageId(anyLong())).thenReturn(1234L);
|
||||
when(mockDatabase.getThreadIdForMessage(anyLong())).thenReturn(1234L);
|
||||
|
||||
// WHEN
|
||||
JobMigration.JobData result = testSubject.migrate(jobData);
|
||||
|
@ -52,7 +53,7 @@ public class SendReadReceiptsJobMigrationTest {
|
|||
.putString("recipient", RecipientId.from(2).serialize())
|
||||
.putLongArray("message_ids", new long[]{})
|
||||
.putLong("timestamp", 292837649).build());
|
||||
when(mockDatabase.getThreadForMessageId(anyLong())).thenReturn(-1L);
|
||||
when(mockDatabase.getThreadIdForMessage(anyLong())).thenReturn(-1L);
|
||||
|
||||
// WHEN
|
||||
JobMigration.JobData result = testSubject.migrate(jobData);
|
||||
|
|
|
@ -10,11 +10,10 @@ import org.mockito.Mock;
|
|||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsTable;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadTable;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -29,22 +28,19 @@ public class RecipientUtilTest {
|
|||
@Rule
|
||||
public MockitoRule rule = MockitoJUnit.rule();
|
||||
|
||||
private Context context = mock(Context.class);
|
||||
private Context context = mock(Context.class);
|
||||
private Recipient recipient = mock(Recipient.class);
|
||||
private ThreadTable mockThreadTable = mock(ThreadTable.class);
|
||||
private MmsSmsTable mockMmsSmsDatabase = mock(MmsSmsTable.class);
|
||||
private MessageTable mockMessageTable = mock(MessageTable.class);
|
||||
private RecipientTable mockRecipientTable = mock(RecipientTable.class);
|
||||
|
||||
@Mock
|
||||
private MockedStatic<SignalDatabase> signalDatabaseMockedStatic;
|
||||
|
||||
@Mock
|
||||
private MockedStatic<FeatureFlags> featureFlagsMockedStatic;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
signalDatabaseMockedStatic.when(SignalDatabase::threads).thenReturn(mockThreadTable);
|
||||
signalDatabaseMockedStatic.when(SignalDatabase::mmsSms).thenReturn(mockMmsSmsDatabase);
|
||||
signalDatabaseMockedStatic.when(SignalDatabase::messages).thenReturn(mockMessageTable);
|
||||
signalDatabaseMockedStatic.when(SignalDatabase::recipients).thenReturn(mockRecipientTable);
|
||||
|
||||
when(recipient.getId()).thenReturn(RecipientId.from(5));
|
||||
|
@ -73,7 +69,7 @@ public class RecipientUtilTest {
|
|||
public void givenIHaveSentASecureMessageInThisThread_whenIsThreadMessageRequestAccepted_thenIExpectTrue() {
|
||||
// GIVEN
|
||||
when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient);
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(1L)).thenReturn(5);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(5);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L);
|
||||
|
@ -87,7 +83,7 @@ public class RecipientUtilTest {
|
|||
// GIVEN
|
||||
when(recipient.isProfileSharing()).thenReturn(true);
|
||||
when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient);
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(1L)).thenReturn(0);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L);
|
||||
|
@ -101,7 +97,7 @@ public class RecipientUtilTest {
|
|||
// GIVEN
|
||||
when(recipient.isSystemContact()).thenReturn(true);
|
||||
when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient);
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(1L)).thenReturn(0);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L);
|
||||
|
@ -115,8 +111,8 @@ public class RecipientUtilTest {
|
|||
public void givenIHaveReceivedASecureMessageIHaveNotSentASecureMessageAndRecipientIsNotSystemContactAndNotProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectFalse() {
|
||||
// GIVEN
|
||||
when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient);
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(1L)).thenReturn(0);
|
||||
when(mockMmsSmsDatabase.getSecureConversationCount(1L)).thenReturn(5);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0);
|
||||
when(mockMessageTable.getSecureMessageCount(1L)).thenReturn(5);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L);
|
||||
|
@ -129,8 +125,8 @@ public class RecipientUtilTest {
|
|||
public void givenIHaveNotReceivedASecureMessageIHaveNotSentASecureMessageAndRecipientIsNotSystemContactAndNotProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectTrue() {
|
||||
// GIVEN
|
||||
when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient);
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(1L)).thenReturn(0);
|
||||
when(mockMmsSmsDatabase.getSecureConversationCount(1L)).thenReturn(0);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0);
|
||||
when(mockMessageTable.getSecureMessageCount(1L)).thenReturn(0);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L);
|
||||
|
@ -151,7 +147,7 @@ public class RecipientUtilTest {
|
|||
@Test
|
||||
public void givenNonZeroOutgoingSecureMessageCount_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() {
|
||||
// GIVEN
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(anyLong())).thenReturn(1);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(anyLong())).thenReturn(1);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient);
|
||||
|
@ -189,7 +185,7 @@ public class RecipientUtilTest {
|
|||
public void givenNoSecureMessagesSentSomeSecureMessagesReceivedNotSharingAndNotSystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectFalse() {
|
||||
// GIVEN
|
||||
when(recipient.isRegistered()).thenReturn(true);
|
||||
when(mockMmsSmsDatabase.getSecureConversationCount(anyLong())).thenReturn(5);
|
||||
when(mockMessageTable.getSecureMessageCount(anyLong())).thenReturn(5);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient);
|
||||
|
@ -201,7 +197,7 @@ public class RecipientUtilTest {
|
|||
@Test
|
||||
public void givenNoSecureMessagesSentNoSecureMessagesReceivedNotSharingAndNotSystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() {
|
||||
// GIVEN
|
||||
when(mockMmsSmsDatabase.getSecureConversationCount(anyLong())).thenReturn(0);
|
||||
when(mockMessageTable.getSecureMessageCount(anyLong())).thenReturn(0);
|
||||
|
||||
// WHEN
|
||||
boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient);
|
||||
|
@ -214,7 +210,7 @@ public class RecipientUtilTest {
|
|||
@Test
|
||||
public void givenNoSecureMessagesSent_whenIShareProfileIfFirstSecureMessage_thenIShareProfile() {
|
||||
// GIVEN
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(anyLong())).thenReturn(0);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(anyLong())).thenReturn(0);
|
||||
|
||||
// WHEN
|
||||
RecipientUtil.shareProfileIfFirstSecureMessage(recipient);
|
||||
|
@ -227,7 +223,7 @@ public class RecipientUtilTest {
|
|||
@Test
|
||||
public void givenSecureMessagesSent_whenIShareProfileIfFirstSecureMessage_thenIShareProfile() {
|
||||
// GIVEN
|
||||
when(mockMmsSmsDatabase.getOutgoingSecureConversationCount(anyLong())).thenReturn(5);
|
||||
when(mockMessageTable.getOutgoingSecureMessageCount(anyLong())).thenReturn(5);
|
||||
|
||||
// WHEN
|
||||
RecipientUtil.shareProfileIfFirstSecureMessage(recipient);
|
||||
|
|
Loading…
Add table
Reference in a new issue