From 0dac6344ab20aabdd006cfd581a8dcba382d2e00 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 5 Sep 2025 14:44:49 -0300 Subject: [PATCH] Access configuration via cache layer when evaluating state. --- .../securesms/backup/v2/BackupRepository.kt | 6 +++-- .../api/donations/DonationsApi.kt | 4 ++++ .../internal/ServiceResponse.java | 22 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt index 957b5042e6..69bd042f0c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt @@ -1830,8 +1830,9 @@ object BackupRepository { @WorkerThread fun getBackupLevelConfiguration(): NetworkResult { - return AppDependencies.donationsApi + return AppDependencies.donationsService .getDonationsConfiguration(Locale.getDefault()) + .toNetworkResult() .then { val config = it.backupConfiguration.backupLevelConfigurationMap[SubscriptionsConfiguration.BACKUPS_LEVEL] if (config != null) { @@ -1844,8 +1845,9 @@ object BackupRepository { @WorkerThread fun getFreeType(): NetworkResult { - return AppDependencies.donationsApi + return AppDependencies.donationsService .getDonationsConfiguration(Locale.getDefault()) + .toNetworkResult() .map { MessageBackupsType.Free( mediaRetentionDays = it.backupConfiguration.freeTierMediaDays diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/donations/DonationsApi.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/donations/DonationsApi.kt index 295681374f..58d4fe3b54 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/donations/DonationsApi.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/donations/DonationsApi.kt @@ -31,12 +31,16 @@ import java.util.Locale /** * One-stop shop for Signal service calls related to in-app payments. + * + * Be sure to check for cached versions of these methods in DonationsService before calling these methods elsewhere. */ class DonationsApi(private val authWebSocket: SignalWebSocket.AuthenticatedWebSocket, private val unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket) { /** * Get configuration data associated with donations, like gift, one-time, and monthly levels, etc. * + * Note, this will skip cached values, causing us to hit the network more than necessary. Consider accessing this method via the DonationsService instead. + * * GET /v1/subscription/configuration * - 200: Success */ diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/ServiceResponse.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/ServiceResponse.java index 026e2bb7ac..41c3ba22a3 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/ServiceResponse.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/ServiceResponse.java @@ -2,11 +2,14 @@ package org.whispersystems.signalservice.internal; +import org.whispersystems.signalservice.api.NetworkResult; +import org.whispersystems.signalservice.api.NetworkResultUtil; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.util.Preconditions; import org.whispersystems.signalservice.internal.websocket.WebsocketResponse; +import java.io.IOException; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -84,6 +87,25 @@ public final class ServiceResponse { } } + public NetworkResult toNetworkResult() { + if (result.isPresent()) { + return new NetworkResult.Success<>(result.get()); + } else if (applicationError.isPresent()) { + return new NetworkResult.ApplicationError<>(applicationError.get()); + } else if (executionError.isPresent()) { + Throwable error = executionError.get(); + if (error instanceof NonSuccessfulResponseCodeException) { + return new NetworkResult.StatusCodeError<>((NonSuccessfulResponseCodeException) error); + } else if (error instanceof IOException) { + return new NetworkResult.NetworkError<>((IOException) error); + } else { + return new NetworkResult.ApplicationError<>(error); + } + } else { + throw new AssertionError("Should never get here"); + } + } + public Result getResultOrThrow() throws Throwable { if (result.isPresent()) { return result.get();