diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt index fa4d6d5024..d4dbffcb48 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt index 08bdd57262..59b796c828 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt @@ -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 } }