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 @@ -104,6 +104,14 @@ class AlbumFileUploadWorker(
}
}

fun pauseActiveUploads() {
activeOperations.values.forEach {
Log_OC.d(TAG, "upload operation is paused: ${it.remotePath}")
it.pause()
}
activeOperations.clear()
}

fun getCurrentUpload(id: Long?): UploadFileOperation? = activeOperations[id]

fun isUploading(remotePath: String?, accountName: String?): Boolean = activeOperations.values.any {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.utils.ForegroundServiceHelper
import com.nextcloud.utils.extensions.getPercent
import com.nextcloud.utils.extensions.isNonRetryable
import com.nextcloud.utils.extensions.isUserCancellation
import com.nextcloud.utils.extensions.toFile
import com.owncloud.android.R
import com.owncloud.android.datamodel.ForegroundServiceType
Expand Down Expand Up @@ -119,6 +120,14 @@ class FileUploadWorker(
}
}

fun pauseActiveUploads() {
activeOperations.values.forEach {
Log_OC.d(TAG, "upload operation is paused: ${it.remotePath}")
it.pause()
}
activeOperations.clear()
}

fun getCurrentUpload(id: Long?): UploadFileOperation? = activeOperations[id]

fun isUploading(remotePath: String?, accountName: String?): Boolean = activeOperations.values.any {
Expand Down Expand Up @@ -290,6 +299,11 @@ class FileUploadWorker(
continue
}

if (isUploading(upload.remotePath, accountName)) {
Log_OC.d(TAG, "skipping upload, another worker is still transferring it: ${upload.remotePath}")
continue
}

delay(retryPolicy.getDelay().milliseconds)

if (!skipAutoUploadCheck && isBelongToAnySyncedFolder(upload, syncFolderHelper, syncedFolders)) {
Expand Down Expand Up @@ -339,11 +353,9 @@ class FileUploadWorker(
break
}

// check upload result for worker
val uploadResult = UploadResult.fromOperationResult(result)
if (!result.isSuccess) {
if (!result.isSuccess && !result.code.isUserCancellation()) {
Log_OC.e(TAG, "upload failed for ${upload.remotePath}: ${result.code}")
if (uploadResult.isNonRetryable()) {
if (UploadResult.fromOperationResult(result).isNonRetryable()) {
hasNonRetryableFailure = true
} else {
hasRetryableFailure = true
Expand All @@ -368,7 +380,7 @@ class FileUploadWorker(
}

private fun skip(upload: OCUpload): Boolean = when (upload.uploadStatus) {
UploadStatus.UPLOAD_SUCCEEDED -> true
UploadStatus.UPLOAD_SUCCEEDED, UploadStatus.UPLOAD_CANCELLED -> true
UploadStatus.UPLOAD_FAILED -> upload.lastResult.isNonRetryable()
else -> false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ fun ResultCode.isFileSpecificError(): Boolean {
return !generalErrorCodes.contains(this)
}

fun ResultCode.isUserCancellation(): Boolean = this == ResultCode.CANCELLED || this == ResultCode.USER_CANCELLED

fun ResultCode.isConflict(): Boolean {
val errorCodes = listOf(
ResultCode.SYNC_CONFLICT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.utils.autoRename.AutoRename
import com.nextcloud.utils.extensions.isConflict
import com.nextcloud.utils.extensions.isUserCancellation
import com.owncloud.android.MainApp
import com.owncloud.android.db.OCUpload
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
Expand Down Expand Up @@ -211,19 +212,6 @@ class UploadsStorageManager(
return result
}

private fun removeUpload(accountName: String?, remotePath: String?): Int {
val result = contentResolver.delete(
ProviderTableMeta.CONTENT_URI_UPLOADS,
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=? AND " + ProviderTableMeta.UPLOADS_REMOTE_PATH + "=?",
arrayOf(accountName, remotePath)
)
Log_OC.d(TAG, "delete returns $result for file $remotePath in $accountName")
if (result > 0) {
notifyObserversNow()
}
return result
}

fun removeUploads(accountName: String?): Int {
val result = contentResolver.delete(
ProviderTableMeta.CONTENT_URI_UPLOADS,
Expand Down Expand Up @@ -476,9 +464,8 @@ class UploadsStorageManager(
fun updateDatabaseUploadResult(uploadResult: RemoteOperationResult<*>, upload: UploadFileOperation) {
Log_OC.d(TAG, "updateDatabaseUploadResult uploadResult: $uploadResult upload: $upload")

if (uploadResult.isCancelled) {
Log_OC.w(TAG, "upload is cancelled, removing upload")
removeUpload(upload.user.accountName, upload.remotePath)
if (upload.isPaused) {
Log_OC.d(TAG, "upload is paused, keeping it queued: ${upload.remotePath}")
return
}

Expand All @@ -492,7 +479,10 @@ class UploadsStorageManager(
var result = UploadResult.fromOperationResult(uploadResult)
val code = uploadResult.code

if (uploadResult.isSuccess) {
if (code.isUserCancellation()) {
status = UploadStatus.UPLOAD_CANCELLED
result = UploadResult.CANCELLED
} else if (uploadResult.isSuccess) {
status = UploadStatus.UPLOAD_SUCCEEDED
result = if (upload.wasSkipped()) UploadResult.SKIPPED else UploadResult.UPLOADED
} else if (code.isConflict()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public static UploadResult fromOperationResult(RemoteOperationResult result) {
case OLD_ANDROID_API -> OLD_ANDROID_API;
case SYNC_CONFLICT -> SYNC_CONFLICT;
case FORBIDDEN -> PRIVILEGES_ERROR;
case CANCELLED -> CANCELLED;
case CANCELLED, USER_CANCELLED -> CANCELLED;
case DELAYED_FOR_WIFI -> DELAYED_FOR_WIFI;
case DELAYED_FOR_CHARGING -> DELAYED_FOR_CHARGING;
case DELAYED_IN_POWER_SAVE_MODE -> DELAYED_IN_POWER_SAVE_MODE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ public class UploadFileOperation extends SyncOperation {

private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
private final AtomicBoolean mUploadStarted = new AtomicBoolean(false);
private final AtomicBoolean mPaused = new AtomicBoolean(false);

private Context mContext;

Expand Down Expand Up @@ -448,6 +449,7 @@ protected RemoteOperationResult run(OwnCloudClient client) {
}

mCancellationRequested.set(false);
mPaused.set(false);
mUploadStarted.set(true);

updateSize(0);
Expand Down Expand Up @@ -1591,6 +1593,15 @@ public void cancel(ResultCode cancellationReason) {
}
}

public void pause() {
mPaused.set(true);
cancel(ResultCode.USER_CANCELLED);
}

public boolean isPaused() {
return mPaused.get();
}

/**
* As soon as this method return true, upload can be cancel via cancel().
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import com.google.android.material.snackbar.Snackbar
import com.nextcloud.client.account.User
import com.nextcloud.client.core.Clock
import com.nextcloud.client.device.PowerManagementService
import com.nextcloud.client.jobs.upload.AlbumFileUploadWorker
import com.nextcloud.client.jobs.upload.FileUploadEventBroadcaster
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.jobs.utils.UploadErrorNotificationManager
import com.nextcloud.client.utils.Throttler
import com.nextcloud.ui.component.UploadWarningCard
Expand Down Expand Up @@ -237,8 +239,15 @@ class UploadListActivity :

@SuppressLint("NotifyDataSetChanged")
private fun toggleGlobalPause(item: MenuItem) {
preferences.setGlobalUploadPaused(!preferences.isGlobalUploadPaused())
val paused = !preferences.isGlobalUploadPaused()
preferences.setGlobalUploadPaused(paused)
updateGlobalPauseIcon(item)

if (paused) {
FileUploadWorker.pauseActiveUploads()
AlbumFileUploadWorker.pauseActiveUploads()
}

val uploadHelper = FileUploadHelper.instance()
accountManager.getAllUsers().filterNotNull().forEach { user ->
val ids = uploadsStorageManager.getCurrentUploadIds(user.accountName)
Expand Down
Loading