mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-19 08:09:12 +01:00
Attempt backing up a subset of messages if you hit the limit.
This commit is contained in:
@@ -417,7 +417,7 @@ object BackupRepository {
|
||||
}
|
||||
|
||||
fun clearBackupFailure() {
|
||||
SignalStore.backup.clearBackupCreationFailed()
|
||||
SignalStore.backup.backupCreationError = null
|
||||
ServiceUtil.getNotificationManager(AppDependencies.application).cancel(NotificationIds.INITIAL_BACKUP_FAILED)
|
||||
}
|
||||
|
||||
@@ -767,7 +767,8 @@ object BackupRepository {
|
||||
progressEmitter = localBackupProgressEmitter,
|
||||
cancellationSignal = cancellationSignal,
|
||||
forTransfer = false,
|
||||
extraFrameOperation = null
|
||||
extraFrameOperation = null,
|
||||
messageInclusionCutoffTime = 0
|
||||
) { dbSnapshot ->
|
||||
val localArchivableAttachments = dbSnapshot
|
||||
.attachmentTable
|
||||
@@ -801,6 +802,7 @@ object BackupRepository {
|
||||
forwardSecrecyToken: BackupForwardSecrecyToken,
|
||||
forwardSecrecyMetadata: ByteArray,
|
||||
currentTime: Long,
|
||||
messageInclusionCutoffTime: Long = 0,
|
||||
progressEmitter: ExportProgressListener? = null,
|
||||
cancellationSignal: () -> Boolean = { false },
|
||||
extraFrameOperation: ((Frame) -> Unit)?
|
||||
@@ -822,7 +824,8 @@ object BackupRepository {
|
||||
progressEmitter = progressEmitter,
|
||||
cancellationSignal = cancellationSignal,
|
||||
extraFrameOperation = extraFrameOperation,
|
||||
endingExportOperation = null
|
||||
endingExportOperation = null,
|
||||
messageInclusionCutoffTime = messageInclusionCutoffTime
|
||||
)
|
||||
}
|
||||
|
||||
@@ -852,7 +855,8 @@ object BackupRepository {
|
||||
progressEmitter = progressEmitter,
|
||||
cancellationSignal = cancellationSignal,
|
||||
extraFrameOperation = null,
|
||||
endingExportOperation = null
|
||||
endingExportOperation = null,
|
||||
messageInclusionCutoffTime = 0
|
||||
)
|
||||
}
|
||||
|
||||
@@ -887,7 +891,8 @@ object BackupRepository {
|
||||
progressEmitter = progressEmitter,
|
||||
cancellationSignal = cancellationSignal,
|
||||
extraFrameOperation = null,
|
||||
endingExportOperation = null
|
||||
endingExportOperation = null,
|
||||
messageInclusionCutoffTime = 0
|
||||
)
|
||||
}
|
||||
|
||||
@@ -907,6 +912,7 @@ object BackupRepository {
|
||||
isLocal: Boolean,
|
||||
writer: BackupExportWriter,
|
||||
forTransfer: Boolean,
|
||||
messageInclusionCutoffTime: Long,
|
||||
progressEmitter: ExportProgressListener?,
|
||||
cancellationSignal: () -> Boolean,
|
||||
extraFrameOperation: ((Frame) -> Unit)?,
|
||||
@@ -1033,7 +1039,7 @@ object BackupRepository {
|
||||
val approximateMessageCount = dbSnapshot.messageTable.getApproximateExportableMessageCount(exportState.threadIds)
|
||||
val frameCountStart = frameCount
|
||||
progressEmitter?.onMessage(0, approximateMessageCount)
|
||||
ChatItemArchiveProcessor.export(dbSnapshot, exportState, selfRecipientId, cancellationSignal) { frame ->
|
||||
ChatItemArchiveProcessor.export(dbSnapshot, exportState, selfRecipientId, messageInclusionCutoffTime, cancellationSignal) { frame ->
|
||||
writer.write(frame)
|
||||
extraFrameOperation?.invoke(frame)
|
||||
eventTimer.emit("message")
|
||||
|
||||
@@ -24,7 +24,7 @@ import kotlin.time.Duration.Companion.days
|
||||
|
||||
private val TAG = "MessageTableArchiveExtensions"
|
||||
|
||||
fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, selfRecipientId: RecipientId, exportState: ExportState): ChatItemArchiveExporter {
|
||||
fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, selfRecipientId: RecipientId, messageInclusionCutoffTime: Long, exportState: ExportState): ChatItemArchiveExporter {
|
||||
// We create a covering index for the query to drastically speed up perf here.
|
||||
// Remember that we're working on a temporary snapshot of the database, so we can create an index and not worry about cleaning it up.
|
||||
val startTime = System.currentTimeMillis()
|
||||
@@ -105,6 +105,12 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, self
|
||||
)
|
||||
Log.d(TAG, "Cleanup took ${System.currentTimeMillis() - cleanupStartTime} ms")
|
||||
|
||||
val cutoffQuery = if (messageInclusionCutoffTime > 0) {
|
||||
" AND $DATE_RECEIVED >= $messageInclusionCutoffTime"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
return ChatItemArchiveExporter(
|
||||
db = db,
|
||||
selfRecipientId = selfRecipientId,
|
||||
@@ -152,7 +158,7 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, self
|
||||
PARENT_STORY_ID
|
||||
)
|
||||
.from("${MessageTable.TABLE_NAME} INDEXED BY $dateReceivedIndex")
|
||||
.where("$STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND ($EXPIRES_IN == 0 OR $EXPIRES_IN > ${1.days.inWholeMilliseconds}) AND $DATE_RECEIVED >= $lastSeenReceivedTime")
|
||||
.where("$STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND ($EXPIRES_IN == 0 OR $EXPIRES_IN > ${1.days.inWholeMilliseconds}) AND $DATE_RECEIVED >= $lastSeenReceivedTime $cutoffQuery")
|
||||
.limit(count)
|
||||
.orderBy("$DATE_RECEIVED ASC")
|
||||
.run()
|
||||
|
||||
@@ -23,8 +23,8 @@ import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
object ChatItemArchiveProcessor {
|
||||
val TAG = Log.tag(ChatItemArchiveProcessor::class.java)
|
||||
|
||||
fun export(db: SignalDatabase, exportState: ExportState, selfRecipientId: RecipientId, cancellationSignal: () -> Boolean, emitter: BackupFrameEmitter) {
|
||||
db.messageTable.getMessagesForBackup(db, exportState.backupTime, selfRecipientId, exportState).use { chatItems ->
|
||||
fun export(db: SignalDatabase, exportState: ExportState, selfRecipientId: RecipientId, messageInclusionCutoffTime: Long, cancellationSignal: () -> Boolean, emitter: BackupFrameEmitter) {
|
||||
db.messageTable.getMessagesForBackup(db, exportState.backupTime, selfRecipientId, messageInclusionCutoffTime, exportState).use { chatItems ->
|
||||
var count = 0
|
||||
while (chatItems.hasNext()) {
|
||||
if (count % 1000 == 0 && cancellationSignal()) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString.Builder
|
||||
@@ -35,6 +36,9 @@ import org.signal.core.ui.compose.DayNightPreviews
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.keyvalue.BackupValues
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import java.util.Locale
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import org.signal.core.ui.R as CoreUiR
|
||||
|
||||
private val YELLOW_DOT = Color(0xFFFFCC00)
|
||||
@@ -45,8 +49,12 @@ private val YELLOW_DOT = Color(0xFFFFCC00)
|
||||
@Composable
|
||||
fun BackupCreateErrorRow(
|
||||
error: BackupValues.BackupCreationError,
|
||||
lastMessageCutoffTime: Long = 0,
|
||||
onLearnMoreClick: () -> Unit = {}
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val locale = Locale.getDefault()
|
||||
|
||||
when (error) {
|
||||
BackupValues.BackupCreationError.TRANSIENT -> {
|
||||
BackupAlertText {
|
||||
@@ -73,7 +81,11 @@ fun BackupCreateErrorRow(
|
||||
|
||||
BackupValues.BackupCreationError.BACKUP_FILE_TOO_LARGE -> {
|
||||
BackupAlertText {
|
||||
append(stringResource(R.string.BackupStatusRow__backup_file_too_large))
|
||||
if (lastMessageCutoffTime > 0) {
|
||||
append(stringResource(R.string.BackupStatusRow__not_backing_up_old_messages, DateUtils.getDayPrecisionTimeString(context, locale, lastMessageCutoffTime)))
|
||||
} else {
|
||||
append(stringResource(R.string.BackupStatusRow__backup_file_too_large))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,6 +126,10 @@ fun BackupStatusRowCouldNotCompleteBackupPreview() {
|
||||
BackupCreateErrorRow(error = error, onLearnMoreClick = {})
|
||||
Spacer(modifier = Modifier.size(8.dp))
|
||||
}
|
||||
|
||||
Text(BackupValues.BackupCreationError.BACKUP_FILE_TOO_LARGE.name + " with cutoff duration")
|
||||
BackupCreateErrorRow(error = BackupValues.BackupCreationError.BACKUP_FILE_TOO_LARGE, lastMessageCutoffTime = System.currentTimeMillis() - 365.days.inWholeMilliseconds, onLearnMoreClick = {})
|
||||
Spacer(modifier = Modifier.size(8.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user