mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-24 11:45:28 +00:00
Schedule message backups when enabled.
This commit is contained in:
@@ -88,6 +88,7 @@ import org.thoughtcrime.securesms.service.AnalyzeDatabaseAlarmListener;
|
||||
import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.service.LocalBackupListener;
|
||||
import org.thoughtcrime.securesms.service.MessageBackupListener;
|
||||
import org.thoughtcrime.securesms.service.RotateSenderCertificateListener;
|
||||
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
||||
import org.thoughtcrime.securesms.service.webrtc.ActiveCallManager;
|
||||
@@ -420,6 +421,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
|
||||
RotateSignedPreKeyListener.schedule(this);
|
||||
DirectoryRefreshListener.schedule(this);
|
||||
LocalBackupListener.schedule(this);
|
||||
MessageBackupListener.schedule(this);
|
||||
RotateSenderCertificateListener.schedule(this);
|
||||
RoutineMessageFetchReceiver.startOrUpdateAlarm(this);
|
||||
AnalyzeDatabaseAlarmListener.schedule(this);
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.signal.core.util.Stopwatch
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.toInt
|
||||
import org.signal.paging.PagedDataSource
|
||||
import org.thoughtcrime.securesms.BuildConfig
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupRestoreManager
|
||||
import org.thoughtcrime.securesms.conversation.ConversationData
|
||||
import org.thoughtcrime.securesms.conversation.ConversationMessage
|
||||
@@ -25,6 +24,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.messagerequests.MessageRequestRepository
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingModel
|
||||
|
||||
private typealias ConversationElement = MappingModel<*>
|
||||
@@ -125,7 +125,7 @@ class ConversationDataSource(
|
||||
records = MessageDataFetcher.updateModelsWithData(records, extraData).toMutableList()
|
||||
stopwatch.split("models")
|
||||
|
||||
if (BuildConfig.MESSAGE_BACKUP_RESTORE_ENABLED && SignalStore.backup().restoreState.inProgress) {
|
||||
if (FeatureFlags.messageBackups() && SignalStore.backup().restoreState.inProgress) {
|
||||
BackupRestoreManager.prioritizeAttachmentsIfNeeded(records)
|
||||
stopwatch.split("restore")
|
||||
}
|
||||
|
||||
@@ -30,13 +30,21 @@ class BackupMessagesJob private constructor(parameters: Parameters) : BaseJob(pa
|
||||
private val TAG = Log.tag(BackupMessagesJob::class.java)
|
||||
|
||||
const val KEY = "BackupMessagesJob"
|
||||
|
||||
const val QUEUE = "BackupMessagesQueue"
|
||||
|
||||
fun enqueue() {
|
||||
val jobManager = ApplicationDependencies.getJobManager()
|
||||
jobManager.add(BackupMessagesJob())
|
||||
}
|
||||
}
|
||||
|
||||
constructor() : this(
|
||||
Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setMaxAttempts(Parameters.UNLIMITED)
|
||||
.setMaxInstancesForFactory(2)
|
||||
.setMaxAttempts(3)
|
||||
.setMaxInstancesForFactory(1)
|
||||
.setQueue(QUEUE)
|
||||
.build()
|
||||
)
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ internal class BackupValues(store: KeyValueStore) : SignalStoreValues(store) {
|
||||
private const val KEY_CDN_READ_CREDENTIALS_TIMESTAMP = "backup.cdn.readCredentials.timestamp"
|
||||
private const val KEY_RESTORE_STATE = "backup.restoreState"
|
||||
|
||||
private const val KEY_NEXT_BACKUP_TIME = "backup.nextBackupTime"
|
||||
|
||||
private const val KEY_CDN_BACKUP_DIRECTORY = "backup.cdn.directory"
|
||||
private const val KEY_CDN_BACKUP_MEDIA_DIRECTORY = "backup.cdn.mediaDirectory"
|
||||
|
||||
@@ -45,6 +47,8 @@ internal class BackupValues(store: KeyValueStore) : SignalStoreValues(store) {
|
||||
var restoreState: RestoreState by enumValue(KEY_RESTORE_STATE, RestoreState.NONE, RestoreState.serializer)
|
||||
var optimizeStorage: Boolean by booleanValue(KEY_OPTIMIZE_STORAGE, false)
|
||||
|
||||
var nextBackupTime: Long by longValue(KEY_NEXT_BACKUP_TIME, -1)
|
||||
|
||||
var areBackupsEnabled: Boolean by booleanValue(KEY_BACKUPS_ENABLED, false)
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.jobs.LocalBackupJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SettingsValues;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.JavaTimeExtensionsKt;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.service
|
||||
|
||||
import android.content.Context
|
||||
import org.thoughtcrime.securesms.jobs.BackupMessagesJob
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.toMillis
|
||||
import java.time.LocalDateTime
|
||||
import java.util.Random
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class MessageBackupListener : PersistentAlarmManagerListener() {
|
||||
override fun shouldScheduleExact(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getNextScheduledExecutionTime(context: Context): Long {
|
||||
return SignalStore.backup().nextBackupTime
|
||||
}
|
||||
|
||||
override fun onAlarm(context: Context, scheduledTime: Long): Long {
|
||||
if (SignalStore.backup().areBackupsEnabled) {
|
||||
BackupMessagesJob.enqueue()
|
||||
}
|
||||
return setNextBackupTimeToIntervalFromNow()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val BACKUP_JITTER_WINDOW_SECONDS = Math.toIntExact(TimeUnit.MINUTES.toSeconds(10))
|
||||
|
||||
@JvmStatic
|
||||
fun schedule(context: Context?) {
|
||||
if (FeatureFlags.messageBackups() && SignalStore.backup().areBackupsEnabled) {
|
||||
MessageBackupListener().onReceive(context, getScheduleIntent())
|
||||
}
|
||||
}
|
||||
|
||||
fun setNextBackupTimeToIntervalFromNow(): Long {
|
||||
val now = LocalDateTime.now()
|
||||
val hour = SignalStore.settings().backupHour
|
||||
val minute = SignalStore.settings().backupMinute
|
||||
var next = now.withHour(hour).withMinute(minute).withSecond(0)
|
||||
val jitter = Random().nextInt(BACKUP_JITTER_WINDOW_SECONDS) - BACKUP_JITTER_WINDOW_SECONDS / 2
|
||||
next.plusSeconds(jitter.toLong())
|
||||
if (now.isAfter(next)) {
|
||||
next = next.plusDays(1)
|
||||
}
|
||||
val nextTime = next.toMillis()
|
||||
SignalStore.backup().nextBackupTime = nextTime
|
||||
return nextTime
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -741,7 +741,7 @@ public final class FeatureFlags {
|
||||
* Note: This feature is in active development and is not intended to currently function.
|
||||
*/
|
||||
public static boolean messageBackups() {
|
||||
return getBoolean(MESSAGE_BACKUPS, false);
|
||||
return BuildConfig.MESSAGE_BACKUP_RESTORE_ENABLED || getBoolean(MESSAGE_BACKUPS, false);
|
||||
}
|
||||
|
||||
/** Whether or not to use the custom CameraX controller class */
|
||||
|
||||
Reference in New Issue
Block a user