mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-22 12:08:34 +00:00
Allow syncing additional types of messages to linked devices.
This commit is contained in:
@@ -23,13 +23,18 @@ object ArchiveValidator {
|
||||
/**
|
||||
* Validates the provided [backupFile] that is encrypted with the provided [backupKey].
|
||||
*/
|
||||
fun validate(backupFile: File, backupKey: MessageBackupKey): ValidationResult {
|
||||
fun validate(backupFile: File, backupKey: MessageBackupKey, forTransfer: Boolean): ValidationResult {
|
||||
return try {
|
||||
val backupId = backupKey.deriveBackupId(SignalStore.account.requireAci())
|
||||
val libSignalBackupKey = LibSignalBackupKey(backupKey.value)
|
||||
val backupKey = LibSignalMessageBackupKey(libSignalBackupKey, backupId.value)
|
||||
|
||||
MessageBackup.validate(backupKey, MessageBackup.Purpose.REMOTE_BACKUP, { backupFile.inputStream() }, backupFile.length())
|
||||
MessageBackup.validate(
|
||||
backupKey,
|
||||
if (forTransfer) MessageBackup.Purpose.DEVICE_TRANSFER else MessageBackup.Purpose.REMOTE_BACKUP,
|
||||
{ backupFile.inputStream() },
|
||||
backupFile.length()
|
||||
)
|
||||
|
||||
ValidationResult.Success
|
||||
} catch (e: IOException) {
|
||||
|
||||
@@ -460,6 +460,7 @@ object BackupRepository {
|
||||
plaintext: Boolean = false,
|
||||
currentTime: Long = System.currentTimeMillis(),
|
||||
mediaBackupEnabled: Boolean = SignalStore.backup.backsUpMedia,
|
||||
forTransfer: Boolean = false,
|
||||
progressEmitter: ExportProgressListener? = null,
|
||||
cancellationSignal: () -> Boolean = { false },
|
||||
exportExtras: ((SignalDatabase) -> Unit)? = null
|
||||
@@ -481,6 +482,7 @@ object BackupRepository {
|
||||
writer = writer,
|
||||
progressEmitter = progressEmitter,
|
||||
mediaBackupEnabled = mediaBackupEnabled,
|
||||
forTransfer = forTransfer,
|
||||
cancellationSignal = cancellationSignal,
|
||||
exportExtras = exportExtras
|
||||
)
|
||||
@@ -500,6 +502,7 @@ object BackupRepository {
|
||||
isLocal: Boolean,
|
||||
writer: BackupExportWriter,
|
||||
mediaBackupEnabled: Boolean = SignalStore.backup.backsUpMedia,
|
||||
forTransfer: Boolean = false,
|
||||
progressEmitter: ExportProgressListener? = null,
|
||||
cancellationSignal: () -> Boolean = { false },
|
||||
exportExtras: ((SignalDatabase) -> Unit)? = null
|
||||
@@ -515,7 +518,7 @@ object BackupRepository {
|
||||
val signalStoreSnapshot: SignalStore = createSignalStoreSnapshot(keyValueDbName)
|
||||
eventTimer.emit("store-db-snapshot")
|
||||
|
||||
val exportState = ExportState(backupTime = currentTime, mediaBackupEnabled = mediaBackupEnabled)
|
||||
val exportState = ExportState(backupTime = currentTime, mediaBackupEnabled = mediaBackupEnabled, forTransfer = forTransfer)
|
||||
val selfAci = signalStoreSnapshot.accountValues.aci!!
|
||||
val selfRecipientId = dbSnapshot.recipientTable.getByAci(selfAci).get().toLong().let { RecipientId.from(it) }
|
||||
|
||||
@@ -1521,7 +1524,11 @@ data class ResumableMessagesBackupUploadSpec(
|
||||
|
||||
data class ArchivedMediaObject(val mediaId: String, val cdn: Int)
|
||||
|
||||
class ExportState(val backupTime: Long, val mediaBackupEnabled: Boolean) {
|
||||
class ExportState(
|
||||
val backupTime: Long,
|
||||
val mediaBackupEnabled: Boolean,
|
||||
val forTransfer: Boolean
|
||||
) {
|
||||
val recipientIds: MutableSet<Long> = hashSetOf()
|
||||
val threadIds: MutableSet<Long> = hashSetOf()
|
||||
val contactRecipientIds: MutableSet<Long> = hashSetOf()
|
||||
|
||||
@@ -562,9 +562,14 @@ private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: Recipien
|
||||
}
|
||||
}
|
||||
|
||||
if (!MessageTypes.isExpirationTimerUpdate(record.type) && builder.expiresInMs != null && builder.expireStartDate != null && builder.expireStartDate!! + builder.expiresInMs!! < backupStartTime + 1.days.inWholeMilliseconds) {
|
||||
Log.w(TAG, ExportSkips.messageExpiresTooSoon(record.dateSent))
|
||||
return null
|
||||
if (!MessageTypes.isExpirationTimerUpdate(record.type) && builder.expiresInMs != null && builder.expireStartDate != null) {
|
||||
val expiresAt = builder.expireStartDate!! + builder.expiresInMs!!
|
||||
val threshold = if (exportState.forTransfer) backupStartTime else backupStartTime + 1.days.inWholeMilliseconds
|
||||
|
||||
if (expiresAt < threshold) {
|
||||
Log.w(TAG, ExportSkips.messageExpiresTooSoon(record.dateSent))
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
if (builder.expireStartDate != null && builder.expiresInMs == null) {
|
||||
@@ -1500,10 +1505,6 @@ private fun Cursor.toBackupMessageRecord(pastIds: Set<Long>, backupStartTime: Lo
|
||||
val expiresIn = this.requireLong(MessageTable.EXPIRES_IN)
|
||||
val expireStarted = this.requireLong(MessageTable.EXPIRE_STARTED)
|
||||
|
||||
if (expireStarted != 0L && expireStarted + expiresIn < backupStartTime + 1.days.inWholeMilliseconds) {
|
||||
return null
|
||||
}
|
||||
|
||||
return BackupMessageRecord(
|
||||
id = id,
|
||||
dateSent = this.requireLong(MessageTable.DATE_SENT).clampToValidBackupRange(),
|
||||
|
||||
@@ -143,7 +143,7 @@ class InternalBackupPlaygroundViewModel : ViewModel() {
|
||||
append = { bytes -> tempFile.appendBytes(bytes) }
|
||||
)
|
||||
_state.value = _state.value.copy(statusMessage = "Export complete! Validating...")
|
||||
ArchiveValidator.validate(tempFile, SignalStore.backup.messageBackupKey)
|
||||
ArchiveValidator.validate(tempFile, SignalStore.backup.messageBackupKey, forTransfer = false)
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
@@ -215,7 +215,7 @@ class BackupMessagesJob private constructor(
|
||||
|
||||
stopwatch.split("export")
|
||||
|
||||
when (val result = ArchiveValidator.validate(tempBackupFile, backupKey)) {
|
||||
when (val result = ArchiveValidator.validate(tempBackupFile, backupKey, forTransfer = false)) {
|
||||
ArchiveValidator.ValidationResult.Success -> {
|
||||
Log.d(TAG, "Successfully passed validation.")
|
||||
}
|
||||
|
||||
@@ -254,6 +254,7 @@ object LinkDeviceRepository {
|
||||
append = { tempBackupFile.appendBytes(it) },
|
||||
messageBackupKey = ephemeralMessageBackupKey,
|
||||
mediaBackupEnabled = false,
|
||||
forTransfer = true,
|
||||
cancellationSignal = cancellationSignal
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
@@ -268,7 +269,7 @@ object LinkDeviceRepository {
|
||||
return LinkUploadArchiveResult.BackupCreationCancelled
|
||||
}
|
||||
|
||||
when (val result = ArchiveValidator.validate(tempBackupFile, ephemeralMessageBackupKey)) {
|
||||
when (val result = ArchiveValidator.validate(tempBackupFile, ephemeralMessageBackupKey, forTransfer = true)) {
|
||||
ArchiveValidator.ValidationResult.Success -> {
|
||||
Log.d(TAG, "[createAndUploadArchive] Successfully passed validation.")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user