From dd8104bf6109ab10035ccbd46bdb809c1ec2c28f Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 12 Nov 2025 14:33:40 -0500 Subject: [PATCH] Add error case for when you don't have enough disk space to create a backup. --- .../v2/ui/status/BackupCreateErrorRow.kt | 6 +++ .../securesms/jobs/BackupMessagesJob.kt | 43 ++++++++++++------- .../securesms/keyvalue/BackupValues.kt | 9 ++-- app/src/main/res/values/strings.xml | 2 + 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/status/BackupCreateErrorRow.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/status/BackupCreateErrorRow.kt index da2b627890..efea0b51e4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/status/BackupCreateErrorRow.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/status/BackupCreateErrorRow.kt @@ -88,6 +88,12 @@ fun BackupCreateErrorRow( } } } + + BackupValues.BackupCreationError.NOT_ENOUGH_DISK_SPACE -> { + BackupAlertText { + append(stringResource(R.string.BackupStatusRow__not_enough_disk_space, DateUtils.getDayPrecisionTimeString(context, locale, lastMessageCutoffTime))) + } + } } } 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 0424b8667a..877765e19f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt @@ -13,6 +13,7 @@ import android.content.pm.PackageManager import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat +import okio.IOException import org.signal.core.util.PendingIntentFlags import org.signal.core.util.Stopwatch import org.signal.core.util.isNotNullOrBlank @@ -445,22 +446,32 @@ class BackupMessagesJob private constructor( val attachmentInfoBuffer: MutableSet = mutableSetOf() val messageInclusionCutoffTime = SignalStore.backup.messageCuttoffDuration?.let { currentTime - it.inWholeMilliseconds } ?: 0 - BackupRepository.exportForSignalBackup( - outputStream = outputStream, - messageBackupKey = backupKey, - forwardSecrecyMetadata = forwardSecrecyMetadata, - forwardSecrecyToken = forwardSecrecyToken, - progressEmitter = ArchiveUploadProgress.ArchiveBackupProgressListener, - append = { tempBackupFile.appendBytes(it) }, - cancellationSignal = { this.isCanceled }, - currentTime = currentTime, - messageInclusionCutoffTime = messageInclusionCutoffTime - ) { frame -> - attachmentInfoBuffer += frame.getAllReferencedArchiveAttachmentInfos() - if (attachmentInfoBuffer.size > ATTACHMENT_SNAPSHOT_BUFFER_SIZE) { - SignalDatabase.backupMediaSnapshots.writePendingMediaEntries(attachmentInfoBuffer.toFullSizeMediaEntries(mediaRootBackupKey)) - SignalDatabase.backupMediaSnapshots.writePendingMediaEntries(attachmentInfoBuffer.toThumbnailMediaEntries(mediaRootBackupKey)) - attachmentInfoBuffer.clear() + try { + BackupRepository.exportForSignalBackup( + outputStream = outputStream, + messageBackupKey = backupKey, + forwardSecrecyMetadata = forwardSecrecyMetadata, + forwardSecrecyToken = forwardSecrecyToken, + progressEmitter = ArchiveUploadProgress.ArchiveBackupProgressListener, + append = { tempBackupFile.appendBytes(it) }, + cancellationSignal = { this.isCanceled }, + currentTime = currentTime, + messageInclusionCutoffTime = messageInclusionCutoffTime + ) { frame -> + attachmentInfoBuffer += frame.getAllReferencedArchiveAttachmentInfos() + if (attachmentInfoBuffer.size > ATTACHMENT_SNAPSHOT_BUFFER_SIZE) { + SignalDatabase.backupMediaSnapshots.writePendingMediaEntries(attachmentInfoBuffer.toFullSizeMediaEntries(mediaRootBackupKey)) + SignalDatabase.backupMediaSnapshots.writePendingMediaEntries(attachmentInfoBuffer.toThumbnailMediaEntries(mediaRootBackupKey)) + attachmentInfoBuffer.clear() + } + } + } catch (e: IOException) { + if (e.message?.contains("ENOSPC") == true) { + Log.w(TAG, "Not enough space to make a backup!", e, true) + tempBackupFile.delete() + this.dataFile = "" + BackupRepository.markBackupCreationFailed(BackupValues.BackupCreationError.NOT_ENOUGH_DISK_SPACE) + return BackupFileResult.Failure } } 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 e88e91206b..65beb72ffc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt @@ -602,11 +602,14 @@ class BackupValues(store: KeyValueStore) : SignalStoreValues(store) { /** A temporary failure, usually cause by poor network. */ TRANSIENT(1), - /** The validation of the backup file failed. This likely cannot be fixed without an app update. */ + /** The validation of the backup file failed. This likely cannot be fixed without an app update. */ VALIDATION(2), - /** The backup file itself is too large. The only resolution would be for the user to delete some number of messages. */ - BACKUP_FILE_TOO_LARGE(3); + /** The backup file itself is too large. The only resolution would be for the user to delete some number of messages. */ + BACKUP_FILE_TOO_LARGE(3), + + /** We do not have enough space on the device to create the backup file. */ + NOT_ENOUGH_DISK_SPACE(4); companion object { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0c53462bef..9153628e43 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8058,6 +8058,8 @@ The number of messages you have exceeds the storage limit. Delete some messages and try again. Messages sent or received before %1$s are not being backed up. + + Your backup couldn\'t be completed because you are low on disk space. Free up space on your device and try again. Learn more