Improve cold start performance.

fork-5.53.8
Cody Henthorne 2022-07-21 12:29:58 -04:00
rodzic d159a0482a
commit fe6058e0df
28 zmienionych plików z 82 dodań i 97 usunięć

Wyświetl plik

@ -381,7 +381,7 @@ sealed class ConversationSettingsViewModel(
private fun getLegacyGroupState(recipient: Recipient): LegacyGroupPreference.State { private fun getLegacyGroupState(recipient: Recipient): LegacyGroupPreference.State {
val showLegacyInfo = recipient.requireGroupId().isV1 val showLegacyInfo = recipient.requireGroupId().isV1
return if (showLegacyInfo && recipient.participants.size > FeatureFlags.groupLimits().hardLimit) { return if (showLegacyInfo && recipient.participantIds.size > FeatureFlags.groupLimits().hardLimit) {
LegacyGroupPreference.State.TOO_LARGE LegacyGroupPreference.State.TOO_LARGE
} else if (showLegacyInfo) { } else if (showLegacyInfo) {
LegacyGroupPreference.State.UPGRADE LegacyGroupPreference.State.UPGRADE

Wyświetl plik

@ -216,7 +216,7 @@ public class ContactSelectionListItem extends ConstraintLayout implements Recipi
if (!recipient.isGroup()) { if (!recipient.isGroup()) {
throw new AssertionError(); throw new AssertionError();
} }
int memberCount = recipient.getParticipants().size(); int memberCount = recipient.getParticipantIds().size();
return getContext().getResources().getQuantityString(R.plurals.contact_selection_list_item__number_of_members, memberCount, memberCount); return getContext().getResources().getQuantityString(R.plurals.contact_selection_list_item__number_of_members, memberCount, memberCount);
} }

Wyświetl plik

@ -101,7 +101,7 @@ object ContactSearchItems {
number.visible = true number.visible = true
val count = if (model.story.recipient.isGroup) { val count = if (model.story.recipient.isGroup) {
model.story.recipient.participants.size model.story.recipient.participantIds.size
} else { } else {
model.story.viewerCount model.story.viewerCount
} }
@ -227,8 +227,9 @@ object ContactSearchItems {
protected open fun bindNumberField(model: T) { protected open fun bindNumberField(model: T) {
number.visible = getRecipient(model).isGroup number.visible = getRecipient(model).isGroup
if (getRecipient(model).isGroup) { if (getRecipient(model).isGroup) {
number.text = getRecipient(model).participants number.text = getRecipient(model).participantIds
.take(10) .take(10)
.map { id -> Recipient.resolved(id) }
.sortedWith(IsSelfComparator()).joinToString(", ") { .sortedWith(IsSelfComparator()).joinToString(", ") {
if (it.isSelf) { if (it.isSelf) {
context.getString(R.string.ConversationTitleView_you) context.getString(R.string.ConversationTitleView_you)

Wyświetl plik

@ -84,7 +84,7 @@ open class ContactSearchPagedDataSourceRepository(
open fun getGroupStories(): Set<ContactSearchData.Story> { open fun getGroupStories(): Set<ContactSearchData.Story> {
return SignalDatabase.groups.groupsToDisplayAsStories.map { return SignalDatabase.groups.groupsToDisplayAsStories.map {
val recipient = Recipient.resolved(SignalDatabase.recipients.getOrInsertFromGroupId(it)) val recipient = Recipient.resolved(SignalDatabase.recipients.getOrInsertFromGroupId(it))
ContactSearchData.Story(recipient, recipient.participants.size) ContactSearchData.Story(recipient, recipient.participantIds.size)
}.toSet() }.toSet()
} }

Wyświetl plik

@ -92,7 +92,7 @@ class ContactSearchViewModel(
state.copy( state.copy(
groupStories = state.groupStories + groupStories.map { groupStories = state.groupStories + groupStories.map {
val recipient = Recipient.resolved(it.recipientId) val recipient = Recipient.resolved(it.recipientId)
ContactSearchData.Story(recipient, recipient.participants.size) ContactSearchData.Story(recipient, recipient.participantIds.size)
} }
) )
} }

Wyświetl plik

@ -329,8 +329,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.Disposable;
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
@ -2359,8 +2357,8 @@ public class ConversationParentFragment extends Fragment
return annotations; return annotations;
} }
Set<String> validRecipientIds = Stream.of(getRecipient().getParticipants()) Set<String> validRecipientIds = Stream.of(getRecipient().getParticipantIds())
.map(r -> MentionAnnotation.idToMentionAnnotationValue(r.getId())) .map(id -> MentionAnnotation.idToMentionAnnotationValue(id))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return Stream.of(annotations) return Stream.of(annotations)

Wyświetl plik

@ -192,7 +192,9 @@ public class ConversationTitleView extends RelativeLayout {
private void setGroupRecipientTitle(@NonNull Recipient recipient) { private void setGroupRecipientTitle(@NonNull Recipient recipient) {
this.title.setText(recipient.getDisplayName(getContext())); this.title.setText(recipient.getDisplayName(getContext()));
this.subtitle.setText(Stream.of(recipient.getParticipants()) this.subtitle.setText(Stream.of(recipient.getParticipantIds())
.limit(10)
.map(Recipient::resolved)
.sorted((a, b) -> Boolean.compare(a.isSelf(), b.isSelf())) .sorted((a, b) -> Boolean.compare(a.isSelf(), b.isSelf()))
.map(r -> r.isSelf() ? getResources().getString(R.string.ConversationTitleView_you) .map(r -> r.isSelf() ? getResources().getString(R.string.ConversationTitleView_you)
: r.getDisplayName(getContext())) : r.getDisplayName(getContext()))

Wyświetl plik

@ -70,7 +70,7 @@ abstract class ConversationListDataSource implements PagedDataSource<Long, Conve
recipients.add(record.getRecipient()); recipients.add(record.getRecipient());
needsResolve.add(record.getGroupMessageSender()); needsResolve.add(record.getGroupMessageSender());
if (!record.getRecipient().isPushV2Group()) { if (!SmsDatabase.Types.isGroupV2(record.getType())) {
needsResolve.add(record.getRecipient().getId()); needsResolve.add(record.getRecipient().getId());
} else if (SmsDatabase.Types.isGroupUpdate(record.getType())) { } else if (SmsDatabase.Types.isGroupUpdate(record.getType())) {
UpdateDescription description = MessageRecord.getGv2ChangeDescription(ApplicationDependencies.getApplication(), record.getBody(), null); UpdateDescription description = MessageRecord.getGv2ChangeDescription(ApplicationDependencies.getApplication(), record.getBody(), null);

Wyświetl plik

@ -426,7 +426,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
ConversationFragment.prepare(requireContext());
ApplicationDependencies.getAppForegroundObserver().addListener(appForegroundObserver); ApplicationDependencies.getAppForegroundObserver().addListener(appForegroundObserver);
itemAnimator.disable(); itemAnimator.disable();
} }
@ -689,6 +688,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
AppStartup.getInstance().onCriticalRenderEventEnd(); AppStartup.getInstance().onCriticalRenderEventEnd();
startupStopwatch.split("first-render"); startupStopwatch.split("first-render");
startupStopwatch.stop(TAG); startupStopwatch.stop(TAG);
ConversationFragment.prepare(requireContext());
}); });
} }
}); });

Wyświetl plik

@ -2892,7 +2892,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
*/ */
fun getRecipientsForRoutineProfileFetch(lastInteractionThreshold: Long, lastProfileFetchThreshold: Long, limit: Int): List<RecipientId> { fun getRecipientsForRoutineProfileFetch(lastInteractionThreshold: Long, lastProfileFetchThreshold: Long, limit: Int): List<RecipientId> {
val threadDatabase = threads val threadDatabase = threads
val recipientsWithinInteractionThreshold: MutableSet<Recipient> = LinkedHashSet() val recipientsWithinInteractionThreshold: MutableSet<RecipientId> = LinkedHashSet()
threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(-1, false)).use { reader -> threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(-1, false)).use { reader ->
var record: ThreadRecord? = reader.next var record: ThreadRecord? = reader.next
@ -2900,15 +2900,16 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
while (record != null && record.date > lastInteractionThreshold) { while (record != null && record.date > lastInteractionThreshold) {
val recipient = Recipient.resolved(record.recipient.id) val recipient = Recipient.resolved(record.recipient.id)
if (recipient.isGroup) { if (recipient.isGroup) {
recipientsWithinInteractionThreshold.addAll(recipient.participants) recipientsWithinInteractionThreshold.addAll(recipient.participantIds)
} else { } else {
recipientsWithinInteractionThreshold.add(recipient) recipientsWithinInteractionThreshold.add(recipient.id)
} }
record = reader.next record = reader.next
} }
} }
return recipientsWithinInteractionThreshold return Recipient.resolvedList(recipientsWithinInteractionThreshold)
.asSequence()
.filterNot { it.isSelf } .filterNot { it.isSelf }
.filter { it.lastProfileFetchTime < lastProfileFetchThreshold } .filter { it.lastProfileFetchTime < lastProfileFetchThreshold }
.take(limit) .take(limit)

Wyświetl plik

@ -52,8 +52,8 @@ public final class GroupsV1MigrationUtil {
throw new InvalidMigrationStateException(); throw new InvalidMigrationStateException();
} }
if (groupRecipient.getParticipants().size() > FeatureFlags.groupLimits().getHardLimit()) { if (groupRecipient.getParticipantIds().size() > FeatureFlags.groupLimits().getHardLimit()) {
Log.w(TAG, "Too many members! Size: " + groupRecipient.getParticipants().size()); Log.w(TAG, "Too many members! Size: " + groupRecipient.getParticipantIds().size());
throw new InvalidMigrationStateException(); throw new InvalidMigrationStateException();
} }
@ -86,7 +86,7 @@ public final class GroupsV1MigrationUtil {
throw new InvalidMigrationStateException(); throw new InvalidMigrationStateException();
} }
List<Recipient> registeredMembers = RecipientUtil.getEligibleForSending(groupRecipient.getParticipants()); List<Recipient> registeredMembers = RecipientUtil.getEligibleForSending(Recipient.resolvedList(groupRecipient.getParticipantIds()));
if (RecipientUtil.ensureUuidsAreAvailable(context, registeredMembers)) { if (RecipientUtil.ensureUuidsAreAvailable(context, registeredMembers)) {
Log.i(TAG, "Newly-discovered UUIDs. Getting fresh recipients."); Log.i(TAG, "Newly-discovered UUIDs. Getting fresh recipients.");

Wyświetl plik

@ -68,7 +68,8 @@ final class GroupsV1MigrationRepository {
return new MigrationState(Collections.emptyList(), Collections.emptyList()); return new MigrationState(Collections.emptyList(), Collections.emptyList());
} }
Set<RecipientId> needsRefresh = Stream.of(group.getParticipants()) List<Recipient> members = Recipient.resolvedList(group.getParticipantIds());
Set<RecipientId> needsRefresh = Stream.of(members)
.filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED) .filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED)
.map(Recipient::getId) .map(Recipient::getId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
@ -82,7 +83,7 @@ final class GroupsV1MigrationRepository {
} }
try { try {
List<Recipient> registered = Stream.of(group.getParticipants()) List<Recipient> registered = Stream.of(members)
.filter(Recipient::isRegistered) .filter(Recipient::isRegistered)
.toList(); .toList();
@ -93,13 +94,13 @@ final class GroupsV1MigrationRepository {
group = group.fresh(); group = group.fresh();
List<Recipient> ineligible = Stream.of(group.getParticipants()) List<Recipient> ineligible = Stream.of(members)
.filter(r -> !r.hasServiceId() || .filter(r -> !r.hasServiceId() ||
r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED || r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED ||
r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED) r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED)
.toList(); .toList();
List<Recipient> invites = Stream.of(group.getParticipants()) List<Recipient> invites = Stream.of(members)
.filterNot(ineligible::contains) .filterNot(ineligible::contains)
.filterNot(Recipient::isSelf) .filterNot(Recipient::isSelf)
.filter(r -> r.getProfileKey() == null) .filter(r -> r.getProfileKey() == null)

Wyświetl plik

@ -21,7 +21,6 @@ import org.whispersystems.signalservice.api.crypto.ContentHint;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.messages.SendMessageResult;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException; import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import java.io.IOException; import java.io.IOException;
@ -57,15 +56,15 @@ public class GroupCallUpdateSendJob extends BaseJob {
throw new AssertionError("We have a recipient, but it's not a V2 Group"); throw new AssertionError("We have a recipient, but it's not a V2 Group");
} }
List<RecipientId> recipients = Stream.of(RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants())) List<RecipientId> recipientIds = Stream.of(RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds())))
.filterNot(Recipient::isSelf) .filterNot(Recipient::isSelf)
.map(Recipient::getId) .map(Recipient::getId)
.toList(); .toList();
return new GroupCallUpdateSendJob(recipientId, return new GroupCallUpdateSendJob(recipientId,
eraId, eraId,
recipients, recipientIds,
recipients.size(), recipientIds.size(),
new Parameters.Builder() new Parameters.Builder()
.setQueue(conversationRecipient.getId().toQueueKey()) .setQueue(conversationRecipient.getId().toQueueKey())
.setLifespan(TimeUnit.MINUTES.toMillis(5)) .setLifespan(TimeUnit.MINUTES.toMillis(5))

Wyświetl plik

@ -96,7 +96,7 @@ public class GroupV1MigrationJob extends BaseJob {
for (ThreadRecord thread : threads) { for (ThreadRecord thread : threads) {
jobManager.add(new GroupV1MigrationJob(thread.getRecipient().getId())); jobManager.add(new GroupV1MigrationJob(thread.getRecipient().getId()));
needsRefresh.addAll(Stream.of(thread.getRecipient().getParticipants()) needsRefresh.addAll(Stream.of(Recipient.resolvedList(thread.getRecipient().getParticipantIds()))
.filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED) .filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED)
.map(Recipient::getId) .map(Recipient::getId)
.toList()); .toList());

Wyświetl plik

@ -1,7 +1,5 @@
package org.thoughtcrime.securesms.jobs; package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread; import androidx.annotation.WorkerThread;
@ -62,8 +60,11 @@ public class ProfileKeySendJob extends BaseJob {
throw new AssertionError("Do not send profile keys directly for GV2"); throw new AssertionError("Do not send profile keys directly for GV2");
} }
List<RecipientId> recipients = conversationRecipient.isGroup() ? Stream.of(RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants())).map(Recipient::getId).toList() List<RecipientId> recipients = conversationRecipient.isGroup() ? Stream.of(RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds())))
: Stream.of(conversationRecipient.getId()).toList(); .map(Recipient::getId)
.toList()
: Stream.of(conversationRecipient.getId())
.toList();
recipients.remove(Recipient.self().getId()); recipients.remove(Recipient.self().getId());

Wyświetl plik

@ -77,7 +77,7 @@ public class ReactionSendJob extends BaseJob {
} }
RecipientId selfId = Recipient.self().getId(); RecipientId selfId = Recipient.self().getId();
List<RecipientId> recipients = conversationRecipient.isGroup() ? RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants()) List<RecipientId> recipients = conversationRecipient.isGroup() ? RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds()))
.stream() .stream()
.map(Recipient::getId) .map(Recipient::getId)
.filter(r -> !r.equals(selfId)) .filter(r -> !r.equals(selfId))

Wyświetl plik

@ -72,7 +72,7 @@ public class RemoteDeleteSendJob extends BaseJob {
return ApplicationDependencies.getJobManager().startChain(MultiDeviceStorySendSyncJob.create(message.getDateSent(), messageId)); return ApplicationDependencies.getJobManager().startChain(MultiDeviceStorySendSyncJob.create(message.getDateSent(), messageId));
} }
} else { } else {
recipients = conversationRecipient.isGroup() ? Stream.of(conversationRecipient.getParticipants()).map(Recipient::getId).toList() recipients = conversationRecipient.isGroup() ? Stream.of(conversationRecipient.getParticipantIds()).toList()
: Stream.of(conversationRecipient.getId()).toList(); : Stream.of(conversationRecipient.getId()).toList();
} }

Wyświetl plik

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.mediasend.v2 package org.thoughtcrime.securesms.mediasend.v2
import androidx.annotation.WorkerThread
import androidx.core.util.Consumer import androidx.core.util.Consumer
import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
@ -27,12 +28,13 @@ object UntrustedRecords {
} }
} }
@WorkerThread
private fun checkForBadIdentityRecordsSync(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>): List<IdentityRecord> { private fun checkForBadIdentityRecordsSync(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>): List<IdentityRecord> {
val recipients: List<Recipient> = contactSearchKeys val recipients: List<Recipient> = contactSearchKeys
.map { Recipient.resolved(it.recipientId) } .map { Recipient.resolved(it.recipientId) }
.map { recipient -> .map { recipient ->
when { when {
recipient.isGroup -> recipient.participants recipient.isGroup -> Recipient.resolvedList(recipient.participantIds)
recipient.isDistributionList -> Recipient.resolvedList(SignalDatabase.distributionLists.getMembers(recipient.distributionListId.get())) recipient.isDistributionList -> Recipient.resolvedList(SignalDatabase.distributionLists.getMembers(recipient.distributionListId.get()))
else -> listOf(recipient) else -> listOf(recipient)
} }

Wyświetl plik

@ -153,8 +153,8 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
annotations annotations
} else { } else {
val validRecipientIds: Set<String> = recipient.participants val validRecipientIds: Set<String> = recipient.participantIds
.map { r -> MentionAnnotation.idToMentionAnnotationValue(r.id) } .map { id -> MentionAnnotation.idToMentionAnnotationValue(id) }
.toSet() .toSet()
annotations annotations

Wyświetl plik

@ -102,7 +102,7 @@ final class MessageRequestRepository {
} }
} else if (recipient.isPushV1Group()) { } else if (recipient.isPushV1Group()) {
if (RecipientUtil.isMessageRequestAccepted(context, threadId)) { if (RecipientUtil.isMessageRequestAccepted(context, threadId)) {
if (recipient.getParticipants().size() > FeatureFlags.groupLimits().getHardLimit()) { if (recipient.getParticipantIds().size() > FeatureFlags.groupLimits().getHardLimit()) {
return MessageRequestState.DEPRECATED_GROUP_V1_TOO_LARGE; return MessageRequestState.DEPRECATED_GROUP_V1_TOO_LARGE;
} else { } else {
return MessageRequestState.DEPRECATED_GROUP_V1; return MessageRequestState.DEPRECATED_GROUP_V1;

Wyświetl plik

@ -963,7 +963,7 @@ public final class MessageContentProcessor {
Recipient threadRecipient = targetThread.getRecipient().resolve(); Recipient threadRecipient = targetThread.getRecipient().resolve();
if (threadRecipient.isGroup() && !threadRecipient.getParticipants().contains(senderRecipient)) { if (threadRecipient.isGroup() && !threadRecipient.getParticipantIds().contains(senderRecipient.getId())) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not in the group! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId()); warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not in the group! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null; return null;
} }

Wyświetl plik

@ -153,18 +153,7 @@ public final class LiveRecipient {
} }
Recipient updated = fetchAndCacheRecipientFromDisk(getId()); Recipient updated = fetchAndCacheRecipientFromDisk(getId());
List<Recipient> participants = Stream.of(updated.getParticipants())
.filter(Recipient::isResolving)
.map(Recipient::getId)
.map(this::fetchAndCacheRecipientFromDisk)
.toList();
for (Recipient participant : participants) {
participant.live().set(participant);
}
set(updated); set(updated);
return updated; return updated;
} }
@ -189,15 +178,6 @@ public final class LiveRecipient {
} }
Recipient recipient = fetchAndCacheRecipientFromDisk(id); Recipient recipient = fetchAndCacheRecipientFromDisk(id);
List<Recipient> participants = Stream.of(recipient.getParticipants())
.map(Recipient::getId)
.map(this::fetchAndCacheRecipientFromDisk)
.toList();
for (Recipient participant : participants) {
participant.live().set(participant);
}
set(recipient); set(recipient);
refreshForceNotify.postValue(new Object()); refreshForceNotify.postValue(new Object());
} }
@ -232,7 +212,7 @@ public final class LiveRecipient {
if (groupRecord.isPresent()) { if (groupRecord.isPresent()) {
String title = groupRecord.get().getTitle(); String title = groupRecord.get().getTitle();
List<Recipient> members = Stream.of(groupRecord.get().getMembers()).filterNot(RecipientId::isUnknown).map(this::fetchAndCacheRecipientFromDisk).toList(); List<RecipientId> members = Stream.of(groupRecord.get().getMembers()).filterNot(RecipientId::isUnknown).toList();
Optional<Long> avatarId = Optional.empty(); Optional<Long> avatarId = Optional.empty();
if (groupRecord.get().hasAvatar()) { if (groupRecord.get().hasAvatar()) {
@ -252,7 +232,7 @@ public final class LiveRecipient {
// TODO [stories] We'll have to see what the perf is like for very large distribution lists. We may not be able to support fetching all the members. // TODO [stories] We'll have to see what the perf is like for very large distribution lists. We may not be able to support fetching all the members.
if (groupRecord != null) { if (groupRecord != null) {
String title = groupRecord.isUnknown() ? null : groupRecord.getName(); String title = groupRecord.isUnknown() ? null : groupRecord.getName();
List<Recipient> members = Stream.of(groupRecord.getMembers()).filterNot(RecipientId::isUnknown).map(this::fetchAndCacheRecipientFromDisk).toList(); List<RecipientId> members = Stream.of(groupRecord.getMembers()).filterNot(RecipientId::isUnknown).toList();
return RecipientDetails.forDistributionList(title, members, record); return RecipientDetails.forDistributionList(title, members, record);
} }

Wyświetl plik

@ -72,6 +72,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
import static org.thoughtcrime.securesms.database.RecipientDatabase.InsightsBannerTier; import static org.thoughtcrime.securesms.database.RecipientDatabase.InsightsBannerTier;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public class Recipient { public class Recipient {
private static final String TAG = Log.tag(Recipient.class); private static final String TAG = Log.tag(Recipient.class);
@ -91,7 +92,7 @@ public class Recipient {
private final String email; private final String email;
private final GroupId groupId; private final GroupId groupId;
private final DistributionListId distributionListId; private final DistributionListId distributionListId;
private final List<Recipient> participants; private final List<RecipientId> participantIds;
private final Optional<Long> groupAvatarId; private final Optional<Long> groupAvatarId;
private final boolean isSelf; private final boolean isSelf;
private final boolean blocked; private final boolean blocked;
@ -368,7 +369,7 @@ public class Recipient {
this.email = null; this.email = null;
this.groupId = null; this.groupId = null;
this.distributionListId = null; this.distributionListId = null;
this.participants = Collections.emptyList(); this.participantIds = Collections.emptyList();
this.groupAvatarId = Optional.empty(); this.groupAvatarId = Optional.empty();
this.isSelf = false; this.isSelf = false;
this.blocked = false; this.blocked = false;
@ -426,7 +427,7 @@ public class Recipient {
this.email = details.email; this.email = details.email;
this.groupId = details.groupId; this.groupId = details.groupId;
this.distributionListId = details.distributionListId; this.distributionListId = details.distributionListId;
this.participants = details.participants; this.participantIds = details.participantIds;
this.groupAvatarId = details.groupAvatarId; this.groupAvatarId = details.groupAvatarId;
this.isSelf = details.isSelf; this.isSelf = details.isSelf;
this.blocked = details.blocked; this.blocked = details.blocked;
@ -488,9 +489,11 @@ public class Recipient {
public @Nullable String getGroupName(@NonNull Context context) { public @Nullable String getGroupName(@NonNull Context context) {
if (groupId != null && Util.isEmpty(this.groupName)) { if (groupId != null && Util.isEmpty(this.groupName)) {
List<Recipient> others = participants.stream() RecipientId selfId = Recipient.self().getId();
.filter(r -> !r.isSelf()) List<Recipient> others = participantIds.stream()
.filter(id -> !id.equals(selfId))
.limit(MAX_MEMBER_NAMES) .limit(MAX_MEMBER_NAMES)
.map(Recipient::resolved)
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<String, Integer> shortNameCounts = new HashMap<>(); Map<String, Integer> shortNameCounts = new HashMap<>();
@ -515,7 +518,7 @@ public class Recipient {
} }
} }
if (participants.stream().anyMatch(Recipient::isSelf)) { if (participantIds.stream().anyMatch(id -> id.equals(selfId))) {
names.add(context.getString(R.string.Recipient_you)); names.add(context.getString(R.string.Recipient_you));
} }
@ -861,11 +864,12 @@ public class Recipient {
} }
public boolean isActiveGroup() { public boolean isActiveGroup() {
return Stream.of(getParticipants()).anyMatch(Recipient::isSelf); RecipientId selfId = Recipient.self().getId();
return Stream.of(getParticipantIds()).anyMatch(p -> p.equals(selfId));
} }
public @NonNull List<Recipient> getParticipants() { public @NonNull List<RecipientId> getParticipantIds() {
return new ArrayList<>(participants); return new ArrayList<>(participantIds);
} }
public @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted) { public @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted) {
@ -1277,7 +1281,7 @@ public class Recipient {
Objects.equals(e164, other.e164) && Objects.equals(e164, other.e164) &&
Objects.equals(email, other.email) && Objects.equals(email, other.email) &&
Objects.equals(groupId, other.groupId) && Objects.equals(groupId, other.groupId) &&
allContentsAreTheSame(participants, other.participants) && Objects.equals(participantIds, other.participantIds) &&
Objects.equals(groupAvatarId, other.groupAvatarId) && Objects.equals(groupAvatarId, other.groupAvatarId) &&
messageVibrate == other.messageVibrate && messageVibrate == other.messageVibrate &&
callVibrate == other.callVibrate && callVibrate == other.callVibrate &&

Wyświetl plik

@ -54,7 +54,7 @@ public class RecipientDetails {
final VibrateState callVibrateState; final VibrateState callVibrateState;
final boolean blocked; final boolean blocked;
final int expireMessages; final int expireMessages;
final List<Recipient> participants; final List<RecipientId> participantIds;
final ProfileName profileName; final ProfileName profileName;
final Optional<Integer> defaultSubscriptionId; final Optional<Integer> defaultSubscriptionId;
final RegisteredState registered; final RegisteredState registered;
@ -96,7 +96,7 @@ public class RecipientDetails {
boolean isSelf, boolean isSelf,
@NonNull RegisteredState registeredState, @NonNull RegisteredState registeredState,
@NonNull RecipientRecord record, @NonNull RecipientRecord record,
@Nullable List<Recipient> participants, @Nullable List<RecipientId> participantIds,
boolean isReleaseChannel) boolean isReleaseChannel)
{ {
this.groupAvatarId = groupAvatarId; this.groupAvatarId = groupAvatarId;
@ -117,7 +117,7 @@ public class RecipientDetails {
this.callVibrateState = record.getCallVibrateState(); this.callVibrateState = record.getCallVibrateState();
this.blocked = record.isBlocked(); this.blocked = record.isBlocked();
this.expireMessages = record.getExpireMessages(); this.expireMessages = record.getExpireMessages();
this.participants = participants == null ? new LinkedList<>() : participants; this.participantIds = participantIds == null ? new LinkedList<>() : participantIds;
this.profileName = record.getProfileName(); this.profileName = record.getProfileName();
this.defaultSubscriptionId = record.getDefaultSubscriptionId(); this.defaultSubscriptionId = record.getDefaultSubscriptionId();
this.registered = registeredState; this.registered = registeredState;
@ -174,7 +174,7 @@ public class RecipientDetails {
this.callVibrateState = VibrateState.DEFAULT; this.callVibrateState = VibrateState.DEFAULT;
this.blocked = false; this.blocked = false;
this.expireMessages = 0; this.expireMessages = 0;
this.participants = new LinkedList<>(); this.participantIds = new LinkedList<>();
this.profileName = ProfileName.EMPTY; this.profileName = ProfileName.EMPTY;
this.insightsBannerTier = InsightsBannerTier.TIER_TWO; this.insightsBannerTier = InsightsBannerTier.TIER_TWO;
this.defaultSubscriptionId = Optional.empty(); this.defaultSubscriptionId = Optional.empty();
@ -231,7 +231,7 @@ public class RecipientDetails {
return new RecipientDetails(null, settings.getSystemDisplayName(), Optional.empty(), systemContact, isSelf, registeredState, settings, null, isReleaseChannel); return new RecipientDetails(null, settings.getSystemDisplayName(), Optional.empty(), systemContact, isSelf, registeredState, settings, null, isReleaseChannel);
} }
public static @NonNull RecipientDetails forDistributionList(String title, @Nullable List<Recipient> members, @NonNull RecipientRecord record) { public static @NonNull RecipientDetails forDistributionList(String title, @Nullable List<RecipientId> members, @NonNull RecipientRecord record) {
return new RecipientDetails(title, null, Optional.empty(), false, false, record.getRegistered(), record, members, false); return new RecipientDetails(title, null, Optional.empty(), false, false, record.getRegistered(), record, members, false);
} }

Wyświetl plik

@ -187,7 +187,7 @@ class SafetyNumberBottomSheetRepository {
} }
private fun getGroupMemberships(recipient: Recipient, groups: List<Recipient>): List<Recipient> { private fun getGroupMemberships(recipient: Recipient, groups: List<Recipient>): List<Recipient> {
return groups.filter { it.participants.contains(recipient) } return groups.filter { it.participantIds.contains(recipient.id) }
} }
data class ResolvedIdentity(val recipient: Recipient, val identityRecord: Optional<IdentityRecord>) data class ResolvedIdentity(val recipient: Recipient, val identityRecord: Optional<IdentityRecord>)

Wyświetl plik

@ -17,7 +17,6 @@ import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SimpleTask; import org.signal.core.util.concurrent.SimpleTask;
import org.signal.core.util.logging.Log; import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey; import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey;
import org.thoughtcrime.securesms.conversation.MessageSendType; import org.thoughtcrime.securesms.conversation.MessageSendType;
import org.thoughtcrime.securesms.conversation.colors.ChatColors; import org.thoughtcrime.securesms.conversation.colors.ChatColors;
@ -36,7 +35,6 @@ import org.thoughtcrime.securesms.mediasend.v2.text.TextStoryBackgroundColors;
import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.ImageSlide;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage; import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.mms.SentMediaQuality; import org.thoughtcrime.securesms.mms.SentMediaQuality;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.mms.SlideDeck;
@ -57,6 +55,7 @@ import org.thoughtcrime.securesms.util.Util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -480,10 +479,7 @@ public final class MultiShareSender {
if (mentions.isEmpty() || !recipient.isPushV2Group() || !recipient.isActiveGroup()) { if (mentions.isEmpty() || !recipient.isPushV2Group() || !recipient.isActiveGroup()) {
return Collections.emptyList(); return Collections.emptyList();
} else { } else {
Set<RecipientId> validRecipientIds = recipient.getParticipants() Set<RecipientId> validRecipientIds = new HashSet<>(recipient.getParticipantIds());
.stream()
.map(Recipient::getId)
.collect(Collectors.toSet());
return mentions.stream() return mentions.stream()
.filter(mention -> validRecipientIds.contains(mention.getRecipientId())) .filter(mention -> validRecipientIds.contains(mention.getRecipientId()))

Wyświetl plik

@ -436,8 +436,8 @@ class StoryGroupReplyFragment :
annotations annotations
} else { } else {
val validRecipientIds: Set<String> = recipient.participants val validRecipientIds: Set<String> = recipient.participantIds
.map { r -> MentionAnnotation.idToMentionAnnotationValue(r.id) } .map { id -> MentionAnnotation.idToMentionAnnotationValue(id) }
.toSet() .toSet()
annotations annotations

Wyświetl plik

@ -30,7 +30,7 @@ object RecipientDatabaseTestUtils {
groupAvatarId: Optional<Long> = Optional.empty(), groupAvatarId: Optional<Long> = Optional.empty(),
systemContact: Boolean = false, systemContact: Boolean = false,
isSelf: Boolean = false, isSelf: Boolean = false,
participants: List<Recipient> = listOf(), participants: List<RecipientId> = listOf(),
recipientId: RecipientId = RecipientId.from(Random.nextLong()), recipientId: RecipientId = RecipientId.from(Random.nextLong()),
serviceId: ServiceId? = ServiceId.from(UUID.randomUUID()), serviceId: ServiceId? = ServiceId.from(UUID.randomUUID()),
username: String? = null, username: String? = null,