From e945efac8bc26d358a0988ea935a8a40ce587dba Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Fri, 17 Jan 2025 11:18:44 -0500 Subject: [PATCH] Fix 'Unknown' shown for PNI group invites. --- .../conversation/ConversationUpdateItem.java | 6 +-- .../model/GroupCallUpdateMessageFactory.java | 2 +- .../model/GroupsV2UpdateMessageProducer.java | 37 ++++++++++++------- .../database/model/MessageRecord.java | 4 +- .../database/model/UpdateDescription.java | 22 +++++------ .../signalservice/api/push/ServiceId.kt | 7 ++++ 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java index c2e0c33471..f8346cbe70 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java @@ -452,11 +452,11 @@ public final class ConversationUpdateItem extends FrameLayout boolean isRingingOnLocalDevice = groupCallUpdateDetails.isRingingOnLocalDevice; boolean endedRecently = GroupCallUpdateDetailsUtil.checkCallEndedRecently(groupCallUpdateDetails); UpdateDescription updateDescription = MessageRecord.getGroupCallUpdateDescription(getContext(), conversationMessage.getMessageRecord().getBody(), true); - Collection acis = updateDescription.getMentioned(); + Collection serviceIds = updateDescription.getMentioned(); int text = 0; - if (Util.hasItems(acis) || isRingingOnLocalDevice) { - if (acis.contains(SignalStore.account().requireAci())) { + if (Util.hasItems(serviceIds) || isRingingOnLocalDevice) { + if (serviceIds.contains(SignalStore.account().requireAci())) { text = R.string.ConversationUpdateItem_return_to_call; } else if (GroupCallUpdateDetailsUtil.parse(conversationMessage.getMessageRecord().getBody()).isCallFull) { text = R.string.ConversationUpdateItem_call_is_full; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java index 9c1fbb0cd7..866b4c5654 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java @@ -32,7 +32,7 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.Spannabl private final ACI selfAci; public GroupCallUpdateMessageFactory(@NonNull Context context, - @NonNull List joinedMembers, + @NonNull List joinedMembers, boolean withTime, @NonNull GroupCallUpdateDetails groupCallUpdateDetails) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java index 47d2214b80..63cd35bb58 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java @@ -233,9 +233,10 @@ final class GroupsV2UpdateMessageProducer { updates.add(updateDescription(R.string.MessageRecord_s_revoked_your_invitation_to_the_group, update.revokerAci, R.drawable.ic_update_group_decline_16)); } } + private void describeGroupExpirationTimerUpdate(@NonNull GroupExpirationTimerUpdate update, @NonNull List updates) { final int duration = Math.toIntExact(update.expiresInMs / 1000); - String time = ExpirationUtil.getExpirationDisplayValue(context, duration); + String time = ExpirationUtil.getExpirationDisplayValue(context, duration); if (update.updaterAci == null) { updates.add(updateDescription(context.getString(R.string.MessageRecord_disappearing_message_time_set_to_s, time), R.drawable.ic_update_timer_16)); } else { @@ -269,11 +270,13 @@ final class GroupsV2UpdateMessageProducer { } private void describeGroupV2MigrationDroppedMembersUpdate(@NonNull GroupV2MigrationDroppedMembersUpdate update, @NonNull List updates) { - updates.add(updateDescription(context.getResources().getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_removed, update.droppedMembersCount, update.droppedMembersCount), R.drawable.ic_update_group_remove_16)); + updates.add(updateDescription(context.getResources() + .getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_removed, update.droppedMembersCount, update.droppedMembersCount), R.drawable.ic_update_group_remove_16)); } private void describeGroupV2MigrationInvitedMembersUpdate(@NonNull GroupV2MigrationInvitedMembersUpdate update, @NonNull List updates) { - updates.add(updateDescription(context.getResources().getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_invited, update.invitedMembersCount, update.invitedMembersCount), R.drawable.ic_update_group_remove_16)); + updates.add(updateDescription(context.getResources() + .getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_invited, update.invitedMembersCount, update.invitedMembersCount), R.drawable.ic_update_group_remove_16)); } private void describeGroupV2MigrationUpdate(@NonNull GroupV2MigrationUpdate update, @NonNull List updates) { @@ -357,7 +360,7 @@ final class GroupsV2UpdateMessageProducer { boolean requestingMemberIsYou = selfIds.matches(update.requestorAci); if (requestingMemberIsYou) { - updates.add(updateDescription(context.getString(R.string.MessageRecord_you_canceled_your_request_to_join_the_group), R.drawable.ic_update_group_decline_16)); + updates.add(updateDescription(context.getString(R.string.MessageRecord_you_canceled_your_request_to_join_the_group), R.drawable.ic_update_group_decline_16)); } else { updates.add(updateDescription(R.string.MessageRecord_s_canceled_their_request_to_join_the_group, update.requestorAci, R.drawable.ic_update_group_decline_16)); } @@ -501,6 +504,7 @@ final class GroupsV2UpdateMessageProducer { updates.add(updateDescription(R.plurals.MessageRecord_s_invited_members, update.inviteeCount, update.inviterAci, update.inviteeCount, R.drawable.ic_update_group_add_16)); } } + private void describeSelfInvitedOtherUserToGroupUpdate(@NonNull SelfInvitedOtherUserToGroupUpdate update, @NonNull List updates) { updates.add(updateDescription(R.string.MessageRecord_you_invited_s_to_the_group, update.inviteeServiceId, R.drawable.ic_update_group_add_16)); } @@ -662,12 +666,17 @@ final class GroupsV2UpdateMessageProducer { private AccessControl.AccessRequired backupGv2AccessLevelToGroups(@NonNull GroupV2AccessLevel accessLevel) { switch (accessLevel) { - case ANY: return AccessControl.AccessRequired.ANY; - case MEMBER: return AccessControl.AccessRequired.MEMBER; - case ADMINISTRATOR: return AccessControl.AccessRequired.ADMINISTRATOR; - case UNSATISFIABLE: return AccessControl.AccessRequired.UNSATISFIABLE; + case ANY: + return AccessControl.AccessRequired.ANY; + case MEMBER: + return AccessControl.AccessRequired.MEMBER; + case ADMINISTRATOR: + return AccessControl.AccessRequired.ADMINISTRATOR; + case UNSATISFIABLE: + return AccessControl.AccessRequired.UNSATISFIABLE; default: - case UNKNOWN: return AccessControl.AccessRequired.UNKNOWN; + case UNKNOWN: + return AccessControl.AccessRequired.UNKNOWN; } } @@ -1483,7 +1492,7 @@ final class GroupsV2UpdateMessageProducer { @NonNull ByteString serviceId1Bytes, @DrawableRes int iconResource) { - ACI serviceId = ACI.parseOrUnknown(serviceId1Bytes); + ServiceId serviceId = ServiceId.parseOrUnknown(serviceId1Bytes); RecipientId recipientId = RecipientId.from(serviceId); return UpdateDescription.mentioning( @@ -1502,8 +1511,8 @@ final class GroupsV2UpdateMessageProducer { @NonNull ByteString serviceId2Bytes, @DrawableRes int iconResource) { - ACI serviceId1 = ACI.parseOrUnknown(serviceId1Bytes); - ACI serviceId2 = ACI.parseOrUnknown(serviceId2Bytes); + ServiceId serviceId1 = ServiceId.parseOrUnknown(serviceId1Bytes); + ServiceId serviceId2 = ServiceId.parseOrUnknown(serviceId2Bytes); RecipientId recipientId1 = RecipientId.from(serviceId1); RecipientId recipientId2 = RecipientId.from(serviceId2); @@ -1525,7 +1534,7 @@ final class GroupsV2UpdateMessageProducer { @NonNull Object formatArg, @DrawableRes int iconResource) { - ACI serviceId = ACI.parseOrUnknown(serviceId1Bytes); + ServiceId serviceId = ServiceId.parseOrUnknown(serviceId1Bytes); RecipientId recipientId = RecipientId.from(serviceId); return UpdateDescription.mentioning( @@ -1546,7 +1555,7 @@ final class GroupsV2UpdateMessageProducer { @NonNull Object formatArg, @DrawableRes int iconResource) { - ACI serviceId = ACI.parseOrUnknown(serviceId1Bytes); + ServiceId serviceId = ServiceId.parseOrUnknown(serviceId1Bytes); RecipientId recipientId = RecipientId.from(serviceId); return UpdateDescription.mentioning( 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 e2c8a30622..53cfa2c86e 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 @@ -526,10 +526,10 @@ public abstract class MessageRecord extends DisplayRecord { public static @NonNull UpdateDescription getGroupCallUpdateDescription(@NonNull Context context, @NonNull String body, boolean withTime) { GroupCallUpdateDetails groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(body); - List joinedMembers = Stream.of(groupCallUpdateDetails.inCallUuids) + List joinedMembers = Stream.of(groupCallUpdateDetails.inCallUuids) .map(UuidUtil::parseOrNull) .withoutNulls() - .map(ACI::from) + .map(ACI::from) .toList(); UpdateDescription.SpannableFactory stringFactory = new GroupCallUpdateMessageFactory(context, joinedMembers, withTime, groupCallUpdateDetails); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java index 9eaaefb4ee..5cc2923212 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java @@ -30,14 +30,14 @@ public final class UpdateDescription { Spannable create(); } - private final Collection mentioned; - private final SpannableFactory stringFactory; - private final Spannable staticString; - private final int lightIconResource; - private final int lightTint; - private final int darkTint; + private final Collection mentioned; + private final SpannableFactory stringFactory; + private final Spannable staticString; + private final int lightIconResource; + private final int lightTint; + private final int darkTint; - private UpdateDescription(@NonNull Collection mentioned, + private UpdateDescription(@NonNull Collection mentioned, @Nullable SpannableFactory stringFactory, @Nullable Spannable staticString, @DrawableRes int iconResource, @@ -62,11 +62,11 @@ public final class UpdateDescription { * @param mentioned UUIDs of recipients that are mentioned in the string. * @param stringFactory The background method for generating the string. */ - public static UpdateDescription mentioning(@NonNull Collection mentioned, + public static UpdateDescription mentioning(@NonNull Collection mentioned, @NonNull SpannableFactory stringFactory, @DrawableRes int iconResource) { - return new UpdateDescription(mentioned.stream().filter(ACI::isValid).collect(Collectors.toList()), + return new UpdateDescription(mentioned.stream().filter(ServiceId::isValid).collect(Collectors.toList()), stringFactory, null, iconResource, @@ -127,7 +127,7 @@ public final class UpdateDescription { } @AnyThread - public @NonNull Collection getMentioned() { + public @NonNull Collection getMentioned() { return mentioned; } @@ -158,7 +158,7 @@ public final class UpdateDescription { ); } - Set allMentioned = new HashSet<>(); + Set allMentioned = new HashSet<>(); for (UpdateDescription updateDescription : updateDescriptions) { allMentioned.addAll(updateDescription.getMentioned()); diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/ServiceId.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/ServiceId.kt index 0dc4de0076..d5b594b284 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/ServiceId.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/ServiceId.kt @@ -98,6 +98,13 @@ sealed class ServiceId(val libSignalServiceId: LibSignalServiceId) { @JvmStatic @Throws(IllegalArgumentException::class) fun parseOrThrow(bytes: ByteString): ServiceId = parseOrThrow(bytes.toByteArray()) + + /** Parses a ServiceId serialized as a ByteString. Returns [ACI.UNKNOWN] if not parseable. */ + @JvmStatic + @Throws(IllegalArgumentException::class) + fun parseOrUnknown(bytes: ByteString): ServiceId { + return parseOrNull(bytes) ?: ACI.UNKNOWN + } } val rawUuid: UUID = libSignalServiceId.rawUUID