From 78e36b85d401d33f4977bc44976885903bfe3ad9 Mon Sep 17 00:00:00 2001 From: moiseev-signal <122060238+moiseev-signal@users.noreply.github.com> Date: Mon, 1 Apr 2024 11:33:10 -0700 Subject: [PATCH] Make sure not more than one libsignal Network instance is ever created Co-authored-by: Greyson Parrelli --- .../contacts/sync/ContactDiscoveryRefreshV2.kt | 4 ++-- .../dependencies/ApplicationDependencies.java | 15 +++++++++++++++ .../ApplicationDependencyProvider.java | 6 ++++++ .../MockApplicationDependencyProvider.java | 6 ++++++ .../api/SignalServiceAccountManager.java | 4 ++-- .../signalservice/api/services/CdsiV2Service.java | 7 ++++--- 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryRefreshV2.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryRefreshV2.kt index ae0ea14e64..1e30725686 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryRefreshV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryRefreshV2.kt @@ -98,7 +98,7 @@ object ContactDiscoveryRefreshV2 { Optional.empty(), BuildConfig.CDSI_MRENCLAVE, 10_000, - if (FeatureFlags.useLibsignalNetForCdsiLookup()) BuildConfig.LIBSIGNAL_NET_ENV else null + if (FeatureFlags.useLibsignalNetForCdsiLookup()) ApplicationDependencies.getLibsignalNetwork() else null ) { Log.i(TAG, "Ignoring token for one-off lookup.") } @@ -163,7 +163,7 @@ object ContactDiscoveryRefreshV2 { Optional.ofNullable(token), BuildConfig.CDSI_MRENCLAVE, timeoutMs, - if (FeatureFlags.useLibsignalNetForCdsiLookup()) BuildConfig.LIBSIGNAL_NET_ENV else null + if (FeatureFlags.useLibsignalNetForCdsiLookup()) ApplicationDependencies.getLibsignalNetwork() else null ) { tokenToSave -> stopwatch.split("network-pre-token") if (!isPartialRefresh) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java index 446d35b4ea..362e910e0e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java @@ -8,6 +8,7 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import org.signal.core.util.concurrent.DeadlockDetector; +import org.signal.libsignal.net.Network; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations; import org.thoughtcrime.securesms.components.TypingStatusRepository; @@ -85,6 +86,7 @@ public class ApplicationDependencies { private static final Object FRAME_RATE_TRACKER_LOCK = new Object(); private static final Object JOB_MANAGER_LOCK = new Object(); private static final Object SIGNAL_HTTP_CLIENT_LOCK = new Object(); + private static final Object LIBSIGNAL_NETWORK_LOCK = new Object(); private static Application application; private static Provider provider; @@ -129,6 +131,7 @@ public class ApplicationDependencies { private static volatile DeadlockDetector deadlockDetector; private static volatile ClientZkReceiptOperations clientZkReceiptOperations; private static volatile ScheduledMessageManager scheduledMessagesManager; + private static volatile Network libsignalNetwork; @MainThread public static void init(@NonNull Application application, @NonNull Provider provider) { @@ -685,6 +688,17 @@ public class ApplicationDependencies { return deadlockDetector; } + public static @NonNull Network getLibsignalNetwork() { + if (libsignalNetwork == null) { + synchronized (LIBSIGNAL_NETWORK_LOCK) { + if (libsignalNetwork == null) { + libsignalNetwork = provider.provideLibsignalNetwork(); + } + } + } + return libsignalNetwork; + } + public interface Provider { @NonNull GroupsV2Operations provideGroupsV2Operations(@NonNull SignalServiceConfiguration signalServiceConfiguration); @NonNull SignalServiceAccountManager provideSignalServiceAccountManager(@NonNull SignalServiceConfiguration signalServiceConfiguration, @NonNull GroupsV2Operations groupsV2Operations); @@ -723,5 +737,6 @@ public class ApplicationDependencies { @NonNull DeadlockDetector provideDeadlockDetector(); @NonNull ClientZkReceiptOperations provideClientZkReceiptOperations(@NonNull SignalServiceConfiguration signalServiceConfiguration); @NonNull ScheduledMessageManager provideScheduledMessageManager(); + @NonNull Network provideLibsignalNetwork(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java index 29442e9d4d..adfbf10e76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -11,6 +11,7 @@ import androidx.annotation.VisibleForTesting; import org.signal.core.util.ThreadUtil; import org.signal.core.util.concurrent.DeadlockDetector; import org.signal.core.util.concurrent.SignalExecutors; +import org.signal.libsignal.net.Network; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations; import org.thoughtcrime.securesms.BuildConfig; @@ -228,6 +229,11 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr return new ScheduledMessageManager(context); } + @Override + public @NonNull Network provideLibsignalNetwork() { + return new Network(BuildConfig.LIBSIGNAL_NET_ENV); + } + @Override public @NonNull TypingStatusRepository provideTypingStatusRepository() { return new TypingStatusRepository(); diff --git a/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java b/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java index 561e9d5754..b600822225 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java +++ b/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.dependencies; import androidx.annotation.NonNull; import org.signal.core.util.concurrent.DeadlockDetector; +import org.signal.libsignal.net.Network; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations; import org.thoughtcrime.securesms.components.TypingStatusRepository; @@ -232,4 +233,9 @@ public class MockApplicationDependencyProvider implements ApplicationDependencie public @NonNull ScheduledMessageManager provideScheduledMessageManager() { return null; } + + @Override + public @NonNull Network provideLibsignalNetwork() { + return null; + } } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java index 676a7dd356..9e2e8ef7f1 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java @@ -365,12 +365,12 @@ public class SignalServiceAccountManager { Optional token, String mrEnclave, Long timeoutMs, - @Nullable Network.Environment libsignalNetEnv, + @Nullable Network libsignalNetwork, Consumer tokenSaver) throws IOException { CdsiAuthResponse auth = pushServiceSocket.getCdsiAuth(); - CdsiV2Service service = new CdsiV2Service(configuration, mrEnclave, libsignalNetEnv); + CdsiV2Service service = new CdsiV2Service(configuration, mrEnclave, libsignalNetwork); CdsiV2Service.Request request = new CdsiV2Service.Request(previousE164s, newE164s, serviceIds, token); Single> single = service.getRegisteredUsers(auth.getUsername(), auth.getPassword(), request, tokenSaver); diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java index 1ca90e5acd..e16519a202 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java @@ -33,6 +33,8 @@ import java.util.concurrent.Future; import java.util.function.Consumer; import java.util.stream.Collectors; +import javax.annotation.Nullable; + import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; import okio.ByteString; @@ -51,10 +53,9 @@ public final class CdsiV2Service { private final CdsiRequestHandler cdsiRequestHandler; - public CdsiV2Service(SignalServiceConfiguration configuration, String mrEnclave, Network.Environment libsignalEnv) { + public CdsiV2Service(SignalServiceConfiguration configuration, String mrEnclave, @Nullable Network network) { - if (libsignalEnv != null) { - Network network = new Network(libsignalEnv); + if (network != null) { this.cdsiRequestHandler = (username, password, request, tokenSaver) -> { try { Log.i(TAG, "Starting CDSI lookup via libsignal-net");