Allow staging users to utilize internal backup switch.

This commit is contained in:
Alex Hart
2025-06-06 12:53:12 -03:00
committed by Greyson Parrelli
parent 882a11c420
commit 23d8969015
4 changed files with 36 additions and 3 deletions

View File

@@ -26,6 +26,7 @@ import org.signal.core.util.getAllTableDefinitions
import org.signal.core.util.getAllTriggerDefinitions
import org.signal.core.util.getForeignKeyViolations
import org.signal.core.util.logging.Log
import org.signal.core.util.money.FiatMoney
import org.signal.core.util.requireIntOrNull
import org.signal.core.util.requireNonNullBlob
import org.signal.core.util.stream.NonClosingOutputStream
@@ -57,6 +58,7 @@ import org.thoughtcrime.securesms.backup.v2.stream.EncryptedBackupWriter
import org.thoughtcrime.securesms.backup.v2.stream.PlainTextBackupReader
import org.thoughtcrime.securesms.backup.v2.stream.PlainTextBackupWriter
import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
import org.thoughtcrime.securesms.components.settings.app.subscription.RecurringInAppPaymentRepository
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider
import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider
import org.thoughtcrime.securesms.database.AttachmentTable
@@ -67,6 +69,7 @@ import org.thoughtcrime.securesms.database.OneTimePreKeyTable
import org.thoughtcrime.securesms.database.SearchTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.SignedPreKeyTable
import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.jobmanager.Job
@@ -114,6 +117,7 @@ import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.time.ZonedDateTime
import java.util.Currency
import java.util.Locale
import java.util.concurrent.atomic.AtomicLong
import kotlin.time.Duration.Companion.days
@@ -1463,11 +1467,25 @@ object BackupRepository {
}
private suspend fun getPaidType(): MessageBackupsType.Paid? {
val product = AppDependencies.billingApi.queryProduct() ?: return null
val productPrice: FiatMoney? = if (SignalStore.backup.backupTierInternalOverride == MessageBackupTier.PAID) {
Log.d(TAG, "Accessing price via mock subscription.")
RecurringInAppPaymentRepository.getActiveSubscriptionSync(InAppPaymentSubscriberRecord.Type.BACKUP).getOrNull()?.activeSubscription?.let {
FiatMoney.fromSignalNetworkAmount(it.amount, Currency.getInstance(it.currency))
}
} else {
Log.d(TAG, "Accessing price via billing api.")
AppDependencies.billingApi.queryProduct()?.price
}
if (productPrice == null) {
Log.w(TAG, "No pricing available. Exiting.")
return null
}
val backupLevelConfiguration = getBackupLevelConfiguration() ?: return null
return MessageBackupsType.Paid(
pricePerMonth = product.price,
pricePerMonth = productPrice,
storageAllowanceBytes = backupLevelConfiguration.storageAllowanceBytes,
mediaTtl = backupLevelConfiguration.mediaTtlDays.days
)

View File

@@ -46,11 +46,13 @@ import org.signal.core.ui.compose.SignalPreview
import org.signal.core.ui.compose.Texts
import org.signal.core.util.money.FiatMoney
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.backup.DeletionState
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
import org.thoughtcrime.securesms.components.settings.app.subscription.MessageBackupsCheckoutLauncher.createBackupsCheckoutLauncher
import org.thoughtcrime.securesms.compose.ComposeFragment
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.navigation.safeNavigate
@@ -382,9 +384,12 @@ private fun InternalBackupOverrideRow(
)
}
val deletionState by SignalStore.backup.deletionStateFlow.collectAsStateWithLifecycle(SignalStore.backup.deletionState)
Row(verticalAlignment = Alignment.CenterVertically) {
options.forEach { option ->
RadioButton(
enabled = deletionState == DeletionState.NONE || deletionState == DeletionState.COMPLETE,
selected = option.value == backupsSettingsState.backupTierInternalOverride,
onClick = { onBackupTierInternalOverrideChanged(option.value) }
)

View File

@@ -21,12 +21,14 @@ import kotlinx.coroutines.rx3.asFlow
import org.signal.core.util.concurrent.SignalDispatchers
import org.signal.core.util.logging.Log
import org.signal.core.util.money.FiatMoney
import org.thoughtcrime.securesms.backup.DeletionState
import org.thoughtcrime.securesms.backup.v2.BackupRepository
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
import org.thoughtcrime.securesms.components.settings.app.subscription.RecurringInAppPaymentRepository
import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.Environment
import org.thoughtcrime.securesms.util.InternetConnectionObserver
import org.thoughtcrime.securesms.util.RemoteConfig
import java.util.Currency
@@ -90,13 +92,20 @@ class BackupsSettingsViewModel : ViewModel() {
}
Log.d(TAG, "Found enabled state $enabledState. Updating UI state.")
internalStateFlow.update { it.copy(enabledState = enabledState, showBackupTierInternalOverride = RemoteConfig.internalUser, backupTierInternalOverride = SignalStore.backup.backupTierInternalOverride) }
internalStateFlow.update {
it.copy(
enabledState = enabledState,
showBackupTierInternalOverride = RemoteConfig.internalUser || Environment.IS_STAGING,
backupTierInternalOverride = SignalStore.backup.backupTierInternalOverride
)
}
}
}
}
fun onBackupTierInternalOverrideChanged(tier: MessageBackupTier?) {
SignalStore.backup.backupTierInternalOverride = tier
SignalStore.backup.deletionState = DeletionState.NONE
refreshState()
}

View File

@@ -266,6 +266,7 @@ class BackupValues(store: KeyValueStore) : SignalStoreValues(store) {
.putBoolean(KEY_BACKUP_UPLOADED, false)
.apply()
backupTier = null
backupTierInternalOverride = null
}
var backupsInitialized: Boolean by booleanValue(KEY_BACKUPS_INITIALIZED, false)