mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 21:15:48 +00:00
Convert calling and payments apis to WebSocket.
This commit is contained in:
committed by
Greyson Parrelli
parent
224a85f5db
commit
92e590aa3b
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -39,11 +39,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
|
||||
@@ -143,7 +144,7 @@ class MockApplicationDependencyProvider : AppDependencies.Provider {
|
||||
return mockk(relaxed = true)
|
||||
}
|
||||
|
||||
override fun providePayments(signalServiceAccountManager: SignalServiceAccountManager): Payments {
|
||||
override fun providePayments(paymentsApi: PaymentsApi): Payments {
|
||||
return mockk(relaxed = true)
|
||||
}
|
||||
|
||||
@@ -183,10 +184,6 @@ class MockApplicationDependencyProvider : AppDependencies.Provider {
|
||||
return mockk(relaxed = true)
|
||||
}
|
||||
|
||||
override fun provideCallLinksService(pushServiceSocket: PushServiceSocket): CallLinksService {
|
||||
return mockk(relaxed = true)
|
||||
}
|
||||
|
||||
override fun provideProfileService(
|
||||
profileOperations: ClientZkProfileOperations,
|
||||
signalServiceMessageReceiver: SignalServiceMessageReceiver,
|
||||
@@ -255,4 +252,12 @@ class MockApplicationDependencyProvider : AppDependencies.Provider {
|
||||
override fun provideUsernameApi(unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket): UsernameApi {
|
||||
return mockk(relaxed = true)
|
||||
}
|
||||
|
||||
override fun provideCallingApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, pushServiceSocket: PushServiceSocket): CallingApi {
|
||||
return mockk(relaxed = true)
|
||||
}
|
||||
|
||||
override fun providePaymentsApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket): PaymentsApi {
|
||||
return mockk(relaxed = true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,19 +230,10 @@ public class SignalServiceAccountManager {
|
||||
return new RemoteConfigResult(out, response.getServerEpochTime());
|
||||
}
|
||||
|
||||
public List<TurnServerInfo> getTurnServerInfo() throws IOException {
|
||||
List<TurnServerInfo> relays = this.pushServiceSocket.getCallingRelays().getRelays();
|
||||
return relays != null ? relays : Collections.emptyList();
|
||||
}
|
||||
|
||||
public void checkNetworkConnection() throws IOException {
|
||||
this.pushServiceSocket.pingStorageService();
|
||||
}
|
||||
|
||||
public CurrencyConversions getCurrencyConversions() throws IOException {
|
||||
return this.pushServiceSocket.getCurrencyConversions();
|
||||
}
|
||||
|
||||
public void reportSpam(ServiceId serviceId, String serverGuid, String reportingToken) throws IOException {
|
||||
this.pushServiceSocket.reportSpam(serviceId, serverGuid, reportingToken);
|
||||
}
|
||||
@@ -333,9 +324,4 @@ public class SignalServiceAccountManager {
|
||||
public RegistrationApi getRegistrationApi() {
|
||||
return new RegistrationApi(pushServiceSocket);
|
||||
}
|
||||
|
||||
public AuthCredentials getPaymentsAuthorization() throws IOException {
|
||||
return pushServiceSocket.getPaymentsAuthorization();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -398,20 +398,6 @@ public class SignalServiceMessageSender {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an http request on behalf of the calling infrastructure.
|
||||
*
|
||||
* @param requestId Request identifier
|
||||
* @param url Fully qualified URL to request
|
||||
* @param httpMethod Http method to use (e.g., "GET", "POST")
|
||||
* @param headers Optional list of headers to send with request
|
||||
* @param body Optional body to send with request
|
||||
* @return
|
||||
*/
|
||||
public CallingResponse makeCallingRequest(long requestId, String url, String httpMethod, List<Pair<String, String>> headers, byte[] body) {
|
||||
return socket.makeCallingRequest(requestId, url, httpMethod, headers, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a single recipient.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.signalservice.api.calling
|
||||
|
||||
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialRequest
|
||||
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialResponse
|
||||
import org.whispersystems.signalservice.api.NetworkResult
|
||||
import org.whispersystems.signalservice.api.messages.calls.CallingResponse
|
||||
import org.whispersystems.signalservice.api.messages.calls.TurnServerInfo
|
||||
import org.whispersystems.signalservice.api.websocket.SignalWebSocket
|
||||
import org.whispersystems.signalservice.internal.get
|
||||
import org.whispersystems.signalservice.internal.post
|
||||
import org.whispersystems.signalservice.internal.push.CreateCallLinkAuthRequest
|
||||
import org.whispersystems.signalservice.internal.push.CreateCallLinkAuthResponse
|
||||
import org.whispersystems.signalservice.internal.push.GetCallingRelaysResponse
|
||||
import org.whispersystems.signalservice.internal.push.PushServiceSocket
|
||||
import org.whispersystems.signalservice.internal.websocket.WebSocketRequestMessage
|
||||
import org.signal.libsignal.protocol.util.Pair as LibSignalPair
|
||||
|
||||
/**
|
||||
* Provide calling specific network apis.
|
||||
*/
|
||||
class CallingApi(
|
||||
private val auth: SignalWebSocket.AuthenticatedWebSocket,
|
||||
private val pushServiceSocket: PushServiceSocket
|
||||
) {
|
||||
|
||||
/**
|
||||
* Get 1:1 relay addresses in IpV4, Ipv6, and URL formats.
|
||||
*
|
||||
* GET /v2/calling/relays
|
||||
* - 200: Success
|
||||
* - 400: Invalid request
|
||||
* - 422: Invalid request format
|
||||
* - 429: Rate limited
|
||||
*/
|
||||
fun getTurnServerInfo(): NetworkResult<List<TurnServerInfo>> {
|
||||
val request = WebSocketRequestMessage.get("/v2/calling/relays")
|
||||
return NetworkResult.fromWebSocketRequest(auth, request, GetCallingRelaysResponse::class)
|
||||
.map { it.relays ?: emptyList() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a call link credential.
|
||||
*
|
||||
* POST /v1/call-link/create-auth
|
||||
* - 200: Success
|
||||
* - 400: Invalid request
|
||||
* - 422: Invalid request format
|
||||
* - 429: Rate limited
|
||||
*/
|
||||
fun createCallLinkCredential(request: CreateCallLinkCredentialRequest): NetworkResult<CreateCallLinkCredentialResponse> {
|
||||
val request = WebSocketRequestMessage.post("/v1/call-link/create-auth", body = CreateCallLinkAuthRequest.create(request))
|
||||
return NetworkResult.fromWebSocketRequest(auth, request, CreateCallLinkAuthResponse::class)
|
||||
.map { it.createCallLinkCredentialResponse }
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an http request on behalf of the calling infrastructure. Only returns [NetworkResult.Success] with the
|
||||
* wrapped [CallingResponse] wrapping the error which in practice should never happen.
|
||||
*
|
||||
* @param requestId Request identifier
|
||||
* @param url Fully qualified URL to request
|
||||
* @param httpMethod Http method to use (e.g., "GET", "POST")
|
||||
* @param headers Optional list of headers to send with request
|
||||
* @param body Optional body to send with request
|
||||
* @return
|
||||
*/
|
||||
fun makeCallingRequest(
|
||||
requestId: Long,
|
||||
url: String,
|
||||
httpMethod: String,
|
||||
headers: List<LibSignalPair<String, String>>?,
|
||||
body: ByteArray?
|
||||
): NetworkResult<CallingResponse> {
|
||||
return when (val result = NetworkResult.fromFetch { pushServiceSocket.makeCallingRequest(requestId, url, httpMethod, headers, body) }) {
|
||||
is NetworkResult.Success -> result
|
||||
else -> NetworkResult.Success(CallingResponse.Error(requestId, result.getCause()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.signalservice.api.payments
|
||||
|
||||
import org.whispersystems.signalservice.api.NetworkResult
|
||||
import org.whispersystems.signalservice.api.websocket.SignalWebSocket
|
||||
import org.whispersystems.signalservice.internal.get
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
import org.whispersystems.signalservice.internal.websocket.WebSocketRequestMessage
|
||||
|
||||
/**
|
||||
* Provide payments specific network apis.
|
||||
*/
|
||||
class PaymentsApi(private val authWebSocket: SignalWebSocket.AuthenticatedWebSocket) {
|
||||
|
||||
/**
|
||||
* GET /v1/payments/auth
|
||||
* - 200: Success
|
||||
*/
|
||||
fun getAuthorization(): NetworkResult<AuthCredentials> {
|
||||
val request = WebSocketRequestMessage.get("/v1/payments/auth")
|
||||
return NetworkResult.fromWebSocketRequest(authWebSocket, request, AuthCredentials::class)
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /v1/payments/conversions
|
||||
* - 200: Success
|
||||
*/
|
||||
fun getCurrencyConversions(): NetworkResult<CurrencyConversions> {
|
||||
val request = WebSocketRequestMessage.get("/v1/payments/conversions")
|
||||
return NetworkResult.fromWebSocketRequest(authWebSocket, request, CurrencyConversions::class)
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package org.whispersystems.signalservice.api.services
|
||||
|
||||
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialRequest
|
||||
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialResponse
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
import org.whispersystems.signalservice.internal.push.PushServiceSocket
|
||||
import java.io.IOException
|
||||
|
||||
class CallLinksService(private val pushServiceSocket: PushServiceSocket) {
|
||||
|
||||
fun getCreateCallLinkAuthCredential(request: CreateCallLinkCredentialRequest): ServiceResponse<CreateCallLinkCredentialResponse> {
|
||||
return try {
|
||||
ServiceResponse.forResult(pushServiceSocket.getCallLinkAuthResponse(request), 200, "")
|
||||
} catch (e: IOException) {
|
||||
ServiceResponse.forUnknownError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.squareup.wire.Message;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.signal.core.util.Base64;
|
||||
import org.signal.core.util.concurrent.FutureTransformers;
|
||||
import org.signal.core.util.concurrent.ListenableFuture;
|
||||
@@ -22,8 +21,6 @@ import org.signal.libsignal.protocol.logging.Log;
|
||||
import org.signal.libsignal.protocol.state.PreKeyBundle;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.signal.libsignal.zkgroup.VerificationFailedException;
|
||||
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialRequest;
|
||||
import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialResponse;
|
||||
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
|
||||
import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
@@ -45,13 +42,6 @@ import org.signal.storageservice.protos.groups.Member;
|
||||
import org.whispersystems.signalservice.api.account.AccountAttributes;
|
||||
import org.whispersystems.signalservice.api.account.PreKeyCollection;
|
||||
import org.whispersystems.signalservice.api.account.PreKeyUpload;
|
||||
import org.whispersystems.signalservice.api.archive.ArchiveCredentialPresentation;
|
||||
import org.whispersystems.signalservice.api.archive.ArchiveGetMediaItemsResponse;
|
||||
import org.whispersystems.signalservice.api.archive.ArchiveMediaRequest;
|
||||
import org.whispersystems.signalservice.api.archive.ArchiveMediaResponse;
|
||||
import org.whispersystems.signalservice.api.archive.BatchArchiveMediaRequest;
|
||||
import org.whispersystems.signalservice.api.archive.BatchArchiveMediaResponse;
|
||||
import org.whispersystems.signalservice.api.archive.DeleteArchivedMediaRequest;
|
||||
import org.whispersystems.signalservice.api.crypto.SealedSenderAccess;
|
||||
import org.whispersystems.signalservice.api.groupsv2.CredentialResponse;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString;
|
||||
@@ -159,7 +149,6 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -211,8 +200,6 @@ public class PushServiceSocket {
|
||||
private static final String PREKEY_DEVICE_PATH = "/v2/keys/%s/%s";
|
||||
private static final String PREKEY_CHECK_PATH = "/v2/keys/check";
|
||||
|
||||
private static final String CALLING_RELAYS = "/v2/calling/relays";
|
||||
|
||||
private static final String PROVISIONING_MESSAGE_PATH = "/v1/provisioning/%s";
|
||||
private static final String SET_RESTORE_METHOD_PATH = "/v1/devices/restore_account/%s";
|
||||
private static final String WAIT_RESTORE_METHOD_PATH = "/v1/devices/restore_account/%s?timeout=%s";
|
||||
@@ -223,9 +210,6 @@ public class PushServiceSocket {
|
||||
private static final String UUID_ACK_MESSAGE_PATH = "/v1/messages/uuid/%s";
|
||||
private static final String ATTACHMENT_V4_PATH = "/v4/attachments/form/upload";
|
||||
|
||||
private static final String PAYMENTS_AUTH_PATH = "/v1/payments/auth";
|
||||
private static final String PAYMENTS_CONVERSIONS = "/v1/payments/conversions";
|
||||
|
||||
private static final String PROFILE_PATH = "/v1/profile/%s";
|
||||
private static final String PROFILE_BATCH_CHECK_PATH = "/v1/profile/identity_check/batch";
|
||||
|
||||
@@ -286,8 +270,6 @@ public class PushServiceSocket {
|
||||
|
||||
private static final String ARCHIVE_MEDIA_DOWNLOAD_PATH = "backups/%s/%s";
|
||||
|
||||
private static final String CALL_LINK_CREATION_AUTH = "/v1/call-link/create-auth";
|
||||
|
||||
private static final String SERVER_DELIVERED_TIMESTAMP_HEADER = "X-Signal-Timestamp";
|
||||
|
||||
private static final Map<String, String> NO_HEADERS = Collections.emptyMap();
|
||||
@@ -1137,32 +1119,6 @@ public class PushServiceSocket {
|
||||
}
|
||||
}
|
||||
|
||||
public CreateCallLinkCredentialResponse getCallLinkAuthResponse(CreateCallLinkCredentialRequest request) throws IOException {
|
||||
String payload = JsonUtil.toJson(CreateCallLinkAuthRequest.create(request));
|
||||
String response = makeServiceRequest(
|
||||
CALL_LINK_CREATION_AUTH,
|
||||
"POST",
|
||||
payload
|
||||
);
|
||||
|
||||
return JsonUtil.fromJson(response, CreateCallLinkAuthResponse.class).getCreateCallLinkCredentialResponse();
|
||||
}
|
||||
|
||||
private AuthCredentials getAuthCredentials(String authPath) throws IOException {
|
||||
String response = makeServiceRequest(authPath, "GET", null);
|
||||
AuthCredentials token = JsonUtil.fromJson(response, AuthCredentials.class);
|
||||
return token;
|
||||
}
|
||||
|
||||
public AuthCredentials getPaymentsAuthorization() throws IOException {
|
||||
return getAuthCredentials(PAYMENTS_AUTH_PATH);
|
||||
}
|
||||
|
||||
public GetCallingRelaysResponse getCallingRelays() throws IOException {
|
||||
String response = makeServiceRequest(CALLING_RELAYS, "GET", null);
|
||||
return JsonUtil.fromJson(response, GetCallingRelaysResponse.class);
|
||||
}
|
||||
|
||||
public String getStorageAuth() throws IOException {
|
||||
String response = makeServiceRequest("/v1/storage/auth", "GET", null);
|
||||
StorageAuthResponse authResponse = JsonUtil.fromJson(response, StorageAuthResponse.class);
|
||||
@@ -1188,14 +1144,6 @@ public class PushServiceSocket {
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<StorageManifest> writeStorageContacts(String authToken, WriteOperation writeOperation) throws IOException {
|
||||
try (Response response = makeStorageRequest(authToken, "/v1/storage", "PUT", protobufRequestBody(writeOperation), NO_HANDLER)) {
|
||||
return Optional.empty();
|
||||
} catch (ContactManifestMismatchException e) {
|
||||
return Optional.of(StorageManifest.ADAPTER.decode(e.getResponseBody()));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeStorageItems(String authToken, WriteOperation writeOperation) throws IOException {
|
||||
makeStorageRequest(authToken, "/v1/storage", "PUT", protobufRequestBody(writeOperation), UNOPINIONATED_BINARY_ERROR_HANDLER);
|
||||
}
|
||||
@@ -1211,10 +1159,6 @@ public class PushServiceSocket {
|
||||
return JsonUtil.fromJson(response, RemoteConfigResponse.class);
|
||||
}
|
||||
|
||||
public void setSoTimeoutMillis(long soTimeoutMillis) {
|
||||
this.soTimeoutMillis = soTimeoutMillis;
|
||||
}
|
||||
|
||||
public void cancelInFlightRequests() {
|
||||
synchronized (connections) {
|
||||
Log.w(TAG, "Canceling: " + connections.size());
|
||||
@@ -2462,8 +2406,6 @@ public class PushServiceSocket {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ClientSet { KeyBackup }
|
||||
|
||||
public CredentialResponse retrieveGroupsV2Credentials(long todaySeconds)
|
||||
throws IOException
|
||||
{
|
||||
@@ -2652,18 +2594,6 @@ public class PushServiceSocket {
|
||||
}
|
||||
}
|
||||
|
||||
public CurrencyConversions getCurrencyConversions()
|
||||
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
|
||||
{
|
||||
String response = makeServiceRequest(PAYMENTS_CONVERSIONS, "GET", null);
|
||||
try {
|
||||
return JsonUtil.fromJson(response, CurrencyConversions.class);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new MalformedResponseException("Unable to parse entity", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void reportSpam(ServiceId serviceId, String serverGuid, String reportingToken)
|
||||
throws NonSuccessfulResponseCodeException, MalformedResponseException, PushNetworkException
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user