Convert calling and payments apis to WebSocket.

This commit is contained in:
Cody Henthorne
2025-03-11 14:48:51 -04:00
committed by Greyson Parrelli
parent 224a85f5db
commit 92e590aa3b
17 changed files with 231 additions and 192 deletions

View File

@@ -45,11 +45,12 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender
import org.whispersystems.signalservice.api.account.AccountApi
import org.whispersystems.signalservice.api.archive.ArchiveApi
import org.whispersystems.signalservice.api.attachment.AttachmentApi
import org.whispersystems.signalservice.api.calling.CallingApi
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations
import org.whispersystems.signalservice.api.keys.KeysApi
import org.whispersystems.signalservice.api.link.LinkDeviceApi
import org.whispersystems.signalservice.api.payments.PaymentsApi
import org.whispersystems.signalservice.api.registration.RegistrationApi
import org.whispersystems.signalservice.api.services.CallLinksService
import org.whispersystems.signalservice.api.services.DonationsService
import org.whispersystems.signalservice.api.services.ProfileService
import org.whispersystems.signalservice.api.storage.StorageServiceApi
@@ -278,10 +279,6 @@ object AppDependencies {
val payments: Payments
get() = networkModule.payments
@JvmStatic
val callLinksService: CallLinksService
get() = networkModule.callLinksService
@JvmStatic
val profileService: ProfileService
get() = networkModule.profileService
@@ -319,6 +316,12 @@ object AppDependencies {
val usernameApi: UsernameApi
get() = networkModule.usernameApi
val callingApi: CallingApi
get() = networkModule.callingApi
val paymentsApi: PaymentsApi
get() = networkModule.paymentsApi
@JvmStatic
val okHttpClient: OkHttpClient
get() = networkModule.okHttpClient
@@ -365,7 +368,7 @@ object AppDependencies {
fun provideTypingStatusRepository(): TypingStatusRepository
fun provideTypingStatusSender(): TypingStatusSender
fun provideDatabaseObserver(): DatabaseObserver
fun providePayments(signalServiceAccountManager: SignalServiceAccountManager): Payments
fun providePayments(paymentsApi: PaymentsApi): Payments
fun provideShakeToReport(): ShakeToReport
fun provideSignalCallManager(): SignalCallManager
fun providePendingRetryReceiptManager(): PendingRetryReceiptManager
@@ -375,7 +378,6 @@ object AppDependencies {
fun provideExoPlayerPool(): SimpleExoPlayerPool
fun provideAndroidCallAudioManager(): AudioManagerCompat
fun provideDonationsService(pushServiceSocket: PushServiceSocket): DonationsService
fun provideCallLinksService(pushServiceSocket: PushServiceSocket): CallLinksService
fun provideProfileService(profileOperations: ClientZkProfileOperations, signalServiceMessageReceiver: SignalServiceMessageReceiver, authWebSocket: SignalWebSocket.AuthenticatedWebSocket, unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket): ProfileService
fun provideDeadlockDetector(): DeadlockDetector
fun provideClientZkReceiptOperations(signalServiceConfiguration: SignalServiceConfiguration): ClientZkReceiptOperations
@@ -392,5 +394,7 @@ object AppDependencies {
fun provideUnauthWebSocket(signalServiceConfigurationSupplier: Supplier<SignalServiceConfiguration>, libSignalNetworkSupplier: Supplier<Network>): SignalWebSocket.UnauthenticatedWebSocket
fun provideAccountApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket): AccountApi
fun provideUsernameApi(unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket): UsernameApi
fun provideCallingApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, pushServiceSocket: PushServiceSocket): CallingApi
fun providePaymentsApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket): PaymentsApi
}
}

View File

@@ -83,14 +83,15 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.account.AccountApi;
import org.whispersystems.signalservice.api.archive.ArchiveApi;
import org.whispersystems.signalservice.api.attachment.AttachmentApi;
import org.whispersystems.signalservice.api.calling.CallingApi;
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
import org.whispersystems.signalservice.api.keys.KeysApi;
import org.whispersystems.signalservice.api.link.LinkDeviceApi;
import org.whispersystems.signalservice.api.payments.PaymentsApi;
import org.whispersystems.signalservice.api.push.ServiceId.ACI;
import org.whispersystems.signalservice.api.push.ServiceId.PNI;
import org.whispersystems.signalservice.api.registration.RegistrationApi;
import org.whispersystems.signalservice.api.services.CallLinksService;
import org.whispersystems.signalservice.api.services.DonationsService;
import org.whispersystems.signalservice.api.services.ProfileService;
import org.whispersystems.signalservice.api.storage.StorageServiceApi;
@@ -267,11 +268,11 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
@SuppressWarnings("ConstantConditions")
@Override
public @NonNull Payments providePayments(@NonNull SignalServiceAccountManager signalServiceAccountManager) {
public @NonNull Payments providePayments(@NonNull PaymentsApi paymentsApi) {
MobileCoinConfig network;
if (BuildConfig.MOBILE_COIN_ENVIRONMENT.equals("mainnet")) network = MobileCoinConfig.getMainNet(signalServiceAccountManager);
else if (BuildConfig.MOBILE_COIN_ENVIRONMENT.equals("testnet")) network = MobileCoinConfig.getTestNet(signalServiceAccountManager);
if (BuildConfig.MOBILE_COIN_ENVIRONMENT.equals("mainnet")) network = MobileCoinConfig.getMainNet(paymentsApi);
else if (BuildConfig.MOBILE_COIN_ENVIRONMENT.equals("testnet")) network = MobileCoinConfig.getTestNet(paymentsApi);
else throw new AssertionError("Unknown network " + BuildConfig.MOBILE_COIN_ENVIRONMENT);
return new Payments(network);
@@ -388,11 +389,6 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
return new DonationsService(pushServiceSocket);
}
@Override
public @NonNull CallLinksService provideCallLinksService(@NonNull PushServiceSocket pushServiceSocket) {
return new CallLinksService(pushServiceSocket);
}
@Override
public @NonNull ProfileService provideProfileService(@NonNull ClientZkProfileOperations clientZkProfileOperations,
@NonNull SignalServiceMessageReceiver receiver,
@@ -504,6 +500,16 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
return new UsernameApi(unauthWebSocket);
}
@Override
public @NonNull CallingApi provideCallingApi(@NonNull SignalWebSocket.AuthenticatedWebSocket authWebSocket, @NonNull PushServiceSocket pushServiceSocket) {
return new CallingApi(authWebSocket, pushServiceSocket);
}
@Override
public @NonNull PaymentsApi providePaymentsApi(@NonNull SignalWebSocket.AuthenticatedWebSocket authWebSocket) {
return new PaymentsApi(authWebSocket);
}
@VisibleForTesting
static class DynamicCredentialsProvider implements CredentialsProvider {

View File

@@ -29,12 +29,13 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender
import org.whispersystems.signalservice.api.account.AccountApi
import org.whispersystems.signalservice.api.archive.ArchiveApi
import org.whispersystems.signalservice.api.attachment.AttachmentApi
import org.whispersystems.signalservice.api.calling.CallingApi
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations
import org.whispersystems.signalservice.api.keys.KeysApi
import org.whispersystems.signalservice.api.link.LinkDeviceApi
import org.whispersystems.signalservice.api.payments.PaymentsApi
import org.whispersystems.signalservice.api.push.TrustStore
import org.whispersystems.signalservice.api.registration.RegistrationApi
import org.whispersystems.signalservice.api.services.CallLinksService
import org.whispersystems.signalservice.api.services.DonationsService
import org.whispersystems.signalservice.api.services.ProfileService
import org.whispersystems.signalservice.api.storage.StorageServiceApi
@@ -120,11 +121,7 @@ class NetworkDependenciesModule(
}
val payments: Payments by lazy {
provider.providePayments(signalServiceAccountManager)
}
val callLinksService: CallLinksService by lazy {
provider.provideCallLinksService(pushServiceSocket)
provider.providePayments(paymentsApi)
}
val profileService: ProfileService by lazy {
@@ -167,6 +164,14 @@ class NetworkDependenciesModule(
provider.provideUsernameApi(unauthWebSocket)
}
val callingApi: CallingApi by lazy {
provider.provideCallingApi(authWebSocket, pushServiceSocket)
}
val paymentsApi: PaymentsApi by lazy {
provider.providePaymentsApi(authWebSocket)
}
val okHttpClient: OkHttpClient by lazy {
OkHttpClient.Builder()
.addInterceptor(StandardUserAgentInterceptor())

View File

@@ -9,8 +9,10 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.whispersystems.signalservice.api.account.AccountApi
import org.whispersystems.signalservice.api.archive.ArchiveApi
import org.whispersystems.signalservice.api.attachment.AttachmentApi
import org.whispersystems.signalservice.api.calling.CallingApi
import org.whispersystems.signalservice.api.keys.KeysApi
import org.whispersystems.signalservice.api.link.LinkDeviceApi
import org.whispersystems.signalservice.api.payments.PaymentsApi
import org.whispersystems.signalservice.api.storage.StorageServiceApi
import org.whispersystems.signalservice.api.username.UsernameApi
@@ -29,12 +31,22 @@ object SignalNetwork {
val attachments: AttachmentApi
get() = AppDependencies.attachmentApi
@JvmStatic
@get:JvmName("calling")
val calling: CallingApi
get() = AppDependencies.callingApi
val keys: KeysApi
get() = AppDependencies.keysApi
val linkDevice: LinkDeviceApi
get() = AppDependencies.linkDeviceApi
@JvmStatic
@get:JvmName("payments")
val payments: PaymentsApi
get() = AppDependencies.paymentsApi
val storageService: StorageServiceApi
get() = AppDependencies.storageServiceApi

View File

@@ -9,6 +9,7 @@ import com.mobilecoin.lib.ClientConfig;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.payments.PaymentsApi;
import org.whispersystems.signalservice.internal.push.AuthCredentials;
import java.io.IOException;
@@ -36,12 +37,12 @@ public abstract class MobileCoinConfig {
abstract @NonNull ClientConfig getConfig();
public static MobileCoinConfig getTestNet(SignalServiceAccountManager signalServiceAccountManager) {
return new MobileCoinTestNetConfig(signalServiceAccountManager);
public static MobileCoinConfig getTestNet(PaymentsApi paymentsApi) {
return new MobileCoinTestNetConfig(paymentsApi);
}
public static MobileCoinConfig getMainNet(SignalServiceAccountManager signalServiceAccountManager) {
return new MobileCoinMainNetConfig(signalServiceAccountManager);
public static MobileCoinConfig getMainNet(PaymentsApi paymentsApi) {
return new MobileCoinMainNetConfig(paymentsApi);
}
protected static Set<X509Certificate> getTrustRoots(@RawRes int pemResource) {

View File

@@ -10,7 +10,9 @@ import com.mobilecoin.lib.exceptions.AttestationException;
import org.thoughtcrime.securesms.R;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.NetworkResultUtil;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.payments.PaymentsApi;
import org.whispersystems.signalservice.internal.push.AuthCredentials;
import java.io.IOException;
@@ -20,11 +22,10 @@ import java.util.List;
import java.util.Set;
final class MobileCoinMainNetConfig extends MobileCoinConfig {
private final PaymentsApi paymentsApi;
private final SignalServiceAccountManager signalServiceAccountManager;
public MobileCoinMainNetConfig(@NonNull SignalServiceAccountManager signalServiceAccountManager) {
this.signalServiceAccountManager = signalServiceAccountManager;
public MobileCoinMainNetConfig(@NonNull PaymentsApi paymentsApi) {
this.paymentsApi = paymentsApi;
}
@Override
@@ -63,7 +64,7 @@ final class MobileCoinMainNetConfig extends MobileCoinConfig {
@Override
@NonNull AuthCredentials getAuth() throws IOException {
return signalServiceAccountManager.getPaymentsAuthorization();
return NetworkResultUtil.toBasicLegacy(paymentsApi.getAuthorization());
}
@Override

View File

@@ -7,9 +7,10 @@ import androidx.annotation.NonNull;
import com.mobilecoin.lib.ClientConfig;
import com.mobilecoin.lib.exceptions.AttestationException;
import org.thoughtcrime.securesms.R;
import org.signal.core.util.Base64;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.thoughtcrime.securesms.R;
import org.whispersystems.signalservice.api.NetworkResultUtil;
import org.whispersystems.signalservice.api.payments.PaymentsApi;
import org.whispersystems.signalservice.internal.push.AuthCredentials;
import java.io.IOException;
@@ -19,11 +20,10 @@ import java.util.List;
import java.util.Set;
final class MobileCoinTestNetConfig extends MobileCoinConfig {
private final PaymentsApi paymentsApi;
private final SignalServiceAccountManager signalServiceAccountManager;
public MobileCoinTestNetConfig(@NonNull SignalServiceAccountManager signalServiceAccountManager) {
this.signalServiceAccountManager = signalServiceAccountManager;
public MobileCoinTestNetConfig(@NonNull PaymentsApi paymentsApi) {
this.paymentsApi = paymentsApi;
}
@Override
@@ -51,7 +51,7 @@ final class MobileCoinTestNetConfig extends MobileCoinConfig {
@Override
@NonNull AuthCredentials getAuth() throws IOException {
return signalServiceAccountManager.getPaymentsAuthorization();
return NetworkResultUtil.toBasicLegacy(paymentsApi.getAuthorization());
}
@Override

View File

@@ -4,9 +4,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.SignalNetwork;
import org.thoughtcrime.securesms.payments.currency.CurrencyExchange;
import org.whispersystems.signalservice.api.NetworkResultUtil;
import org.whispersystems.signalservice.api.payments.CurrencyConversion;
import org.whispersystems.signalservice.api.payments.CurrencyConversions;
@@ -46,7 +47,7 @@ public final class Payments {
public synchronized @NonNull CurrencyExchange getCurrencyExchange(boolean refreshIfAble) throws IOException {
if (currencyConversions == null || shouldRefresh(refreshIfAble, currencyConversions.getTimestamp())) {
Log.i(TAG, "Currency conversion data is unavailable or a refresh was requested and available");
CurrencyConversions newCurrencyConversions = AppDependencies.getSignalServiceAccountManager().getCurrencyConversions();
CurrencyConversions newCurrencyConversions = NetworkResultUtil.toBasicLegacy(SignalNetwork.payments().getCurrencyConversions());
if (currencyConversions == null || (newCurrencyConversions != null && newCurrencyConversions.getTimestamp() > currencyConversions.getTimestamp())) {
currencyConversions = newCurrencyConversions;
}

View File

@@ -53,6 +53,7 @@ import org.thoughtcrime.securesms.jobs.GroupCallUpdateSendJob;
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.messages.GroupSendUtil;
import org.thoughtcrime.securesms.net.SignalNetwork;
import org.thoughtcrime.securesms.notifications.v2.ConversationId;
import org.thoughtcrime.securesms.ratelimit.ProofRequiredExceptionHandler;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -74,6 +75,8 @@ import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder;
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
import org.webrtc.PeerConnection;
import org.whispersystems.signalservice.api.NetworkResult;
import org.whispersystems.signalservice.api.NetworkResultUtil;
import org.whispersystems.signalservice.api.crypto.SealedSenderAccess;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.SendMessageResult;
@@ -876,9 +879,10 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
headerPairs = Collections.emptyList();
}
CallingResponse response = AppDependencies.getSignalServiceMessageSender()
.makeCallingRequest(requestId, url, httpMethod.name(), headerPairs, body);
NetworkResult<CallingResponse> result = SignalNetwork.calling()
.makeCallingRequest(requestId, url, httpMethod.name(), headerPairs, body);
CallingResponse response = ((NetworkResult.Success<CallingResponse>) result).getResult();
try {
if (response instanceof CallingResponse.Success) {
CallingResponse.Success success = (CallingResponse.Success) response;
@@ -1029,7 +1033,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
public void retrieveTurnServers(@NonNull RemotePeer remotePeer) {
networkExecutor.execute(() -> {
try {
List<TurnServerInfo> turnServerInfos = AppDependencies.getSignalServiceAccountManager().getTurnServerInfo();
List<TurnServerInfo> turnServerInfos = NetworkResultUtil.toBasicLegacy(SignalNetwork.calling().getTurnServerInfo());
List<PeerConnection.IceServer> iceServers = mapToIceServers(turnServerInfos);
process((s, p) -> {
RemotePeer activePeer = s.getCallInfoState().getActivePeer();

View File

@@ -6,9 +6,7 @@
package org.thoughtcrime.securesms.service.webrtc.links
import io.reactivex.rxjava3.core.Single
import org.signal.core.util.isAbsent
import org.signal.core.util.logging.Log
import org.signal.core.util.or
import org.signal.libsignal.zkgroup.GenericServerPublicParams
import org.signal.libsignal.zkgroup.calllinks.CallLinkAuthCredentialPresentation
import org.signal.libsignal.zkgroup.calllinks.CallLinkSecretParams
@@ -22,8 +20,9 @@ import org.signal.ringrtc.CallLinkState.Restrictions
import org.signal.ringrtc.CallManager
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.net.SignalNetwork
import org.thoughtcrime.securesms.recipients.Recipient
import org.whispersystems.signalservice.internal.ServiceResponse
import org.whispersystems.signalservice.api.NetworkResult
import java.io.IOException
/**
@@ -51,27 +50,28 @@ class SignalCallLinkManager(
Log.d(TAG, "Requesting call link credential response.")
val serviceResponse: ServiceResponse<CreateCallLinkCredentialResponse> = AppDependencies.callLinksService.getCreateCallLinkAuthCredential(request)
if (serviceResponse.result.isAbsent()) {
throw IOException("Failed to create credential response", serviceResponse.applicationError.or(serviceResponse.executionError).get())
when (val result: NetworkResult<CreateCallLinkCredentialResponse> = SignalNetwork.calling.createCallLinkCredential(request)) {
is NetworkResult.Success -> {
Log.d(TAG, "Requesting call link credential.")
val createCallLinkCredential: CreateCallLinkCredential = requestContext.receiveResponse(
result.result,
userAci.libSignalAci,
genericServerPublicParams
)
Log.d(TAG, "Requesting and returning call link presentation.")
return createCallLinkCredential.present(
roomId,
userAci.libSignalAci,
genericServerPublicParams,
CallLinkSecretParams.deriveFromRootKey(linkRootKey)
)
}
else -> throw IOException("Failed to create credential response", result.getCause())
}
Log.d(TAG, "Requesting call link credential.")
val createCallLinkCredential: CreateCallLinkCredential = requestContext.receiveResponse(
serviceResponse.result.get(),
userAci.libSignalAci,
genericServerPublicParams
)
Log.d(TAG, "Requesting and returning call link presentation.")
return createCallLinkCredential.present(
roomId,
userAci.libSignalAci,
genericServerPublicParams,
CallLinkSecretParams.deriveFromRootKey(linkRootKey)
)
}
private fun requestCallLinkAuthCredentialPresentation(