From a385cb0b6898bd8d239946a0c8ab22b4731c69cf Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 1 Oct 2021 14:21:41 -0400 Subject: [PATCH] Dedupe network and identity failures. --- .../securesms/database/MessageDatabase.java | 22 ++++--- .../securesms/database/MmsDatabase.java | 59 +++++++++---------- .../securesms/database/SmsDatabase.java | 17 +++--- .../database/documents/Document.java | 8 +-- ...hList.java => IdentityKeyMismatchSet.java} | 14 +++-- ...ailureList.java => NetworkFailureSet.java} | 14 +++-- .../database/model/InMemoryMessageRecord.java | 4 +- .../database/model/MediaMmsMessageRecord.java | 4 +- .../database/model/MessageRecord.java | 37 ++++++------ .../database/model/MmsMessageRecord.java | 5 +- .../model/NotificationMmsMessageRecord.java | 3 +- .../database/model/SmsMessageRecord.java | 6 +- .../securesms/jobs/PushGroupSendJob.java | 34 ++++------- .../mediasend/v2/MediaSelectionRepository.kt | 2 +- .../messages/MessageContentProcessor.java | 2 +- .../securesms/mms/OutgoingMediaMessage.java | 22 +++---- .../mms/OutgoingSecureMediaMessage.java | 2 +- .../notifications/RemoteReplyReceiver.java | 4 +- .../securesms/database/TestMms.kt | 4 +- 19 files changed, 133 insertions(+), 130 deletions(-) rename app/src/main/java/org/thoughtcrime/securesms/database/documents/{IdentityKeyMismatchList.java => IdentityKeyMismatchSet.java} (56%) rename app/src/main/java/org/thoughtcrime/securesms/database/documents/{NetworkFailureList.java => NetworkFailureSet.java} (58%) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java index 1c22b5b6b5..680ed0b7f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java @@ -17,7 +17,7 @@ import net.sqlcipher.database.SQLiteStatement; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.documents.Document; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList; +import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageId; @@ -138,7 +138,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns public abstract @NonNull List setIncomingMessagesViewed(@NonNull List messageIds); public abstract void addFailures(long messageId, List failure); - public abstract void removeFailure(long messageId, NetworkFailure failure); + public abstract void setNetworkFailures(long messageId, Set failures); public abstract @NonNull Pair insertReceivedCall(@NonNull RecipientId address, boolean isVideoOffer); public abstract @NonNull Pair insertOutgoingCall(@NonNull RecipientId address, boolean isVideoOffer); @@ -395,7 +395,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns try { addToDocument(messageId, MISMATCHED_IDENTITIES, new IdentityKeyMismatch(recipientId, identityKey), - IdentityKeyMismatchList.class); + IdentityKeyMismatchSet.class); } catch (IOException e) { Log.w(TAG, e); } @@ -405,7 +405,15 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns try { removeFromDocument(messageId, MISMATCHED_IDENTITIES, new IdentityKeyMismatch(recipientId, identityKey), - IdentityKeyMismatchList.class); + IdentityKeyMismatchSet.class); + } catch (IOException e) { + Log.w(TAG, e); + } + } + + public void setMismatchedIdentities(long messageId, @NonNull Set mismatches) { + try { + setDocument(databaseHelper.getSignalWritableDatabase(), messageId, MISMATCHED_IDENTITIES, new IdentityKeyMismatchSet(mismatches)); } catch (IOException e) { Log.w(TAG, e); } @@ -458,7 +466,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns try { D document = getDocument(database, messageId, column, clazz); - Iterator iterator = document.getList().iterator(); + Iterator iterator = document.getItems().iterator(); while (iterator.hasNext()) { I item = iterator.next(); @@ -490,7 +498,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns try { T document = getDocument(database, messageId, column, clazz); - document.getList().addAll(objects); + document.getItems().addAll(objects); setDocument(database, messageId, column, document); database.setTransactionSuccessful(); @@ -499,7 +507,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns } } - private void setDocument(SQLiteDatabase database, long messageId, String column, Document document) throws IOException { + protected void setDocument(SQLiteDatabase database, long messageId, String column, Document document) throws IOException { ContentValues contentValues = new ContentValues(); if (document == null || document.size() == 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index fd323ba6c8..964c914737 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -41,9 +41,9 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment; import org.thoughtcrime.securesms.contactshare.Contact; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList; +import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet; import org.thoughtcrime.securesms.database.documents.NetworkFailure; -import org.thoughtcrime.securesms.database.documents.NetworkFailureList; +import org.thoughtcrime.securesms.database.documents.NetworkFailureSet; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.Mention; @@ -56,7 +56,6 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange; -import org.thoughtcrime.securesms.jobs.ThreadUpdateJob; import org.thoughtcrime.securesms.jobs.TrimThreadJob; import org.thoughtcrime.securesms.linkpreview.LinkPreview; import org.thoughtcrime.securesms.mms.IncomingMediaMessage; @@ -603,16 +602,16 @@ public class MmsDatabase extends MessageDatabase { @Override public void addFailures(long messageId, List failure) { try { - addToDocument(messageId, NETWORK_FAILURE, failure, NetworkFailureList.class); + addToDocument(messageId, NETWORK_FAILURE, failure, NetworkFailureSet.class); } catch (IOException e) { Log.w(TAG, e); } } @Override - public void removeFailure(long messageId, NetworkFailure failure) { + public void setNetworkFailures(long messageId, Set failures) { try { - removeFromDocument(messageId, NETWORK_FAILURE, failure, NetworkFailureList.class); + setDocument(databaseHelper.getSignalWritableDatabase(), messageId, NETWORK_FAILURE, new NetworkFailureSet(failures)); } catch (IOException e) { Log.w(TAG, e); } @@ -1175,10 +1174,10 @@ public class MmsDatabase extends MessageDatabase { .sorted(new DatabaseAttachment.DisplayOrderComparator()) .map(a -> (Attachment)a).toList(); - Recipient recipient = Recipient.resolved(RecipientId.from(recipientId)); - List networkFailures = new LinkedList<>(); - List mismatches = new LinkedList<>(); - QuoteModel quote = null; + Recipient recipient = Recipient.resolved(RecipientId.from(recipientId)); + Set networkFailures = new HashSet<>(); + Set mismatches = new HashSet<>(); + QuoteModel quote = null; if (quoteId > 0 && quoteAuthor > 0 && (!TextUtils.isEmpty(quoteText) || !quoteAttachments.isEmpty())) { quote = new QuoteModel(quoteId, RecipientId.from(quoteAuthor), quoteText, quoteMissing, quoteAttachments, quoteMentions); @@ -1186,7 +1185,7 @@ public class MmsDatabase extends MessageDatabase { if (!TextUtils.isEmpty(mismatchDocument)) { try { - mismatches = JsonUtils.fromJson(mismatchDocument, IdentityKeyMismatchList.class).getList(); + mismatches = JsonUtils.fromJson(mismatchDocument, IdentityKeyMismatchSet.class).getItems(); } catch (IOException e) { Log.w(TAG, e); } @@ -1194,7 +1193,7 @@ public class MmsDatabase extends MessageDatabase { if (!TextUtils.isEmpty(networkDocument)) { try { - networkFailures = JsonUtils.fromJson(networkDocument, NetworkFailureList.class).getList(); + networkFailures = JsonUtils.fromJson(networkDocument, NetworkFailureSet.class).getItems(); } catch (IOException e) { Log.w(TAG, e); } @@ -1975,8 +1974,8 @@ public class MmsDatabase extends MessageDatabase { slideDeck, slideDeck.getSlides().size(), message.isSecure() ? MmsSmsColumns.Types.getOutgoingEncryptedMessageType() : MmsSmsColumns.Types.getOutgoingSmsMessageType(), - new LinkedList<>(), - new LinkedList<>(), + Collections.emptySet(), + Collections.emptySet(), message.getSubscriptionId(), message.getExpiresIn(), System.currentTimeMillis(), @@ -2110,16 +2109,16 @@ public class MmsDatabase extends MessageDatabase { } } - Recipient recipient = Recipient.live(RecipientId.from(recipientId)).get(); - List mismatches = getMismatchedIdentities(mismatchDocument); - List networkFailures = getFailures(networkDocument); - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachments(cursor); - List contacts = getSharedContacts(cursor, attachments); - Set contactAttachments = Stream.of(contacts).map(Contact::getAvatarAttachment).withoutNulls().collect(Collectors.toSet()); - List previews = getLinkPreviews(cursor, attachments); - Set previewAttachments = Stream.of(previews).filter(lp -> lp.getThumbnail().isPresent()).map(lp -> lp.getThumbnail().get()).collect(Collectors.toSet()); - SlideDeck slideDeck = buildSlideDeck(context, Stream.of(attachments).filterNot(contactAttachments::contains).filterNot(previewAttachments::contains).toList()); - Quote quote = getQuote(cursor); + Recipient recipient = Recipient.live(RecipientId.from(recipientId)).get(); + Set mismatches = getMismatchedIdentities(mismatchDocument); + Set networkFailures = getFailures(networkDocument); + List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachments(cursor); + List contacts = getSharedContacts(cursor, attachments); + Set contactAttachments = Stream.of(contacts).map(Contact::getAvatarAttachment).withoutNulls().collect(Collectors.toSet()); + List previews = getLinkPreviews(cursor, attachments); + Set previewAttachments = Stream.of(previews).filter(lp -> lp.getThumbnail().isPresent()).map(lp -> lp.getThumbnail().get()).collect(Collectors.toSet()); + SlideDeck slideDeck = buildSlideDeck(context, Stream.of(attachments).filterNot(contactAttachments::contains).filterNot(previewAttachments::contains).toList()); + Quote quote = getQuote(cursor); return new MediaMmsMessageRecord(id, recipient, recipient, addressDeviceId, dateSent, dateReceived, dateServer, deliveryReceiptCount, @@ -2129,28 +2128,28 @@ public class MmsDatabase extends MessageDatabase { remoteDelete, mentionsSelf, notifiedTimestamp, viewedReceiptCount, receiptTimestamp); } - private List getMismatchedIdentities(String document) { + private Set getMismatchedIdentities(String document) { if (!TextUtils.isEmpty(document)) { try { - return JsonUtils.fromJson(document, IdentityKeyMismatchList.class).getList(); + return JsonUtils.fromJson(document, IdentityKeyMismatchSet.class).getItems(); } catch (IOException e) { Log.w(TAG, e); } } - return new LinkedList<>(); + return Collections.emptySet(); } - private List getFailures(String document) { + private Set getFailures(String document) { if (!TextUtils.isEmpty(document)) { try { - return JsonUtils.fromJson(document, NetworkFailureList.class).getList(); + return JsonUtils.fromJson(document, NetworkFailureSet.class).getItems(); } catch (IOException ioe) { Log.w(TAG, ioe); } } - return new LinkedList<>(); + return Collections.emptySet(); } public static SlideDeck buildSlideDeck(@NonNull Context context, @NonNull List attachments) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 4fba73cc3a..45eb66b0d8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -33,7 +33,7 @@ import net.sqlcipher.database.SQLiteStatement; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList; +import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.GroupCallUpdateDetailsUtil; @@ -45,7 +45,6 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.GroupCallUpdateD import org.thoughtcrime.securesms.database.model.databaseprotos.ProfileChangeDetails; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange; -import org.thoughtcrime.securesms.jobs.ThreadUpdateJob; import org.thoughtcrime.securesms.jobs.TrimThreadJob; import org.thoughtcrime.securesms.mms.IncomingMediaMessage; import org.thoughtcrime.securesms.mms.MmsException; @@ -1548,7 +1547,7 @@ public class SmsDatabase extends MessageDatabase { } @Override - public void removeFailure(long messageId, NetworkFailure failure) { + public void setNetworkFailures(long messageId, Set failures) { throw new UnsupportedOperationException(); } @@ -1642,7 +1641,7 @@ public class SmsDatabase extends MessageDatabase { message.isSecureMessage() ? MmsSmsColumns.Types.getOutgoingEncryptedMessageType() : MmsSmsColumns.Types.getOutgoingSmsMessageType(), threadId, 0, - new LinkedList<>(), + new HashSet<>(), message.getSubscriptionId(), message.getExpiresIn(), System.currentTimeMillis(), @@ -1704,8 +1703,8 @@ public class SmsDatabase extends MessageDatabase { readReceiptCount = 0; } - List mismatches = getMismatches(mismatchDocument); - Recipient recipient = Recipient.live(RecipientId.from(recipientId)).get(); + Set mismatches = getMismatches(mismatchDocument); + Recipient recipient = Recipient.live(RecipientId.from(recipientId)).get(); return new SmsMessageRecord(messageId, body, recipient, recipient, @@ -1717,16 +1716,16 @@ public class SmsDatabase extends MessageDatabase { notifiedTimestamp, receiptTimestamp); } - private List getMismatches(String document) { + private Set getMismatches(String document) { try { if (!TextUtils.isEmpty(document)) { - return JsonUtils.fromJson(document, IdentityKeyMismatchList.class).getList(); + return JsonUtils.fromJson(document, IdentityKeyMismatchSet.class).getItems(); } } catch (IOException e) { Log.w(TAG, e); } - return new LinkedList<>(); + return Collections.emptySet(); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/Document.java b/app/src/main/java/org/thoughtcrime/securesms/database/documents/Document.java index 2b226f66da..cba71db9d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/Document.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/documents/Document.java @@ -1,10 +1,8 @@ package org.thoughtcrime.securesms.database.documents; -import java.util.List; +import java.util.Set; public interface Document { - - public int size(); - public List getList(); - + int size(); + Set getItems(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchList.java b/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchSet.java similarity index 56% rename from app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchList.java rename to app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchSet.java index eaceb4d93f..9903bcb6eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchList.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchSet.java @@ -3,19 +3,21 @@ package org.thoughtcrime.securesms.database.documents; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; -public class IdentityKeyMismatchList implements Document { +public class IdentityKeyMismatchSet implements Document { @JsonProperty(value = "m") - private List mismatches; + private Set mismatches; - public IdentityKeyMismatchList() { - this.mismatches = new LinkedList<>(); + public IdentityKeyMismatchSet() { + this.mismatches = new HashSet<>(); } - public IdentityKeyMismatchList(List mismatches) { + public IdentityKeyMismatchSet(Set mismatches) { this.mismatches = mismatches; } @@ -27,7 +29,7 @@ public class IdentityKeyMismatchList implements Document { @Override @JsonIgnore - public List getList() { + public Set getItems() { return mismatches; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureList.java b/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureSet.java similarity index 58% rename from app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureList.java rename to app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureSet.java index 3347c42846..51622a9fc7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureList.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureSet.java @@ -3,19 +3,21 @@ package org.thoughtcrime.securesms.database.documents; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; -public class NetworkFailureList implements Document { +public class NetworkFailureSet implements Document { @JsonProperty(value = "l") - private List failures; + private Set failures; - public NetworkFailureList() { - this.failures = new LinkedList<>(); + public NetworkFailureSet() { + this.failures = new HashSet<>(); } - public NetworkFailureList(List failures) { + public NetworkFailureSet(Set failures) { this.failures = failures; } @@ -27,7 +29,7 @@ public class NetworkFailureList implements Document { @Override @JsonIgnore - public List getList() { + public Set getItems() { return failures; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/InMemoryMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/InMemoryMessageRecord.java index 147b17f3c2..19f9e559d8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/InMemoryMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/InMemoryMessageRecord.java @@ -40,8 +40,8 @@ public class InMemoryMessageRecord extends MessageRecord { 0, 0, type, - Collections.emptyList(), - Collections.emptyList(), + Collections.emptySet(), + Collections.emptySet(), -1, 0, System.currentTimeMillis(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java index 2e50fc6468..35562e8104 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java @@ -72,8 +72,8 @@ public class MediaMmsMessageRecord extends MmsMessageRecord { @NonNull SlideDeck slideDeck, int partCount, long mailbox, - List mismatches, - List failures, + Set mismatches, + Set failures, int subscriptionId, long expiresIn, long expireStarted, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java index 510ba37773..4cf67f62c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -61,6 +61,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.UUID; /** @@ -75,27 +76,27 @@ public abstract class MessageRecord extends DisplayRecord { private static final String TAG = Log.tag(MessageRecord.class); - private final Recipient individualRecipient; - private final int recipientDeviceId; - private final long id; - private final List mismatches; - private final List networkFailures; - private final int subscriptionId; - private final long expiresIn; - private final long expireStarted; - private final boolean unidentified; - private final List reactions; - private final long serverTimestamp; - private final boolean remoteDelete; - private final long notifiedTimestamp; - private final long receiptTimestamp; + private final Recipient individualRecipient; + private final int recipientDeviceId; + private final long id; + private final Set mismatches; + private final Set networkFailures; + private final int subscriptionId; + private final long expiresIn; + private final long expireStarted; + private final boolean unidentified; + private final List reactions; + private final long serverTimestamp; + private final boolean remoteDelete; + private final long notifiedTimestamp; + private final long receiptTimestamp; MessageRecord(long id, String body, Recipient conversationRecipient, Recipient individualRecipient, int recipientDeviceId, long dateSent, long dateReceived, long dateServer, long threadId, int deliveryStatus, int deliveryReceiptCount, long type, - List mismatches, - List networkFailures, + Set mismatches, + Set networkFailures, int subscriptionId, long expiresIn, long expireStarted, int readReceiptCount, boolean unidentified, @NonNull List reactions, boolean remoteDelete, long notifiedTimestamp, @@ -512,11 +513,11 @@ public abstract class MessageRecord extends DisplayRecord { return type; } - public List getIdentityKeyMismatches() { + public Set getIdentityKeyMismatches() { return mismatches; } - public List getNetworkFailures() { + public Set getNetworkFailures() { return networkFailures; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java index 92b28b8b3b..4c45a3e10a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java @@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import java.util.LinkedList; import java.util.List; +import java.util.Set; public abstract class MmsMessageRecord extends MessageRecord { @@ -27,8 +28,8 @@ public abstract class MmsMessageRecord extends MessageRecord { MmsMessageRecord(long id, String body, Recipient conversationRecipient, Recipient individualRecipient, int recipientDeviceId, long dateSent, long dateReceived, long dateServer, long threadId, int deliveryStatus, int deliveryReceiptCount, - long type, List mismatches, - List networkFailures, int subscriptionId, long expiresIn, + long type, Set mismatches, + Set networkFailures, int subscriptionId, long expiresIn, long expireStarted, boolean viewOnce, @NonNull SlideDeck slideDeck, int readReceiptCount, @Nullable Quote quote, @NonNull List contacts, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java index 74881c7547..af51018e70 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java @@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.recipients.Recipient; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedList; /** @@ -56,7 +57,7 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord { { super(id, "", conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, -1, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, - new LinkedList<>(), new LinkedList<>(), subscriptionId, + new HashSet<>(), new HashSet<>(), subscriptionId, 0, 0, false, slideDeck, readReceiptCount, null, Collections.emptyList(), Collections.emptyList(), false, Collections.emptyList(), false, 0, viewedReceiptCount, receiptTimestamp); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java index badd764444..ceb658186c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java @@ -29,8 +29,10 @@ import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.recipients.Recipient; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; /** * The message record model which represents standard SMS messages. @@ -48,7 +50,7 @@ public class SmsMessageRecord extends MessageRecord { long dateSent, long dateReceived, long dateServer, int deliveryReceiptCount, long type, long threadId, - int status, List mismatches, + int status, Set mismatches, int subscriptionId, long expiresIn, long expireStarted, int readReceiptCount, boolean unidentified, @NonNull List reactions, boolean remoteDelete, @@ -56,7 +58,7 @@ public class SmsMessageRecord extends MessageRecord { { super(id, body, recipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, dateServer, threadId, status, deliveryReceiptCount, type, - mismatches, new LinkedList<>(), subscriptionId, + mismatches, new HashSet<>(), subscriptionId, expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete, notifiedTimestamp, 0, receiptTimestamp); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index 528f062050..2263f57eef 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -150,11 +150,11 @@ public final class PushGroupSendJob extends PushSendJob { { SignalLocalMetrics.GroupMessageSend.onJobStarted(messageId); - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); - OutgoingMediaMessage message = database.getOutgoingMessage(messageId); - long threadId = database.getMessageRecord(messageId).getThreadId(); - List existingNetworkFailures = message.getNetworkFailures(); - List existingIdentityMismatches = message.getIdentityKeyMismatches(); + MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + OutgoingMediaMessage message = database.getOutgoingMessage(messageId); + long threadId = database.getMessageRecord(messageId).getThreadId(); + Set existingNetworkFailures = message.getNetworkFailures(); + Set existingIdentityMismatches = message.getIdentityKeyMismatches(); ApplicationDependencies.getJobManager().cancelAllInQueue(TypingSendJob.getQueue(threadId)); @@ -183,8 +183,8 @@ public final class PushGroupSendJob extends PushSendJob { List target; if (filterRecipient != null) target = Collections.singletonList(Recipient.resolved(filterRecipient)); - else if (!existingNetworkFailures.isEmpty()) target = Stream.of(existingNetworkFailures).map(nf -> Recipient.resolved(nf.getRecipientId(context))).toList(); - else target = getGroupMessageRecipients(groupRecipient.requireGroupId(), messageId); + else if (!existingNetworkFailures.isEmpty()) target = Stream.of(existingNetworkFailures).map(nf -> nf.getRecipientId(context)).distinct().map(Recipient::resolved).toList(); + else target = Stream.of(getGroupMessageRecipients(groupRecipient.requireGroupId(), messageId)).distinctBy(Recipient::getId).toList(); RecipientAccessList accessList = new RecipientAccessList(target); @@ -206,23 +206,11 @@ public final class PushGroupSendJob extends PushSendJob { recipientDatabase.markUnregistered(unregistered.getId()); } - for (NetworkFailure resolvedFailure : resolvedNetworkFailures) { - database.removeFailure(messageId, resolvedFailure); - existingNetworkFailures.remove(resolvedFailure); - } + existingNetworkFailures.removeAll(resolvedNetworkFailures); + database.setNetworkFailures(messageId, existingNetworkFailures); - for (IdentityKeyMismatch resolvedIdentity : resolvedIdentityFailures) { - database.removeMismatchedIdentity(messageId, resolvedIdentity.getRecipientId(context), resolvedIdentity.getIdentityKey()); - existingIdentityMismatches.remove(resolvedIdentity); - } - - if (!networkFailures.isEmpty()) { - database.addFailures(messageId, networkFailures); - } - - for (IdentityKeyMismatch mismatch : identityMismatches) { - database.addMismatchedIdentity(messageId, mismatch.getRecipientId(context), mismatch.getIdentityKey()); - } + existingIdentityMismatches.removeAll(resolvedIdentityFailures); + database.setMismatchedIdentities(messageId, existingIdentityMismatches); DatabaseFactory.getGroupReceiptDatabase(context).setUnidentified(successUnidentifiedStatus, messageId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt index 5648bfe571..814244aaf8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt @@ -201,7 +201,7 @@ class MediaSelectionRepository(context: Context) { isViewOnce, ThreadDatabase.DistributionTypes.DEFAULT, null, emptyList(), emptyList(), - mentions, emptyList(), emptyList() + mentions, mutableSetOf(), mutableSetOf() ) messages.add(OutgoingSecureMediaMessage(message)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java index 6ad787993a..a9e80da06d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java @@ -1359,7 +1359,7 @@ public final class MessageContentProcessor { sharedContacts.or(Collections.emptyList()), previews.or(Collections.emptyList()), mentions.or(Collections.emptyList()), - Collections.emptyList(), Collections.emptyList()); + Collections.emptySet(), Collections.emptySet()); mediaMessage = new OutgoingSecureMediaMessage(mediaMessage); diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java index 58b602f847..db6903c236 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java @@ -13,8 +13,10 @@ import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.linkpreview.LinkPreview; import org.thoughtcrime.securesms.recipients.Recipient; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; public class OutgoingMediaMessage { @@ -28,11 +30,11 @@ public class OutgoingMediaMessage { private final boolean viewOnce; private final QuoteModel outgoingQuote; - private final List networkFailures = new LinkedList<>(); - private final List identityKeyMismatches = new LinkedList<>(); - private final List contacts = new LinkedList<>(); - private final List linkPreviews = new LinkedList<>(); - private final List mentions = new LinkedList<>(); + private final Set networkFailures = new HashSet<>(); + private final Set identityKeyMismatches = new HashSet<>(); + private final List contacts = new LinkedList<>(); + private final List linkPreviews = new LinkedList<>(); + private final List mentions = new LinkedList<>(); public OutgoingMediaMessage(Recipient recipient, String message, List attachments, long sentTimeMillis, @@ -42,8 +44,8 @@ public class OutgoingMediaMessage { @NonNull List contacts, @NonNull List linkPreviews, @NonNull List mentions, - @NonNull List networkFailures, - @NonNull List identityKeyMismatches) + @NonNull Set networkFailures, + @NonNull Set identityKeyMismatches) { this.recipient = recipient; this.body = message; @@ -75,7 +77,7 @@ public class OutgoingMediaMessage { slideDeck.asAttachments(), sentTimeMillis, subscriptionId, expiresIn, viewOnce, distributionType, outgoingQuote, - contacts, linkPreviews, mentions, new LinkedList<>(), new LinkedList<>()); + contacts, linkPreviews, mentions, new HashSet<>(), new HashSet<>()); } public OutgoingMediaMessage(OutgoingMediaMessage that) { @@ -175,11 +177,11 @@ public class OutgoingMediaMessage { return mentions; } - public @NonNull List getNetworkFailures() { + public @NonNull Set getNetworkFailures() { return networkFailures; } - public @NonNull List getIdentityKeyMismatches() { + public @NonNull Set getIdentityKeyMismatches() { return identityKeyMismatches; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java index 51c73ba00f..df5a89b35a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java @@ -25,7 +25,7 @@ public class OutgoingSecureMediaMessage extends OutgoingMediaMessage { @NonNull List previews, @NonNull List mentions) { - super(recipient, body, attachments, sentTimeMillis, -1, expiresIn, viewOnce, distributionType, quote, contacts, previews, mentions, Collections.emptyList(), Collections.emptyList()); + super(recipient, body, attachments, sentTimeMillis, -1, expiresIn, viewOnce, distributionType, quote, contacts, previews, mentions, Collections.emptySet(), Collections.emptySet()); } public OutgoingSecureMediaMessage(OutgoingMediaMessage base) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java index ed78a3d114..0fd9c125da 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java @@ -90,8 +90,8 @@ public class RemoteReplyReceiver extends BroadcastReceiver { Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList()); + Collections.emptySet(), + Collections.emptySet()); threadId = MessageSender.send(context, reply, -1, false, null, null); break; } diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt b/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt index 4b63878153..d79fe75045 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt @@ -38,8 +38,8 @@ object TestMms { emptyList(), emptyList(), emptyList(), - emptyList(), - emptyList() + emptySet(), + emptySet() ) return insertMmsMessage(