From a892aa6deee67651e8ff65a522175db2866f1864 Mon Sep 17 00:00:00 2001 From: Ritika Pahwa <83745993+RitikaPahwa4444@users.noreply.github.com> Date: Tue, 19 Aug 2025 21:16:02 +0530 Subject: [PATCH] 6357: Fix java.lang.SecurityException for multi-uploads (#6402) * Fix java.lang.SecurityException for ACTION_OPEN_DOCUMENT * Handle SecurityException in case of multi-upload * Remove unused import * Clean up code * Clean up code * Handle SecurityException for other upload methods * Release persisted URI permissions for successful uploads * Remove persistable permission for custom picker as it's not required * Remove persistable permission for in-app camera as it's not required --- .../free/nrw/commons/filepicker/FilePicker.kt | 18 ++++++++++++++---- .../nrw/commons/upload/worker/UploadWorker.kt | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt b/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt index bb0a371e1..a7e3a671d 100644 --- a/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt +++ b/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt @@ -296,10 +296,19 @@ object FilePicker : Constants { * https://github.com/commons-app/apps-android-commons/issues/6357 */ private fun takePersistableUriPermissions(context: Context, result: ActivityResult) { - result.data?.data?.also { uri -> - val takeFlags: Int = (Intent.FLAG_GRANT_READ_URI_PERMISSION - or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) - context.contentResolver.takePersistableUriPermission(uri, takeFlags) + result.data?.let { intentData -> + val takeFlags: Int = (Intent.FLAG_GRANT_READ_URI_PERMISSION) + // Persist the URI permission for all URIs in the clip data + // if multiple images are selected, + // or for the single URI if only one image is selected + intentData.clipData?.let { clipData -> + for (i in 0 until clipData.itemCount) { + context.contentResolver.takePersistableUriPermission( + clipData.getItemAt(i).uri, takeFlags) + } + } ?: intentData.data?.let { uri -> + context.contentResolver.takePersistableUriPermission(uri, takeFlags) + } } } @@ -358,6 +367,7 @@ object FilePicker : Constants { callbacks: Callbacks ) { if (result.resultCode == Activity.RESULT_OK && !isPhoto(result.data)) { + takePersistableUriPermissions(activity, result) try { val files = getFilesFromGalleryPictures(result.data, activity) callbacks.onImagesPicked(files, ImageSource.GALLERY, restoreType(activity)) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt index c8a1d9b98..21db20f1b 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt @@ -393,6 +393,12 @@ class UploadWorker( makeWikiDataEdit(uploadResult, contribution) } showSuccessNotification(contribution) + if (appContext.contentResolver.persistedUriPermissions.any { + it.uri == contribution.contentUri }) { + appContext.contentResolver.releasePersistableUriPermission( + contribution.contentUri!!, Intent.FLAG_GRANT_READ_URI_PERMISSION + ) + } } else { Timber.e("Stash Upload failed") showFailedNotification(contribution)