From 33334f80c324dc10746a7811a6a75c636f5c7399 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 8 Oct 2019 19:14:52 -0700 Subject: [PATCH] Add back proper support for unknown recipients. Fixes #9085 --- .../securesms/database/MmsDatabase.java | 2 +- .../securesms/database/RecipientDatabase.java | 4 +-- .../securesms/database/SmsMigrator.java | 2 +- .../securesms/database/ThreadDatabase.java | 4 +++ .../database/loaders/ThreadMediaLoader.java | 2 ++ .../securesms/jobs/MmsDownloadJob.java | 1 - .../notifications/NotificationChannels.java | 14 +++++---- .../securesms/recipients/LiveRecipient.java | 6 ++-- .../recipients/LiveRecipientCache.java | 4 +++ .../securesms/recipients/Recipient.java | 2 ++ .../recipients/RecipientDetails.java | 30 +++++++++++++++++++ .../securesms/recipients/RecipientId.java | 9 +++++- 12 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 359d568e4d..927c09399c 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -1542,7 +1542,7 @@ public class MmsDatabase extends MessagingDatabase { List quoteAttachments = Stream.of(attachments).filter(Attachment::isQuote).toList(); SlideDeck quoteDeck = new SlideDeck(context, quoteAttachments); - if (quoteId > 0) { + if (quoteId > 0 && !quoteAuthor.isUnknown()) { return new Quote(quoteId, quoteAuthor, quoteText, quoteMissing, quoteDeck); } else { return null; diff --git a/src/org/thoughtcrime/securesms/database/RecipientDatabase.java b/src/org/thoughtcrime/securesms/database/RecipientDatabase.java index 87f90d6f6a..499eec5c52 100644 --- a/src/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/src/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -625,9 +625,9 @@ public class RecipientDatabase extends Database { } else { throw new AssertionError("Failed to insert recipient!"); } + } else { + return RecipientId.from(id); } - - return RecipientId.from(id); } } diff --git a/src/org/thoughtcrime/securesms/database/SmsMigrator.java b/src/org/thoughtcrime/securesms/database/SmsMigrator.java index 33b6facc2d..ced1ecad29 100644 --- a/src/org/thoughtcrime/securesms/database/SmsMigrator.java +++ b/src/org/thoughtcrime/securesms/database/SmsMigrator.java @@ -221,7 +221,7 @@ public class SmsMigrator { while (cursor != null && cursor.moveToNext()) { long theirThreadId = cursor.getLong(cursor.getColumnIndexOrThrow("_id")); String theirRecipients = cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids")); - Set ourRecipients = getOurRecipients(context, theirRecipients); + Set ourRecipients = getOurRecipients(context, theirRecipients); ProgressDescription progress = new ProgressDescription(cursor.getCount(), cursor.getPosition(), 100, 0); if (ourRecipients != null) { diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java index d526566470..5b245f9a16 100644 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -117,6 +117,10 @@ public class ThreadDatabase extends Database { } private long createThreadForRecipient(@NonNull RecipientId recipientId, boolean group, int distributionType) { + if (recipientId.isUnknown()) { + throw new AssertionError("Cannot create a thread for an unknown recipient!"); + } + ContentValues contentValues = new ContentValues(4); long date = System.currentTimeMillis(); diff --git a/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java b/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java index 7f28923ceb..cfc1b37c76 100644 --- a/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java +++ b/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java @@ -24,6 +24,8 @@ public class ThreadMediaLoader extends AbstractCursorLoader { @Override public Cursor getCursor() { + if (recipientId.isUnknown()) return null; + long threadId = DatabaseFactory.getThreadDatabase(getContext()).getThreadIdFor(Recipient.resolved(recipientId)); if (gallery) return DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId); diff --git a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java index 7a5b1bb4b3..e4b75f2ca1 100644 --- a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java @@ -212,7 +212,6 @@ public class MmsDownloadJob extends BaseJob { if (from != null) { members.add(from); } - members.add(Recipient.self().getId()); if (retrieved.getBody() != null) { diff --git a/src/org/thoughtcrime/securesms/notifications/NotificationChannels.java b/src/org/thoughtcrime/securesms/notifications/NotificationChannels.java index 27eb95fce0..e30b0073a5 100644 --- a/src/org/thoughtcrime/securesms/notifications/NotificationChannels.java +++ b/src/org/thoughtcrime/securesms/notifications/NotificationChannels.java @@ -140,7 +140,9 @@ public class NotificationChannels { * Creates a channel for the specified recipient. * @return The channel ID for the newly-created channel. */ - public static synchronized String createChannelFor(@NonNull Context context, @NonNull Recipient recipient) { + public static synchronized @Nullable String createChannelFor(@NonNull Context context, @NonNull Recipient recipient) { + if (recipient.getId().isUnknown()) return null; + VibrateState vibrateState = recipient.getMessageVibrate(); boolean vibrationEnabled = vibrateState == VibrateState.DEFAULT ? TextSecurePreferences.isNotificationVibrateEnabled(context) : vibrateState == VibrateState.ENABLED; Uri messageRingtone = recipient.getMessageRingtone() != null ? recipient.getMessageRingtone() : getMessageRingtone(context); @@ -152,11 +154,11 @@ public class NotificationChannels { /** * More verbose version of {@link #createChannelFor(Context, Recipient)}. */ - public static synchronized @Nullable String createChannelFor(@NonNull Context context, - @NonNull Address address, - @NonNull String displayName, - @Nullable Uri messageSound, - boolean vibrationEnabled) + public static synchronized @Nullable String createChannelFor(@NonNull Context context, + @NonNull Address address, + @NonNull String displayName, + @Nullable Uri messageSound, + boolean vibrationEnabled) { if (!supported()) { return null; diff --git a/src/org/thoughtcrime/securesms/recipients/LiveRecipient.java b/src/org/thoughtcrime/securesms/recipients/LiveRecipient.java index 61ea3df7d8..d3f0f35f0e 100644 --- a/src/org/thoughtcrime/securesms/recipients/LiveRecipient.java +++ b/src/org/thoughtcrime/securesms/recipients/LiveRecipient.java @@ -119,7 +119,7 @@ public final class LiveRecipient { public @NonNull Recipient resolve() { Recipient current = recipient.get(); - if (!current.isResolving()) { + if (!current.isResolving() || current.getId().isUnknown()) { return current; } @@ -150,6 +150,8 @@ public final class LiveRecipient { */ @WorkerThread public void refresh() { + if (getId().isUnknown()) return; + if (Util.isMainThread()) { Log.w(TAG, "[Refresh][MAIN] " + getId(), new Throwable()); } else { @@ -189,7 +191,7 @@ public final class LiveRecipient { if (groupRecord.isPresent()) { String title = groupRecord.get().getTitle(); - List members = Stream.of(groupRecord.get().getMembers()).map(this::fetchRecipientFromDisk).toList(); + List members = Stream.of(groupRecord.get().getMembers()).filterNot(RecipientId::isUnknown).map(this::fetchRecipientFromDisk).toList(); Optional avatarId = Optional.absent(); if (!settings.getAddress().isMmsGroup() && title == null) { diff --git a/src/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java b/src/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java index d87d0c3271..06e3e53a50 100644 --- a/src/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java +++ b/src/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java @@ -23,6 +23,7 @@ public final class LiveRecipientCache { private final Context context; private final RecipientDatabase recipientDatabase; private final Map recipients; + private final LiveRecipient unknown; private RecipientId localRecipientId; @@ -31,10 +32,13 @@ public final class LiveRecipientCache { this.context = context.getApplicationContext(); this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context); this.recipients = new LRUCache<>(1000); + this.unknown = new LiveRecipient(context, new MutableLiveData<>(), Recipient.UNKNOWN); } @AnyThread synchronized @NonNull LiveRecipient getLive(@NonNull RecipientId id) { + if (id.isUnknown()) return unknown; + LiveRecipient live = recipients.get(id); if (live == null) { diff --git a/src/org/thoughtcrime/securesms/recipients/Recipient.java b/src/org/thoughtcrime/securesms/recipients/Recipient.java index 2ed4d2ede6..f39b12dbcf 100644 --- a/src/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/src/org/thoughtcrime/securesms/recipients/Recipient.java @@ -44,6 +44,8 @@ import java.util.Objects; public class Recipient { + public static final Recipient UNKNOWN = new Recipient(RecipientId.UNKNOWN, new RecipientDetails()); + private final RecipientId id; private final boolean resolving; private final Address address; diff --git a/src/org/thoughtcrime/securesms/recipients/RecipientDetails.java b/src/org/thoughtcrime/securesms/recipients/RecipientDetails.java index a9afda852c..1890662837 100644 --- a/src/org/thoughtcrime/securesms/recipients/RecipientDetails.java +++ b/src/org/thoughtcrime/securesms/recipients/RecipientDetails.java @@ -87,4 +87,34 @@ public class RecipientDetails { if (name == null) this.name = settings.getSystemDisplayName(); else this.name = name; } + + public RecipientDetails() { + this.groupAvatarId = null; + this.systemContactPhoto = null; + this.customLabel = null; + this.contactUri = null; + this.address = Address.UNKNOWN; + this.color = null; + this.messageRingtone = null; + this.callRingtone = null; + this.mutedUntil = 0; + this.messageVibrateState = VibrateState.DEFAULT; + this.callVibrateState = VibrateState.DEFAULT; + this.blocked = false; + this.expireMessages = 0; + this.participants = new LinkedList<>(); + this.profileName = null; + this.seenInviteReminder = true; + this.defaultSubscriptionId = Optional.absent(); + this.registered = RegisteredState.UNKNOWN; + this.profileKey = null; + this.profileAvatar = null; + this.profileSharing = false; + this.systemContact = true; + this.isLocalNumber = false; + this.notificationChannel = null; + this.unidentifiedAccessMode = UnidentifiedAccessMode.UNKNOWN; + this.forceSmsSelection = false; + this.name = null; + } } diff --git a/src/org/thoughtcrime/securesms/recipients/RecipientId.java b/src/org/thoughtcrime/securesms/recipients/RecipientId.java index 9b5f9c1576..be23a92db1 100644 --- a/src/org/thoughtcrime/securesms/recipients/RecipientId.java +++ b/src/org/thoughtcrime/securesms/recipients/RecipientId.java @@ -15,7 +15,10 @@ import java.util.List; public class RecipientId implements Parcelable, Comparable { - private static final char DELIMITER = ','; + private static final long UNKNOWN_ID = -1; + private static final char DELIMITER = ','; + + public static final RecipientId UNKNOWN = RecipientId.from(UNKNOWN_ID); private final long id; @@ -51,6 +54,10 @@ public class RecipientId implements Parcelable, Comparable { return out; } + public boolean isUnknown() { + return id == UNKNOWN_ID; + } + public @NonNull String serialize() { return String.valueOf(id); }