Merge pull request #1832 from vector-im/renovate/org.matrix.rustcomponents-sdk-android-0.x
Update dependency org.matrix.rustcomponents:sdk-android to v0.1.68
This commit is contained in:
commit
be8ccee0c7
26 changed files with 210 additions and 33 deletions
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.features.securebackup.impl.root
|
||||||
|
|
||||||
|
sealed interface SecureBackupRootEvents {
|
||||||
|
data object RetryKeyBackupState : SecureBackupRootEvents
|
||||||
|
}
|
||||||
|
|
@ -17,14 +17,24 @@
|
||||||
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.MutableState
|
||||||
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.rememberCoroutineScope
|
||||||
import io.element.android.features.securebackup.impl.loggerTagRoot
|
import io.element.android.features.securebackup.impl.loggerTagRoot
|
||||||
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||||
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 kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -36,6 +46,7 @@ class SecureBackupRootPresenter @Inject constructor(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): SecureBackupRootState {
|
override fun present(): SecureBackupRootState {
|
||||||
|
val localCoroutineScope = rememberCoroutineScope()
|
||||||
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
||||||
|
|
||||||
val backupState by encryptionService.backupStateStateFlow.collectAsState()
|
val backupState by encryptionService.backupStateStateFlow.collectAsState()
|
||||||
|
|
@ -44,11 +55,33 @@ 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")
|
||||||
|
|
||||||
|
val doesBackupExistOnServerAction: MutableState<Async<Boolean>> = remember { mutableStateOf(Async.Uninitialized) }
|
||||||
|
|
||||||
|
LaunchedEffect(backupState) {
|
||||||
|
if (backupState == BackupState.UNKNOWN) {
|
||||||
|
getKeyBackupStatus(doesBackupExistOnServerAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleEvents(event: SecureBackupRootEvents) {
|
||||||
|
when (event) {
|
||||||
|
SecureBackupRootEvents.RetryKeyBackupState -> localCoroutineScope.getKeyBackupStatus(doesBackupExistOnServerAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SecureBackupRootState(
|
return SecureBackupRootState(
|
||||||
backupState = backupState,
|
backupState = backupState,
|
||||||
|
doesBackupExistOnServer = doesBackupExistOnServerAction.value,
|
||||||
recoveryState = recoveryState,
|
recoveryState = recoveryState,
|
||||||
appName = buildMeta.applicationName,
|
appName = buildMeta.applicationName,
|
||||||
snackbarMessage = snackbarMessage,
|
snackbarMessage = snackbarMessage,
|
||||||
|
eventSink = ::handleEvents,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun CoroutineScope.getKeyBackupStatus(action: MutableState<Async<Boolean>>) = launch {
|
||||||
|
suspend {
|
||||||
|
encryptionService.doesBackupExistOnServer().getOrThrow()
|
||||||
|
}.runCatchingUpdatingState(action)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
|
|
||||||
package io.element.android.features.securebackup.impl.root
|
package io.element.android.features.securebackup.impl.root
|
||||||
|
|
||||||
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||||
|
|
||||||
data class SecureBackupRootState(
|
data class SecureBackupRootState(
|
||||||
val backupState: BackupState,
|
val backupState: BackupState,
|
||||||
|
val doesBackupExistOnServer: Async<Boolean>,
|
||||||
val recoveryState: RecoveryState,
|
val recoveryState: RecoveryState,
|
||||||
val appName: String,
|
val appName: String,
|
||||||
val snackbarMessage: SnackbarMessage?,
|
val snackbarMessage: SnackbarMessage?,
|
||||||
|
val eventSink: (SecureBackupRootEvents) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package io.element.android.features.securebackup.impl.root
|
package io.element.android.features.securebackup.impl.root
|
||||||
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||||
|
|
@ -24,9 +25,11 @@ 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 = Async.Uninitialized),
|
||||||
|
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = Async.Success(true)),
|
||||||
|
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = Async.Success(false)),
|
||||||
|
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = Async.Failure(Exception("An error"))),
|
||||||
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,11 +40,14 @@ open class SecureBackupRootStateProvider : PreviewParameterProvider<SecureBackup
|
||||||
|
|
||||||
fun aSecureBackupRootState(
|
fun aSecureBackupRootState(
|
||||||
backupState: BackupState = BackupState.UNKNOWN,
|
backupState: BackupState = BackupState.UNKNOWN,
|
||||||
|
doesBackupExistOnServer: Async<Boolean> = Async.Uninitialized,
|
||||||
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,
|
||||||
|
eventSink = {},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,27 @@
|
||||||
|
|
||||||
package io.element.android.features.securebackup.impl.root
|
package io.element.android.features.securebackup.impl.root
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import io.element.android.features.securebackup.impl.R
|
import io.element.android.features.securebackup.impl.R
|
||||||
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.designsystem.components.async.AsyncLoading
|
import io.element.android.libraries.designsystem.components.async.AsyncLoading
|
||||||
|
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
||||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceDivider
|
import io.element.android.libraries.designsystem.components.preferences.PreferenceDivider
|
||||||
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
|
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
|
||||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithStyledPart
|
import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithStyledPart
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.ListItem
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState
|
import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState
|
||||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||||
|
|
@ -70,13 +79,58 @@ 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(
|
is Async.Success -> when (state.doesBackupExistOnServer.data) {
|
||||||
title = stringResource(id = R.string.screen_chat_backup_key_backup_action_enable),
|
true -> {
|
||||||
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Async.Loading,
|
||||||
|
Async.Uninitialized -> {
|
||||||
|
ListItem(headlineContent = {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
is Async.Failure -> {
|
||||||
|
ListItem(
|
||||||
|
headlineContent = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = CommonStrings.error_unknown),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailingContent = ListItemContent.Custom {
|
||||||
|
TextButton(
|
||||||
|
text = stringResource(
|
||||||
|
id = CommonStrings.action_retry
|
||||||
|
),
|
||||||
|
onClick = { state.eventSink.invoke(SecureBackupRootEvents.RetryKeyBackupState) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
PreferenceText(
|
||||||
|
title = stringResource(id = R.string.screen_chat_backup_key_backup_action_enable),
|
||||||
|
onClick = onEnableClicked,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BackupState.CREATING,
|
BackupState.CREATING,
|
||||||
BackupState.ENABLING,
|
BackupState.ENABLING,
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,12 @@ import app.cash.molecule.RecompositionMode
|
||||||
import app.cash.molecule.moleculeFlow
|
import app.cash.molecule.moleculeFlow
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
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 io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||||
|
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
|
|
@ -40,9 +43,39 @@ class SecureBackupRootPresenterTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
skipItems(2)
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
|
assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
|
||||||
|
assertThat(initialState.doesBackupExistOnServer.dataOrNull()).isTrue()
|
||||||
|
assertThat(initialState.recoveryState).isEqualTo(RecoveryState.UNKNOWN)
|
||||||
assertThat(initialState.appName).isEqualTo("Element")
|
assertThat(initialState.appName).isEqualTo("Element")
|
||||||
|
assertThat(initialState.snackbarMessage).isNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `present - Unknown state`() = runTest {
|
||||||
|
val encryptionService = FakeEncryptionService()
|
||||||
|
val presenter = createSecureBackupRootPresenter(
|
||||||
|
encryptionService = encryptionService,
|
||||||
|
)
|
||||||
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
presenter.present()
|
||||||
|
}.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
encryptionService.givenDoesBackupExistOnServerResult(Result.failure(AN_EXCEPTION))
|
||||||
|
assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
|
||||||
|
assertThat(initialState.doesBackupExistOnServer).isEqualTo(Async.Uninitialized)
|
||||||
|
val loadingState1 = awaitItem()
|
||||||
|
assertThat(loadingState1.doesBackupExistOnServer).isInstanceOf(Async.Loading::class.java)
|
||||||
|
val errorState = awaitItem()
|
||||||
|
assertThat(errorState.doesBackupExistOnServer).isEqualTo(Async.Failure<Boolean>(AN_EXCEPTION))
|
||||||
|
encryptionService.givenDoesBackupExistOnServerResult(Result.success(false))
|
||||||
|
errorState.eventSink.invoke(SecureBackupRootEvents.RetryKeyBackupState)
|
||||||
|
val loadingState2 = awaitItem()
|
||||||
|
assertThat(loadingState2.doesBackupExistOnServer).isInstanceOf(Async.Loading::class.java)
|
||||||
|
val finalState = awaitItem()
|
||||||
|
assertThat(finalState.doesBackupExistOnServer.dataOrNull()).isFalse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ jsoup = "org.jsoup:jsoup:1.16.2"
|
||||||
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
||||||
molecule-runtime = "app.cash.molecule:molecule-runtime:1.3.0"
|
molecule-runtime = "app.cash.molecule:molecule-runtime:1.3.0"
|
||||||
timber = "com.jakewharton.timber:timber:5.0.1"
|
timber = "com.jakewharton.timber:timber:5.0.1"
|
||||||
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.67"
|
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.68"
|
||||||
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
|
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
|
||||||
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
|
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
|
||||||
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ class FakeEncryptionService : EncryptionService {
|
||||||
private var waitForBackupUploadSteadyStateFlow: Flow<BackupUploadState> = flowOf()
|
private var waitForBackupUploadSteadyStateFlow: Flow<BackupUploadState> = flowOf()
|
||||||
|
|
||||||
private var fixRecoveryIssuesFailure: Exception? = null
|
private var fixRecoveryIssuesFailure: Exception? = null
|
||||||
|
private var doesBackupExistOnServerResult: Result<Boolean> = Result.success(true)
|
||||||
|
|
||||||
override suspend fun enableBackups(): Result<Unit> = simulateLongTask {
|
override suspend fun enableBackups(): Result<Unit> = simulateLongTask {
|
||||||
return Result.success(Unit)
|
return Result.success(Unit)
|
||||||
|
|
@ -52,6 +53,14 @@ class FakeEncryptionService : EncryptionService {
|
||||||
return Result.success(Unit)
|
return Result.success(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun givenDoesBackupExistOnServerResult(result: Result<Boolean>) {
|
||||||
|
doesBackupExistOnServerResult = result
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun doesBackupExistOnServer(): Result<Boolean> = simulateLongTask {
|
||||||
|
return doesBackupExistOnServerResult
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1aef9057653b917425621448d0ef62975b02b6cae0e572758a2749ac9cc71189
|
oid sha256:fafe906b308c604f4ef98dab36b55b84fd235598aea738913301940bf4222a93
|
||||||
size 39364
|
size 41473
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1aef9057653b917425621448d0ef62975b02b6cae0e572758a2749ac9cc71189
|
oid sha256:7f395fed6dfabb7f26a10f851e0fca7ea475722e1def7159f36d05cc9e47e09a
|
||||||
size 39364
|
size 47990
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b159c6b39ad05b3d0dc10ae0da1826bcaae45c94e0150b09c2cf6ddf2353d305
|
oid sha256:92ce51c885eb9c5efb80b747ef107e185114401d235bfd261ec06a1bb9f53f85
|
||||||
size 24831
|
size 42518
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1aef9057653b917425621448d0ef62975b02b6cae0e572758a2749ac9cc71189
|
oid sha256:fafe906b308c604f4ef98dab36b55b84fd235598aea738913301940bf4222a93
|
||||||
size 39364
|
size 41473
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:cb83490002e584be9f268eadc014345740d0026c929e79f2bb4c407fdf2ba926
|
oid sha256:3747da81312e3f34da13e6bd530301550c7307856cc7a31aa009be2d60002ecc
|
||||||
size 29777
|
size 26338
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:fafe906b308c604f4ef98dab36b55b84fd235598aea738913301940bf4222a93
|
||||||
|
size 41473
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:083440e0fa8699c8fd370bb13351d04c01fa2c78c273f8e2b07bff0b09e4f2f1
|
||||||
|
size 31938
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:870c36e4f7a64e258af75e22845d05dd8c8217d6dc65826b6405537bed9bc848
|
oid sha256:94869b0aaccbbc1e82fb96de5f71fa7e9a59ba36317213c0f9a6bb4f9448e2b1
|
||||||
size 37439
|
size 39451
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:870c36e4f7a64e258af75e22845d05dd8c8217d6dc65826b6405537bed9bc848
|
oid sha256:0a8411a6c7df7bdc79a526755745fd2b2fed1c32676acd9c9b1135b2391e5abe
|
||||||
size 37439
|
size 45326
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:837be69c85fb1a7f08ac0780ca34a56fa5d4d1f2134b4255efc68a78b33cab65
|
oid sha256:19965ae446d383e69f8f05dc3e3cb1d3956a9962c472d9246b765ae467ef8d56
|
||||||
size 23591
|
size 40318
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:870c36e4f7a64e258af75e22845d05dd8c8217d6dc65826b6405537bed9bc848
|
oid sha256:94869b0aaccbbc1e82fb96de5f71fa7e9a59ba36317213c0f9a6bb4f9448e2b1
|
||||||
size 37439
|
size 39451
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:eda4aab1ded791ad60e417818ad49070c1c53b9c1353da6dd843fae0934459a5
|
oid sha256:14cb5e199172c0b325175e913708fb88111d479af06c1ac2c380a8cd68a80021
|
||||||
size 28387
|
size 25090
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:94869b0aaccbbc1e82fb96de5f71fa7e9a59ba36317213c0f9a6bb4f9448e2b1
|
||||||
|
size 39451
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:59912e13e6cfec021b7c12d689029f159a0b69e91905323f710d47124e67a7ea
|
||||||
|
size 30051
|
||||||
Loading…
Add table
Add a link
Reference in a new issue