Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,11 @@ public void uploadFiles() {
preferences.setLastUploadPath(mUploadPath);

if (resultCode == UriUploader.UriUploaderResultCode.OK) {
finish();
// While content:// URIs are copied to temporary files this Activity has to stay alive, otherwise its
// temporary read permission for those URIs is revoked. onTmpFilesCopied() finishes it once done.
if (!uploader.isTmpCopyInProgress()) {
finish();
}
} else {

int messageResTitle = R.string.uploader_error_title_file_cannot_be_uploaded;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.InputStream
import java.lang.ref.WeakReference

@Suppress("TooGenericExceptionCaught")
Expand All @@ -50,20 +49,8 @@ class CopyAndUploadContentUrisTask(
behaviour: Int,
contentResolver: ContentResolver
) {
val inputStreams: List<InputStream?> = try {
sourceUris.map { contentResolver.openInputStream(it) }
} catch (e: FileNotFoundException) {
Log_OC.e(TAG, "Source file not found", e)
dispatchResult(ResultCode.LOCAL_FILE_NOT_FOUND)
return
} catch (e: SecurityException) {
Log_OC.e(TAG, "Insufficient permissions to open source URIs", e)
dispatchResult(ResultCode.FORBIDDEN)
return
}

scope.launch(Dispatchers.IO) {
val result = performCopy(user, sourceUris, remotePaths, behaviour, contentResolver, inputStreams)
val result = performCopy(user, sourceUris, remotePaths, behaviour, contentResolver)
withContext(Dispatchers.Main) {
dispatchResult(result)
}
Expand All @@ -75,8 +62,7 @@ class CopyAndUploadContentUrisTask(
sourceUris: Array<Uri>,
remotePaths: Array<String>,
behaviour: Int,
contentResolver: ContentResolver,
inputStreams: List<InputStream?>
contentResolver: ContentResolver
): ResultCode {
val localPaths = arrayOfNulls<String>(sourceUris.size)
val resolvedRemotePaths = arrayOfNulls<String>(sourceUris.size)
Expand All @@ -95,7 +81,7 @@ class CopyAndUploadContentUrisTask(
}
Log_OC.d(TAG, "Cache file creation result: ${cacheFile.createNewFile()}")

inputStreams[index]?.use { input ->
contentResolver.openInputStream(uri)?.use { input ->
FileOutputStream(currentTempPath).use { output ->
input.copyTo(output)
}
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/com/owncloud/android/ui/helpers/UriUploader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ class UriUploader @JvmOverloads constructor(
ERROR_SENSITIVE_PATH
}

/**
* True when content:// URIs are being copied to temporary files in the background.
*
* The temporary read permission for those URIs belongs to the calling Activity and is revoked once that Activity is
* destroyed. Callers must therefore stay alive until [OnCopyTmpFilesTaskListener.onTmpFilesCopied] is invoked,
* otherwise opening the URIs fails with a SecurityException.
*/
var isTmpCopyInProgress: Boolean = false
private set

@Suppress("NestedBlockDepth")
fun uploadUris(): UriUploaderResultCode {
var code = UriUploaderResultCode.OK
Expand Down Expand Up @@ -165,6 +175,7 @@ class UriUploader @JvmOverloads constructor(
val taskRetainerFragment =
fm.findFragmentByTag(TaskRetainerFragment.FTAG_TASK_RETAINER_FRAGMENT) as TaskRetainerFragment?
taskRetainerFragment?.setTask(copyTask)
isTmpCopyInProgress = true
copyTask.execute(
user,
sourceUris,
Expand Down
Loading