Persist regV5 scratch data with BlobProvider.

This commit is contained in:
Greyson Parrelli
2026-07-06 16:14:20 -04:00
parent 184e0bc3c2
commit bdbe69c7b0
2 changed files with 24 additions and 11 deletions
@@ -23,6 +23,7 @@ class RegistrationValues internal constructor(store: KeyValueStore) : SignalStor
private const val RESTORE_BACKUP_MEDIA_SIZE = "registration.restore_backup_media_size"
private const val IS_OTHER_DEVICE_ANDROID = "registration.is_other_device_android"
private const val RESTORING_ON_NEW_DEVICE = "registration.restoring_on_new_device"
private const val IN_PROGRESS_DATA_BLOB_URI = "registration.in_progress_data_blob_uri"
@VisibleForTesting
const val RESTORE_DECISION_STATE = "registration.restore_decision_state.2"
@@ -81,6 +82,9 @@ class RegistrationValues internal constructor(store: KeyValueStore) : SignalStor
var sessionId: String? by stringValue(SESSION_ID, null)
var sessionE164: String? by stringValue(SESSION_E164, null)
/** URI of the encrypted [org.signal.core.util.contentproviders.BlobProvider] blob holding the in-progress registration data, if any. */
var inProgressRegistrationDataBlobUri: String? by stringValue(IN_PROGRESS_DATA_BLOB_URI, null)
var isOtherDeviceAndroid: Boolean by booleanValue(IS_OTHER_DEVICE_ANDROID, false)
var restoreMethodToken: String? by stringValue(RESTORE_METHOD_TOKEN, null)
var restoreBackupMediaSize: Long by longValue(RESTORE_BACKUP_MEDIA_SIZE, 0L)
@@ -7,6 +7,7 @@ package org.thoughtcrime.securesms.registration.v2
import android.content.Context
import android.net.Uri
import androidx.core.net.toUri
import androidx.documentfile.provider.DocumentFile
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
@@ -51,6 +52,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.databaseprotos.LinkedDeviceInfo
import org.thoughtcrime.securesms.database.model.databaseprotos.LocalRegistrationMetadata
import org.thoughtcrime.securesms.database.model.databaseprotos.RestoreDecisionState
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.keyvalue.Completed
import org.thoughtcrime.securesms.keyvalue.NewAccount
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
@@ -108,6 +110,10 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo
}
override suspend fun clearAllData() = withContext(Dispatchers.IO) {
SignalStore.registration.inProgressRegistrationDataBlobUri?.toUri()?.let { AppDependencies.blobs.delete(context, it) }
SignalStore.registration.inProgressRegistrationDataBlobUri = null
// Best-effort cleanup of the legacy plaintext file written by older builds.
File(context.cacheDir, TEMP_PROTO_FILENAME).takeIf { it.exists() }?.delete()
Unit
}
@@ -151,15 +157,11 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo
}
override suspend fun readInProgressRegistrationData(): RegistrationData = withContext(Dispatchers.IO) {
val file = File(context.cacheDir, TEMP_PROTO_FILENAME)
if (file.exists()) {
try {
RegistrationData.ADAPTER.decode(file.readBytes())
} catch (e: Exception) {
Log.w(TAG, "Failed to decode registration data, returning empty.", e)
RegistrationData()
}
} else {
val uri = SignalStore.registration.inProgressRegistrationDataBlobUri?.toUri() ?: return@withContext RegistrationData()
try {
AppDependencies.blobs.getStream(context, uri).use { RegistrationData.ADAPTER.decode(it) }
} catch (e: Exception) {
Log.w(TAG, "Failed to read/decode in-progress registration data, returning empty.", e)
RegistrationData()
}
}
@@ -529,7 +531,14 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo
private suspend fun writeRegistrationData(data: RegistrationData) = withContext(Dispatchers.IO) {
val stamped = data.newBuilder().lastUpdatedMillis(System.currentTimeMillis()).build()
val file = File(context.cacheDir, TEMP_PROTO_FILENAME)
file.writeBytes(RegistrationData.ADAPTER.encode(stamped))
val previousUri = SignalStore.registration.inProgressRegistrationDataBlobUri?.toUri()
val newUri = AppDependencies.blobs
.forData(RegistrationData.ADAPTER.encode(stamped))
.createForMultipleSessionsOnDisk(context)
SignalStore.registration.inProgressRegistrationDataBlobUri = newUri.toString()
previousUri?.let { AppDependencies.blobs.delete(context, it) }
Unit
}
}