From 52965da8a5f4f12a0cc9a7126908ea2837d7595b Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 30 Sep 2022 10:49:29 -0400 Subject: [PATCH] Stop checking very old capabilities. --- .../InternalConversationSettingsFragment.kt | 29 ++++++---- .../securesms/database/RecipientDatabase.kt | 41 ++++++++++---- .../database/model/RecipientRecord.kt | 34 +++++++++--- .../groups/GroupsV1MigrationUtil.java | 14 +---- .../GroupsV1MigrationRepository.java | 18 +------ .../securesms/jobs/GroupV1MigrationJob.java | 43 --------------- .../jobs/SenderKeyDistributionSendJob.java | 5 -- .../keyvalue/MiscellaneousValues.java | 9 ---- .../logsubmit/LogSectionCapabilities.java | 43 +++++++++------ .../securesms/messages/GroupSendUtil.java | 7 +-- .../messages/MessageDecryptionUtil.java | 2 +- .../securesms/recipients/Recipient.java | 53 +++---------------- .../recipients/RecipientDetails.java | 24 ++------- .../database/RecipientDatabaseTestUtils.kt | 18 ++++--- 14 files changed, 129 insertions(+), 211 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt index 6caa16f27..737861e11 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt @@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.database.SignalDatabase +import org.thoughtcrime.securesms.database.model.RecipientRecord import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -266,17 +267,23 @@ class InternalConversationSettingsFragment : DSLSettingsFragment( } private fun buildCapabilitySpan(recipient: Recipient): CharSequence { - return TextUtils.concat( - colorize("GV1Migration", recipient.groupsV1MigrationCapability), - ", ", - colorize("AnnouncementGroup", recipient.announcementGroupCapability), - ", ", - colorize("SenderKey", recipient.senderKeyCapability), - ", ", - colorize("ChangeNumber", recipient.changeNumberCapability), - ", ", - colorize("Stories", recipient.storiesCapability), - ) + val capabilities: RecipientRecord.Capabilities? = SignalDatabase.recipients.getCapabilities(recipient.id) + + return if (capabilities != null) { + TextUtils.concat( + colorize("GV1Migration", capabilities.groupsV1MigrationCapability), + ", ", + colorize("AnnouncementGroup", capabilities.announcementGroupCapability), + ", ", + colorize("SenderKey", capabilities.senderKeyCapability), + ", ", + colorize("ChangeNumber", capabilities.changeNumberCapability), + ", ", + colorize("Stories", capabilities.storiesCapability), + ) + } else { + "Recipient not found!" + } } private fun colorize(name: String, support: Recipient.Capability): CharSequence { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt index 654919815..76d314f43 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt @@ -3431,6 +3431,21 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : updateExtras(recipientId) { b: RecipientExtras.Builder -> b.setManuallyShownAvatar(true) } } + fun getCapabilities(id: RecipientId): RecipientRecord.Capabilities? { + readableDatabase + .select(CAPABILITIES) + .from(TABLE_NAME) + .where("$ID = ?", id) + .run() + .use { cursor -> + return if (cursor.moveToFirst()) { + readCapabilities(cursor) + } else { + null + } + } + } + private fun updateExtras(recipientId: RecipientId, updater: java.util.function.Function) { val db = writableDatabase db.beginTransaction() @@ -3626,7 +3641,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : SYSTEM_PHONE_LABEL to secondaryRecord.systemPhoneLabel, SYSTEM_CONTACT_URI to secondaryRecord.systemContactUri, PROFILE_SHARING to (primaryRecord.profileSharing || secondaryRecord.profileSharing), - CAPABILITIES to max(primaryRecord.rawCapabilities, secondaryRecord.rawCapabilities), + CAPABILITIES to max(primaryRecord.capabilities.rawBits, secondaryRecord.capabilities.rawBits), MENTION_SETTING to if (primaryRecord.mentionSetting != MentionSetting.ALWAYS_NOTIFY) primaryRecord.mentionSetting.id else secondaryRecord.mentionSetting.id ) @@ -3901,7 +3916,6 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : } val recipientId = RecipientId.from(cursor.requireLong(idColumnName)) - val capabilities = cursor.requireLong(CAPABILITIES) val distributionListId: DistributionListId? = DistributionListId.fromNullable(cursor.requireLong(DISTRIBUTION_LIST_ID)) val avatarColor: AvatarColor = if (distributionListId != null) AvatarColor.UNKNOWN else AvatarColor.deserialize(cursor.requireString(AVATAR_COLOR)) @@ -3939,14 +3953,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : notificationChannel = cursor.requireString(NOTIFICATION_CHANNEL), unidentifiedAccessMode = UnidentifiedAccessMode.fromMode(cursor.requireInt(UNIDENTIFIED_ACCESS_MODE)), forceSmsSelection = cursor.requireBoolean(FORCE_SMS_SELECTION), - rawCapabilities = capabilities, - groupsV1MigrationCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.GROUPS_V1_MIGRATION, Capabilities.BIT_LENGTH).toInt()), - senderKeyCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.SENDER_KEY, Capabilities.BIT_LENGTH).toInt()), - announcementGroupCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.ANNOUNCEMENT_GROUPS, Capabilities.BIT_LENGTH).toInt()), - changeNumberCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.CHANGE_NUMBER, Capabilities.BIT_LENGTH).toInt()), - storiesCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.STORIES, Capabilities.BIT_LENGTH).toInt()), - giftBadgesCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.GIFT_BADGES, Capabilities.BIT_LENGTH).toInt()), - pnpCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.PNP, Capabilities.BIT_LENGTH).toInt()), + capabilities = readCapabilities(cursor), insightsBannerTier = InsightsBannerTier.fromId(cursor.requireInt(SEEN_INVITE_REMINDER)), storageId = Base64.decodeNullableOrThrow(cursor.requireString(STORAGE_SERVICE_ID)), mentionSetting = MentionSetting.fromId(cursor.requireInt(MENTION_SETTING)), @@ -3964,6 +3971,20 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : ) } + private fun readCapabilities(cursor: Cursor): RecipientRecord.Capabilities { + val capabilities = cursor.requireLong(CAPABILITIES) + return RecipientRecord.Capabilities( + rawBits = capabilities, + groupsV1MigrationCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.GROUPS_V1_MIGRATION, Capabilities.BIT_LENGTH).toInt()), + senderKeyCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.SENDER_KEY, Capabilities.BIT_LENGTH).toInt()), + announcementGroupCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.ANNOUNCEMENT_GROUPS, Capabilities.BIT_LENGTH).toInt()), + changeNumberCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.CHANGE_NUMBER, Capabilities.BIT_LENGTH).toInt()), + storiesCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.STORIES, Capabilities.BIT_LENGTH).toInt()), + giftBadgesCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.GIFT_BADGES, Capabilities.BIT_LENGTH).toInt()), + pnpCapability = Recipient.Capability.deserialize(Bitmask.read(capabilities, Capabilities.PNP, Capabilities.BIT_LENGTH).toInt()), + ) + } + private fun parseBadgeList(serializedBadgeList: ByteArray?): List { var badgeList: BadgeList? = null if (serializedBadgeList != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt index 80a23c849..118909df9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt @@ -63,14 +63,7 @@ data class RecipientRecord( val unidentifiedAccessMode: UnidentifiedAccessMode, @get:JvmName("isForceSmsSelection") val forceSmsSelection: Boolean, - val rawCapabilities: Long, - val groupsV1MigrationCapability: Recipient.Capability, - val senderKeyCapability: Recipient.Capability, - val announcementGroupCapability: Recipient.Capability, - val changeNumberCapability: Recipient.Capability, - val storiesCapability: Recipient.Capability, - val giftBadgesCapability: Recipient.Capability, - val pnpCapability: Recipient.Capability, + val capabilities: Capabilities, val insightsBannerTier: InsightsBannerTier, val storageId: ByteArray?, val mentionSetting: MentionSetting, @@ -122,4 +115,29 @@ data class RecipientRecord( val isForcedUnread: Boolean, val unregisteredTimestamp: Long ) + + data class Capabilities( + val rawBits: Long, + val groupsV1MigrationCapability: Recipient.Capability, + val senderKeyCapability: Recipient.Capability, + val announcementGroupCapability: Recipient.Capability, + val changeNumberCapability: Recipient.Capability, + val storiesCapability: Recipient.Capability, + val giftBadgesCapability: Recipient.Capability, + val pnpCapability: Recipient.Capability, + ) { + companion object { + @JvmField + val UNKNOWN = Capabilities( + 0, + Recipient.Capability.UNKNOWN, + Recipient.Capability.UNKNOWN, + Recipient.Capability.UNKNOWN, + Recipient.Capability.UNKNOWN, + Recipient.Capability.UNKNOWN, + Recipient.Capability.UNKNOWN, + Recipient.Capability.UNKNOWN + ) + } + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java index e45b76c68..f6c8fb0c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java @@ -88,7 +88,7 @@ public final class GroupsV1MigrationUtil { registeredMembers = Stream.of(registeredMembers).map(Recipient::fresh).toList(); } - List possibleMembers = forced ? getMigratableManualMigrationMembers(registeredMembers) + List possibleMembers = forced ? registeredMembers : getMigratableAutoMigrationMembers(registeredMembers); if (!forced && !groupRecipient.hasName()) { @@ -200,17 +200,8 @@ public final class GroupsV1MigrationUtil { * to consider them migratable in an auto-migration. */ private static @NonNull List getMigratableAutoMigrationMembers(@NonNull List registeredMembers) { - return Stream.of(getMigratableManualMigrationMembers(registeredMembers)) - .filter(r -> r.getProfileKey() != null) - .toList(); - } - - /** - * You can only migrate users that have the required capabilities. - */ - private static @NonNull List getMigratableManualMigrationMembers(@NonNull List registeredMembers) { return Stream.of(registeredMembers) - .filter(r -> r.getGroupsV1MigrationCapability() == Recipient.Capability.SUPPORTED) + .filter(r -> r.getProfileKey() != null) .toList(); } @@ -219,7 +210,6 @@ public final class GroupsV1MigrationUtil { */ public static boolean isAutoMigratable(@NonNull Recipient recipient) { return recipient.hasServiceId() && - recipient.getGroupsV1MigrationCapability() == Recipient.Capability.SUPPORTED && recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED && recipient.getProfileKey() != null; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java index 9f827a119..e813f9270 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java @@ -68,19 +68,7 @@ final class GroupsV1MigrationRepository { return new MigrationState(Collections.emptyList(), Collections.emptyList()); } - List members = Recipient.resolvedList(group.getParticipantIds()); - Set needsRefresh = Stream.of(members) - .filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED) - .map(Recipient::getId) - .collect(Collectors.toSet()); - - List jobs = RetrieveProfileJob.forRecipients(needsRefresh); - - for (Job job : jobs) { - if (!ApplicationDependencies.getJobManager().runSynchronously(job, TimeUnit.SECONDS.toMillis(3)).isPresent()) { - Log.w(TAG, "Failed to refresh capabilities in time!"); - } - } + List members = Recipient.resolvedList(group.getParticipantIds()); try { List registered = Stream.of(members) @@ -95,9 +83,7 @@ final class GroupsV1MigrationRepository { group = group.fresh(); List ineligible = Stream.of(members) - .filter(r -> !r.hasServiceId() || - r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED || - r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED) + .filter(r -> !r.hasServiceId() || r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED) .toList(); List invites = Stream.of(members) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java index 2f37c995a..36e423e44 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java @@ -66,49 +66,6 @@ public class GroupV1MigrationJob extends BaseJob { }); } - public static void enqueueRoutineMigrationsIfNecessary(@NonNull Application application) { - if (!SignalStore.registrationValues().isRegistrationComplete() || - !SignalStore.account().isRegistered() || - SignalStore.account().getAci() == null) - { - Log.i(TAG, "Registration not complete. Skipping."); - return; - } - - long timeSinceRefresh = System.currentTimeMillis() - SignalStore.misc().getLastGv1RoutineMigrationTime(); - - if (timeSinceRefresh < REFRESH_INTERVAL) { - Log.i(TAG, "Too soon to refresh. Did the last refresh " + timeSinceRefresh + " ms ago."); - return; - } - - SignalStore.misc().setLastGv1RoutineMigrationTime(System.currentTimeMillis()); - - SignalExecutors.BOUNDED.execute(() -> { - JobManager jobManager = ApplicationDependencies.getJobManager(); - List threads = SignalDatabase.threads().getRecentV1Groups(ROUTINE_LIMIT); - Set needsRefresh = new HashSet<>(); - - if (threads.size() > 0) { - Log.d(TAG, "About to enqueue refreshes for " + threads.size() + " groups."); - } - - for (ThreadRecord thread : threads) { - jobManager.add(new GroupV1MigrationJob(thread.getRecipient().getId())); - - needsRefresh.addAll(Stream.of(Recipient.resolvedList(thread.getRecipient().getParticipantIds())) - .filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED) - .map(Recipient::getId) - .toList()); - } - - if (needsRefresh.size() > 0) { - Log.w(TAG, "Enqueuing profile refreshes for " + needsRefresh.size() + " GV1 participants."); - RetrieveProfileJob.enqueue(needsRefresh); - } - }); - } - @Override public @NonNull Data serialize() { return new Data.Builder().putString(KEY_RECIPIENT_ID, recipientId.serialize()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java index 55a329100..eaeea0af5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java @@ -79,11 +79,6 @@ public final class SenderKeyDistributionSendJob extends BaseJob { Recipient targetRecipient = Recipient.resolved(targetRecipientId); Recipient threadRecipient = Recipient.resolved(threadRecipientId); - if (targetRecipient.getSenderKeyCapability() != Recipient.Capability.SUPPORTED) { - Log.w(TAG, targetRecipientId + " does not support sender key! Not sending."); - return; - } - if (targetRecipient.isUnregistered()) { Log.w(TAG, threadRecipient.getId() + " not registered!"); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java index 8b35d39b5..104636d9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java @@ -13,7 +13,6 @@ public final class MiscellaneousValues extends SignalStoreValues { private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time"; private static final String MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time"; private static final String LAST_PROFILE_REFRESH_TIME = "misc.last_profile_refresh_time"; - private static final String LAST_GV1_ROUTINE_MIGRATION_TIME = "misc.last_gv1_routine_migration_time"; private static final String USERNAME_SHOW_REMINDER = "username.show.reminder"; private static final String CLIENT_DEPRECATED = "misc.client_deprecated"; private static final String OLD_DEVICE_TRANSFER_LOCKED = "misc.old_device.transfer.locked"; @@ -62,14 +61,6 @@ public final class MiscellaneousValues extends SignalStoreValues { putLong(LAST_PROFILE_REFRESH_TIME, time); } - public long getLastGv1RoutineMigrationTime() { - return getLong(LAST_GV1_ROUTINE_MIGRATION_TIME, 0); - } - - public void setLastGv1RoutineMigrationTime(long time) { - putLong(LAST_GV1_ROUTINE_MIGRATION_TIME, time); - } - public void hideUsernameReminder() { putBoolean(USERNAME_SHOW_REMINDER, false); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java index 7f2f2bbf0..acec125f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java @@ -5,6 +5,9 @@ import android.content.Context; import androidx.annotation.NonNull; import org.thoughtcrime.securesms.AppCapabilities; +import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; +import org.thoughtcrime.securesms.database.model.RecipientRecord; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.whispersystems.signalservice.api.account.AccountAttributes; @@ -28,23 +31,31 @@ public final class LogSectionCapabilities implements LogSection { Recipient self = Recipient.self(); - AccountAttributes.Capabilities capabilities = AppCapabilities.getCapabilities(false); + AccountAttributes.Capabilities localCapabilities = AppCapabilities.getCapabilities(false); + RecipientRecord.Capabilities globalCapabilities = SignalDatabase.recipients().getCapabilities(self.getId()); - return new StringBuilder().append("-- Local").append("\n") - .append("GV2 : ").append(capabilities.isGv2()).append("\n") - .append("GV1 Migration : ").append(capabilities.isGv1Migration()).append("\n") - .append("Sender Key : ").append(capabilities.isSenderKey()).append("\n") - .append("Announcement Groups: ").append(capabilities.isAnnouncementGroup()).append("\n") - .append("Change Number : ").append(capabilities.isChangeNumber()).append("\n") - .append("Stories : ").append(capabilities.isStories()).append("\n") - .append("Gift Badges : ").append(capabilities.isGiftBadges()).append("\n") + StringBuilder builder = new StringBuilder().append("-- Local").append("\n") + .append("GV2 : ").append(localCapabilities.isGv2()).append("\n") + .append("GV1 Migration : ").append(localCapabilities.isGv1Migration()).append("\n") + .append("Sender Key : ").append(localCapabilities.isSenderKey()).append("\n") + .append("Announcement Groups: ").append(localCapabilities.isAnnouncementGroup()).append("\n") + .append("Change Number : ").append(localCapabilities.isChangeNumber()).append("\n") + .append("Stories : ").append(localCapabilities.isStories()).append("\n") + .append("Gift Badges : ").append(localCapabilities.isGiftBadges()).append("\n") .append("\n") - .append("-- Global").append("\n") - .append("GV1 Migration : ").append(self.getGroupsV1MigrationCapability()).append("\n") - .append("Sender Key : ").append(self.getSenderKeyCapability()).append("\n") - .append("Announcement Groups: ").append(self.getAnnouncementGroupCapability()).append("\n") - .append("Change Number : ").append(self.getChangeNumberCapability()).append("\n") - .append("Stories : ").append(self.getStoriesCapability()).append("\n") - .append("Gift Badges : ").append(self.getGiftBadgesCapability()).append("\n"); + .append("-- Global").append("\n"); + + if (globalCapabilities != null) { + builder.append("GV1 Migration : ").append(globalCapabilities.getGroupsV1MigrationCapability()).append("\n") + .append("Sender Key : ").append(globalCapabilities.getSenderKeyCapability()).append("\n") + .append("Announcement Groups: ").append(globalCapabilities.getAnnouncementGroupCapability()).append("\n") + .append("Change Number : ").append(globalCapabilities.getChangeNumberCapability()).append("\n") + .append("Stories : ").append(globalCapabilities.getStoriesCapability()).append("\n") + .append("Gift Badges : ").append(globalCapabilities.getGiftBadgesCapability()).append("\n"); + } else { + builder.append("Self not found!"); + } + + return builder; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java b/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java index 5b083501c..fbf9886ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java @@ -242,8 +242,7 @@ public final class GroupSendUtil { validMembership = false; } - if (recipient.getSenderKeyCapability() == Recipient.Capability.SUPPORTED && - recipient.hasServiceId() && + if (recipient.hasServiceId() && access.isPresent() && access.get().getTargetUnidentifiedAccess().isPresent() && validMembership) @@ -258,10 +257,6 @@ public final class GroupSendUtil { Log.i(TAG, "No DistributionId. Using legacy."); legacyTargets.addAll(senderKeyTargets); senderKeyTargets.clear(); - } else if (Recipient.self().getSenderKeyCapability() != Recipient.Capability.SUPPORTED) { - Log.i(TAG, "All of our devices do not support sender key. Using legacy."); - legacyTargets.addAll(senderKeyTargets); - senderKeyTargets.clear(); } else if (SignalStore.internalValues().removeSenderKeyMinimum()) { Log.i(TAG, "Sender key minimum removed. Using for " + senderKeyTargets.size() + " recipients."); } else if (senderKeyTargets.size() < 2) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java index e97fa69db..819a9c923 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java @@ -127,7 +127,7 @@ public final class MessageDecryptionUtil { Log.w(TAG, String.valueOf(envelope.getTimestamp()), e, true); Recipient sender = Recipient.external(context, e.getSender()); - if (sender.supportsMessageRetries() && Recipient.self().supportsMessageRetries() && FeatureFlags.retryReceipts()) { + if (FeatureFlags.retryReceipts()) { jobs.add(handleRetry(context, sender, envelope, e)); postInternalErrorNotification(context); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index e89f9082e..de69e8e43 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.DistributionListId; import org.thoughtcrime.securesms.database.model.ProfileAvatarFileDetails; +import org.thoughtcrime.securesms.database.model.RecipientRecord; import org.thoughtcrime.securesms.database.model.databaseprotos.RecipientExtras; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; @@ -118,13 +119,7 @@ public class Recipient { private final String notificationChannel; private final UnidentifiedAccessMode unidentifiedAccessMode; private final boolean forceSmsSelection; - private final Capability groupsV1MigrationCapability; - private final Capability senderKeyCapability; - private final Capability announcementGroupCapability; - private final Capability changeNumberCapability; - private final Capability storiesCapability; - private final Capability giftBadgesCapability; - private final Capability pnpCapability; + private final RecipientRecord.Capabilities capabilities; private final InsightsBannerTier insightsBannerTier; private final byte[] storageId; private final MentionSetting mentionSetting; @@ -421,13 +416,7 @@ public class Recipient { this.notificationChannel = null; this.unidentifiedAccessMode = UnidentifiedAccessMode.DISABLED; this.forceSmsSelection = false; - this.groupsV1MigrationCapability = Capability.UNKNOWN; - this.senderKeyCapability = Capability.UNKNOWN; - this.announcementGroupCapability = Capability.UNKNOWN; - this.changeNumberCapability = Capability.UNKNOWN; - this.storiesCapability = Capability.UNKNOWN; - this.giftBadgesCapability = Capability.UNKNOWN; - this.pnpCapability = Capability.UNKNOWN; + this.capabilities = RecipientRecord.Capabilities.UNKNOWN; this.storageId = null; this.mentionSetting = MentionSetting.ALWAYS_NOTIFY; this.wallpaper = null; @@ -481,13 +470,7 @@ public class Recipient { this.notificationChannel = details.notificationChannel; this.unidentifiedAccessMode = details.unidentifiedAccessMode; this.forceSmsSelection = details.forceSmsSelection; - this.groupsV1MigrationCapability = details.groupsV1MigrationCapability; - this.senderKeyCapability = details.senderKeyCapability; - this.announcementGroupCapability = details.announcementGroupCapability; - this.changeNumberCapability = details.changeNumberCapability; - this.storiesCapability = details.storiesCapability; - this.giftBadgesCapability = details.giftBadgesCapability; - this.pnpCapability = details.pnpCapability; + this.capabilities = details.capabilities; this.storageId = details.storageId; this.mentionSetting = details.mentionSetting; this.wallpaper = details.wallpaper; @@ -1022,39 +1005,20 @@ public class Recipient { return forceSmsSelection; } - public @NonNull Capability getGroupsV1MigrationCapability() { - return groupsV1MigrationCapability; - } - - public @NonNull Capability getSenderKeyCapability() { - return senderKeyCapability; - } - - public @NonNull Capability getAnnouncementGroupCapability() { - return announcementGroupCapability; - } - public @NonNull Capability getChangeNumberCapability() { - return changeNumberCapability; + return capabilities.getChangeNumberCapability(); } public @NonNull Capability getStoriesCapability() { - return storiesCapability; + return capabilities.getStoriesCapability(); } public @NonNull Capability getGiftBadgesCapability() { - return giftBadgesCapability; + return capabilities.getGiftBadgesCapability(); } public @NonNull Capability getPnpCapability() { - return pnpCapability; - } - - /** - * True if this recipient supports the message retry system, or false if we should use the legacy session reset system. - */ - public boolean supportsMessageRetries() { - return getSenderKeyCapability() == Capability.SUPPORTED; + return capabilities.getPnpCapability(); } public @Nullable byte[] getProfileKey() { @@ -1336,7 +1300,6 @@ public class Recipient { Objects.equals(profileAvatar, other.profileAvatar) && Objects.equals(notificationChannel, other.notificationChannel) && unidentifiedAccessMode == other.unidentifiedAccessMode && - groupsV1MigrationCapability == other.groupsV1MigrationCapability && insightsBannerTier == other.insightsBannerTier && Arrays.equals(storageId, other.storageId) && mentionSetting == other.mentionSetting && diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java index 98be1ce31..4d854eb46 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java @@ -69,13 +69,7 @@ public class RecipientDetails { final String notificationChannel; final UnidentifiedAccessMode unidentifiedAccessMode; final boolean forceSmsSelection; - final Recipient.Capability groupsV1MigrationCapability; - final Recipient.Capability senderKeyCapability; - final Recipient.Capability announcementGroupCapability; - final Recipient.Capability changeNumberCapability; - final Recipient.Capability storiesCapability; - final Recipient.Capability giftBadgesCapability; - final Recipient.Capability pnpCapability; + final RecipientRecord.Capabilities capabilities; final InsightsBannerTier insightsBannerTier; final byte[] storageId; final MentionSetting mentionSetting; @@ -134,13 +128,7 @@ public class RecipientDetails { this.notificationChannel = record.getNotificationChannel(); this.unidentifiedAccessMode = record.getUnidentifiedAccessMode(); this.forceSmsSelection = record.isForceSmsSelection(); - this.groupsV1MigrationCapability = record.getGroupsV1MigrationCapability(); - this.senderKeyCapability = record.getSenderKeyCapability(); - this.announcementGroupCapability = record.getAnnouncementGroupCapability(); - this.changeNumberCapability = record.getChangeNumberCapability(); - this.storiesCapability = record.getStoriesCapability(); - this.giftBadgesCapability = record.getGiftBadgesCapability(); - this.pnpCapability = record.getPnpCapability(); + this.capabilities = record.getCapabilities(); this.insightsBannerTier = record.getInsightsBannerTier(); this.storageId = record.getStorageId(); this.mentionSetting = record.getMentionSetting(); @@ -195,13 +183,7 @@ public class RecipientDetails { this.unidentifiedAccessMode = UnidentifiedAccessMode.UNKNOWN; this.forceSmsSelection = false; this.groupName = null; - this.groupsV1MigrationCapability = Recipient.Capability.UNKNOWN; - this.senderKeyCapability = Recipient.Capability.UNKNOWN; - this.announcementGroupCapability = Recipient.Capability.UNKNOWN; - this.changeNumberCapability = Recipient.Capability.UNKNOWN; - this.storiesCapability = Recipient.Capability.UNKNOWN; - this.giftBadgesCapability = Recipient.Capability.UNKNOWN; - this.pnpCapability = Recipient.Capability.UNKNOWN; + this.capabilities = RecipientRecord.Capabilities.UNKNOWN; this.storageId = null; this.mentionSetting = MentionSetting.ALWAYS_NOTIFY; this.wallpaper = null; diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt index 570af53f2..16ee8025e 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt @@ -127,14 +127,16 @@ object RecipientDatabaseTestUtils { notificationChannel, unidentifiedAccessMode, forceSmsSelection, - capabilities, - Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.GROUPS_V1_MIGRATION, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), - Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.SENDER_KEY, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), - Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.ANNOUNCEMENT_GROUPS, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), - Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.CHANGE_NUMBER, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), - Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.STORIES, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), - Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.GIFT_BADGES, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), - Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.PNP, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + RecipientRecord.Capabilities( + capabilities, + Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.GROUPS_V1_MIGRATION, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.SENDER_KEY, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.ANNOUNCEMENT_GROUPS, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.CHANGE_NUMBER, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.STORIES, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.GIFT_BADGES, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + Recipient.Capability.deserialize(Bitmask.read(capabilities, RecipientDatabase.Capabilities.PNP, RecipientDatabase.Capabilities.BIT_LENGTH).toInt()), + ), insightBannerTier, storageId, mentionSetting,