From de3b0d4ca23678973cc88321e23af023923dac1d Mon Sep 17 00:00:00 2001 From: Clark Date: Mon, 6 May 2024 12:55:13 -0400 Subject: [PATCH] Integrate the backup size into backup settings. --- .../securesms/backup/v2/BackupRepository.kt | 12 ++++++++++++ .../chats/backups/RemoteBackupsSettingsFragment.kt | 12 ++++++++---- .../chats/backups/RemoteBackupsSettingsViewModel.kt | 13 +++++++++++-- .../securesms/jobs/ArchiveAttachmentJob.kt | 2 ++ .../securesms/jobs/BackupMessagesJob.kt | 7 +++++++ .../thoughtcrime/securesms/keyvalue/BackupValues.kt | 6 ++++++ 6 files changed, 46 insertions(+), 6 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 370c47c38c..1d12147f74 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 @@ -243,6 +243,17 @@ object BackupRepository { } } + fun getRemoteBackupUsedSpace(): NetworkResult { + val api = ApplicationDependencies.getSignalServiceAccountManager().archiveApi + val backupKey = SignalStore.svr().getOrCreateMasterKey().deriveBackupKey() + + return initBackupAndFetchAuth(backupKey) + .then { credential -> + api.getBackupInfo(backupKey, credential) + .map { it.usedSpace } + } + } + /** * Returns an object with details about the remote backup state. */ @@ -551,6 +562,7 @@ object BackupRepository { return initBackupAndFetchAuth(backupKey) .then { credential -> api.getBackupInfo(backupKey, credential).map { + SignalStore.backup().usedBackupMediaSpace = it.usedSpace ?: 0L BackupDirectories(it.backupDir!!, it.mediaDir!!) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsFragment.kt index 6ea10b550c..a38091eb99 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsFragment.kt @@ -60,6 +60,7 @@ import org.thoughtcrime.securesms.compose.ComposeFragment import org.thoughtcrime.securesms.conversation.v2.registerForLifecycle import org.thoughtcrime.securesms.payments.FiatMoneyUtil import org.thoughtcrime.securesms.util.DateUtils +import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.viewModel import java.util.Locale @@ -88,7 +89,8 @@ class RemoteBackupsSettingsFragment : ComposeFragment() { requestedDialog = state.dialog, requestedSnackbar = state.snackbar, contentCallbacks = callbacks, - backupProgress = state.backupProgress + backupProgress = state.backupProgress, + backupSize = state.backupSize ) } @@ -181,7 +183,8 @@ private fun RemoteBackupsSettingsContent( requestedDialog: RemoteBackupsSettingsState.Dialog, requestedSnackbar: RemoteBackupsSettingsState.Snackbar, contentCallbacks: ContentCallbacks, - backupProgress: BackupV2Event? + backupProgress: BackupV2Event?, + backupSize: Long ) { val snackbarHostState = remember { SnackbarHostState() @@ -245,7 +248,7 @@ private fun RemoteBackupsSettingsContent( color = MaterialTheme.colorScheme.onSurface ) Text( - text = "2.3GB", + text = Util.getPrettyFileSize(backupSize ?: 0), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant ) @@ -572,7 +575,8 @@ private fun RemoteBackupsSettingsContentPreview() { requestedDialog = RemoteBackupsSettingsState.Dialog.NONE, requestedSnackbar = RemoteBackupsSettingsState.Snackbar.NONE, contentCallbacks = object : ContentCallbacks {}, - backupProgress = null + backupProgress = null, + backupSize = 2300000 ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsViewModel.kt index 7ab97a69ea..f67fad72e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/backups/RemoteBackupsSettingsViewModel.kt @@ -29,7 +29,8 @@ class RemoteBackupsSettingsViewModel : ViewModel() { } else { null }, - lastBackupTimestamp = SignalStore.backup().lastBackupTime + lastBackupTimestamp = SignalStore.backup().lastBackupTime, + backupSize = SignalStore.backup().totalBackupSize ) ) @@ -60,7 +61,15 @@ class RemoteBackupsSettingsViewModel : ViewModel() { } fun updateBackupProgress(backupEvent: BackupV2Event?) { - internalState.value = state.value.copy(backupProgress = backupEvent, lastBackupTimestamp = SignalStore.backup().lastBackupTime) + internalState.value = state.value.copy(backupProgress = backupEvent) + refreshBackupState() + } + + private fun refreshBackupState() { + internalState.value = state.value.copy( + lastBackupTimestamp = SignalStore.backup().lastBackupTime, + backupSize = SignalStore.backup().totalBackupSize + ) } fun onBackupNowClick() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentJob.kt index 312a517c00..ebdbb9df89 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentJob.kt @@ -61,6 +61,8 @@ class ArchiveAttachmentJob private constructor(private val attachmentId: Attachm } BackupRepository.archiveMedia(attachment).successOrThrow() + + SignalStore.backup().usedBackupMediaSpace += attachment.size } override fun onShouldRetry(e: Exception): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt index d73daf77cd..3e469a054f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt @@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.providers.BlobProvider import org.whispersystems.signalservice.api.NetworkResult import java.io.FileInputStream import java.io.FileOutputStream +import java.io.IOException /** * Job that is responsible for exporting the DB as a backup proto and @@ -115,12 +116,18 @@ class BackupMessagesJob private constructor(parameters: Parameters) : BaseJob(pa BackupRepository.uploadBackupFile(it, tempBackupFile.length()) } val needBackfill = archiveAttachments() + SignalStore.backup().lastBackupProtoSize = tempBackupFile.length() if (!tempBackupFile.delete()) { Log.e(TAG, "Failed to delete temp backup file") } SignalStore.backup().lastBackupTime = System.currentTimeMillis() if (!needBackfill) { EventBus.getDefault().postSticky(BackupV2Event(BackupV2Event.Type.FINISHED, 0, 0)) + try { + SignalStore.backup().usedBackupMediaSpace = (BackupRepository.getRemoteBackupUsedSpace().successOrThrow() ?: 0) + } catch (e: IOException) { + Log.e(TAG, "Failed to update used space") + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt index a5189e4348..c93ed9f5bb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt @@ -19,6 +19,8 @@ internal class BackupValues(store: KeyValueStore) : SignalStoreValues(store) { private const val KEY_CDN_READ_CREDENTIALS = "backup.cdn.readCredentials" private const val KEY_CDN_READ_CREDENTIALS_TIMESTAMP = "backup.cdn.readCredentials.timestamp" private const val KEY_RESTORE_STATE = "backup.restoreState" + private const val KEY_BACKUP_USED_MEDIA_SPACE = "backup.usedMediaSpace" + private const val KEY_BACKUP_LAST_PROTO_SIZE = "backup.lastProtoSize" private const val KEY_NEXT_BACKUP_TIME = "backup.nextBackupTime" private const val KEY_LAST_BACKUP_TIME = "backup.lastBackupTime" @@ -41,6 +43,8 @@ internal class BackupValues(store: KeyValueStore) : SignalStoreValues(store) { private var cachedCdnCredentials: String? by stringValue(KEY_CDN_READ_CREDENTIALS, null) var cachedBackupDirectory: String? by stringValue(KEY_CDN_BACKUP_DIRECTORY, null) var cachedBackupMediaDirectory: String? by stringValue(KEY_CDN_BACKUP_MEDIA_DIRECTORY, null) + var usedBackupMediaSpace: Long by longValue(KEY_BACKUP_USED_MEDIA_SPACE, 0L) + var lastBackupProtoSize: Long by longValue(KEY_BACKUP_LAST_PROTO_SIZE, 0L) override fun onFirstEverAppLaunch() = Unit override fun getKeysToIncludeInBackup(): List = emptyList() @@ -52,6 +56,8 @@ internal class BackupValues(store: KeyValueStore) : SignalStoreValues(store) { var nextBackupTime: Long by longValue(KEY_NEXT_BACKUP_TIME, -1) var lastBackupTime: Long by longValue(KEY_LAST_BACKUP_TIME, -1) + val totalBackupSize: Long get() = lastBackupProtoSize + usedBackupMediaSpace + var areBackupsEnabled: Boolean get() { return getBoolean(KEY_BACKUPS_ENABLED, false)