Store restoreDecision separately in regV5.

This commit is contained in:
Greyson Parrelli
2026-06-25 16:56:22 -04:00
committed by Michelle Tang
parent 2c35a6a3fe
commit e07a3e05bf
22 changed files with 58 additions and 45 deletions
@@ -41,7 +41,6 @@ import org.signal.registration.NetworkController.SessionMetadata
import org.signal.registration.NetworkController.SvrCredentials
import org.signal.registration.NetworkController.UpdateSessionError
import org.signal.registration.proto.ProvisioningData
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.proto.SvrCredential
import org.signal.registration.screens.localbackuprestore.LocalBackupInfo
import org.signal.registration.screens.remotebackuprestore.RemoteBackupRestoreProgress
@@ -543,10 +542,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ
*/
suspend fun setRestoreDecision(decision: RestoreDecision): Unit = withContext(Dispatchers.IO) {
Log.i(TAG, "[setRestoreDecision] Recording restore decision: $decision")
storageController.updateInProgressRegistrationData {
this.restoreDecision = decision
}
storageController.commitRegistrationData()
storageController.setRestoreDecision(decision)
}
suspend fun getPreExistingRegistrationData(): PreExistingRegistrationData? {
@@ -0,0 +1,17 @@
/*
* Copyright 2025 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.signal.registration
/**
* The terminal restore decision the user reached during registration. Mirrors the terminal states of the app's
* RestoreDecisionState. We intentionally do not model the transient pending states (START / INTEND_TO_RESTORE)
* here, as the registration flow performs any restore inline before completing.
*/
enum class RestoreDecision {
NEW_ACCOUNT,
SKIPPED,
COMPLETED
}
@@ -83,6 +83,12 @@ interface StorageController {
*/
suspend fun commitRegistrationData()
/**
* Persists the terminal [RestoreDecision] the user reached during registration directly to permanent app state,
* so the rest of the app knows whether we're a fresh account, skipped a restore, or successfully restored data.
*/
suspend fun setRestoreDecision(decision: RestoreDecision)
/**
* Begins restoring from a V1 (.backup) file identified by the given [uri].
*
@@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.StateFlow
import org.signal.core.util.logging.Log
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationRepository
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
import org.signal.registration.screens.EventDrivenViewModel
class DeviceTransferCompleteViewModel(
@@ -23,7 +23,7 @@ import org.signal.core.util.logging.Log
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationRepository
import org.signal.registration.RegistrationRoute
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
import org.signal.registration.screens.EventDrivenViewModel
import org.signal.registration.screens.util.navigateBack
import org.signal.registration.screens.util.navigateTo
@@ -21,7 +21,7 @@ import org.signal.registration.NetworkController
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationFlowState
import org.signal.registration.RegistrationRepository
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
import org.signal.registration.screens.EventDrivenViewModel
/**
@@ -21,7 +21,7 @@ import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationFlowState
import org.signal.registration.RegistrationRepository
import org.signal.registration.RegistrationRoute
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
import org.signal.registration.screens.EventDrivenViewModel
import org.signal.registration.screens.util.navigateTo
@@ -23,7 +23,7 @@ import org.signal.libsignal.net.RequestResult
import org.signal.registration.NetworkController
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationRepository
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
import org.signal.registration.screens.EventDrivenViewModel
import org.signal.registration.screens.util.navigateBack
import kotlin.coroutines.CoroutineContext
@@ -23,7 +23,7 @@ import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationFlowState
import org.signal.registration.RegistrationRepository
import org.signal.registration.RegistrationRoute
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
import org.signal.registration.screens.EventDrivenViewModel
import org.signal.registration.screens.util.navigateTo
@@ -52,20 +52,6 @@ message RegistrationData {
// JSON-serialized flow state snapshot (from saveFlowState/restoreFlowState)
string flowStateJson = 21;
// The terminal restore decision the user reached during this flow. The app translates this into its own
// RestoreDecisionState when committing, so the rest of the app knows whether we're a fresh account, skipped a
// restore, or successfully restored data.
RestoreDecision restoreDecision = 25;
}
// Mirrors the terminal states of the app's RestoreDecisionState. We intentionally do not model the transient
// pending states (START / INTEND_TO_RESTORE) here, as the new flow performs any restore inline before completing.
enum RestoreDecision {
UNSET = 0;
NEW_ACCOUNT = 1;
SKIPPED = 2;
COMPLETED = 3;
}
message SvrCredential {
@@ -18,7 +18,7 @@ import org.junit.Before
import org.junit.Test
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationRepository
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
@OptIn(ExperimentalCoroutinesApi::class)
class DeviceTransferCompleteViewModelTest {
@@ -33,7 +33,7 @@ import org.signal.core.ui.navigation.ResultEventBus
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationRepository
import org.signal.registration.RegistrationRoute
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
import java.time.LocalDateTime
@OptIn(ExperimentalCoroutinesApi::class)
@@ -33,7 +33,7 @@ import org.signal.registration.NetworkController
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationFlowState
import org.signal.registration.RegistrationRepository
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
@OptIn(ExperimentalCoroutinesApi::class)
class PinCreationViewModelTest {
@@ -24,7 +24,7 @@ import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationFlowState
import org.signal.registration.RegistrationRepository
import org.signal.registration.RegistrationRoute
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
class PinEntryForSvrRestoreViewModelTest {
@@ -30,7 +30,7 @@ import org.signal.libsignal.net.RequestResult
import org.signal.registration.NetworkController
import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationRepository
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
@OptIn(ExperimentalCoroutinesApi::class)
class RemoteBackupRestoreViewModelTest {
@@ -23,7 +23,7 @@ import org.signal.registration.RegistrationFlowEvent
import org.signal.registration.RegistrationFlowState
import org.signal.registration.RegistrationRepository
import org.signal.registration.RegistrationRoute
import org.signal.registration.proto.RestoreDecision
import org.signal.registration.RestoreDecision
class ArchiveRestoreSelectionViewModelTest {