diff --git a/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/DefaultOnSharedData.kt b/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/DefaultOnSharedData.kt index 3a71f02dc3..b3ae822790 100644 --- a/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/DefaultOnSharedData.kt +++ b/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/DefaultOnSharedData.kt @@ -7,6 +7,7 @@ package io.element.android.features.share.impl +import android.content.ContentResolver import android.content.Context import android.content.Intent import android.net.Uri @@ -15,13 +16,14 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import io.element.android.features.share.api.OnSharedData import io.element.android.features.share.api.ShareIntentData +import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.di.annotations.ApplicationContext import timber.log.Timber -import kotlin.collections.forEach @ContributesBinding(AppScope::class) class DefaultOnSharedData( @ApplicationContext private val context: Context, + private val buildMeta: BuildMeta, ) : OnSharedData { override fun invoke(data: ShareIntentData) { when (data) { @@ -29,6 +31,13 @@ class DefaultOnSharedData( // No-op, there is nothing to do for plain text intents. } is ShareIntentData.Uris -> { + val fileProvider = "${buildMeta.applicationId}.fileprovider" + for (sharedUri in data.uris) { + // Remove the local copy of the shared file, as it is not needed anymore + if (sharedUri.uri.scheme == ContentResolver.SCHEME_CONTENT && sharedUri.uri.host == fileProvider) { + context.contentResolver.delete(sharedUri.uri, null) + } + } revokeUriPermissions(data.uris.map { it.uri }) } } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/AndroidLocalMediaActions.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/AndroidLocalMediaActions.kt index c7a01ea494..071e0dba64 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/AndroidLocalMediaActions.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/AndroidLocalMediaActions.kt @@ -100,7 +100,11 @@ class AndroidLocalMediaActions( override suspend fun share(localMedia: LocalMedia): Result = withContext(coroutineDispatchers.io) { require(localMedia.uri.scheme == ContentResolver.SCHEME_FILE) runCatchingExceptions { - val shareableUri = localMedia.toShareableUri() + // Make a copy of the shared file in the cache directory, otherwise the original file will be gone once this screen is dismissed + // and will prevent sharing the media to another room inside the app. + val copiedFile = localMedia.uri.toFile() + .copyTo(File(context.cacheDir, "temp/media/" + (localMedia.uri.lastPathSegment ?: "shared_file")), true) + val shareableUri = copiedFile.toShareableUri() val shareMediaIntent = Intent(Intent.ACTION_SEND) .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) .putExtra(Intent.EXTRA_STREAM, shareableUri) @@ -157,10 +161,13 @@ class AndroidLocalMediaActions( } } - private fun LocalMedia.toShareableUri(): Uri { - val mediaAsFile = this.toFile() + private fun File.toShareableUri(): Uri { val authority = "${buildMeta.applicationId}.fileprovider" - return FileProvider.getUriForFile(context, authority, mediaAsFile).normalizeScheme() + return FileProvider.getUriForFile(context, authority, this).normalizeScheme() + } + + private fun LocalMedia.toShareableUri(): Uri { + return this.toFile().toShareableUri() } @RequiresApi(Build.VERSION_CODES.Q)