BackupState.DISABLED has been removed. Now when the value is UNKNOWN, the app need to invoke EncryptionService.doesBackupExistOnServer() to check if a Backup exists.
This commit is contained in:
parent
38aa0ad1cf
commit
3c79390e45
9 changed files with 57 additions and 12 deletions
|
|
@ -17,13 +17,18 @@
|
||||||
package io.element.android.features.securebackup.impl.root
|
package io.element.android.features.securebackup.impl.root
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import io.element.android.features.securebackup.impl.loggerTagRoot
|
import io.element.android.features.securebackup.impl.loggerTagRoot
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.core.meta.BuildMeta
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
||||||
|
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -44,8 +49,20 @@ class SecureBackupRootPresenter @Inject constructor(
|
||||||
Timber.tag(loggerTagRoot.value).d("backupState: $backupState")
|
Timber.tag(loggerTagRoot.value).d("backupState: $backupState")
|
||||||
Timber.tag(loggerTagRoot.value).d("recoveryState: $recoveryState")
|
Timber.tag(loggerTagRoot.value).d("recoveryState: $recoveryState")
|
||||||
|
|
||||||
|
var doesBackupExistOnServer: Boolean? by remember { mutableStateOf(null) }
|
||||||
|
|
||||||
|
LaunchedEffect(backupState) {
|
||||||
|
doesBackupExistOnServer = if (backupState == BackupState.UNKNOWN) {
|
||||||
|
encryptionService.doesBackupExistOnServer().getOrNull() == true
|
||||||
|
} else {
|
||||||
|
// The value will not be used when the backupState is not UNKNOWN.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SecureBackupRootState(
|
return SecureBackupRootState(
|
||||||
backupState = backupState,
|
backupState = backupState,
|
||||||
|
doesBackupExistOnServer = doesBackupExistOnServer,
|
||||||
recoveryState = recoveryState,
|
recoveryState = recoveryState,
|
||||||
appName = buildMeta.applicationName,
|
appName = buildMeta.applicationName,
|
||||||
snackbarMessage = snackbarMessage,
|
snackbarMessage = snackbarMessage,
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||||
|
|
||||||
data class SecureBackupRootState(
|
data class SecureBackupRootState(
|
||||||
val backupState: BackupState,
|
val backupState: BackupState,
|
||||||
|
val doesBackupExistOnServer: Boolean?,
|
||||||
val recoveryState: RecoveryState,
|
val recoveryState: RecoveryState,
|
||||||
val appName: String,
|
val appName: String,
|
||||||
val snackbarMessage: SnackbarMessage?,
|
val snackbarMessage: SnackbarMessage?,
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,10 @@ import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||||
open class SecureBackupRootStateProvider : PreviewParameterProvider<SecureBackupRootState> {
|
open class SecureBackupRootStateProvider : PreviewParameterProvider<SecureBackupRootState> {
|
||||||
override val values: Sequence<SecureBackupRootState>
|
override val values: Sequence<SecureBackupRootState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aSecureBackupRootState(backupState = BackupState.UNKNOWN),
|
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = null),
|
||||||
|
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = true),
|
||||||
|
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = false),
|
||||||
aSecureBackupRootState(backupState = BackupState.ENABLED),
|
aSecureBackupRootState(backupState = BackupState.ENABLED),
|
||||||
aSecureBackupRootState(backupState = BackupState.DISABLED),
|
|
||||||
aSecureBackupRootState(recoveryState = RecoveryState.UNKNOWN),
|
aSecureBackupRootState(recoveryState = RecoveryState.UNKNOWN),
|
||||||
aSecureBackupRootState(recoveryState = RecoveryState.ENABLED),
|
aSecureBackupRootState(recoveryState = RecoveryState.ENABLED),
|
||||||
aSecureBackupRootState(recoveryState = RecoveryState.DISABLED),
|
aSecureBackupRootState(recoveryState = RecoveryState.DISABLED),
|
||||||
|
|
@ -37,10 +38,12 @@ open class SecureBackupRootStateProvider : PreviewParameterProvider<SecureBackup
|
||||||
|
|
||||||
fun aSecureBackupRootState(
|
fun aSecureBackupRootState(
|
||||||
backupState: BackupState = BackupState.UNKNOWN,
|
backupState: BackupState = BackupState.UNKNOWN,
|
||||||
|
doesBackupExistOnServer: Boolean? = true,
|
||||||
recoveryState: RecoveryState = RecoveryState.UNKNOWN,
|
recoveryState: RecoveryState = RecoveryState.UNKNOWN,
|
||||||
snackbarMessage: SnackbarMessage? = null,
|
snackbarMessage: SnackbarMessage? = null,
|
||||||
) = SecureBackupRootState(
|
) = SecureBackupRootState(
|
||||||
backupState = backupState,
|
backupState = backupState,
|
||||||
|
doesBackupExistOnServer = doesBackupExistOnServer,
|
||||||
recoveryState = recoveryState,
|
recoveryState = recoveryState,
|
||||||
appName = "Element",
|
appName = "Element",
|
||||||
snackbarMessage = snackbarMessage,
|
snackbarMessage = snackbarMessage,
|
||||||
|
|
|
||||||
|
|
@ -70,13 +70,27 @@ fun SecureBackupRootView(
|
||||||
|
|
||||||
// Disable / Enable backup
|
// Disable / Enable backup
|
||||||
when (state.backupState) {
|
when (state.backupState) {
|
||||||
BackupState.WAITING_FOR_SYNC,
|
BackupState.WAITING_FOR_SYNC -> Unit
|
||||||
BackupState.UNKNOWN -> Unit
|
BackupState.UNKNOWN -> {
|
||||||
BackupState.DISABLED -> {
|
when (state.doesBackupExistOnServer) {
|
||||||
PreferenceText(
|
true -> {
|
||||||
title = stringResource(id = R.string.screen_chat_backup_key_backup_action_enable),
|
// Should not happen, we will have the state BackupState.ENABLED
|
||||||
onClick = onEnableClicked,
|
PreferenceText(
|
||||||
)
|
title = stringResource(id = R.string.screen_chat_backup_key_backup_action_disable),
|
||||||
|
tintColor = ElementTheme.colors.textCriticalPrimary,
|
||||||
|
onClick = onDisableClicked,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
false -> {
|
||||||
|
PreferenceText(
|
||||||
|
title = stringResource(id = R.string.screen_chat_backup_key_backup_action_enable),
|
||||||
|
onClick = onEnableClicked,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
null -> {
|
||||||
|
AsyncLoading()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BackupState.CREATING,
|
BackupState.CREATING,
|
||||||
BackupState.ENABLING,
|
BackupState.ENABLING,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,5 @@ enum class BackupState {
|
||||||
RESUMING,
|
RESUMING,
|
||||||
ENABLED,
|
ENABLED,
|
||||||
DOWNLOADING,
|
DOWNLOADING,
|
||||||
DISABLING,
|
DISABLING;
|
||||||
DISABLED;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ interface EncryptionService {
|
||||||
|
|
||||||
suspend fun disableRecovery(): Result<Unit>
|
suspend fun disableRecovery(): Result<Unit>
|
||||||
|
|
||||||
|
suspend fun doesBackupExistOnServer(): Result<Boolean>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: accept bot recoveryKey and passphrase.
|
* Note: accept bot recoveryKey and passphrase.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ class BackupStateMapper {
|
||||||
RustBackupState.ENABLED -> BackupState.ENABLED
|
RustBackupState.ENABLED -> BackupState.ENABLED
|
||||||
RustBackupState.DOWNLOADING -> BackupState.DOWNLOADING
|
RustBackupState.DOWNLOADING -> BackupState.DOWNLOADING
|
||||||
RustBackupState.DISABLING -> BackupState.DISABLING
|
RustBackupState.DISABLING -> BackupState.DISABLING
|
||||||
RustBackupState.DISABLED -> BackupState.DISABLED
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,12 @@ internal class RustEncryptionService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun doesBackupExistOnServer(): Result<Boolean> = withContext(dispatchers.io) {
|
||||||
|
runCatching {
|
||||||
|
service.backupExistsOnServer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun waitForBackupUploadSteadyState(): Flow<BackupUploadState> {
|
override fun waitForBackupUploadSteadyState(): Flow<BackupUploadState> {
|
||||||
return callbackFlow {
|
return callbackFlow {
|
||||||
runCatching {
|
runCatching {
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,10 @@ class FakeEncryptionService : EncryptionService {
|
||||||
return Result.success(Unit)
|
return Result.success(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun doesBackupExistOnServer(): Result<Boolean> = simulateLongTask {
|
||||||
|
return Result.success(true)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun fixRecoveryIssues(recoveryKey: String): Result<Unit> = simulateLongTask {
|
override suspend fun fixRecoveryIssues(recoveryKey: String): Result<Unit> = simulateLongTask {
|
||||||
fixRecoveryIssuesFailure?.let { return Result.failure(it) }
|
fixRecoveryIssuesFailure?.let { return Result.failure(it) }
|
||||||
return Result.success(Unit)
|
return Result.success(Unit)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue