mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 04:28:35 +00:00
Fix backup message job cancel and start bugs.
This commit is contained in:
@@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.signal.core.util.throttleLatest
|
import org.signal.core.util.throttleLatest
|
||||||
@@ -22,6 +23,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase
|
|||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
import org.thoughtcrime.securesms.jobs.ArchiveCommitAttachmentDeletesJob
|
import org.thoughtcrime.securesms.jobs.ArchiveCommitAttachmentDeletesJob
|
||||||
import org.thoughtcrime.securesms.jobs.ArchiveThumbnailUploadJob
|
import org.thoughtcrime.securesms.jobs.ArchiveThumbnailUploadJob
|
||||||
|
import org.thoughtcrime.securesms.jobs.BackupMessagesJob
|
||||||
import org.thoughtcrime.securesms.jobs.UploadAttachmentToArchiveJob
|
import org.thoughtcrime.securesms.jobs.UploadAttachmentToArchiveJob
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
||||||
@@ -88,6 +90,7 @@ object ArchiveUploadProgress {
|
|||||||
.onEach { updated ->
|
.onEach { updated ->
|
||||||
updateState(notify = false) { updated }
|
updateState(notify = false) { updated }
|
||||||
}
|
}
|
||||||
|
.onStart { emit(uploadProgress) }
|
||||||
.flowOn(Dispatchers.IO)
|
.flowOn(Dispatchers.IO)
|
||||||
|
|
||||||
val inProgress
|
val inProgress
|
||||||
@@ -108,6 +111,8 @@ object ArchiveUploadProgress {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BackupMessagesJob.cancel()
|
||||||
|
|
||||||
AppDependencies.jobManager.cancelAllInQueue(ArchiveCommitAttachmentDeletesJob.ARCHIVE_ATTACHMENT_QUEUE)
|
AppDependencies.jobManager.cancelAllInQueue(ArchiveCommitAttachmentDeletesJob.ARCHIVE_ATTACHMENT_QUEUE)
|
||||||
UploadAttachmentToArchiveJob.getAllQueueKeys().forEach {
|
UploadAttachmentToArchiveJob.getAllQueueKeys().forEach {
|
||||||
AppDependencies.jobManager.cancelAllInQueue(it)
|
AppDependencies.jobManager.cancelAllInQueue(it)
|
||||||
|
|||||||
@@ -511,6 +511,7 @@ private fun RemoteBackupsSettingsContent(
|
|||||||
canViewBackupKey = state.canViewBackupKey,
|
canViewBackupKey = state.canViewBackupKey,
|
||||||
backupRestoreState = backupRestoreState,
|
backupRestoreState = backupRestoreState,
|
||||||
backupProgress = backupProgress,
|
backupProgress = backupProgress,
|
||||||
|
canBackupMessagesRun = state.canBackupMessagesJobRun,
|
||||||
lastBackupTimestamp = state.lastBackupTimestamp,
|
lastBackupTimestamp = state.lastBackupTimestamp,
|
||||||
backupMediaSize = state.backupMediaSize,
|
backupMediaSize = state.backupMediaSize,
|
||||||
backupsFrequency = state.backupsFrequency,
|
backupsFrequency = state.backupsFrequency,
|
||||||
@@ -815,6 +816,7 @@ private fun LazyListScope.appendBackupDetailsItems(
|
|||||||
canViewBackupKey: Boolean,
|
canViewBackupKey: Boolean,
|
||||||
backupRestoreState: BackupRestoreState,
|
backupRestoreState: BackupRestoreState,
|
||||||
backupProgress: ArchiveUploadProgressState?,
|
backupProgress: ArchiveUploadProgressState?,
|
||||||
|
canBackupMessagesRun: Boolean,
|
||||||
lastBackupTimestamp: Long,
|
lastBackupTimestamp: Long,
|
||||||
backupMediaSize: Long,
|
backupMediaSize: Long,
|
||||||
backupsFrequency: BackupFrequency,
|
backupsFrequency: BackupFrequency,
|
||||||
@@ -868,6 +870,8 @@ private fun LazyListScope.appendBackupDetailsItems(
|
|||||||
item {
|
item {
|
||||||
InProgressBackupRow(
|
InProgressBackupRow(
|
||||||
archiveUploadProgressState = backupProgress,
|
archiveUploadProgressState = backupProgress,
|
||||||
|
canBackupMessagesRun = canBackupMessagesRun,
|
||||||
|
canBackupUsingCellular = canBackUpUsingCellular,
|
||||||
cancelArchiveUpload = contentCallbacks::onCancelUploadClick
|
cancelArchiveUpload = contentCallbacks::onCancelUploadClick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1326,6 +1330,8 @@ private fun SubscriptionMismatchMissingGooglePlayCard(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun InProgressBackupRow(
|
private fun InProgressBackupRow(
|
||||||
archiveUploadProgressState: ArchiveUploadProgressState,
|
archiveUploadProgressState: ArchiveUploadProgressState,
|
||||||
|
canBackupMessagesRun: Boolean = true,
|
||||||
|
canBackupUsingCellular: Boolean = true,
|
||||||
cancelArchiveUpload: () -> Unit = {}
|
cancelArchiveUpload: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
@@ -1361,7 +1367,7 @@ private fun InProgressBackupRow(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = getProgressStateMessage(archiveUploadProgressState),
|
text = getProgressStateMessage(archiveUploadProgressState, canBackupMessagesRun, canBackupUsingCellular),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
@@ -1399,18 +1405,26 @@ private fun ArchiveProgressIndicator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun getProgressStateMessage(archiveUploadProgressState: ArchiveUploadProgressState): String {
|
private fun getProgressStateMessage(archiveUploadProgressState: ArchiveUploadProgressState, canBackupMessagesRun: Boolean, canBackupUsingCellular: Boolean): String {
|
||||||
return when (archiveUploadProgressState.state) {
|
return when (archiveUploadProgressState.state) {
|
||||||
ArchiveUploadProgressState.State.None, ArchiveUploadProgressState.State.UserCanceled -> stringResource(R.string.RemoteBackupsSettingsFragment__processing_backup)
|
ArchiveUploadProgressState.State.None, ArchiveUploadProgressState.State.UserCanceled -> stringResource(R.string.RemoteBackupsSettingsFragment__processing_backup)
|
||||||
ArchiveUploadProgressState.State.Export -> getBackupExportPhaseProgressString(archiveUploadProgressState)
|
ArchiveUploadProgressState.State.Export -> getBackupExportPhaseProgressString(archiveUploadProgressState, canBackupMessagesRun, canBackupUsingCellular)
|
||||||
ArchiveUploadProgressState.State.UploadBackupFile, ArchiveUploadProgressState.State.UploadMedia -> getBackupUploadPhaseProgressString(archiveUploadProgressState)
|
ArchiveUploadProgressState.State.UploadBackupFile, ArchiveUploadProgressState.State.UploadMedia -> getBackupUploadPhaseProgressString(archiveUploadProgressState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun getBackupExportPhaseProgressString(state: ArchiveUploadProgressState): String {
|
private fun getBackupExportPhaseProgressString(state: ArchiveUploadProgressState, canBackupMessagesRun: Boolean, canBackupUsingCellular: Boolean): String {
|
||||||
return when (state.backupPhase) {
|
return when (state.backupPhase) {
|
||||||
ArchiveUploadProgressState.BackupPhase.BackupPhaseNone -> stringResource(R.string.RemoteBackupsSettingsFragment__processing_backup)
|
ArchiveUploadProgressState.BackupPhase.BackupPhaseNone -> {
|
||||||
|
if (canBackupMessagesRun) {
|
||||||
|
stringResource(R.string.RemoteBackupsSettingsFragment__processing_backup)
|
||||||
|
} else if (canBackupUsingCellular) {
|
||||||
|
stringResource(R.string.RemoteBackupsSettingsFragment__Waiting_for_internet_connection)
|
||||||
|
} else {
|
||||||
|
stringResource(R.string.RemoteBackupsSettingsFragment__Waiting_for_Wifi)
|
||||||
|
}
|
||||||
|
}
|
||||||
ArchiveUploadProgressState.BackupPhase.Message -> {
|
ArchiveUploadProgressState.BackupPhase.Message -> {
|
||||||
pluralStringResource(
|
pluralStringResource(
|
||||||
R.plurals.RemoteBackupsSettingsFragment__processing_messages_progress_text,
|
R.plurals.RemoteBackupsSettingsFragment__processing_messages_progress_text,
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ data class RemoteBackupsSettingsState(
|
|||||||
val lastBackupTimestamp: Long = 0,
|
val lastBackupTimestamp: Long = 0,
|
||||||
val dialog: Dialog = Dialog.NONE,
|
val dialog: Dialog = Dialog.NONE,
|
||||||
val snackbar: Snackbar = Snackbar.NONE,
|
val snackbar: Snackbar = Snackbar.NONE,
|
||||||
val includeDebuglog: Boolean? = null
|
val includeDebuglog: Boolean? = null,
|
||||||
|
val canBackupMessagesJobRun: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
enum class Dialog {
|
enum class Dialog {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import org.thoughtcrime.securesms.database.InAppPaymentTable
|
|||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
import org.thoughtcrime.securesms.database.attachmentUpdates
|
import org.thoughtcrime.securesms.database.attachmentUpdates
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.impl.BackupMessagesConstraint
|
||||||
import org.thoughtcrime.securesms.jobs.BackupMessagesJob
|
import org.thoughtcrime.securesms.jobs.BackupMessagesJob
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
||||||
@@ -62,6 +63,7 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
|||||||
RemoteBackupsSettingsState(
|
RemoteBackupsSettingsState(
|
||||||
tier = SignalStore.backup.backupTier,
|
tier = SignalStore.backup.backupTier,
|
||||||
backupsEnabled = SignalStore.backup.areBackupsEnabled,
|
backupsEnabled = SignalStore.backup.areBackupsEnabled,
|
||||||
|
canBackupMessagesJobRun = BackupMessagesConstraint.isMet(AppDependencies.application),
|
||||||
canViewBackupKey = !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application),
|
canViewBackupKey = !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application),
|
||||||
lastBackupTimestamp = SignalStore.backup.lastBackupTime,
|
lastBackupTimestamp = SignalStore.backup.lastBackupTime,
|
||||||
backupsFrequency = SignalStore.backup.backupFrequency,
|
backupsFrequency = SignalStore.backup.backupFrequency,
|
||||||
@@ -152,7 +154,12 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
|||||||
|
|
||||||
fun setCanBackUpUsingCellular(canBackUpUsingCellular: Boolean) {
|
fun setCanBackUpUsingCellular(canBackUpUsingCellular: Boolean) {
|
||||||
SignalStore.backup.backupWithCellular = canBackUpUsingCellular
|
SignalStore.backup.backupWithCellular = canBackUpUsingCellular
|
||||||
_state.update { it.copy(canBackUpUsingCellular = canBackUpUsingCellular) }
|
_state.update {
|
||||||
|
it.copy(
|
||||||
|
canBackupMessagesJobRun = BackupMessagesConstraint.isMet(AppDependencies.application),
|
||||||
|
canBackUpUsingCellular = canBackUpUsingCellular
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setCanRestoreUsingCellular() {
|
fun setCanRestoreUsingCellular() {
|
||||||
@@ -257,6 +264,7 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
|||||||
tier = SignalStore.backup.backupTier,
|
tier = SignalStore.backup.backupTier,
|
||||||
backupsEnabled = SignalStore.backup.areBackupsEnabled,
|
backupsEnabled = SignalStore.backup.areBackupsEnabled,
|
||||||
lastBackupTimestamp = SignalStore.backup.lastBackupTime,
|
lastBackupTimestamp = SignalStore.backup.lastBackupTime,
|
||||||
|
canBackupMessagesJobRun = BackupMessagesConstraint.isMet(AppDependencies.application),
|
||||||
backupMediaSize = SignalDatabase.attachments.getEstimatedArchiveMediaSize(),
|
backupMediaSize = SignalDatabase.attachments.getEstimatedArchiveMediaSize(),
|
||||||
backupsFrequency = SignalStore.backup.backupFrequency,
|
backupsFrequency = SignalStore.backup.backupFrequency,
|
||||||
canBackUpUsingCellular = SignalStore.backup.backupWithCellular,
|
canBackUpUsingCellular = SignalStore.backup.backupWithCellular,
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thoughtcrime.securesms.jobmanager.impl
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.app.job.JobInfo
|
||||||
|
import android.content.Context
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.Constraint
|
||||||
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constraint that, when added, means that a job cannot be performed unless the user either has Wifi or, if they enabled it, cellular
|
||||||
|
*/
|
||||||
|
class BackupMessagesConstraint(private val application: Application) : Constraint {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val KEY = "BackupMessagesConstraint"
|
||||||
|
|
||||||
|
fun isMet(context: Context): Boolean {
|
||||||
|
if (SignalStore.backup.backupWithCellular) {
|
||||||
|
return NetworkConstraint.isMet(context)
|
||||||
|
}
|
||||||
|
return WifiConstraint.isMet(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isMet(): Boolean {
|
||||||
|
return isMet(application)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFactoryKey(): String = KEY
|
||||||
|
|
||||||
|
override fun applyToJobInfo(jobInfoBuilder: JobInfo.Builder) = Unit
|
||||||
|
|
||||||
|
class Factory(val application: Application) : Constraint.Factory<BackupMessagesConstraint> {
|
||||||
|
override fun create(): BackupMessagesConstraint {
|
||||||
|
return BackupMessagesConstraint(application)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.thoughtcrime.securesms.jobmanager.impl
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An observer for the [BackupMessagesConstraint]. This is called when users change whether or not backup is allowed via cellular
|
||||||
|
*/
|
||||||
|
object BackupMessagesConstraintObserver : ConstraintObserver {
|
||||||
|
|
||||||
|
private const val REASON = "BackupMessagesConstraint"
|
||||||
|
|
||||||
|
private var notifier: ConstraintObserver.Notifier? = null
|
||||||
|
|
||||||
|
override fun register(notifier: ConstraintObserver.Notifier) {
|
||||||
|
this.notifier = notifier
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Let the observer know that the backup using cellular flag has changed.
|
||||||
|
*/
|
||||||
|
fun onChange() {
|
||||||
|
if (BackupMessagesConstraint.isMet(AppDependencies.application)) {
|
||||||
|
notifier?.onConstraintMet(REASON)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,8 +18,7 @@ import org.thoughtcrime.securesms.backup.v2.ResumableMessagesBackupUploadSpec
|
|||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
import org.thoughtcrime.securesms.jobmanager.Job
|
import org.thoughtcrime.securesms.jobmanager.Job
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
import org.thoughtcrime.securesms.jobmanager.impl.BackupMessagesConstraint
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.WifiConstraint
|
|
||||||
import org.thoughtcrime.securesms.jobs.protos.BackupMessagesJobData
|
import org.thoughtcrime.securesms.jobs.protos.BackupMessagesJobData
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.keyvalue.isDecisionPending
|
import org.thoughtcrime.securesms.keyvalue.isDecisionPending
|
||||||
@@ -96,6 +95,10 @@ class BackupMessagesJob private constructor(
|
|||||||
|
|
||||||
chain.enqueue()
|
chain.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun cancel() {
|
||||||
|
AppDependencies.jobManager.find { it.factoryKey == KEY }.forEach { AppDependencies.jobManager.cancel(it.id) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() : this(
|
constructor() : this(
|
||||||
@@ -103,7 +106,7 @@ class BackupMessagesJob private constructor(
|
|||||||
dataFile = "",
|
dataFile = "",
|
||||||
resumableMessagesBackupUploadSpec = null,
|
resumableMessagesBackupUploadSpec = null,
|
||||||
parameters = Parameters.Builder()
|
parameters = Parameters.Builder()
|
||||||
.addConstraint(if (SignalStore.backup.backupWithCellular) NetworkConstraint.KEY else WifiConstraint.KEY)
|
.addConstraint(BackupMessagesConstraint.KEY)
|
||||||
.setMaxAttempts(3)
|
.setMaxAttempts(3)
|
||||||
.setMaxInstancesForFactory(1)
|
.setMaxInstancesForFactory(1)
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
|||||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
import org.thoughtcrime.securesms.jobmanager.JobMigration;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.AutoDownloadEmojiConstraint;
|
import org.thoughtcrime.securesms.jobmanager.impl.AutoDownloadEmojiConstraint;
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.impl.BackupMessagesConstraint;
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.impl.BackupMessagesConstraintObserver;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.BatteryNotLowConstraint;
|
import org.thoughtcrime.securesms.jobmanager.impl.BatteryNotLowConstraint;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraintObserver;
|
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraintObserver;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.ChangeNumberConstraint;
|
import org.thoughtcrime.securesms.jobmanager.impl.ChangeNumberConstraint;
|
||||||
@@ -404,6 +406,7 @@ public final class JobManagerFactories {
|
|||||||
return new HashMap<String, Constraint.Factory>() {{
|
return new HashMap<String, Constraint.Factory>() {{
|
||||||
put(NoRemoteArchiveGarbageCollectionPendingConstraint.KEY, new NoRemoteArchiveGarbageCollectionPendingConstraint.Factory());
|
put(NoRemoteArchiveGarbageCollectionPendingConstraint.KEY, new NoRemoteArchiveGarbageCollectionPendingConstraint.Factory());
|
||||||
put(AutoDownloadEmojiConstraint.KEY, new AutoDownloadEmojiConstraint.Factory(application));
|
put(AutoDownloadEmojiConstraint.KEY, new AutoDownloadEmojiConstraint.Factory(application));
|
||||||
|
put(BackupMessagesConstraint.KEY, new BackupMessagesConstraint.Factory(application));
|
||||||
put(BatteryNotLowConstraint.KEY, new BatteryNotLowConstraint.Factory());
|
put(BatteryNotLowConstraint.KEY, new BatteryNotLowConstraint.Factory());
|
||||||
put(ChangeNumberConstraint.KEY, new ChangeNumberConstraint.Factory());
|
put(ChangeNumberConstraint.KEY, new ChangeNumberConstraint.Factory());
|
||||||
put(ChargingConstraint.KEY, new ChargingConstraint.Factory());
|
put(ChargingConstraint.KEY, new ChargingConstraint.Factory());
|
||||||
@@ -431,7 +434,8 @@ public final class JobManagerFactories {
|
|||||||
DataRestoreConstraintObserver.INSTANCE,
|
DataRestoreConstraintObserver.INSTANCE,
|
||||||
RestoreAttachmentConstraintObserver.INSTANCE,
|
RestoreAttachmentConstraintObserver.INSTANCE,
|
||||||
NoRemoteArchiveGarbageCollectionPendingConstraint.Observer.INSTANCE,
|
NoRemoteArchiveGarbageCollectionPendingConstraint.Observer.INSTANCE,
|
||||||
RegisteredConstraint.Observer.INSTANCE);
|
RegisteredConstraint.Observer.INSTANCE,
|
||||||
|
BackupMessagesConstraintObserver.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<JobMigration> getJobMigrations(@NonNull Application application) {
|
public static List<JobMigration> getJobMigrations(@NonNull Application application) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.backup.RestoreState
|
|||||||
import org.thoughtcrime.securesms.backup.v2.BackupFrequency
|
import org.thoughtcrime.securesms.backup.v2.BackupFrequency
|
||||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
||||||
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
|
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.impl.BackupMessagesConstraintObserver
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NoRemoteArchiveGarbageCollectionPendingConstraint
|
import org.thoughtcrime.securesms.jobmanager.impl.NoRemoteArchiveGarbageCollectionPendingConstraint
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.RestoreAttachmentConstraintObserver
|
import org.thoughtcrime.securesms.jobmanager.impl.RestoreAttachmentConstraintObserver
|
||||||
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
||||||
@@ -60,7 +61,7 @@ class BackupValues(store: KeyValueStore) : SignalStoreValues(store) {
|
|||||||
private const val KEY_OPTIMIZE_STORAGE = "backup.optimizeStorage"
|
private const val KEY_OPTIMIZE_STORAGE = "backup.optimizeStorage"
|
||||||
private const val KEY_BACKUPS_INITIALIZED = "backup.initialized"
|
private const val KEY_BACKUPS_INITIALIZED = "backup.initialized"
|
||||||
|
|
||||||
private const val KEY_ARCHIVE_UPLOAD_STATE = "backup.archiveUploadState"
|
const val KEY_ARCHIVE_UPLOAD_STATE = "backup.archiveUploadState"
|
||||||
|
|
||||||
private const val KEY_BACKUP_UPLOADED = "backup.backupUploaded"
|
private const val KEY_BACKUP_UPLOADED = "backup.backupUploaded"
|
||||||
private const val KEY_SUBSCRIPTION_STATE_MISMATCH = "backup.subscriptionStateMismatch"
|
private const val KEY_SUBSCRIPTION_STATE_MISMATCH = "backup.subscriptionStateMismatch"
|
||||||
@@ -104,7 +105,12 @@ class BackupValues(store: KeyValueStore) : SignalStoreValues(store) {
|
|||||||
|
|
||||||
var restoreState: RestoreState by enumValue(KEY_RESTORE_STATE, RestoreState.NONE, RestoreState.serializer)
|
var restoreState: RestoreState by enumValue(KEY_RESTORE_STATE, RestoreState.NONE, RestoreState.serializer)
|
||||||
var optimizeStorage: Boolean by booleanValue(KEY_OPTIMIZE_STORAGE, false)
|
var optimizeStorage: Boolean by booleanValue(KEY_OPTIMIZE_STORAGE, false)
|
||||||
var backupWithCellular: Boolean by booleanValue(KEY_BACKUP_OVER_CELLULAR, false)
|
var backupWithCellular: Boolean
|
||||||
|
get() = getBoolean(KEY_BACKUP_OVER_CELLULAR, false)
|
||||||
|
set(value) {
|
||||||
|
putBoolean(KEY_BACKUP_OVER_CELLULAR, value)
|
||||||
|
BackupMessagesConstraintObserver.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
var backupDownloadNotifierState: BackupDownloadNotifierState? by protoValue(KEY_BACKUP_DOWNLOAD_NOTIFIER_STATE, BackupDownloadNotifierState.ADAPTER)
|
var backupDownloadNotifierState: BackupDownloadNotifierState? by protoValue(KEY_BACKUP_DOWNLOAD_NOTIFIER_STATE, BackupDownloadNotifierState.ADAPTER)
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -8249,6 +8249,10 @@
|
|||||||
<string name="RemoteBackupsSettingsFragment__processing_backup">Processing backup…</string>
|
<string name="RemoteBackupsSettingsFragment__processing_backup">Processing backup…</string>
|
||||||
<!-- Linear progress dialog text shown when preparing a backup -->
|
<!-- Linear progress dialog text shown when preparing a backup -->
|
||||||
<string name="RemoteBackupsSettingsFragment__preparing_backup">Preparing backup…</string>
|
<string name="RemoteBackupsSettingsFragment__preparing_backup">Preparing backup…</string>
|
||||||
|
<!-- Linear progress dialog text shown when backup is paused because unmetered connectivity, such as WiFi, is unavailable. -->
|
||||||
|
<string name="RemoteBackupsSettingsFragment__Waiting_for_Wifi">Waiting for WiFi…</string>
|
||||||
|
<!-- Linear progress dialog text shown when backup is paused because internet is unavailable. -->
|
||||||
|
<string name="RemoteBackupsSettingsFragment__Waiting_for_internet_connection">Waiting for Internet connection…</string>
|
||||||
<!-- Linear progress dialog text shown when processing messages for backup. First placeholder is completed count, second is approximate total count, third is percent completed. -->
|
<!-- Linear progress dialog text shown when processing messages for backup. First placeholder is completed count, second is approximate total count, third is percent completed. -->
|
||||||
<plurals name="RemoteBackupsSettingsFragment__processing_messages_progress_text">
|
<plurals name="RemoteBackupsSettingsFragment__processing_messages_progress_text">
|
||||||
<item quantity="one">Processing %1$s of %2$s message (%3$d%%)</item>
|
<item quantity="one">Processing %1$s of %2$s message (%3$d%%)</item>
|
||||||
|
|||||||
@@ -6,12 +6,15 @@
|
|||||||
package org.thoughtcrime.securesms.database
|
package org.thoughtcrime.securesms.database
|
||||||
|
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
|
import com.squareup.wire.ProtoAdapter
|
||||||
import org.signal.core.util.requireBlob
|
import org.signal.core.util.requireBlob
|
||||||
import org.signal.core.util.requireString
|
import org.signal.core.util.requireString
|
||||||
import org.signal.spinner.ColumnTransformer
|
import org.signal.spinner.ColumnTransformer
|
||||||
import org.signal.spinner.DefaultColumnTransformer
|
import org.signal.spinner.DefaultColumnTransformer
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.RestoreDecisionState
|
import org.thoughtcrime.securesms.database.model.databaseprotos.RestoreDecisionState
|
||||||
|
import org.thoughtcrime.securesms.keyvalue.BackupValues
|
||||||
import org.thoughtcrime.securesms.keyvalue.RegistrationValues
|
import org.thoughtcrime.securesms.keyvalue.RegistrationValues
|
||||||
|
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform non-user friendly store values into less-non-user friendly representations.
|
* Transform non-user friendly store values into less-non-user friendly representations.
|
||||||
@@ -23,13 +26,13 @@ object SignalStoreTransformer : ColumnTransformer {
|
|||||||
|
|
||||||
override fun transform(tableName: String?, columnName: String, cursor: Cursor): String? {
|
override fun transform(tableName: String?, columnName: String, cursor: Cursor): String? {
|
||||||
return when (cursor.requireString(KeyValueDatabase.KEY)) {
|
return when (cursor.requireString(KeyValueDatabase.KEY)) {
|
||||||
RegistrationValues.RESTORE_DECISION_STATE -> transformRestoreDecisionState(cursor)
|
RegistrationValues.RESTORE_DECISION_STATE -> decodeProto(cursor, RestoreDecisionState.ADAPTER)
|
||||||
|
BackupValues.KEY_ARCHIVE_UPLOAD_STATE -> decodeProto(cursor, ArchiveUploadProgressState.ADAPTER)
|
||||||
else -> DefaultColumnTransformer.transform(tableName, columnName, cursor)
|
else -> DefaultColumnTransformer.transform(tableName, columnName, cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun transformRestoreDecisionState(cursor: Cursor): String? {
|
private fun decodeProto(cursor: Cursor, adapter: ProtoAdapter<*>): String? {
|
||||||
val restoreDecisionState = cursor.requireBlob(KeyValueDatabase.VALUE)?.let { RestoreDecisionState.ADAPTER.decode(it) }
|
return cursor.requireBlob(KeyValueDatabase.VALUE)?.let { adapter.decode(it) }?.toString()
|
||||||
return restoreDecisionState.toString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user