55
66package org.thoughtcrime.securesms.backup.v2
77
8+ import kotlinx.collections.immutable.persistentListOf
9+ import kotlinx.coroutines.Dispatchers
10+ import kotlinx.coroutines.withContext
811import org.greenrobot.eventbus.EventBus
912import org.signal.core.util.Base64
1013import org.signal.core.util.EventTimer
11- import org.signal.core.util.LongSerializer
1214import org.signal.core.util.logging.Log
15+ import org.signal.core.util.money.FiatMoney
1316import org.signal.core.util.withinTransaction
1417import org.signal.libsignal.messagebackup.MessageBackup
1518import org.signal.libsignal.messagebackup.MessageBackup.ValidationResult
1619import org.signal.libsignal.messagebackup.MessageBackupKey
1720import org.signal.libsignal.protocol.ServiceId.Aci
1821import org.signal.libsignal.zkgroup.backups.BackupLevel
1922import org.signal.libsignal.zkgroup.profiles.ProfileKey
23+ import org.thoughtcrime.securesms.R
2024import org.thoughtcrime.securesms.attachments.Attachment
2125import org.thoughtcrime.securesms.attachments.AttachmentId
2226import org.thoughtcrime.securesms.attachments.Cdn
@@ -35,8 +39,11 @@ import org.thoughtcrime.securesms.backup.v2.stream.EncryptedBackupReader
3539import org.thoughtcrime.securesms.backup.v2.stream.EncryptedBackupWriter
3640import org.thoughtcrime.securesms.backup.v2.stream.PlainTextBackupReader
3741import org.thoughtcrime.securesms.backup.v2.stream.PlainTextBackupWriter
42+ import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
43+ import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsTypeFeature
3844import org.thoughtcrime.securesms.database.DistributionListTables
3945import org.thoughtcrime.securesms.database.SignalDatabase
46+ import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
4047import org.thoughtcrime.securesms.dependencies.AppDependencies
4148import org.thoughtcrime.securesms.groups.GroupId
4249import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob
@@ -58,13 +65,16 @@ import org.whispersystems.signalservice.api.messages.SignalServiceAttachment.Pro
5865import org.whispersystems.signalservice.api.push.ServiceId.ACI
5966import org.whispersystems.signalservice.api.push.ServiceId.PNI
6067import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
68+ import org.whispersystems.signalservice.internal.push.SubscriptionsConfiguration
6169import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec
6270import java.io.ByteArrayOutputStream
6371import java.io.File
6472import java.io.InputStream
6573import java.io.OutputStream
66- import java.lang.Exception
74+ import java.math.BigDecimal
6775import java.time.ZonedDateTime
76+ import java.util.Currency
77+ import java.util.Locale
6878import kotlin.time.Duration.Companion.milliseconds
6979
7080object BackupRepository {
@@ -673,6 +683,82 @@ object BackupRepository {
673683 }
674684 }
675685
686+ suspend fun getAvailableBackupsTypes (availableBackupTiers : List <MessageBackupTier >): List <MessageBackupsType > {
687+ return availableBackupTiers.map { getBackupsType(it) }
688+ }
689+
690+ suspend fun getBackupsType (tier : MessageBackupTier ): MessageBackupsType {
691+ val backupCurrency = SignalStore .donationsValues().getSubscriptionCurrency(InAppPaymentSubscriberRecord .Type .BACKUP )
692+ return when (tier) {
693+ MessageBackupTier .FREE -> getFreeType(backupCurrency)
694+ MessageBackupTier .PAID -> getPaidType(backupCurrency)
695+ }
696+ }
697+
698+ private fun getFreeType (currency : Currency ): MessageBackupsType {
699+ return MessageBackupsType (
700+ tier = MessageBackupTier .FREE ,
701+ pricePerMonth = FiatMoney (BigDecimal .ZERO , currency),
702+ title = " Text + 30 days of media" , // TODO [message-backups] Finalize text (does this come from server?)
703+ features = persistentListOf(
704+ MessageBackupsTypeFeature (
705+ iconResourceId = R .drawable.symbol_thread_compact_bold_16,
706+ label = " Full text message backup" // TODO [message-backups] Finalize text (does this come from server?)
707+ ),
708+ MessageBackupsTypeFeature (
709+ iconResourceId = R .drawable.symbol_album_compact_bold_16,
710+ label = " Last 30 days of media" // TODO [message-backups] Finalize text (does this come from server?)
711+ )
712+ )
713+ )
714+ }
715+
716+ private suspend fun getPaidType (currency : Currency ): MessageBackupsType {
717+ val serviceResponse = withContext(Dispatchers .IO ) {
718+ AppDependencies
719+ .donationsService
720+ .getDonationsConfiguration(Locale .getDefault())
721+ }
722+
723+ if (serviceResponse.result.isEmpty) {
724+ if (serviceResponse.applicationError.isPresent) {
725+ throw serviceResponse.applicationError.get()
726+ }
727+
728+ if (serviceResponse.executionError.isPresent) {
729+ throw serviceResponse.executionError.get()
730+ }
731+
732+ error(" Unhandled error occurred while downloading configuration." )
733+ }
734+
735+ val config = serviceResponse.result.get()
736+
737+ return MessageBackupsType (
738+ tier = MessageBackupTier .PAID ,
739+ pricePerMonth = FiatMoney (config.currencies[currency.currencyCode.lowercase()]!! .backupSubscription[SubscriptionsConfiguration .BACKUPS_LEVEL ]!! , currency),
740+ title = " Text + All your media" , // TODO [message-backups] Finalize text (does this come from server?)
741+ features = persistentListOf(
742+ MessageBackupsTypeFeature (
743+ iconResourceId = R .drawable.symbol_thread_compact_bold_16,
744+ label = " Full text message backup" // TODO [message-backups] Finalize text (does this come from server?)
745+ ),
746+ MessageBackupsTypeFeature (
747+ iconResourceId = R .drawable.symbol_album_compact_bold_16,
748+ label = " Full media backup" // TODO [message-backups] Finalize text (does this come from server?)
749+ ),
750+ MessageBackupsTypeFeature (
751+ iconResourceId = R .drawable.symbol_thread_compact_bold_16,
752+ label = " 1TB of storage (~250K photos)" // TODO [message-backups] Finalize text (does this come from server?)
753+ ),
754+ MessageBackupsTypeFeature (
755+ iconResourceId = R .drawable.symbol_heart_compact_bold_16,
756+ label = " Thanks for supporting Signal!" // TODO [message-backups] Finalize text (does this come from server?)
757+ )
758+ )
759+ )
760+ }
761+
676762 /* *
677763 * Ensures that the backupId has been reserved and that your public key has been set, while also returning an auth credential.
678764 * Should be the basis of all backup operations.
@@ -765,18 +851,3 @@ class BackupMetadata(
765851 val usedSpace : Long ,
766852 val mediaCount : Long
767853)
768-
769- enum class MessageBackupTier (val value : Int ) {
770- FREE (0 ),
771- PAID (1 );
772-
773- companion object Serializer : LongSerializer<MessageBackupTier?> {
774- override fun serialize (data : MessageBackupTier ? ): Long {
775- return data?.value?.toLong() ? : - 1
776- }
777-
778- override fun deserialize (data : Long ): MessageBackupTier ? {
779- return values().firstOrNull { it.value == data.toInt() }
780- }
781- }
782- }
0 commit comments