Remove more usages of annimon.stream.

Resolves #14717
This commit is contained in:
Jesse Weinstein
2026-04-06 16:14:18 -04:00
committed by jeffrey-signal
parent 469421fcf3
commit e6cbb0073c
61 changed files with 226 additions and 220 deletions
@@ -11,8 +11,6 @@ import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import androidx.documentfile.provider.DocumentFile;
import com.annimon.stream.function.Predicate;
import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.greenrobot.eventbus.EventBus;
@@ -71,6 +69,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import okio.ByteString;
@@ -3,8 +3,7 @@ package org.thoughtcrime.securesms.components.webrtc;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import java.util.stream.Collectors;
import org.signal.core.util.SetUtil;
import org.thoughtcrime.securesms.events.CallParticipant;
@@ -68,12 +67,12 @@ public final class CallParticipantListUpdate {
public static @NonNull CallParticipantListUpdate computeDeltaUpdate(@NonNull List<CallParticipant> oldList,
@NonNull List<CallParticipant> newList)
{
Set<CallParticipantListUpdate.Wrapper> oldParticipants = Stream.of(oldList)
.filter(p -> p.getCallParticipantId().demuxId != CallParticipantId.DEFAULT_ID)
Set<CallParticipantListUpdate.Wrapper> oldParticipants = oldList.stream()
.filter(p -> p.getCallParticipantId().demuxId != CallParticipantId.DEFAULT_ID)
.map(CallParticipantListUpdate::createWrapper)
.collect(Collectors.toSet());
Set<CallParticipantListUpdate.Wrapper> newParticipants = Stream.of(newList)
.filter(p -> p.getCallParticipantId().demuxId != CallParticipantId.DEFAULT_ID)
Set<CallParticipantListUpdate.Wrapper> newParticipants = newList.stream()
.filter(p -> p.getCallParticipantId().demuxId != CallParticipantId.DEFAULT_ID)
.map(CallParticipantListUpdate::createWrapper)
.collect(Collectors.toSet());
Set<CallParticipantListUpdate.Wrapper> added = SetUtil.difference(newParticipants, oldParticipants);
@@ -4,7 +4,6 @@ import android.content.Context
import androidx.annotation.Discouraged
import androidx.annotation.PluralsRes
import androidx.annotation.StringRes
import com.annimon.stream.OptionalLong
import kotlinx.collections.immutable.toImmutableList
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.webrtc.WebRtcControls.FoldableState
@@ -19,6 +18,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.ringrtc.CameraState
import org.thoughtcrime.securesms.service.webrtc.collections.ParticipantCollection
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcEphemeralState
import java.util.Optional
import java.util.concurrent.TimeUnit
/**
@@ -37,7 +37,7 @@ data class CallParticipantsState(
val isInPipMode: Boolean = false,
private val showVideoForOutgoing: Boolean = false,
val isViewingFocusedParticipant: Boolean = false,
val remoteDevicesCount: OptionalLong = OptionalLong.empty(),
val remoteDevicesCount: Optional<Long> = Optional.empty(),
private val foldableState: FoldableState = FoldableState.flat(),
val isInOutgoingRingingMode: Boolean = false,
val recipient: Recipient = Recipient.UNKNOWN,
@@ -87,11 +87,11 @@ data class CallParticipantsState(
return listParticipants
}
val participantCount: OptionalLong
val participantCount: Optional<Long>
get() {
val includeSelf = groupCallState == WebRtcViewModel.GroupCallState.CONNECTED_AND_JOINED
return remoteDevicesCount.map { l: Long -> l + if (includeSelf) 1L else 0L }
.or { if (includeSelf) OptionalLong.of(1L) else OptionalLong.empty() }
.or { if (includeSelf) Optional.of(1L) else Optional.empty() }
}
fun getPreJoinGroupDescription(context: Context): String? {
@@ -91,7 +91,7 @@ object CallInfoView {
inCallLobby = state.callState == WebRtcViewModel.State.CALL_PRE_JOIN,
ringGroup = state.ringGroup,
includeSelf = state.groupCallState === WebRtcViewModel.GroupCallState.CONNECTED_AND_JOINED || state.groupCallState === WebRtcViewModel.GroupCallState.IDLE,
participantCount = if (state.participantCount.isPresent) state.participantCount.asLong.toInt() else 0,
participantCount = if (state.participantCount.isPresent) state.participantCount.get().toInt() else 0,
remoteParticipants = state.allRemoteParticipants.sortedBy { it.callParticipantId.recipientId },
localParticipant = state.localParticipant,
groupMembers = state.groupMembers.filterNot { it.member.isSelf },
@@ -9,9 +9,6 @@ import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.components.Outliner;
import org.thoughtcrime.securesms.util.Projection;
import org.signal.core.util.Util;
@@ -20,6 +17,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ConversationItemBodyBubble extends LinearLayout {
@@ -99,7 +98,7 @@ public class ConversationItemBodyBubble extends LinearLayout {
public @NonNull Set<Projection> getProjections() {
return Stream.of(quoteViewProjection, videoPlayerProjection)
.filterNot(Objects::isNull)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
@@ -50,6 +50,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.LongStream;
import kotlin.Unit;
@@ -776,14 +777,14 @@ public final class ConversationReactionOverlay extends FrameLayout {
int revealDuration = getContext().getResources().getInteger(R.integer.reaction_scrubber_reveal_duration);
int revealOffset = getContext().getResources().getInteger(R.integer.reaction_scrubber_reveal_offset);
List<Animator> reveals = Stream.of(emojiViews)
.mapIndexed((idx, v) -> {
Animator anim = AnimatorInflaterCompat.loadAnimator(getContext(), R.animator.reactions_scrubber_reveal);
anim.setTarget(v);
anim.setStartDelay(idx * animationEmojiStartDelayFactor);
return anim;
})
.toList();
List<Animator> reveals = LongStream.range(0, emojiViews.length)
.boxed()
.map(idx -> {
Animator anim = AnimatorInflaterCompat.loadAnimator(getContext(), R.animator.reactions_scrubber_reveal);
anim.setTarget(emojiViews[idx.intValue()]);
anim.setStartDelay(idx * animationEmojiStartDelayFactor);
return anim;
}).collect(java.util.stream.Collectors.toList());
Animator backgroundRevealAnim = AnimatorInflaterCompat.loadAnimator(getContext(), android.R.animator.fade_in);
backgroundRevealAnim.setTarget(backgroundView);
@@ -821,8 +822,8 @@ public final class ConversationReactionOverlay extends FrameLayout {
int duration = getContext().getResources().getInteger(R.integer.reaction_scrubber_hide_duration);
List<Animator> animators = new ArrayList<>(Stream.of(emojiViews)
.mapIndexed((idx, v) -> {
Animator anim = AnimatorInflaterCompat.loadAnimator(getContext(), R.animator.reactions_scrubber_hide);
.map( v -> {
Animator anim = AnimatorInflaterCompat.loadAnimator(getContext(), R.animator.reactions_scrubber_hide);
anim.setTarget(v);
return anim;
})
@@ -72,7 +72,7 @@ public final class SafetyNumberChangeDialog extends DialogFragment implements Sa
public static void showForGroupCall(@NonNull FragmentManager fragmentManager, @NonNull List<IdentityRecord> identityRecords) {
List<String> ids = Stream.of(identityRecords)
.filterNot(IdentityRecord::isFirstUse)
.filter(identityRecord -> !identityRecord.isFirstUse())
.map(record -> record.getRecipientId().serialize())
.distinct()
.toList();
@@ -57,7 +57,6 @@ import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
import com.airbnb.lottie.SimpleColorFilter;
import com.annimon.stream.Stream;
import com.bumptech.glide.Glide;
import com.google.android.material.animation.ArgbEvaluatorCompat;
import com.google.android.material.appbar.AppBarLayout;
@@ -1234,10 +1233,10 @@ public class ConversationListFragment extends MainFragment implements Conversati
}
private void handlePin(@NonNull Collection<Conversation> conversations) {
final Set<Long> toPin = new LinkedHashSet<>(Stream.of(conversations)
.filterNot(conversation -> conversation.getThreadRecord().isPinned())
final Set<Long> toPin = new LinkedHashSet<>(conversations.stream()
.filter(conversation -> !conversation.getThreadRecord().isPinned())
.map(conversation -> conversation.getThreadRecord().getThreadId())
.toList());
.collect(Collectors.toList()));
if (toPin.size() + viewModel.getPinnedCount() > RemoteConfig.pinnedChatLimit()) {
mainNavigationViewModel.getSnackbarRegistry().emit(new SnackbarState(
@@ -1512,9 +1511,9 @@ public class ConversationListFragment extends MainFragment implements Conversati
private void updateMultiSelectState() {
int count = viewModel.currentSelectedConversations().size();
boolean hasUnread = Stream.of(viewModel.currentSelectedConversations()).anyMatch(conversation -> !conversation.getThreadRecord().isRead());
boolean hasUnpinned = Stream.of(viewModel.currentSelectedConversations()).anyMatch(conversation -> !conversation.getThreadRecord().isPinned());
boolean hasUnmuted = Stream.of(viewModel.currentSelectedConversations()).anyMatch(conversation -> !conversation.getThreadRecord().getRecipient().live().get().isMuted());
boolean hasUnread = viewModel.currentSelectedConversations().stream().anyMatch(conversation -> !conversation.getThreadRecord().isRead());
boolean hasUnpinned = viewModel.currentSelectedConversations().stream().anyMatch(conversation -> !conversation.getThreadRecord().isPinned());
boolean hasUnmuted = viewModel.currentSelectedConversations().stream().anyMatch(conversation -> !conversation.getThreadRecord().getRecipient().live().get().isMuted());
boolean canPin = viewModel.getPinnedCount() < RemoteConfig.pinnedChatLimit();
if (mainToolbarViewModel.isInActionMode()) {
@@ -9,7 +9,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
import com.annimon.stream.Stream;
import com.annimon.stream.function.Function;
import java.util.function.Function;
import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.database.model.MessageRecord;
@@ -87,6 +87,9 @@ public final class PaymentMetaDataUtil {
}
public static byte[] receiptPublic(@NonNull PaymentMetaData paymentMetaData) {
return Stream.of(paymentMetaData.mobileCoinTxoIdentification.publicKey).single().toByteArray();
if (paymentMetaData.mobileCoinTxoIdentification.publicKey.size() != 1) {
throw new IllegalStateException("Unexpected number of public keys!");
}
return paymentMetaData.mobileCoinTxoIdentification.publicKey.get(0).toByteArray();
}
}
@@ -594,8 +594,7 @@ public abstract class MessageRecord extends DisplayRecord {
GroupCallUpdateDetails groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(body);
List<ServiceId> joinedMembers = Stream.of(groupCallUpdateDetails.inCallUuids)
.map(UuidUtil::parseOrNull)
.withoutNulls()
.map(UuidUtil::parseOrNull).filter(Objects::nonNull)
.<ServiceId>map(ACI::from)
.toList();
@@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.events
import com.annimon.stream.OptionalLong
import org.signal.ringrtc.CallManager.CallEndReason
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink
import org.thoughtcrime.securesms.events.CallParticipant.Companion.createLocal
@@ -11,6 +10,7 @@ import org.thoughtcrime.securesms.service.webrtc.PendingParticipantCollection
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager
import org.webrtc.PeerConnection
import java.util.Optional
class WebRtcViewModel(state: WebRtcServiceState) {
@@ -100,7 +100,7 @@ class WebRtcViewModel(state: WebRtcServiceState) {
val callConnectedTime: Long = state.callInfoState.callConnectedTime
val remoteParticipants: List<CallParticipant> = state.callInfoState.remoteCallParticipants
val identityChangedParticipants: Set<RecipientId> = state.callInfoState.identityChangedRecipients
val remoteDevicesCount: OptionalLong = state.callInfoState.remoteDevicesCount
val remoteDevicesCount: Optional<Long> = state.callInfoState.remoteDevicesCount
val participantLimit: Long? = state.callInfoState.participantLimit
val pendingParticipants: PendingParticipantCollection = state.callInfoState.pendingParticipants
val isCallLink: Boolean = state.callInfoState.callRecipient.isCallLink
@@ -151,7 +151,7 @@ class WebRtcViewModel(state: WebRtcServiceState) {
get() = remoteParticipants.any(CallParticipant::isVideoEnabled) || groupState.isNotIdle && remoteParticipants.size > 1
fun areRemoteDevicesInCall(): Boolean {
return remoteDevicesCount.isPresent && remoteDevicesCount.asLong > 0
return remoteDevicesCount.isPresent && remoteDevicesCount.get() > 0
}
override fun toString(): String {
@@ -8,14 +8,14 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* Controls playback of gifs in a {@link RecyclerView}. The maximum number of gifs that will play back at any one
@@ -95,11 +95,12 @@ public final class GiphyMp4PlaybackController extends RecyclerView.OnScrollListe
}
private @NonNull Set<Integer> getPlaybackSet(@NonNull Set<Integer> playablePositions, int firstVisiblePosition, int lastVisiblePosition) {
return Stream.rangeClosed(firstVisiblePosition, lastVisiblePosition)
.sorted(new RangeComparator(firstVisiblePosition, lastVisiblePosition))
.filter(playablePositions::contains)
.limit(maxSimultaneousPlayback)
.collect(Collectors.toSet());
return IntStream.rangeClosed(firstVisiblePosition, lastVisiblePosition)
.boxed()
.sorted(new RangeComparator(firstVisiblePosition, lastVisiblePosition))
.filter(playablePositions::contains)
.limit(maxSimultaneousPlayback)
.collect(Collectors.toSet());
}
private static int[] findFirstVisibleItemPositions(@NonNull RecyclerView.LayoutManager layoutManager) {
@@ -45,11 +45,11 @@ public final class GiphyMp4ViewModel extends ViewModel {
this.saveResultEvents = new SingleLiveEvent<>();
this.pagingController = Transformations.map(pagedData, PagedData::getController);
this.images = Transformations.switchMap(pagedData, pagedData -> Transformations.map(pagedData.getData(),
data -> Stream.of(data)
data -> data.stream()
.filter(g -> g != null)
.filterNot(g -> TextUtils.isEmpty(isForMms ? g.getGifMmsUrl() : g.getGifUrl()))
.filterNot(g -> TextUtils.isEmpty(g.getMp4PreviewUrl()))
.filterNot(g -> TextUtils.isEmpty(g.getStillUrl()))
.filter(g -> !TextUtils.isEmpty(isForMms ? g.getGifMmsUrl() : g.getGifUrl()))
.filter(g -> !TextUtils.isEmpty(g.getMp4PreviewUrl()))
.filter(g -> !TextUtils.isEmpty(g.getStillUrl()))
.collect(MappingModelList.toMappingModelList())));
}
@@ -196,7 +196,7 @@ public final class LiveGroup {
public LiveData<List<GroupMemberEntry.FullMember>> getNonAdminFullMembers() {
return Transformations.map(fullMembers,
members -> Stream.of(members)
.filterNot(GroupMemberEntry.FullMember::isAdmin)
.filter(fullMember -> !fullMember.isAdmin())
.toList());
}
@@ -75,7 +75,8 @@ public final class ChooseNewAdminActivity extends PassphraseRequiredActivity {
groupList.initializeAdapter(this);
groupList.setRecipientSelectionChangeListener(selection -> viewModel.setSelection(Stream.of(selection)
.select(GroupMemberEntry.FullMember.class)
.filter(x -> x instanceof GroupMemberEntry.FullMember)
.map(x-> (GroupMemberEntry.FullMember)x)
.collect(Collectors.toSet())));
done.setOnClickListener(v -> {
@@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
import com.annimon.stream.Collectors;
import okio.ByteString;
@@ -60,7 +61,8 @@ final class PendingMemberInvitesRepository {
boolean selfIsAdmin = v2GroupProperties.isAdmin(Recipient.self());
Stream.of(pendingMembersList)
.groupBy(m -> m.addedByAci)
.collect(Collectors.groupingBy(m -> m.addedByAci))
.entrySet()
.forEach(g ->
{
ByteString inviterAci = g.getKey();
@@ -43,7 +43,7 @@ public final class GroupDescriptionUtil {
if (hasLinks) {
Stream.of(descriptionSpannable.getSpans(0, descriptionSpannable.length(), URLSpan.class))
.filterNot(url -> LinkUtil.isLegalUrl(url.getURL()))
.filter(url -> !LinkUtil.isLegalUrl(url.getURL()))
.forEach(descriptionSpannable::removeSpan);
URLSpan[] urlSpans = descriptionSpannable.getSpans(0, descriptionSpannable.length(), URLSpan.class);
@@ -120,7 +120,7 @@ class JobController {
@WorkerThread
void submitNewJobChain(@NonNull List<List<Job>> chain) {
synchronized (this) {
chain = Stream.of(chain).filterNot(List::isEmpty).toList();
chain = Stream.of(chain).filter(jobs -> !jobs.isEmpty()).toList();
if (chain.isEmpty()) {
Log.w(TAG, "Tried to submit an empty job chain. Skipping.");
@@ -348,8 +348,7 @@ class JobController {
synchronized @NonNull List<Job> onFailure(@NonNull Job job) {
List<Job> dependents = Stream.of(jobStorage.getDependencySpecsThatDependOnJob(job.getId()))
.map(DependencySpec::getJobId)
.map(jobStorage::getJobSpec)
.withoutNulls()
.map(jobStorage::getJobSpec).filter(Objects::nonNull)
.map(jobSpec -> {
List<ConstraintSpec> constraintSpecs = jobStorage.getConstraintSpecs(jobSpec.getId());
return createJob(jobSpec, constraintSpecs);
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@RequiresApi(26)
public final class JobSchedulerScheduler implements Scheduler {
@@ -39,8 +40,7 @@ public final class JobSchedulerScheduler implements Scheduler {
String constraintNames = constraints.isEmpty() ? ""
: Stream.of(constraints)
.map(Constraint::getJobSchedulerKeyPart)
.withoutNulls()
.map(Constraint::getJobSchedulerKeyPart).filter(Objects::nonNull)
.sorted()
.collect(Collectors.joining("-"));
@@ -6,7 +6,6 @@ import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.IntPair;
import com.annimon.stream.Stream;
import org.signal.core.util.logging.Log;
@@ -35,6 +34,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
/**
* Downloads Emoji JSON and Images to local persistent storage.
@@ -215,20 +215,20 @@ public class DownloadLatestEmojiDataJob extends BaseJob {
}
}
return Stream.of(allDensities)
.indexed()
return IntStream.range(0, allDensities.size())
.boxed()
.sorted((lhs, rhs) -> {
int lhsDistance = Math.abs(desiredIndex - lhs.getFirst());
int rhsDistance = Math.abs(desiredIndex - rhs.getFirst());
int lhsDistance = Math.abs(desiredIndex - lhs);
int rhsDistance = Math.abs(desiredIndex - rhs);
int comp = Integer.compare(lhsDistance, rhsDistance);
if (comp == 0) {
return Integer.compare(lhs.getFirst(), rhs.getFirst());
return Integer.compare(lhs, rhs);
} else {
return comp;
}
})
.map(IntPair::getSecond)
.map(allDensities::get)
.filter(supportedDensities::contains)
.findFirst()
.orElseThrow(() -> new IllegalStateException("No density available."));
@@ -346,8 +346,8 @@ public class DownloadLatestEmojiDataJob extends BaseJob {
Stream.of(files)
.filter(File::isDirectory)
.filterNot(file -> file.getName().equals(currentDirectoryName))
.filterNot(file -> file.getName().equals(newVersionDirectoryName))
.filter(file -> !file.getName().equals(currentDirectoryName))
.filter(file -> !file.getName().equals(newVersionDirectoryName))
.forEach(FileUtils::deleteDirectory);
EmojiPageCache.INSTANCE.clear();
@@ -62,7 +62,7 @@ public class GroupCallUpdateSendJob extends BaseJob {
}
List<RecipientId> recipientIds = Stream.of(RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds())))
.filterNot(Recipient::isSelf)
.filter(recipient -> !recipient.isSelf())
.map(Recipient::getId)
.toList();
@@ -277,7 +277,7 @@ public class IndividualSendJob extends PushSendJob {
SignalServiceMessageSender messageSender = AppDependencies.getSignalServiceMessageSender();
SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, messageRecipient);
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
List<Attachment> attachments = Stream.of(message.getAttachments()).filter(attachment -> !attachment.isSticker()).toList();
List<SignalServiceAttachment> serviceAttachments = getAttachmentPointersFor(attachments);
Optional<byte[]> profileKey = getProfileKey(messageRecipient);
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
@@ -4,8 +4,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.annimon.stream.Stream;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.jobmanager.Job;
@@ -30,6 +28,8 @@ import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedExcept
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ProfileKeySendJob extends BaseJob {
@@ -92,11 +92,13 @@ public class ProfileKeySendJob extends BaseJob {
throw new AssertionError("Do not send profile keys directly for GV2");
}
List<RecipientId> recipients = conversationRecipient.isGroup() ? Stream.of(RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds())))
.map(Recipient::getId)
.toList()
: Stream.of(conversationRecipient.getId())
.toList();
List<RecipientId> recipients = conversationRecipient.isGroup()
? RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds()))
.stream()
.map(Recipient::getId)
.collect(Collectors.toList())
: Stream.of(conversationRecipient.getId())
.collect(Collectors.toList());
recipients.remove(Recipient.self().getId());
@@ -142,7 +144,7 @@ public class ProfileKeySendJob extends BaseJob {
}
}
List<Recipient> destinations = Stream.of(recipients).map(Recipient::resolved).toList();
List<Recipient> destinations = recipients.stream().map(Recipient::resolved).collect(Collectors.toList());
List<Recipient> completions = deliver(destinations);
for (Recipient completion : completions) {
@@ -195,7 +197,7 @@ public class ProfileKeySendJob extends BaseJob {
.withProfileKey(Recipient.self().resolve().getProfileKey());
List<SendMessageResult> results = GroupSendUtil.sendUnresendableDataMessage(context, null, destinations, false, ContentHint.IMPLICIT, dataMessage.build(), false, null);
ProofRequiredException proofRequired = Stream.of(results).filter(r -> r.getProofRequiredFailure() != null).findLast().map(SendMessageResult::getProofRequiredFailure).orElse(null);
ProofRequiredException proofRequired = results.stream().filter(r -> r.getProofRequiredFailure() != null).reduce((a,b) -> b).map(SendMessageResult::getProofRequiredFailure).orElse(null);
GroupSendJobHelper.SendResult groupResult = GroupSendJobHelper.getCompletedSends(destinations, results);
@@ -206,7 +206,7 @@ public final class PushDistributionListSendJob extends PushSendJob {
throws IOException, UntrustedIdentityException, UndeliverableMessageException
{
try {
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
List<Attachment> attachments = Stream.of(message.getAttachments()).filter(attachment -> !attachment.isSticker()).toList();
List<SignalServiceAttachment> attachmentPointers = getAttachmentPointersFor(attachments);
List<BodyRange> bodyRanges = getBodyRanges(message);
boolean isRecipientUpdate = Stream.of(SignalDatabase.groupReceipts().getGroupReceiptInfo(messageId))
@@ -288,7 +288,7 @@ public final class PushGroupSendJob extends PushSendJob {
SignalServiceDataMessage.PollCreate pollCreate = getPollCreate(message);
SignalServiceDataMessage.PollTerminate pollTerminate = getPollTerminate(message);
SignalServiceDataMessage.PinnedMessage pinnedMessage = getPinnedMessage(message);
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
List<Attachment> attachments = Stream.of(message.getAttachments()).filter(attachment -> !attachment.isSticker()).toList();
List<SignalServiceAttachment> attachmentPointers = getAttachmentPointersFor(attachments);
boolean isRecipientUpdate = Stream.of(SignalDatabase.groupReceipts().getGroupReceiptInfo(messageId))
.anyMatch(info -> info.getStatus() > GroupReceiptTable.STATUS_UNDELIVERED);
@@ -447,7 +447,7 @@ public final class PushGroupSendJob extends PushSendJob {
List<NetworkFailure> networkFailures = Stream.of(results).filter(SendMessageResult::isNetworkFailure).map(result -> new NetworkFailure(accessList.requireIdByAddress(result.getAddress()))).toList();
List<IdentityKeyMismatch> identityMismatches = Stream.of(results).filter(result -> result.getIdentityFailure() != null)
.map(result -> new IdentityKeyMismatch(accessList.requireIdByAddress(result.getAddress()), result.getIdentityFailure().getIdentityKey())).toList();
ProofRequiredException proofRequired = Stream.of(results).filter(r -> r.getProofRequiredFailure() != null).findLast().map(SendMessageResult::getProofRequiredFailure).orElse(null);
ProofRequiredException proofRequired = Stream.of(results).filter(r -> r.getProofRequiredFailure() != null).reduce((a,b) -> b).map(SendMessageResult::getProofRequiredFailure).orElse(null);
List<SendMessageResult> successes = Stream.of(results).filter(result -> result.getSuccess() != null).toList();
List<Pair<RecipientId, Boolean>> successUnidentifiedStatus = Stream.of(successes).map(result -> new Pair<>(accessList.requireIdByAddress(result.getAddress()), result.getSuccess().isUnidentified())).toList();
Set<RecipientId> successIds = Stream.of(successUnidentifiedStatus).map(Pair::getFirst).collect(Collectors.toSet());
@@ -551,14 +551,14 @@ public final class PushGroupSendJob extends PushSendJob {
possible = Stream.of(destinations)
.map(GroupReceiptInfo::getRecipientId)
.map(Recipient::resolved)
.distinctBy(Recipient::getId)
.distinct()
.toList();
} else {
Log.w(TAG, "No destinations found for group message " + groupId + " using current group membership");
possible = Stream.of(SignalDatabase.groups()
.getGroupMembers(groupId, GroupTable.MemberSet.FULL_MEMBERS_EXCLUDING_SELF))
.map(Recipient::resolve)
.distinctBy(Recipient::getId)
.distinct()
.toList();
}
@@ -6,9 +6,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import org.signal.core.models.ServiceId;
import org.signal.core.models.ServiceId.ACI;
import org.signal.core.util.Base64;
@@ -43,6 +40,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Sends an update to a group without inserting a change message locally.
@@ -74,11 +73,11 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
List<ACI> memberAcis = DecryptedGroupUtil.toAciList(decryptedGroup.members);
List<ServiceId> pendingServiceIds = DecryptedGroupUtil.pendingToServiceIdList(decryptedGroup.pendingMembers);
Stream<ACI> memberServiceIds = Stream.of(memberAcis)
.filter(ACI::isValid)
.filter(aci -> !SignalStore.account().requireAci().equals(aci));
Stream<ServiceId> filteredPendingServiceIds = Stream.of(pendingServiceIds)
.filterNot(ServiceId::isUnknown);
Stream<ACI> memberServiceIds = memberAcis.stream()
.filter(ACI::isValid)
.filter(aci -> !SignalStore.account().requireAci().equals(aci));
Stream<ServiceId> filteredPendingServiceIds = pendingServiceIds.stream()
.filter(serviceId1 -> !serviceId1.isUnknown());
Set<RecipientId> recipients = Stream.concat(memberServiceIds, filteredPendingServiceIds)
.map(serviceId -> Recipient.externalPush(serviceId))
@@ -145,7 +144,7 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
return;
}
List<Recipient> destinations = Stream.of(recipients).map(Recipient::resolved).toList();
List<Recipient> destinations = recipients.stream().map(Recipient::resolved).collect(Collectors.toList());
List<Recipient> completions = deliver(destinations, groupId);
for (Recipient completion : completions) {
@@ -79,6 +79,7 @@ import java.io.InputStream;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -222,8 +223,8 @@ public abstract class PushSendJob extends SendJob {
.toList());
attachments.addAll(Stream.of(message.getSharedContacts())
.map(Contact::getAvatar).withoutNulls()
.map(Contact.Avatar::getAttachment).withoutNulls()
.map(Contact::getAvatar).filter(Objects::nonNull)
.map(Contact.Avatar::getAttachment).filter(Objects::nonNull)
.toList());
HashSet<String> jobs = new HashSet<>(Stream.of(attachments).map(a -> {
@@ -4,8 +4,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.annimon.stream.Stream;
import org.signal.core.util.SetUtil;
import org.signal.core.util.Util;
import org.signal.core.util.logging.Log;
@@ -38,6 +36,8 @@ import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedExcept
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class RemoteDeleteSendJob extends BaseJob {
@@ -73,8 +73,9 @@ public class RemoteDeleteSendJob extends BaseJob {
return AppDependencies.getJobManager().startChain(MultiDeviceStorySendSyncJob.create(message.getDateSent(), messageId));
}
} else {
recipients = conversationRecipient.isGroup() ? Stream.of(conversationRecipient.getParticipantIds()).toList()
: Stream.of(conversationRecipient.getId()).toList();
recipients = conversationRecipient.isGroup()
? conversationRecipient.getParticipantIds().stream().collect(Collectors.toList())
: Stream.of(conversationRecipient.getId()).collect(Collectors.toList());
}
recipients.remove(Recipient.self().getId());
@@ -158,9 +159,9 @@ public class RemoteDeleteSendJob extends BaseJob {
return;
}
List<Recipient> possible = Stream.of(recipients).map(Recipient::resolved).toList();
List<Recipient> eligible = RecipientUtil.getEligibleForSending(Stream.of(recipients).map(Recipient::resolved).filter(Recipient::getHasServiceId).toList());
List<RecipientId> skipped = Stream.of(SetUtil.difference(possible, eligible)).map(Recipient::getId).toList();
List<Recipient> possible = recipients.stream().map(Recipient::resolved).collect(Collectors.toList());
List<Recipient> eligible = RecipientUtil.getEligibleForSending(recipients.stream().map(Recipient::resolved).filter(Recipient::getHasServiceId).collect(Collectors.toList()));
List<RecipientId> skipped = SetUtil.difference(possible, eligible).stream().map(Recipient::getId).collect(Collectors.toList());
boolean isForStory = message.isMms() && (((MmsMessageRecord) message).getStoryType().isStory() || ((MmsMessageRecord) message).getParentStoryId() != null);
DistributionListId distributionListId = isForStory ? message.getToRecipient().getDistributionListId().orElse(null) : null;
@@ -19,6 +19,7 @@ import org.signal.core.util.Util;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public abstract class SendJob extends BaseJob {
@@ -49,8 +50,8 @@ public abstract class SendJob extends BaseJob {
List<Attachment> attachments = new LinkedList<>();
attachments.addAll(message.getAttachments());
attachments.addAll(Stream.of(message.getLinkPreviews()).map(lp -> lp.getThumbnail().orElse(null)).withoutNulls().toList());
attachments.addAll(Stream.of(message.getSharedContacts()).map(Contact::getAvatarAttachment).withoutNulls().toList());
attachments.addAll(Stream.of(message.getLinkPreviews()).map(lp -> lp.getThumbnail().orElse(null)).filter(Objects::nonNull).toList());
attachments.addAll(Stream.of(message.getSharedContacts()).map(Contact::getAvatarAttachment).filter(Objects::nonNull).toList());
if (message.getOutgoingQuote() != null && message.getOutgoingQuote().getAttachment() != null) {
attachments.add(message.getOutgoingQuote().getAttachment());
@@ -156,10 +156,10 @@ public final class LinkPreviewUtil {
@SuppressLint("ObsoleteSdkInt")
public long getDate() {
return Stream.of(values.get(KEY_PUBLISHED_TIME_1),
values.get(KEY_PUBLISHED_TIME_2),
values.get(KEY_MODIFIED_TIME_1),
values.get(KEY_MODIFIED_TIME_2))
return Stream.of(new String[] { values.get(KEY_PUBLISHED_TIME_1),
values.get(KEY_PUBLISHED_TIME_2),
values.get(KEY_MODIFIED_TIME_1),
values.get(KEY_MODIFIED_TIME_2) })
.map(DateUtils::parseIso8601)
.filter(time -> time > 0)
.findFirst()
@@ -365,7 +365,7 @@ public class SubmitDebugLogRepository {
private @NonNull List<LogLine> getPrefixLogLinesInternal() {
long startTime = System.currentTimeMillis();
int maxTitleLength = Stream.of(SECTIONS).reduce(0, (max, section) -> Math.max(max, section.getTitle().length()));
int maxTitleLength = SECTIONS.stream().reduce(0, (max, section) -> Math.max(max, section.getTitle().length()), Integer::sum);
List<LogLine> allLines = new ArrayList<>();
@@ -170,7 +170,7 @@ public class MediaRepository {
Uri allMediaThumbnail = imageFolders.getThumbnailTimestamp() > videoFolders.getThumbnailTimestamp() ? imageFolders.getThumbnail() : videoFolders.getThumbnail();
if (allMediaThumbnail != null) {
int allMediaCount = Stream.of(mediaFolders).reduce(0, (count, folder) -> count + folder.getItemCount());
int allMediaCount = mediaFolders.stream().reduce(0, (count, folder) -> count + folder.getItemCount(), Integer::sum);
if (cameraFolder != null) {
allMediaCount += cameraFolder.getCount();
@@ -124,7 +124,7 @@ public class MegaphoneRepository {
private void init() {
List<MegaphoneRecord> records = database.getAllAndDeleteMissing();
Set<Event> events = Stream.of(records).map(MegaphoneRecord::getEvent).collect(Collectors.toSet());
Set<Event> missing = Stream.of(Megaphones.Event.values()).filterNot(events::contains).collect(Collectors.toSet());
Set<Event> missing = Stream.of(Megaphones.Event.values()).filter(o -> !events.contains(o)).collect(Collectors.toSet());
database.insert(missing);
resetDatabaseCache();
@@ -99,7 +99,7 @@ public final class Megaphones {
.map(Map.Entry::getKey)
.map(records::get)
.map(record -> Megaphones.forRecord(context, record))
.filterNot(Objects::isNull)
.filter(Objects::nonNull)
.toList();
if (megaphones.size() > 0) {
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.messagedetails;
import androidx.annotation.NonNull;
import com.annimon.stream.ComparatorCompat;
import org.thoughtcrime.securesms.conversation.ConversationMessage;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
@@ -15,7 +14,7 @@ import java.util.TreeSet;
public final class MessageDetails {
private static final Comparator<RecipientDeliveryStatus> HAS_DISPLAY_NAME = (r1, r2) -> Boolean.compare(r2.getRecipient().hasAUserSetDisplayName(AppDependencies.getApplication()), r1.getRecipient().hasAUserSetDisplayName(AppDependencies.getApplication()));
private static final Comparator<RecipientDeliveryStatus> ALPHABETICAL = (r1, r2) -> r1.getRecipient().getDisplayName(AppDependencies.getApplication()).compareToIgnoreCase(r2.getRecipient().getDisplayName(AppDependencies.getApplication()));
private static final Comparator<RecipientDeliveryStatus> RECIPIENT_COMPARATOR = ComparatorCompat.chain(HAS_DISPLAY_NAME).thenComparing(ALPHABETICAL);
private static final Comparator<RecipientDeliveryStatus> RECIPIENT_COMPARATOR = HAS_DISPLAY_NAME.thenComparing(ALPHABETICAL);
private final ConversationMessage conversationMessage;
@@ -25,7 +25,10 @@ import org.whispersystems.signalservice.internal.push.GroupContextV2;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Represents either a GroupV1 or GroupV2 encoded context.
@@ -131,9 +134,9 @@ public final class MessageGroupContext {
return Stream.of(groupContext.members)
.filter(m -> SignalE164Util.isPotentialE164(m.e164))
.map(m -> m.e164)
.withoutNulls()
.filter(Objects::nonNull)
.map(RecipientId::fromE164)
.filterNot(selfId::equals)
.filter(other -> !selfId.equals(other))
.toList();
}
}
@@ -170,14 +173,13 @@ public final class MessageGroupContext {
DecryptedGroup groupState = decryptedGroupV2Context.groupState;
DecryptedGroupChange groupChange = getChange();
return Stream.of(DecryptedGroupUtil.toAciList(groupState.members),
return java.util.stream.Stream.of(DecryptedGroupUtil.toAciList(groupState.members),
DecryptedGroupUtil.pendingToServiceIdList(groupState.pendingMembers),
DecryptedGroupUtil.removedMembersServiceIdList(groupChange),
DecryptedGroupUtil.removedPendingMembersServiceIdList(groupChange),
DecryptedGroupUtil.removedRequestingMembersServiceIdList(groupChange))
.flatMap(Stream::of)
.filterNot(ServiceId::isUnknown)
.toList();
.flatMap(Collection::stream)
.filter(serviceId -> !serviceId.isUnknown()).collect(Collectors.toList());
}
@Override
@@ -3,8 +3,6 @@ package org.thoughtcrime.securesms.payments;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.ComparatorCompat;
import org.thoughtcrime.securesms.payments.proto.PaymentMetaData;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.payments.Money;
@@ -20,9 +18,8 @@ import java.util.UUID;
public interface Payment {
Comparator<Payment> UNKNOWN_BLOCK_INDEX_FIRST = (a, b) -> Boolean.compare(b.getBlockIndex() == 0, a.getBlockIndex() == 0);
Comparator<Payment> ASCENDING_BLOCK_INDEX = (a, b) -> Long.compare(a.getBlockIndex(), b.getBlockIndex());
Comparator<Payment> DESCENDING_BLOCK_INDEX = ComparatorCompat.reversed(ASCENDING_BLOCK_INDEX);
Comparator<Payment> DESCENDING_BLOCK_INDEX_UNKNOWN_FIRST = ComparatorCompat.chain(UNKNOWN_BLOCK_INDEX_FIRST)
.thenComparing(DESCENDING_BLOCK_INDEX);
Comparator<Payment> DESCENDING_BLOCK_INDEX = ASCENDING_BLOCK_INDEX.reversed();
Comparator<Payment> DESCENDING_BLOCK_INDEX_UNKNOWN_FIRST = UNKNOWN_BLOCK_INDEX_FIRST.thenComparing(DESCENDING_BLOCK_INDEX);
@NonNull UUID getUuid();
@@ -3,9 +3,8 @@ package org.thoughtcrime.securesms.payments;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import java.util.List;
import java.util.stream.Collectors;
/**
* A payment may be comprised of zero or more defrag transactions and the payment transaction.
@@ -22,17 +21,16 @@ public final class PaymentSubmissionResult {
if (transactions.isEmpty()) {
throw new IllegalStateException();
}
this.defrags = Stream.of(transactions)
.filter(TransactionSubmissionResult::isDefrag)
.toList();
this.nonDefrag = Stream.of(transactions)
.filterNot(TransactionSubmissionResult::isDefrag)
.findSingle()
.orElse(null);
this.erroredTransaction = Stream.of(transactions)
.filter(t -> t.getErrorCode() != TransactionSubmissionResult.ErrorCode.NONE)
.findSingle()
.orElse(null);
this.defrags = transactions.stream()
.filter(TransactionSubmissionResult::isDefrag).collect(Collectors.toList());
final List<TransactionSubmissionResult> nonDefragTransactions = transactions.stream().filter(x -> !x.isDefrag()).collect(Collectors.toList());
if (nonDefragTransactions.size() > 1) throw new IllegalStateException("Too many defrag transaction results!");
this.nonDefrag = nonDefragTransactions.isEmpty() ? null : nonDefragTransactions.get(0);
final List<TransactionSubmissionResult> erroredTransactions = transactions.stream().filter(
t -> t.getErrorCode() != TransactionSubmissionResult.ErrorCode.NONE).collect(Collectors.toList());
if (erroredTransactions.size() > 1) throw new IllegalStateException("Too many errored transaction results!");
this.erroredTransaction = erroredTransactions.isEmpty() ? null : erroredTransactions.get(0);
}
public List<TransactionSubmissionResult> defrags() {
@@ -19,7 +19,6 @@ import androidx.navigation.Navigation;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.annimon.stream.Stream;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.signal.core.util.ClearClipboardAlarmReceiver;
@@ -35,6 +34,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class PaymentsRecoveryPhraseFragment extends Fragment {
@@ -69,10 +69,9 @@ public class PaymentsRecoveryPhraseFragment extends Fragment {
setUpForDisplay(message, next, edit, copy, words, args);
}
List<MnemonicPart> parts = Stream.of(words)
.mapIndexed(MnemonicPart::new)
.sorted(new MnemonicPartComparator(words.size(), SPAN_COUNT))
.toList();
List<MnemonicPart> parts = IntStream.range(0, words.size()).boxed()
.map(index -> new MnemonicPart(index, words.get(index)))
.sorted(new MnemonicPartComparator(words.size(), SPAN_COUNT)).collect(java.util.stream.Collectors.toList());
MnemonicPartAdapter adapter = new MnemonicPartAdapter();
@@ -2,8 +2,6 @@ package org.thoughtcrime.securesms.payments.history;
import androidx.annotation.NonNull;
import com.annimon.stream.ComparatorCompat;
import org.thoughtcrime.securesms.payments.Direction;
import org.whispersystems.signalservice.api.payments.Money;
@@ -82,8 +80,7 @@ public final class TransactionReconstruction {
* <p>
* Then smaller first is just to show more important ones higher on a reversed list.
*/
public static final Comparator<Transaction> ORDER = ComparatorCompat.chain(RECEIVED_FIRST)
.thenComparing(ABSOLUTE_SIZE);
public static final Comparator<Transaction> ORDER = RECEIVED_FIRST.thenComparing(ABSOLUTE_SIZE);
private final Money.MobileCoin value;
private final Direction direction;
@@ -57,7 +57,8 @@ public class PaymentsRepository {
private void updateDatabaseWithNewBlockInformation(@NonNull List<Payment> reconcileOutput) {
List<LedgerReconcile.BlockOverridePayment> blockOverridePayments = Stream.of(reconcileOutput)
.select(LedgerReconcile.BlockOverridePayment.class)
.filter(x -> x instanceof LedgerReconcile.BlockOverridePayment)
.map(x -> (LedgerReconcile.BlockOverridePayment)x)
.toList();
if (blockOverridePayments.isEmpty()) {
@@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.util.adapter.mapping.MappingModelList;
import org.thoughtcrime.securesms.util.livedata.Store;
import java.util.Collection;
import java.util.Comparator;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
@@ -87,21 +88,19 @@ public final class SetCurrencyViewModel extends ViewModel {
}
private @NonNull MappingModelList fromCurrencies(@NonNull Collection<Currency> currencies, @NonNull Currency currentCurrency) {
return Stream.of(currencies)
return currencies.stream()
.map(c -> new SingleSelectSetting.Item(c, c.getDisplayName(Locale.getDefault()), c.getCurrencyCode(), c.equals(currentCurrency)))
.sortBy(SingleSelectSetting.Item::getText)
.sorted(Comparator.comparing(SingleSelectSetting.Item::getText))
.collect(MappingModelList.toMappingModelList());
}
private int findSelectedIndex(MappingModelList items) {
return Stream.of(items)
.mapIndexed(Pair::new)
.filter(p -> p.getSecond() instanceof SingleSelectSetting.Item)
.map(p -> new Pair<>(p.getFirst(), (SingleSelectSetting.Item) p.getSecond()))
.filter(pair -> pair.getSecond().isSelected())
.findFirst()
.map(Pair::getFirst)
.orElse(-1);
for (int i=0; i<items.size(); i++) {
if (items.get(i) instanceof SingleSelectSetting.Item model && model.isSelected()) {
return i;
}
}
return -1;
}
public static class CurrencyListState {
@@ -131,7 +130,7 @@ public final class SetCurrencyViewModel extends ViewModel {
public static class SetCurrencyState {
private static final List<Currency> DEFAULT_CURRENCIES = Stream.of(BuildConfig.DEFAULT_CURRENCIES.split(","))
.map(CurrencyUtil::getCurrencyByCurrencyCode)
.withoutNulls()
.filter(Objects::nonNull)
.toList();
private final Currency currentCurrency;
@@ -35,7 +35,7 @@ public final class PaymentItem implements MappingModel<PaymentItem> {
private final PaymentType paymentType;
public static @NonNull MappingModelList fromPayment(@NonNull List<Payment> transactions) {
return Stream.of(transactions)
return transactions.stream()
.map(PaymentItem::fromPayment)
.collect(MappingModelList.toMappingModelList());
}
@@ -4,7 +4,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import com.annimon.stream.Collectors;
import com.annimon.stream.ComparatorCompat;
import com.annimon.stream.Stream;
import org.signal.core.util.MapUtil;
@@ -170,9 +169,8 @@ public final class LedgerReconcile {
public static class DetailedTransaction {
private static final Comparator<DetailedTransaction> BLOCK_INDEX = (a, b) -> BlockDetail.BLOCK_INDEX.compare(a.blockDetail, b.blockDetail);
private static final Comparator<DetailedTransaction> TRANSACTION = (a, b) -> TransactionReconstruction.Transaction.ORDER.compare(a.transaction, b.transaction);
public static final Comparator<DetailedTransaction> ASCENDING = ComparatorCompat.chain(BLOCK_INDEX)
.thenComparing(TRANSACTION);
public static final Comparator<DetailedTransaction> DESCENDING = ComparatorCompat.reversed(ASCENDING);
public static final Comparator<DetailedTransaction> ASCENDING = BLOCK_INDEX.thenComparing(TRANSACTION);
public static final Comparator<DetailedTransaction> DESCENDING = ASCENDING.reversed();
private final BlockDetail blockDetail;
@@ -7,13 +7,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.annimon.stream.Stream;
import org.signal.core.util.StringUtil;
import org.thoughtcrime.securesms.util.cjkv.CJKVUtil;
import org.whispersystems.signalservice.api.crypto.ProfileCipher;
import java.util.Objects;
import java.util.stream.Stream;
public final class ProfileName implements Parcelable {
@@ -130,8 +129,10 @@ public final class ProfileName implements Parcelable {
return false;
} else {
return Stream.of(givenName, familyName)
.filterNot(String::isEmpty)
.reduce(true, (a, s) -> a && CJKVUtil.isCJKV(s));
.filter(s1 -> !s1.isEmpty())
.reduce(true,
(a, s) -> a && CJKVUtil.isCJKV(s),
(a,b) -> a && b);
}
}
@@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.database.model.MessageId;
@@ -29,8 +30,9 @@ public class ReactionsViewModel extends ViewModel {
public @NonNull Observable<List<EmojiCount>> getEmojiCounts() {
return repository.getReactions(messageId)
.map(reactionList -> {
List<EmojiCount> emojiCounts = Stream.of(reactionList)
.groupBy(ReactionDetails::getBaseEmoji)
List<EmojiCount> emojiCounts = Stream.of(Stream.of(reactionList)
.collect(Collectors.groupingBy(ReactionDetails::getBaseEmoji))
.entrySet())
.sorted(this::compareReactions)
.map(entry -> new EmojiCount(entry.getKey(),
getCountDisplayEmoji(entry.getValue()),
@@ -39,7 +39,7 @@ final class ReactWithAnyEmojiRepository {
this.emojiPages = new LinkedList<>();
emojiPages.addAll(Stream.of(EmojiSource.getLatest().getDisplayPages())
.filterNot(p -> p.getIconAttr() == EmojiCategory.EMOTICONS.getIcon())
.filter(p -> p.getIconAttr() != EmojiCategory.EMOTICONS.getIcon())
.map(page -> new ReactWithAnyEmojiPage(Collections.singletonList(new ReactWithAnyEmojiPageBlock(EmojiCategory.getCategoryLabel(page.getIconAttr()), page))))
.toList());
}
@@ -108,7 +108,7 @@ public class RecipientUtil {
{
List<Recipient> recipientsWithoutUuids = Stream.of(recipients)
.map(Recipient::resolve)
.filterNot(Recipient::getHasServiceId)
.filter(recipient -> !recipient.getHasServiceId())
.toList();
if (recipientsWithoutUuids.size() > 0) {
@@ -9,8 +9,6 @@ import android.hardware.camera2.CameraMetadata;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import org.signal.core.util.logging.Log;
import org.signal.ringrtc.CameraControl;
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
@@ -26,6 +24,8 @@ import org.webrtc.VideoSink;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.thoughtcrime.securesms.ringrtc.CameraState.Direction.BACK;
import static org.thoughtcrime.securesms.ringrtc.CameraState.Direction.FRONT;
@@ -276,10 +276,10 @@ public class Camera implements CameraControl, CameraVideoCapturer.CameraSwitchHa
if (cameraManager != null) {
List<String> devices = Stream.of(cameraManager.getCameraIdList())
.filterNot(id -> isMonochrome(id, cameraManager))
.toList();
.filter(id -> !isMonochrome(id, cameraManager))
.collect(Collectors.toList());
String frontCamera = Stream.of(devices)
String frontCamera = devices.stream()
.filter(id -> isLensFacing(id, cameraManager, CameraMetadata.LENS_FACING_FRONT))
.findFirst()
.orElse(null);
@@ -288,7 +288,7 @@ public class Camera implements CameraControl, CameraVideoCapturer.CameraSwitchHa
cameraList.add(frontCamera);
}
String backCamera = Stream.of(devices)
String backCamera = devices.stream()
.filter(id -> isLensFacing(id, cameraManager, CameraMetadata.LENS_FACING_BACK))
.findFirst()
.orElse(null);
@@ -3,9 +3,6 @@ package org.thoughtcrime.securesms.service.webrtc.collections;
import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import com.annimon.stream.ComparatorCompat;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.CallParticipantId;
@@ -34,9 +31,9 @@ public class ParticipantCollection {
return 0;
}
};
private static final Comparator<CallParticipant> COMPLEX_COMPARATOR_CHAIN = ComparatorCompat.chain(HAND_RAISED)
.thenComparing(MOST_RECENTLY_SPOKEN)
.thenComparing(LEAST_RECENTLY_ADDED);
private static final Comparator<CallParticipant> COMPLEX_COMPARATOR_CHAIN = HAND_RAISED
.thenComparing(MOST_RECENTLY_SPOKEN)
.thenComparing(LEAST_RECENTLY_ADDED);
private final int maxGridCellCount;
private final List<CallParticipant> participants;
@@ -63,18 +60,18 @@ public class ParticipantCollection {
List<CallParticipant> newParticipants = new ArrayList<>(participants);
Collections.sort(newParticipants, COMPLEX_COMPARATOR_CHAIN);
List<CallParticipantId> oldGridParticipantIds = Stream.of(getGridParticipants())
.map(CallParticipant::getCallParticipantId)
.toList();
List<CallParticipantId> oldGridParticipantIds = getGridParticipants().stream()
.map(CallParticipant::getCallParticipantId)
.collect(Collectors.toList());
for (int i = 0; i < oldGridParticipantIds.size(); i++) {
CallParticipantId oldId = oldGridParticipantIds.get(i);
int newIndex = Stream.of(newParticipants)
.takeUntilIndexed((j, p) -> j >= maxGridCellCount)
.map(CallParticipant::getCallParticipantId)
.toList()
.indexOf(oldId);
int newIndex = newParticipants.stream()
.limit(maxGridCellCount)
.map(CallParticipant::getCallParticipantId)
.collect(Collectors.toList())
.indexOf(oldId);
if (newIndex != -1 && newIndex != i) {
Collections.swap(newParticipants, newIndex, Math.min(i, newParticipants.size() - 1));
@@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.service.webrtc.state
import com.annimon.stream.OptionalLong
import org.signal.ringrtc.CallId
import org.signal.ringrtc.CallManager.CallEndReason
import org.signal.ringrtc.GroupCall
@@ -13,6 +12,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.ringrtc.RemotePeer
import org.thoughtcrime.securesms.service.webrtc.CallLinkDisconnectReason
import org.thoughtcrime.securesms.service.webrtc.PendingParticipantCollection
import java.util.Optional
/**
* General state of ongoing calls.
@@ -29,7 +29,7 @@ data class CallInfoState(
var groupCall: GroupCall? = null,
@get:JvmName("getGroupCallState") var groupState: WebRtcViewModel.GroupCallState = WebRtcViewModel.GroupCallState.IDLE,
var identityChangedRecipients: MutableSet<RecipientId> = mutableSetOf(),
var remoteDevicesCount: OptionalLong = OptionalLong.empty(),
var remoteDevicesCount: Optional<Long> = Optional.empty(),
var participantLimit: Long? = null,
var pendingParticipants: PendingParticipantCollection = PendingParticipantCollection(),
var callLinkDisconnectReason: CallLinkDisconnectReason? = null,
@@ -3,8 +3,6 @@ package org.thoughtcrime.securesms.service.webrtc.state;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.OptionalLong;
import org.checkerframework.checker.units.qual.N;
import org.signal.ringrtc.CallId;
import org.signal.ringrtc.CallManager;
@@ -28,6 +26,7 @@ import org.webrtc.PeerConnection;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
@@ -359,7 +358,7 @@ public class WebRtcServiceStateBuilder {
}
public @NonNull CallInfoStateBuilder remoteDevicesCount(long remoteDevicesCount) {
toBuild.setRemoteDevicesCount(OptionalLong.of(remoteDevicesCount));
toBuild.setRemoteDevicesCount(Optional.of(remoteDevicesCount));
return this;
}
@@ -11,8 +11,6 @@ import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.sharing.MultiShareArgs;
import org.thoughtcrime.securesms.sharing.MultiShareSender;
@@ -20,6 +18,8 @@ import org.thoughtcrime.securesms.util.DefaultValueLiveData;
import org.signal.core.util.Util;
import org.thoughtcrime.securesms.util.adapter.mapping.MappingModelList;
import java.util.stream.Stream;
class ShareInterstitialViewModel extends ViewModel {
private final MultiShareArgs args;
@@ -34,9 +34,13 @@ private final MultiShareArgs args;
this.draftText = new DefaultValueLiveData<>(Util.firstNonNull(args.getDraftText(), ""));
repository.loadRecipients(args.getRecipientSearchKeys(),
list -> recipients.postValue(Stream.of(list)
.mapIndexed((i, r) -> new ShareInterstitialMappingModel(r, i == 0))
.collect(MappingModelList.toMappingModelList())));
list -> recipients.postValue(
Stream.concat(
list.stream().limit(1)
.map(r -> new ShareInterstitialMappingModel(r, true)),
list.stream().skip(1)
.map(r -> new ShareInterstitialMappingModel(r, false)))
.collect(MappingModelList.toMappingModelList())));
}
@@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -101,7 +102,7 @@ public final class ConversationUtil {
*/
public static void clearShortcuts(@NonNull Context context, @NonNull Collection<RecipientId> recipientIds) {
SignalExecutors.BOUNDED.execute(() -> {
ShortcutManagerCompat.removeLongLivedShortcuts(context, Stream.of(recipientIds).withoutNulls().map(ConversationUtil::getShortcutId).toList());
ShortcutManagerCompat.removeLongLivedShortcuts(context, Stream.of(recipientIds).filter(Objects::nonNull).map(ConversationUtil::getShortcutId).toList());
});
}
@@ -12,6 +12,7 @@ import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.BuildConfig;
import java.io.IOException;
import java.util.Comparator;
import java.util.Objects;
public final class RemoteDeprecation {
@@ -53,7 +54,7 @@ public final class RemoteDeprecation {
ClientExpiration expiration = Stream.of(expirations)
.filter(c -> c.getVersion() != null && c.getExpiration() != -1)
.filter(c -> c.requireVersion().compareTo(ourVersion) > 0)
.sortBy(ClientExpiration::getExpiration)
.sorted(Comparator.comparing(ClientExpiration::getExpiration))
.findFirst()
.orElse(null);
@@ -4,8 +4,6 @@ import androidx.annotation.Nullable;
import org.signal.core.util.Util;
import com.annimon.stream.ComparatorCompat;
import java.util.Comparator;
import java.util.Objects;
import java.util.regex.Matcher;
@@ -18,8 +16,7 @@ public final class SemanticVersion implements Comparable<SemanticVersion> {
private static final Comparator<SemanticVersion> MAJOR_COMPARATOR = (s1, s2) -> Integer.compare(s1.major, s2.major);
private static final Comparator<SemanticVersion> MINOR_COMPARATOR = (s1, s2) -> Integer.compare(s1.minor, s2.minor);
private static final Comparator<SemanticVersion> PATCH_COMPARATOR = (s1, s2) -> Integer.compare(s1.patch, s2.patch);
private static final Comparator<SemanticVersion> COMPARATOR = ComparatorCompat.chain(MAJOR_COMPARATOR)
.thenComparing(MINOR_COMPARATOR)
private static final Comparator<SemanticVersion> COMPARATOR = MAJOR_COMPARATOR.thenComparing(MINOR_COMPARATOR)
.thenComparing(PATCH_COMPARATOR);
private final int major;
@@ -87,7 +87,7 @@ public abstract class SectionedRecyclerViewAdapter<IdType, SectionImpl extends S
@Override
public int getItemCount() {
return Stream.of(getSections()).reduce(0, (sum, section) -> sum + section.size());
return getSections().stream().reduce(0, (sum, section) -> sum + section.size(), Integer::sum);
}
/**
@@ -2,16 +2,17 @@ package org.thoughtcrime.securesms.util.adapter.mapping;
import androidx.annotation.NonNull;
import com.annimon.stream.Collector;
import com.annimon.stream.function.BiConsumer;
import com.annimon.stream.function.Function;
import com.annimon.stream.function.Supplier;
import java.util.Collections;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.stream.Collector;
public class MappingModelList extends ArrayList<MappingModel<?>> {
@@ -71,6 +72,14 @@ public class MappingModelList extends ArrayList<MappingModel<?>> {
return MappingModelList::add;
}
@Override public Set<Characteristics> characteristics() {
return Collections.emptySet();
}
@Override public BinaryOperator<MappingModelList> combiner() {
return (x, y) -> {x.addAll(y); return x;};
}
@Override
public @NonNull Function<MappingModelList, MappingModelList> finisher() {
return mappingModels -> mappingModels;
@@ -10,8 +10,6 @@ import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.Transformations;
import com.annimon.stream.function.Predicate;
import org.signal.core.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor;
import org.whispersystems.signalservice.api.util.Preconditions;
@@ -22,6 +20,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Predicate;
import kotlin.jvm.functions.Function1;
@@ -7,7 +7,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.LiveDataReactiveStreams;
import androidx.lifecycle.MediatorLiveData;
import com.annimon.stream.function.Function;
import java.util.function.Function;
import org.signal.core.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;