From 2dde0b43b805d7b566118a5c9c4fafb77a75b027 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 14 Jul 2026 15:43:49 -0400 Subject: [PATCH] Take a persistent URI permission for local backups in regV5. --- .../securesms/jobs/RestoreLocalAttachmentJob.kt | 4 ++++ .../v2/AppRegistrationStorageController.kt | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt index 0f8ae42d0e..ab3acb7305 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt @@ -186,6 +186,10 @@ class RestoreLocalAttachmentJob private constructor( } catch (e: IOException) { Log.w(TAG, "Experienced an exception while trying to read attachment.", e) return Result.retry(defaultBackoff()) + } catch (e: SecurityException) { + Log.w(TAG, "Lost access to the backup directory. Unable to restore attachment.", e) + SignalStore.backup.localRestoreDirectoryError = true + return Result.failure() } return Result.success() 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 c8d9ad5b1d..906cd19baf 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 @@ -402,8 +402,6 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo // Skip it if the folder is the SignalBackups directory itself, since it can't be reused as a destination. val archiveFileSystem = ArchiveFileSystem.openForRestore(context, rootUri) if (archiveFileSystem != null && !archiveFileSystem.isRootedAtSignalBackups) { - val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION - context.contentResolver.takePersistableUriPermission(rootUri, takeFlags) SignalStore.backup.newLocalBackupsDirectory = rootUri.toString() SignalStore.backup.newLocalBackupsEnabled = true LocalBackupListener.setNextBackupTimeToIntervalFromNow(context) @@ -436,6 +434,15 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo } override suspend fun scanLocalBackupFolder(folderUri: Uri): List = withContext(Dispatchers.IO) { + // Persist access immediately, while the picker's transient grant is still alive. Restore jobs read from this + // folder long after the registration activity (and its grant) are gone. + try { + val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION + context.contentResolver.takePersistableUriPermission(folderUri, takeFlags) + } catch (e: SecurityException) { + Log.w(TAG, "Unable to take persistable permission for backup folder", e) + } + val folder = DocumentFile.fromTreeUri(context, folderUri) ?: return@withContext emptyList() val children = folder.listFiles()