Skip to content
Open
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 @@ -44,6 +44,7 @@ import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.lib.resources.status.OCCapability
import com.owncloud.android.operations.UploadFileOperation
import com.owncloud.android.ui.activity.SettingsActivity
import com.owncloud.android.utils.PermissionUtil
import com.owncloud.android.utils.theme.CapabilityUtils
import com.owncloud.android.utils.theme.ViewThemeUtils
import kotlinx.coroutines.Dispatchers
Expand All @@ -53,6 +54,7 @@ import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext
import java.io.File
import kotlin.coroutines.cancellation.CancellationException
import kotlin.time.Duration.Companion.milliseconds

@Suppress("LongParameterList", "TooManyFunctions", "TooGenericExceptionCaught")
class AutoUploadWorker(
Expand Down Expand Up @@ -94,6 +96,13 @@ class AutoUploadWorker(

Log_OC.d(TAG, syncedFolder.getLog())

if (!PermissionUtil.checkStoragePermission(context)) {
Log_OC.w(
TAG,
"⚠️ storage/media permission missing or partial — MediaStore scan may return no files"
)
}

if (canExitEarly(syncFolderId)) {
return Result.success()
}
Expand Down Expand Up @@ -274,7 +283,7 @@ class AutoUploadWorker(
filePathsWithIds.forEachIndexed { batchIndex, (path, id) ->
ensureActive()

delay(retryPolicy.getDelay())
delay(retryPolicy.getDelay().milliseconds)

val file = File(path)
val localPath = file.absolutePath
Expand Down Expand Up @@ -308,8 +317,8 @@ class AutoUploadWorker(
val operation = createUploadFileOperation(upload, user)
Log_OC.d(TAG, "🕒 uploading: $localPath, id: $generatedId")

val result = operation.execute(client)
fileUploadEventBroadcaster.sendUploadStarted(operation, context)
val result = operation.execute(client)

UploadErrorNotificationManager.handleResult(
context,
Expand All @@ -330,7 +339,6 @@ class AutoUploadWorker(
"❌ upload failed $localPath (${upload.accountName}): ${result.logMessage}"
)

// Mark CONFLICT files as handled to prevent retries
if (result.code.isConflict()) {
repository.markFileAsHandled(localPath, syncedFolder)
Log_OC.w(TAG, "Marked CONFLICT file as handled: $localPath")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.nextcloud.client.jobs.autoUpload

import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
Expand Down Expand Up @@ -142,38 +143,32 @@ class FileSystemRepository(
null
)

cursor?.use {
val idxData = cursor.getColumnIndex(MediaStore.MediaColumns.DATA)
val idxModified = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED)
val idxAdded = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED)
if (cursor == null) {
Log_OC.w(TAG, "MediaStore query returned null (missing permission or unavailable provider): $uri")
return
}

if (idxData == -1) {
Log_OC.e(TAG, "MediaStore column DATA missing — cannot process URI: $uri")
return
}
cursor.use { insertFromCursor(it, uri, syncedFolder, checkFileType) }
}

while (cursor.moveToNext()) {
val filePath = cursor.getString(idxData)
private fun insertFromCursor(cursor: Cursor, uri: Uri, syncedFolder: SyncedFolder, checkFileType: Boolean) {
val idxData = cursor.getColumnIndex(MediaStore.MediaColumns.DATA)
val idxModified = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED)
val idxAdded = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED)

val lastModifiedMs = if (idxModified != -1) {
cursor.getLong(idxModified) * 1000
} else {
null
}
if (idxData == -1) {
Log_OC.e(TAG, "MediaStore column DATA missing — cannot process URI: $uri")
return
}

val creationTimeMs = if (idxAdded != -1) {
cursor.getLong(idxAdded) * 1000
} else {
null
}
while (cursor.moveToNext()) {
val filePath = cursor.getString(idxData)
val lastModifiedMs = if (idxModified != -1) cursor.getLong(idxModified) * 1000 else null
val creationTimeMs = if (idxAdded != -1) cursor.getLong(idxAdded) * 1000 else null

Log_OC.d(
TAG,
"Found file: $filePath (created=$creationTimeMs, modified=$lastModifiedMs)"
)
Log_OC.d(TAG, "Found file: $filePath (created=$creationTimeMs, modified=$lastModifiedMs)")

insertOrReplace(filePath, lastModifiedMs, creationTimeMs, syncedFolder, checkFileType)
}
insertOrReplace(filePath, lastModifiedMs, creationTimeMs, syncedFolder, checkFileType)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ fun UploadResult.isNonRetryable(): Boolean = when (this) {
UploadResult.PRIVILEGES_ERROR,
UploadResult.CREDENTIAL_ERROR,

// most cases covered and mapped from RemoteOperationResult. Most likely UploadResult.UNKNOWN this error will
// occur again
UploadResult.UNKNOWN,

// user's choice
UploadResult.CANCELLED -> true

Expand Down
Loading