From b0eb4a4c40e4750d03301ee2a08a9979de03fcb1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 5 Jul 2022 15:50:39 +0200 Subject: [PATCH 01/38] Created new TransferStatus in domain layer --- .../domain/transfers/model/TransferStatus.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferStatus.kt diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferStatus.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferStatus.kt new file mode 100644 index 00000000000..3d6ef56fd98 --- /dev/null +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferStatus.kt @@ -0,0 +1,38 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.domain.transfers.model + +enum class TransferStatus constructor(val value: Int) { + TRANSFER_QUEUED(value = 0), + TRANSFER_IN_PROGRESS(value = 1), + TRANSFER_FAILED(value = 2), + TRANSFER_SUCCEEDED(value = 3); + + companion object { + fun fromValue(value: Int): TransferStatus = + when (value) { + 0 -> TRANSFER_QUEUED + 1 -> TRANSFER_IN_PROGRESS + 2 -> TRANSFER_FAILED + else -> TRANSFER_SUCCEEDED + } + } +} From 3de8f7e413af0cd3c349f99f35bb3a66fc783725 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 5 Jul 2022 16:33:26 +0200 Subject: [PATCH 02/38] Created TransferResult in domain layer --- .../domain/transfers/model/TransferResult.kt | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt new file mode 100644 index 00000000000..9127b19edc5 --- /dev/null +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt @@ -0,0 +1,66 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.domain.transfers.model + +enum class TransferResult constructor(val value: Int) { + UNKNOWN(value = -1), + UPLOADED(value = 0), + NETWORK_CONNECTION(value = 1), + CREDENTIAL_ERROR(value = 2), + FOLDER_ERROR(value = 3), + CONFLICT_ERROR(value = 4), + FILE_ERROR(value = 5), + PRIVILEGES_ERROR(value = 6), + CANCELLED(value = 7), + FILE_NOT_FOUND(value = 8), + DELAYED_FOR_WIFI(value = 9), + SERVICE_INTERRUPTED(value = 10), + SERVICE_UNAVAILABLE(value = 11), + QUOTA_EXCEEDED(value = 12), + SSL_RECOVERABLE_PEER_UNVERIFIED(value = 13), + SPECIFIC_FORBIDDEN(value = 14), + SPECIFIC_SERVICE_UNAVAILABLE(value = 15), + SPECIFIC_UNSUPPORTED_MEDIA_TYPE(value = 16); + + companion object { + fun fromValue(value: Int): TransferResult = + when (value) { + 0 -> UPLOADED + 1 -> NETWORK_CONNECTION + 2 -> CREDENTIAL_ERROR + 3 -> FOLDER_ERROR + 4 -> CONFLICT_ERROR + 5 -> FILE_ERROR + 6 -> PRIVILEGES_ERROR + 7 -> CANCELLED + 8 -> FILE_NOT_FOUND + 9 -> DELAYED_FOR_WIFI + 10 -> SERVICE_INTERRUPTED + 11 -> SERVICE_UNAVAILABLE + 12 -> QUOTA_EXCEEDED + 13 -> SSL_RECOVERABLE_PEER_UNVERIFIED + 14 -> SPECIFIC_FORBIDDEN + 15 -> SPECIFIC_SERVICE_UNAVAILABLE + 16 -> SPECIFIC_UNSUPPORTED_MEDIA_TYPE + else -> UNKNOWN + } + } +} From a19b4b4d90d3d5ad0ba64994f91d02fc188f0323 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 5 Jul 2022 17:33:28 +0200 Subject: [PATCH 03/38] Created OCTransfer in domain layer --- .../domain/transfers/model/OCTransfer.kt | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt new file mode 100644 index 00000000000..3d3a5469189 --- /dev/null +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt @@ -0,0 +1,46 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.domain.transfers.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize +import java.io.File + +@Parcelize +data class OCTransfer( + var id: Long? = null, + val localPath: String, + val remotePath: String, + val accountName: String, + val fileSize: Long, + val status: TransferStatus, + val localBehaviour: Int, + val forceOverwrite: Boolean, + val transferEndTimestamp: Long? = null, + val lastResult: TransferResult? = null, + val createdBy: Int, + val transferId: String? = null +) : Parcelable { + init { + if (!remotePath.startsWith(File.separator)) throw IllegalArgumentException("Remote path must be an absolute path in the local file system") + if (accountName.isEmpty()) throw IllegalArgumentException("Invalid account name") + } +} From fad99d376a0e9e800482e08e11e44b6feb8753e5 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 6 Jul 2022 13:51:47 +0200 Subject: [PATCH 04/38] Created TransferRepository interface in domain layer --- .../domain/transfers/TransferRepository.kt | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt new file mode 100644 index 00000000000..eee7301edc8 --- /dev/null +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt @@ -0,0 +1,42 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.domain.transfers + +import android.database.Cursor +import com.owncloud.android.domain.files.model.OCFile +import com.owncloud.android.domain.transfers.model.OCTransfer + +interface TransferRepository { + fun storeTransfer(transfer: OCTransfer): Long + fun updateTransfer(transfer: OCTransfer) + fun removeTransfer(transfer: OCTransfer) + fun removeAllTransfersFromAccount(accountName: String) + fun getTransfers(selection: String, selectionArgs: Array, sortOrder: String): Array + fun getAllTransfers(): Array + fun getLastTransferFor(file: OCFile, accountName: String): OCTransfer + fun createTransferFromCursor(cursor: Cursor): OCTransfer + fun getCurrentAndPendingTransfers(): Array + fun getFailedTransfers(): Array + fun getFinishedTransfers(): Array + fun getFailedButNotDelayedByWifiTransfers(): Array + fun clearFailedButNotDelayedByWifiTransfers() + fun clearSuccessfulTransfers() +} From 6ba77ae05db2851c3e30f2112834026a2e4f8ff9 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 6 Jul 2022 14:42:24 +0200 Subject: [PATCH 05/38] Created OCTransferEntity in data layer --- .../owncloud/android/data/ProviderMeta.java | 1 + .../data/transfers/db/OCTransferEntity.kt | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 owncloudData/src/main/java/com/owncloud/android/data/transfers/db/OCTransferEntity.kt diff --git a/owncloudData/src/main/java/com/owncloud/android/data/ProviderMeta.java b/owncloudData/src/main/java/com/owncloud/android/data/ProviderMeta.java index 151c93ea176..f4fe04c35c6 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/ProviderMeta.java +++ b/owncloudData/src/main/java/com/owncloud/android/data/ProviderMeta.java @@ -42,6 +42,7 @@ static public class ProviderTableMeta implements BaseColumns { public static final String FILES_TABLE_NAME = "files"; public static final String USER_QUOTAS_TABLE_NAME = "user_quotas"; public static final String FOLDER_BACKUP_TABLE_NAME = "folder_backup"; + public static final String TRANSFERS_TABLE_NAME = "transfers"; // Columns of ocshares table public static final String OCSHARES_SHARE_TYPE = "share_type"; diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/OCTransferEntity.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/OCTransferEntity.kt new file mode 100644 index 00000000000..f2fc9c2f927 --- /dev/null +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/OCTransferEntity.kt @@ -0,0 +1,45 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.data.transfers.db + +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.owncloud.android.data.ProviderMeta.ProviderTableMeta.TRANSFERS_TABLE_NAME + +@Entity( + tableName = TRANSFERS_TABLE_NAME +) +data class OCTransferEntity( + val localPath: String, + val remotePath: String, + val accountName: String, + val fileSize: Long, + val status: Int, + val localBehaviour: Int, + val forceOverwrite: Boolean, + val transferEndTimestamp: Long? = null, + val lastResult: Int? = null, + val createdBy: Int, + val transferId: String? = null +) { + @PrimaryKey(autoGenerate = true) + var id: Long = 0 +} From 76cff8c72cbd97e37a1362f85a35bfd980c8c3f0 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 6 Jul 2022 18:19:13 +0200 Subject: [PATCH 06/38] Created TransferDao in data layer --- .../android/data/transfers/db/TransferDao.kt | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt new file mode 100644 index 00000000000..ae515c7782d --- /dev/null +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt @@ -0,0 +1,51 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.data.transfers.db + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.owncloud.android.data.ProviderMeta.ProviderTableMeta.TRANSFERS_TABLE_NAME +import com.owncloud.android.data.files.db.OCFileEntity + +@Dao +abstract class TransferDao { + @Query(SELECT_TRANSFER_WITH_ID) + abstract fun getFileById(id: Long): OCFileEntity? + + @Insert(onConflict = OnConflictStrategy.REPLACE) + abstract fun insert(ocTransferEntity: OCTransferEntity): Long + + @Query(DELETE_TRANSFER_WITH_ID) + abstract fun deleteTransferWithId(id: Long) + + companion object { + private const val SELECT_TRANSFER_WITH_ID = + "SELECT * " + + "FROM $TRANSFERS_TABLE_NAME " + + "WHERE id = :id" + + private const val DELETE_TRANSFER_WITH_ID = + "DELETE FROM $TRANSFERS_TABLE_NAME " + + "WHERE id = :id" + } +} From c461441f595ca8c7d90cdba8fc9fd3ee046ae4db Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Thu, 7 Jul 2022 08:59:03 +0200 Subject: [PATCH 07/38] Removed unnecessary methods from TransferRepository --- .../owncloud/android/domain/transfers/TransferRepository.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt index eee7301edc8..95f371c62cb 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt @@ -20,7 +20,6 @@ package com.owncloud.android.domain.transfers -import android.database.Cursor import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.domain.transfers.model.OCTransfer @@ -29,10 +28,8 @@ interface TransferRepository { fun updateTransfer(transfer: OCTransfer) fun removeTransfer(transfer: OCTransfer) fun removeAllTransfersFromAccount(accountName: String) - fun getTransfers(selection: String, selectionArgs: Array, sortOrder: String): Array fun getAllTransfers(): Array fun getLastTransferFor(file: OCFile, accountName: String): OCTransfer - fun createTransferFromCursor(cursor: Cursor): OCTransfer fun getCurrentAndPendingTransfers(): Array fun getFailedTransfers(): Array fun getFinishedTransfers(): Array From 0d3eafa13b2c6f2c8464c9321bc12fa0cedae00e Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Thu, 7 Jul 2022 09:09:03 +0200 Subject: [PATCH 08/38] Fix a method of TransferDao --- .../java/com/owncloud/android/data/transfers/db/TransferDao.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt index ae515c7782d..a5ff7b17d29 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt @@ -25,12 +25,11 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import com.owncloud.android.data.ProviderMeta.ProviderTableMeta.TRANSFERS_TABLE_NAME -import com.owncloud.android.data.files.db.OCFileEntity @Dao abstract class TransferDao { @Query(SELECT_TRANSFER_WITH_ID) - abstract fun getFileById(id: Long): OCFileEntity? + abstract fun getTransferById(id: Long): OCTransferEntity? @Insert(onConflict = OnConflictStrategy.REPLACE) abstract fun insert(ocTransferEntity: OCTransferEntity): Long From b2e35dc44aa258e5b1b6bc49698a04528b151367 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Thu, 7 Jul 2022 10:42:00 +0200 Subject: [PATCH 09/38] Updated Room database with new table "transfers" --- .../37.json | 90 ++++++++++++++++++- .../owncloud/android/data/OwncloudDatabase.kt | 4 + .../android/data/migrations/Migration_37.kt | 1 + 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/owncloudData/schemas/com.owncloud.android.data.OwncloudDatabase/37.json b/owncloudData/schemas/com.owncloud.android.data.OwncloudDatabase/37.json index 2d78e30c5f1..f5656ed89be 100644 --- a/owncloudData/schemas/com.owncloud.android.data.OwncloudDatabase/37.json +++ b/owncloudData/schemas/com.owncloud.android.data.OwncloudDatabase/37.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 37, - "identityHash": "421a3f1cccacb7dcb64727953f7d8616", + "identityHash": "38c32b00476bbb19c99051fd0c32d0ce", "entities": [ { "tableName": "folder_backup", @@ -571,12 +571,98 @@ }, "indices": [], "foreignKeys": [] + }, + { + "tableName": "transfers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localPath` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `accountName` TEXT NOT NULL, `fileSize` INTEGER NOT NULL, `status` INTEGER NOT NULL, `localBehaviour` INTEGER NOT NULL, `forceOverwrite` INTEGER NOT NULL, `transferEndTimestamp` INTEGER, `lastResult` INTEGER, `createdBy` INTEGER NOT NULL, `transferId` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "localPath", + "columnName": "localPath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "remotePath", + "columnName": "remotePath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountName", + "columnName": "accountName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fileSize", + "columnName": "fileSize", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localBehaviour", + "columnName": "localBehaviour", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "forceOverwrite", + "columnName": "forceOverwrite", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "transferEndTimestamp", + "columnName": "transferEndTimestamp", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "lastResult", + "columnName": "lastResult", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "createdBy", + "columnName": "createdBy", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "transferId", + "columnName": "transferId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] } ], "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '421a3f1cccacb7dcb64727953f7d8616')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '38c32b00476bbb19c99051fd0c32d0ce')" ] } } \ No newline at end of file diff --git a/owncloudData/src/main/java/com/owncloud/android/data/OwncloudDatabase.kt b/owncloudData/src/main/java/com/owncloud/android/data/OwncloudDatabase.kt index 66b6fad7830..17b67a06601 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/OwncloudDatabase.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/OwncloudDatabase.kt @@ -45,6 +45,8 @@ import com.owncloud.android.data.migrations.MIGRATION_35_36 import com.owncloud.android.data.migrations.MIGRATION_36_37 import com.owncloud.android.data.sharing.shares.db.OCShareDao import com.owncloud.android.data.sharing.shares.db.OCShareEntity +import com.owncloud.android.data.transfers.db.OCTransferEntity +import com.owncloud.android.data.transfers.db.TransferDao import com.owncloud.android.data.user.db.UserDao import com.owncloud.android.data.user.db.UserQuotaEntity @@ -55,6 +57,7 @@ import com.owncloud.android.data.user.db.UserQuotaEntity OCFileEntity::class, OCShareEntity::class, UserQuotaEntity::class, + OCTransferEntity::class, ], version = ProviderMeta.DB_VERSION, exportSchema = true @@ -65,6 +68,7 @@ abstract class OwncloudDatabase : RoomDatabase() { abstract fun folderBackUpDao(): FolderBackupDao abstract fun shareDao(): OCShareDao abstract fun userDao(): UserDao + abstract fun transferDao(): TransferDao companion object { @Volatile diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_37.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_37.kt index bf2eec8b5a0..a0832a6a107 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_37.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_37.kt @@ -24,5 +24,6 @@ import androidx.sqlite.db.SupportSQLiteDatabase val MIGRATION_36_37 = object : Migration(36, 37) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("CREATE TABLE IF NOT EXISTS `files` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `parentId` INTEGER, `owner` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `remoteId` TEXT, `length` INTEGER NOT NULL, `creationTimestamp` INTEGER, `modificationTimestamp` INTEGER NOT NULL, `mimeType` TEXT NOT NULL, `etag` TEXT, `permissions` TEXT, `privateLink` TEXT, `storagePath` TEXT, `name` TEXT, `treeEtag` TEXT, `keepInSync` INTEGER, `lastSyncDateForData` INTEGER, `fileShareViaLink` INTEGER, `lastSyncDateForProperties` INTEGER, `needsToUpdateThumbnail` INTEGER NOT NULL, `modifiedAtLastSyncForData` INTEGER, `etagInConflict` TEXT, `fileIsDownloading` INTEGER, `sharedWithSharee` INTEGER, `sharedByLink` INTEGER NOT NULL)") + database.execSQL("CREATE TABLE IF NOT EXISTS `transfers` (`localPath` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `accountName` TEXT NOT NULL, `fileSize` INTEGER NOT NULL, `status` INTEGER NOT NULL, `localBehaviour` INTEGER NOT NULL, `forceOverwrite` INTEGER NOT NULL, `transferEndTimestamp` INTEGER, `lastResult` INTEGER, `createdBy` INTEGER NOT NULL, `transferId` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)") } } From 2fc0267c45abe0962c3a4215d54b8179afe3070c Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Thu, 7 Jul 2022 10:51:16 +0200 Subject: [PATCH 10/38] Created LocalTransferDataSource interface in data layer --- .../datasources/LocalTransferDataSource.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt new file mode 100644 index 00000000000..8d8afb33623 --- /dev/null +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt @@ -0,0 +1,39 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.data.transfers.datasources + +import com.owncloud.android.domain.files.model.OCFile +import com.owncloud.android.domain.transfers.model.OCTransfer + +interface LocalTransferDataSource { + fun storeTransfer(transfer: OCTransfer): Long + fun updateTransfer(transfer: OCTransfer) + fun removeTransfer(transfer: OCTransfer) + fun removeAllTransfersFromAccount(accountName: String) + fun getAllTransfers(): Array + fun getLastTransferFor(file: OCFile, accountName: String): OCTransfer + fun getCurrentAndPendingTransfers(): Array + fun getFailedTransfers(): Array + fun getFinishedTransfers(): Array + fun getFailedButNotDelayedByWifiTransfers(): Array + fun clearFailedButNotDelayedByWifiTransfers() + fun clearSuccessfulTransfers() +} From 3dae2ce66dd77113cc1137b7717c4548eb38d16a Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Fri, 8 Jul 2022 11:25:24 +0200 Subject: [PATCH 11/38] Changed some methods of Repository and LocalDataSource interfaces --- .../datasources/LocalTransferDataSource.kt | 15 +++++++-------- .../domain/transfers/TransferRepository.kt | 15 +++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt index 8d8afb33623..062efb982a9 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt @@ -26,14 +26,13 @@ import com.owncloud.android.domain.transfers.model.OCTransfer interface LocalTransferDataSource { fun storeTransfer(transfer: OCTransfer): Long fun updateTransfer(transfer: OCTransfer) - fun removeTransfer(transfer: OCTransfer) + fun removeTransferById(id: Long) fun removeAllTransfersFromAccount(accountName: String) - fun getAllTransfers(): Array - fun getLastTransferFor(file: OCFile, accountName: String): OCTransfer - fun getCurrentAndPendingTransfers(): Array - fun getFailedTransfers(): Array - fun getFinishedTransfers(): Array - fun getFailedButNotDelayedByWifiTransfers(): Array - fun clearFailedButNotDelayedByWifiTransfers() + fun getAllTransfers(): List + fun getLastTransferFor(remotePath: String, accountName: String): OCTransfer? + fun getCurrentAndPendingTransfers(): List + fun getFailedTransfers(): List + fun getFinishedTransfers(): List + fun clearFailedTransfers() fun clearSuccessfulTransfers() } diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt index 95f371c62cb..9fdbdac004a 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt @@ -20,20 +20,19 @@ package com.owncloud.android.domain.transfers -import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.domain.transfers.model.OCTransfer interface TransferRepository { fun storeTransfer(transfer: OCTransfer): Long fun updateTransfer(transfer: OCTransfer) - fun removeTransfer(transfer: OCTransfer) + fun removeTransferById(id: Long) fun removeAllTransfersFromAccount(accountName: String) - fun getAllTransfers(): Array - fun getLastTransferFor(file: OCFile, accountName: String): OCTransfer - fun getCurrentAndPendingTransfers(): Array - fun getFailedTransfers(): Array - fun getFinishedTransfers(): Array - fun getFailedButNotDelayedByWifiTransfers(): Array + fun getAllTransfers(): List + fun getLastTransferFor(remotePath: String, accountName: String): OCTransfer + fun getCurrentAndPendingTransfers(): List + fun getFailedTransfers(): List + fun getFinishedTransfers(): List + fun getFailedButNotDelayedByWifiTransfers(): List fun clearFailedButNotDelayedByWifiTransfers() fun clearSuccessfulTransfers() } From 9bfd9e5919c55922dd4a6f99800c91a25ddb0272 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Fri, 8 Jul 2022 11:29:00 +0200 Subject: [PATCH 12/38] Created LocalTransferDataSource implementation in data layer and added some methods to DAO --- .../OCLocalTransferDataSource.kt | 114 ++++++++++++++++++ .../android/data/transfers/db/TransferDao.kt | 39 +++++- 2 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt new file mode 100644 index 00000000000..93d79fb223d --- /dev/null +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt @@ -0,0 +1,114 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.data.transfers.datasources.implementation + +import com.owncloud.android.data.transfers.datasources.LocalTransferDataSource +import com.owncloud.android.data.transfers.db.OCTransferEntity +import com.owncloud.android.data.transfers.db.TransferDao +import com.owncloud.android.domain.files.model.OCFile +import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferResult +import com.owncloud.android.domain.transfers.model.TransferStatus + +class OCLocalTransferDataSource( + private val transferDao: TransferDao +): LocalTransferDataSource { + override fun storeTransfer(transfer: OCTransfer): Long { + return transferDao.insert(transfer.toEntity()) + } + + override fun updateTransfer(transfer: OCTransfer) { + transferDao.insert(transfer.toEntity()) + } + + override fun removeTransferById(id: Long) { + transferDao.deleteTransferWithId(id) + } + + override fun removeAllTransfersFromAccount(accountName: String) { + transferDao.deleteTransfersWithAccountName(accountName) + } + + override fun getAllTransfers(): List { + return transferDao.getAllTransfers().map { it.toModel() } + } + + override fun getLastTransferFor(remotePath: String, accountName: String): OCTransfer? { + return transferDao.getLastTransferWithRemotePathAndAccountName(remotePath, accountName)?.toModel() + } + + override fun getCurrentAndPendingTransfers(): List { + return transferDao.getTransfersWithStatus( + listOf(TransferStatus.TRANSFER_IN_PROGRESS.value, TransferStatus.TRANSFER_QUEUED.value) + ).map { it.toModel() } + } + + override fun getFailedTransfers(): List { + return transferDao.getTransfersWithStatus( + listOf(TransferStatus.TRANSFER_FAILED.value) + ).map { it.toModel() } + } + + override fun getFinishedTransfers(): List { + return transferDao.getTransfersWithStatus( + listOf(TransferStatus.TRANSFER_SUCCEEDED.value) + ).map { it.toModel() } + } + + override fun clearFailedTransfers() { + transferDao.deleteTransfersWithStatus(TransferStatus.TRANSFER_FAILED.value) + } + + override fun clearSuccessfulTransfers() { + transferDao.deleteTransfersWithStatus(TransferStatus.TRANSFER_SUCCEEDED.value) + } + + companion object { + private fun OCTransferEntity.toModel() = OCTransfer( + id = id, + localPath = localPath, + remotePath = remotePath, + accountName = accountName, + fileSize = fileSize, + status = TransferStatus.fromValue(status), + localBehaviour = localBehaviour, + forceOverwrite = forceOverwrite, + transferEndTimestamp = transferEndTimestamp, + lastResult = lastResult?.let { TransferResult.fromValue(it) }, + createdBy = createdBy, + transferId = transferId + ) + + private fun OCTransfer.toEntity() = OCTransferEntity( + localPath = localPath, + remotePath = remotePath, + accountName = accountName, + fileSize = fileSize, + status = status.value, + localBehaviour = localBehaviour, + forceOverwrite = forceOverwrite, + transferEndTimestamp = transferEndTimestamp, + lastResult = lastResult?.value, + createdBy = createdBy, + transferId = transferId + ).apply { this@toEntity.id?.let { this.id = it } } + } +} diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt index a5ff7b17d29..b645074613c 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt @@ -28,8 +28,14 @@ import com.owncloud.android.data.ProviderMeta.ProviderTableMeta.TRANSFERS_TABLE_ @Dao abstract class TransferDao { - @Query(SELECT_TRANSFER_WITH_ID) - abstract fun getTransferById(id: Long): OCTransferEntity? + @Query(SELECT_LAST_TRANSFER_WITH_REMOTE_PATH_AND_ACCOUNT_NAME) + abstract fun getLastTransferWithRemotePathAndAccountName(remotePath: String, accountName: String): OCTransferEntity? + + @Query(SELECT_TRANSFERS_WITH_STATUS) + abstract fun getTransfersWithStatus(status: List): List + + @Query(SELECT_ALL_TRANSFERS) + abstract fun getAllTransfers(): List @Insert(onConflict = OnConflictStrategy.REPLACE) abstract fun insert(ocTransferEntity: OCTransferEntity): Long @@ -37,14 +43,39 @@ abstract class TransferDao { @Query(DELETE_TRANSFER_WITH_ID) abstract fun deleteTransferWithId(id: Long) + @Query(DELETE_TRANSFERS_WITH_ACCOUNT_NAME) + abstract fun deleteTransfersWithAccountName(accountName: String) + + @Query(DELETE_TRANSFERS_WITH_STATUS) + abstract fun deleteTransfersWithStatus(status: Int) + companion object { - private const val SELECT_TRANSFER_WITH_ID = + private const val SELECT_LAST_TRANSFER_WITH_REMOTE_PATH_AND_ACCOUNT_NAME = "SELECT * " + "FROM $TRANSFERS_TABLE_NAME " + - "WHERE id = :id" + "WHERE remotePath = :remotePath AND accountName = :accountName " + + "ORDER BY transferEndTimestamp DESC " + + "LIMIT 1" + + private const val SELECT_TRANSFERS_WITH_STATUS = + "SELECT * " + + "FROM $TRANSFERS_TABLE_NAME " + + "WHERE status IN (:status)" + + private const val SELECT_ALL_TRANSFERS = + "SELECT * " + + "FROM $TRANSFERS_TABLE_NAME " private const val DELETE_TRANSFER_WITH_ID = "DELETE FROM $TRANSFERS_TABLE_NAME " + "WHERE id = :id" + + private const val DELETE_TRANSFERS_WITH_ACCOUNT_NAME = + "DELETE FROM $TRANSFERS_TABLE_NAME " + + "WHERE accountName = :accountName" + + private const val DELETE_TRANSFERS_WITH_STATUS = + "DELETE FROM $TRANSFERS_TABLE_NAME " + + "WHERE status = :status" } } From 1917a190faed8547d83389464b28dcce11be39ec Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Fri, 8 Jul 2022 14:10:04 +0200 Subject: [PATCH 13/38] Created OCTransferRepository implementation in data layer and fixed some stuff in interfaces --- .../datasources/LocalTransferDataSource.kt | 1 - .../repository/OCTransferRepository.kt | 62 +++++++++++++++++++ .../domain/transfers/TransferRepository.kt | 5 +- 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt index 062efb982a9..67bdbdefa28 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt @@ -20,7 +20,6 @@ package com.owncloud.android.data.transfers.datasources -import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.domain.transfers.model.OCTransfer interface LocalTransferDataSource { diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt new file mode 100644 index 00000000000..bbb2b5eb8bd --- /dev/null +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt @@ -0,0 +1,62 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.data.transfers.repository + +import com.owncloud.android.data.transfers.datasources.LocalTransferDataSource +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer + +class OCTransferRepository( + private val localTransferDataSource: LocalTransferDataSource +): TransferRepository { + override fun storeTransfer(transfer: OCTransfer) = + localTransferDataSource.storeTransfer(transfer = transfer) + + override fun updateTransfer(transfer: OCTransfer) = + localTransferDataSource.updateTransfer(transfer = transfer) + + override fun removeTransferById(id: Long) = + localTransferDataSource.removeTransferById(id = id) + + override fun removeAllTransfersFromAccount(accountName: String) = + localTransferDataSource.removeAllTransfersFromAccount(accountName = accountName) + + override fun getAllTransfers(): List = + localTransferDataSource.getAllTransfers() + + override fun getLastTransferFor(remotePath: String, accountName: String) = + localTransferDataSource.getLastTransferFor(remotePath = remotePath, accountName = accountName) + + override fun getCurrentAndPendingTransfers() = + localTransferDataSource.getCurrentAndPendingTransfers() + + override fun getFailedTransfers() = + localTransferDataSource.getFailedTransfers() + + override fun getFinishedTransfers() = + localTransferDataSource.getFinishedTransfers() + + override fun clearFailedTransfers() = + localTransferDataSource.clearFailedTransfers() + + override fun clearSuccessfulTransfers() = + localTransferDataSource.clearSuccessfulTransfers() +} \ No newline at end of file diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt index 9fdbdac004a..39f9cf47022 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt @@ -28,11 +28,10 @@ interface TransferRepository { fun removeTransferById(id: Long) fun removeAllTransfersFromAccount(accountName: String) fun getAllTransfers(): List - fun getLastTransferFor(remotePath: String, accountName: String): OCTransfer + fun getLastTransferFor(remotePath: String, accountName: String): OCTransfer? fun getCurrentAndPendingTransfers(): List fun getFailedTransfers(): List fun getFinishedTransfers(): List - fun getFailedButNotDelayedByWifiTransfers(): List - fun clearFailedButNotDelayedByWifiTransfers() + fun clearFailedTransfers() fun clearSuccessfulTransfers() } From ed91c1c41a55b14d837823d66870822f4a4822df Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Mon, 11 Jul 2022 08:50:39 +0200 Subject: [PATCH 14/38] Added necessary dependency injection --- .../dependecyinjection/LocalDataSourceModule.kt | 12 +++++++++--- .../android/dependecyinjection/RepositoryModule.kt | 8 +++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt index 09dead943eb..ec36ab4b526 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt @@ -3,7 +3,9 @@ * * @author David González Verdugo * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -26,18 +28,20 @@ import com.owncloud.android.MainApp.Companion.dataFolder import com.owncloud.android.data.OwncloudDatabase import com.owncloud.android.data.authentication.datasources.LocalAuthenticationDataSource import com.owncloud.android.data.authentication.datasources.implementation.OCLocalAuthenticationDataSource -import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource -import com.owncloud.android.data.folderbackup.datasources.implementation.FolderBackupLocalDataSourceImpl import com.owncloud.android.data.capabilities.datasources.LocalCapabilitiesDataSource import com.owncloud.android.data.capabilities.datasources.implementation.OCLocalCapabilitiesDataSource import com.owncloud.android.data.files.datasources.LocalFileDataSource import com.owncloud.android.data.files.datasources.implementation.OCLocalFileDataSource +import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource +import com.owncloud.android.data.folderbackup.datasources.implementation.FolderBackupLocalDataSourceImpl import com.owncloud.android.data.preferences.datasources.SharedPreferencesProvider import com.owncloud.android.data.preferences.datasources.implementation.SharedPreferencesProviderImpl import com.owncloud.android.data.sharing.shares.datasources.LocalShareDataSource import com.owncloud.android.data.sharing.shares.datasources.implementation.OCLocalShareDataSource import com.owncloud.android.data.storage.LocalStorageProvider import com.owncloud.android.data.storage.ScopedStorageProvider +import com.owncloud.android.data.transfers.datasources.LocalTransferDataSource +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource import com.owncloud.android.data.user.datasources.LocalUserDataSource import com.owncloud.android.data.user.datasources.implementation.OCLocalUserDataSource import org.koin.android.ext.koin.androidContext @@ -51,6 +55,7 @@ val localDataSourceModule = module { single { OwncloudDatabase.getDatabase(androidContext()).shareDao() } single { OwncloudDatabase.getDatabase(androidContext()).userDao() } single { OwncloudDatabase.getDatabase(androidContext()).folderBackUpDao() } + single { OwncloudDatabase.getDatabase(androidContext()).transferDao() } single { SharedPreferencesProviderImpl(get()) } single { ScopedStorageProvider(dataFolder, androidContext()) } @@ -61,4 +66,5 @@ val localDataSourceModule = module { factory { OCLocalShareDataSource(get()) } factory { OCLocalUserDataSource(get()) } factory { FolderBackupLocalDataSourceImpl(get()) } + factory { OCLocalTransferDataSource(get()) } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/RepositoryModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/RepositoryModule.kt index d53dab98960..17cd746feb1 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/RepositoryModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/RepositoryModule.kt @@ -2,7 +2,10 @@ * ownCloud Android client application * * @author David González Verdugo - * Copyright (C) 2020 ownCloud GmbH. + * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -27,6 +30,7 @@ import com.owncloud.android.data.oauth.OAuthRepositoryImpl import com.owncloud.android.data.server.repository.OCServerInfoRepository import com.owncloud.android.data.sharing.sharees.repository.OCShareeRepository import com.owncloud.android.data.sharing.shares.repository.OCShareRepository +import com.owncloud.android.data.transfers.repository.OCTransferRepository import com.owncloud.android.data.user.repository.OCUserRepository import com.owncloud.android.domain.authentication.AuthenticationRepository import com.owncloud.android.domain.authentication.oauth.OAuthRepository @@ -36,6 +40,7 @@ import com.owncloud.android.domain.files.FileRepository import com.owncloud.android.domain.server.ServerInfoRepository import com.owncloud.android.domain.sharing.sharees.ShareeRepository import com.owncloud.android.domain.sharing.shares.ShareRepository +import com.owncloud.android.domain.transfers.TransferRepository import com.owncloud.android.domain.user.UserRepository import org.koin.dsl.module @@ -49,4 +54,5 @@ val repositoryModule = module { factory { OCUserRepository(get(), get()) } factory { OAuthRepositoryImpl(get()) } factory { FolderBackupRepositoryImpl(get()) } + factory { OCTransferRepository(get()) } } From 99cfc5fb44e8bf39192f22efeaf91c8d97fa1bc1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Mon, 11 Jul 2022 08:59:49 +0200 Subject: [PATCH 15/38] Deprecate old OCUpload datamodel --- .../src/main/java/com/owncloud/android/datamodel/OCUpload.java | 1 + 1 file changed, 1 insertion(+) diff --git a/owncloudApp/src/main/java/com/owncloud/android/datamodel/OCUpload.java b/owncloudApp/src/main/java/com/owncloud/android/datamodel/OCUpload.java index 6523dd6690b..3d7424ee60b 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/datamodel/OCUpload.java +++ b/owncloudApp/src/main/java/com/owncloud/android/datamodel/OCUpload.java @@ -38,6 +38,7 @@ import java.io.File; +@Deprecated /** * Stores all information in order to start upload operations. PersistentUploadObject can * be stored persistently by {@link UploadsStorageManager}. From 16c79f08c00bd17be31c6a04caf75a66967e6684 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Tue, 12 Jul 2022 09:21:47 +0200 Subject: [PATCH 16/38] Move UploadFilesFromSAFUseCase to new arch --- .../dependecyinjection/UseCaseModule.kt | 7 ++- .../dependecyinjection/ViewModelModule.kt | 2 + .../transfers/TransfersViewModel.kt | 49 +++++++++++++++++++ .../ui/activity/FileDisplayActivity.kt | 9 ++-- .../uploads/UploadFilesFromSAFUseCase.kt | 36 ++++++++------ 5 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt index 7f76b386319..ec7a2972f18 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt @@ -2,7 +2,10 @@ * ownCloud Android client application * * @author David González Verdugo - * Copyright (C) 2020 ownCloud GmbH. + * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -131,7 +134,7 @@ val useCaseModule = module { factory { DownloadFileUseCase(get()) } factory { GetLiveDataForDownloadingFileUseCase(get()) } factory { GetLiveDataForFinishedDownloadsFromAccountUseCase(get()) } - factory { UploadFilesFromSAFUseCase(get()) } + factory { UploadFilesFromSAFUseCase(get(), get()) } factory { UploadFilesFromSystemUseCase(get()) } factory { UploadFileInConflictUseCase(get()) } factory { CancelUploadForFileUseCase(get()) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt index b597d497aa5..32b957fb212 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt @@ -46,6 +46,7 @@ import com.owncloud.android.presentation.viewmodels.settings.SettingsSecurityVie import com.owncloud.android.presentation.viewmodels.settings.SettingsVideoUploadsViewModel import com.owncloud.android.presentation.viewmodels.settings.SettingsViewModel import com.owncloud.android.presentation.viewmodels.sharing.OCShareViewModel +import com.owncloud.android.presentation.viewmodels.transfers.TransfersViewModel import com.owncloud.android.ui.dialog.RemoveAccountDialogViewModel import com.owncloud.android.ui.preview.PreviewImageViewModel import org.koin.androidx.viewmodel.dsl.viewModel @@ -87,4 +88,5 @@ val viewModelModule = module { viewModel { FileDetailsViewModel(get(), get(), get(), get(), get()) } viewModel { FileOperationsViewModel(get(), get(), get(), get(), get(), get(), get(), get()) } viewModel { MainFileListViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } + viewModel { TransfersViewModel(get(), get()) } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt new file mode 100644 index 00000000000..7110f47bb9e --- /dev/null +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt @@ -0,0 +1,49 @@ +/** + * ownCloud Android client application + * + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.presentation.viewmodels.transfers + +import android.net.Uri +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.owncloud.android.providers.CoroutinesDispatcherProvider +import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSAFUseCase +import kotlinx.coroutines.launch + +class TransfersViewModel( + private val uploadFilesFromSAFUseCase: UploadFilesFromSAFUseCase, + private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider, +): ViewModel() { + fun uploadFilesFromSAF( + accountName: String, + listOfContentUris: List, + uploadFolderPath: String + ) { + viewModelScope.launch(coroutinesDispatcherProvider.io) { + uploadFilesFromSAFUseCase.execute( + UploadFilesFromSAFUseCase.Params( + accountName = accountName, + listOfContentUris = listOfContentUris, + uploadFolderPath = uploadFolderPath + ) + ) + } + } +} diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index a7a6d8e815e..6f5b340b1c1 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -7,8 +7,10 @@ * @author Christian Schabesberger * @author Shashvat Kedia * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón + * * Copyright (C) 2011 Bartek Przybylski - * Copyright (C) 2020 ownCloud GmbH. + * Copyright (C) 2022 ownCloud GmbH. * * * This program is free software: you can redistribute it and/or modify @@ -74,6 +76,7 @@ import com.owncloud.android.presentation.ui.files.filelist.MainFileListFragment import com.owncloud.android.presentation.ui.files.operations.FileOperation import com.owncloud.android.presentation.ui.files.operations.FileOperationsViewModel import com.owncloud.android.presentation.ui.security.bayPassUnlockOnce +import com.owncloud.android.presentation.viewmodels.transfers.TransfersViewModel import com.owncloud.android.syncadapter.FileSyncAdapter import com.owncloud.android.ui.fragment.FileDetailFragment import com.owncloud.android.ui.fragment.FileFragment @@ -153,6 +156,7 @@ class FileDisplayActivity : FileActivity(), private var localBroadcastManager: LocalBroadcastManager? = null private val fileOperationsViewModel: FileOperationsViewModel by viewModel() + private val transfersViewModel: TransfersViewModel by viewModel() var filesUploadHelper: FilesUploadHelper? = null internal set @@ -566,12 +570,11 @@ class FileDisplayActivity : FileActivity(), val currentDir = currentDir val remotePath = currentDir?.remotePath ?: OCFile.ROOT_PATH - val uploadFileUseCaseParams = UploadFilesFromSAFUseCase.Params( + transfersViewModel.uploadFilesFromSAF( accountName = account.name, listOfContentUris = streamsToUpload, uploadFolderPath = remotePath, ) - uploadFileUseCase.execute(uploadFileUseCaseParams) } /** diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSAFUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSAFUseCase.kt index c8b2f8aa9ef..cbf5d212a55 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSAFUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSAFUseCase.kt @@ -2,30 +2,34 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. - *

+ * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. - *

+ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - *

+ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import android.net.Uri import androidx.documentfile.provider.DocumentFile import androidx.work.WorkManager import com.owncloud.android.MainApp -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.camerauploads.model.UploadBehavior +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferStatus import timber.log.Timber import java.io.File @@ -38,6 +42,7 @@ import java.io.File */ class UploadFilesFromSAFUseCase( private val workManager: WorkManager, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params) { @@ -70,17 +75,18 @@ class UploadFilesFromSAFUseCase( uploadPath: String, accountName: String, ): Long { - val uploadStorageManager = UploadsStorageManager(MainApp.appContext.contentResolver) - - val ocUpload = OCUpload(documentFile.uri.toString(), uploadPath, accountName).apply { - fileSize = documentFile.length() - isForceOverwrite = false + val ocTransfer = OCTransfer( + localPath = documentFile.uri.toString(), + remotePath = uploadPath, + accountName = accountName, + fileSize = documentFile.length(), + status = TransferStatus.TRANSFER_QUEUED, + localBehaviour = UploadBehavior.COPY.ordinal, + forceOverwrite = false, createdBy = UploadEnqueuedBy.ENQUEUED_BY_USER.ordinal - localAction = UploadBehavior.COPY.ordinal - uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS - } + ) - return uploadStorageManager.storeUpload(ocUpload).also { + return transferRepository.storeTransfer(ocTransfer).also { Timber.i("Upload of $uploadPath has been stored in the uploads database with id: $it") } } From aaf91ab96e5e19f8daef4c495f1ad6d0863b3857 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Tue, 12 Jul 2022 14:27:24 +0200 Subject: [PATCH 17/38] Move UploadFileFromContentUriWorker to new arch --- .../workers/UploadFileFromContentUriWorker.kt | 62 ++++++++++--------- .../datasources/LocalTransferDataSource.kt | 9 +++ .../OCLocalTransferDataSource.kt | 9 +++ .../android/data/transfers/db/TransferDao.kt | 17 +++++ .../repository/OCTransferRepository.kt | 20 ++++++ .../domain/transfers/TransferRepository.kt | 9 +++ 6 files changed, 97 insertions(+), 29 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt index d6718233c49..9585fcba909 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.workers import android.accounts.Account @@ -29,9 +32,6 @@ import androidx.work.workDataOf import com.owncloud.android.R import com.owncloud.android.authentication.AccountUtils import com.owncloud.android.data.executeRemoteOperation -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager -import com.owncloud.android.db.UploadResult import com.owncloud.android.domain.camerauploads.model.UploadBehavior import com.owncloud.android.domain.exceptions.ConflictException import com.owncloud.android.domain.exceptions.FileNotFoundException @@ -43,6 +43,9 @@ import com.owncloud.android.domain.exceptions.SSLRecoverablePeerUnverifiedExcept import com.owncloud.android.domain.exceptions.ServiceUnavailableException import com.owncloud.android.domain.exceptions.SpecificUnsupportedMediaTypeException import com.owncloud.android.domain.exceptions.UnauthorizedException +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.TransferResult +import com.owncloud.android.domain.transfers.model.TransferStatus import com.owncloud.android.extensions.parseError import com.owncloud.android.lib.common.OwnCloudAccount import com.owncloud.android.lib.common.OwnCloudClient @@ -60,6 +63,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.koin.core.component.KoinComponent +import org.koin.core.component.inject import timber.log.Timber import java.io.File @@ -80,10 +84,14 @@ class UploadFileFromContentUriWorker( private var lastPercent = 0 + private val transferRepository: TransferRepository by inject() + override suspend fun doWork(): Result { if (!areParametersValid()) return Result.failure() + transferRepository.updateTransferStatusToInProgressById(uploadIdInStorageManager) + return try { checkDocumentFileExists() checkPermissionsToReadDocumentAreGranted() @@ -176,23 +184,19 @@ class UploadFileFromContentUriWorker( } private fun updateUploadsDatabaseWithResult(throwable: Throwable?) { - val uploadStorageManager = UploadsStorageManager(appContext.contentResolver) - - val ocUpload = OCUpload(contentUri.toString(), uploadPath, account.name).apply { - uploadStatus = getUploadStatusForThrowable(throwable) - uploadEndTimestamp = System.currentTimeMillis() + transferRepository.updateTransferWhenFinished( + id = uploadIdInStorageManager, + status = getUploadStatusForThrowable(throwable), + transferEndTimestamp = System.currentTimeMillis(), lastResult = getUploadResultFromThrowable(throwable) - uploadId = uploadIdInStorageManager - } - - uploadStorageManager.updateUpload(ocUpload) + ) } - private fun getUploadStatusForThrowable(throwable: Throwable?): UploadsStorageManager.UploadStatus { + private fun getUploadStatusForThrowable(throwable: Throwable?): TransferStatus { return if (throwable == null) { - UploadsStorageManager.UploadStatus.UPLOAD_SUCCEEDED + TransferStatus.TRANSFER_SUCCEEDED } else { - UploadsStorageManager.UploadStatus.UPLOAD_FAILED + TransferStatus.TRANSFER_FAILED } } @@ -221,21 +225,21 @@ class UploadFileFromContentUriWorker( ) } - private fun getUploadResultFromThrowable(throwable: Throwable?): UploadResult { - if (throwable == null) return UploadResult.UPLOADED + private fun getUploadResultFromThrowable(throwable: Throwable?): TransferResult { + if (throwable == null) return TransferResult.UPLOADED return when (throwable) { - is LocalFileNotFoundException -> UploadResult.FOLDER_ERROR - is NoConnectionWithServerException -> UploadResult.NETWORK_CONNECTION - is UnauthorizedException -> UploadResult.CREDENTIAL_ERROR - is FileNotFoundException -> UploadResult.FILE_NOT_FOUND - is ConflictException -> UploadResult.CONFLICT_ERROR - is ForbiddenException -> UploadResult.PRIVILEGES_ERROR - is ServiceUnavailableException -> UploadResult.SERVICE_UNAVAILABLE - is QuotaExceededException -> UploadResult.QUOTA_EXCEEDED - is SpecificUnsupportedMediaTypeException -> UploadResult.SPECIFIC_UNSUPPORTED_MEDIA_TYPE - is SSLRecoverablePeerUnverifiedException -> UploadResult.SSL_RECOVERABLE_PEER_UNVERIFIED - else -> UploadResult.UNKNOWN + is LocalFileNotFoundException -> TransferResult.FOLDER_ERROR + is NoConnectionWithServerException -> TransferResult.NETWORK_CONNECTION + is UnauthorizedException -> TransferResult.CREDENTIAL_ERROR + is FileNotFoundException -> TransferResult.FILE_NOT_FOUND + is ConflictException -> TransferResult.CONFLICT_ERROR + is ForbiddenException -> TransferResult.PRIVILEGES_ERROR + is ServiceUnavailableException -> TransferResult.SERVICE_UNAVAILABLE + is QuotaExceededException -> TransferResult.QUOTA_EXCEEDED + is SpecificUnsupportedMediaTypeException -> TransferResult.SPECIFIC_UNSUPPORTED_MEDIA_TYPE + is SSLRecoverablePeerUnverifiedException -> TransferResult.SSL_RECOVERABLE_PEER_UNVERIFIED + else -> TransferResult.UNKNOWN } } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt index 67bdbdefa28..0051b40f9da 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt @@ -21,10 +21,19 @@ package com.owncloud.android.data.transfers.datasources import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferResult +import com.owncloud.android.domain.transfers.model.TransferStatus interface LocalTransferDataSource { fun storeTransfer(transfer: OCTransfer): Long fun updateTransfer(transfer: OCTransfer) + fun updateTransferStatusToInProgressById(id: Long) + fun updateTransferWhenFinished( + id: Long, + status: TransferStatus, + transferEndTimestamp: Long, + lastResult: TransferResult + ) fun removeTransferById(id: Long) fun removeAllTransfersFromAccount(accountName: String) fun getAllTransfers(): List diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt index 93d79fb223d..6208a460e3f 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt @@ -39,6 +39,15 @@ class OCLocalTransferDataSource( transferDao.insert(transfer.toEntity()) } + override fun updateTransferStatusToInProgressById(id: Long) { + transferDao.updateTransferStatusWithId(id, TransferStatus.TRANSFER_IN_PROGRESS.value) + } + + override fun updateTransferWhenFinished(id: Long, status: TransferStatus, + transferEndTimestamp: Long, lastResult: TransferResult) { + transferDao.updateTransferWhenFinished(id, status.value, transferEndTimestamp, lastResult.value) + } + override fun removeTransferById(id: Long) { transferDao.deleteTransferWithId(id) } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt index b645074613c..1ea4a2cf3bd 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt @@ -40,6 +40,11 @@ abstract class TransferDao { @Insert(onConflict = OnConflictStrategy.REPLACE) abstract fun insert(ocTransferEntity: OCTransferEntity): Long + @Query(UPDATE_TRANSFER_STATUS_WITH_ID) + abstract fun updateTransferStatusWithId(id: Long, newStatus: Int) + + abstract fun updateTransferWhenFinished(id: Long, status: Int, transferEndTimestamp: Long, lastResult: Int) + @Query(DELETE_TRANSFER_WITH_ID) abstract fun deleteTransferWithId(id: Long) @@ -66,6 +71,18 @@ abstract class TransferDao { "SELECT * " + "FROM $TRANSFERS_TABLE_NAME " + private const val UPDATE_TRANSFER_STATUS_WITH_ID = + "UPDATE $TRANSFERS_TABLE_NAME " + + "SET status = :newStatus " + + "WHERE id = :id" + + private const val UPDATE_TRANSFER_WHEN_FINISHED = + "UPDATE $TRANSFERS_TABLE_NAME " + + "SET status = :status, " + + "transferEndTimestamp = :transferEndTimestamp," + + "lastResult = :lastResult " + + "WHERE id = :id" + private const val DELETE_TRANSFER_WITH_ID = "DELETE FROM $TRANSFERS_TABLE_NAME " + "WHERE id = :id" diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt index bbb2b5eb8bd..0d02263d5d5 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt @@ -23,6 +23,8 @@ package com.owncloud.android.data.transfers.repository import com.owncloud.android.data.transfers.datasources.LocalTransferDataSource import com.owncloud.android.domain.transfers.TransferRepository import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferResult +import com.owncloud.android.domain.transfers.model.TransferStatus class OCTransferRepository( private val localTransferDataSource: LocalTransferDataSource @@ -33,6 +35,24 @@ class OCTransferRepository( override fun updateTransfer(transfer: OCTransfer) = localTransferDataSource.updateTransfer(transfer = transfer) + override fun updateTransferStatusToInProgressById(id: Long) { + localTransferDataSource.updateTransferStatusToInProgressById(id = id) + } + + override fun updateTransferWhenFinished( + id: Long, + status: TransferStatus, + transferEndTimestamp: Long, + lastResult: TransferResult + ) { + localTransferDataSource.updateTransferWhenFinished( + id = id, + status = status, + transferEndTimestamp = transferEndTimestamp, + lastResult = lastResult + ) + } + override fun removeTransferById(id: Long) = localTransferDataSource.removeTransferById(id = id) diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt index 39f9cf47022..68cbbf6ae4f 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt @@ -21,10 +21,19 @@ package com.owncloud.android.domain.transfers import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferResult +import com.owncloud.android.domain.transfers.model.TransferStatus interface TransferRepository { fun storeTransfer(transfer: OCTransfer): Long fun updateTransfer(transfer: OCTransfer) + fun updateTransferStatusToInProgressById(id: Long) + fun updateTransferWhenFinished( + id: Long, + status: TransferStatus, + transferEndTimestamp: Long, + lastResult: TransferResult + ) fun removeTransferById(id: Long) fun removeAllTransfersFromAccount(accountName: String) fun getAllTransfers(): List From ebfa59be46c6586121c1c9700aafdb2353748eff Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Tue, 12 Jul 2022 15:35:37 +0200 Subject: [PATCH 18/38] Fix mistake in TransferDao --- .../java/com/owncloud/android/data/transfers/db/TransferDao.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt index 1ea4a2cf3bd..4a0b4511de3 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt @@ -43,6 +43,7 @@ abstract class TransferDao { @Query(UPDATE_TRANSFER_STATUS_WITH_ID) abstract fun updateTransferStatusWithId(id: Long, newStatus: Int) + @Query(UPDATE_TRANSFER_WHEN_FINISHED) abstract fun updateTransferWhenFinished(id: Long, status: Int, transferEndTimestamp: Long, lastResult: Int) @Query(DELETE_TRANSFER_WITH_ID) From f96ba9b6f130559b134dc83fe09fcf916c8cf262 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Tue, 12 Jul 2022 16:22:18 +0200 Subject: [PATCH 19/38] Move UploadFileFromFileSystemWorker to new arch --- .../workers/UploadFileFromFileSystemWorker.kt | 86 ++++++++++--------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt index bb35b74e825..cec9f7868d6 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt @@ -2,6 +2,8 @@ * ownCloud Android client application * * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón + * * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify @@ -16,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.workers import android.accounts.Account @@ -26,9 +29,6 @@ import androidx.work.workDataOf import com.owncloud.android.R import com.owncloud.android.authentication.AccountUtils import com.owncloud.android.data.executeRemoteOperation -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager -import com.owncloud.android.db.UploadResult import com.owncloud.android.domain.camerauploads.model.UploadBehavior import com.owncloud.android.domain.capabilities.usecases.GetStoredCapabilitiesUseCase import com.owncloud.android.domain.exceptions.ConflictException @@ -44,6 +44,10 @@ import com.owncloud.android.domain.exceptions.UnauthorizedException import com.owncloud.android.domain.files.model.OCFile.Companion.PATH_SEPARATOR import com.owncloud.android.domain.files.usecases.GetFileByRemotePathUseCase import com.owncloud.android.domain.files.usecases.SaveFileOrFolderUseCase +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferResult +import com.owncloud.android.domain.transfers.model.TransferStatus import com.owncloud.android.extensions.parseError import com.owncloud.android.lib.common.OwnCloudAccount import com.owncloud.android.lib.common.OwnCloudClient @@ -82,7 +86,7 @@ class UploadFileFromFileSystemWorker( private lateinit var uploadPath: String private lateinit var mimetype: String private var uploadIdInStorageManager: Long = -1 - private lateinit var ocUpload: OCUpload + private lateinit var ocTransfer: OCTransfer private var fileSize: Long = 0 private lateinit var uploadFileOperation: UploadFileFromFileSystemOperation @@ -93,10 +97,14 @@ class UploadFileFromFileSystemWorker( private var lastPercent = 0 + private val transferRepository: TransferRepository by inject() + override suspend fun doWork(): Result { if (!areParametersValid()) return Result.failure() + transferRepository.updateTransferStatusToInProgressById(uploadIdInStorageManager) + return try { checkPermissionsToReadDocumentAreGranted() checkParentFolderExistence() @@ -121,14 +129,14 @@ class UploadFileFromFileSystemWorker( */ private fun updateFilesDatabaseWithNewEtag() { val currentTime = System.currentTimeMillis() - if (ocUpload.isForceOverwrite) { + if (ocTransfer.forceOverwrite) { val getFileByRemotePathUseCase: GetFileByRemotePathUseCase by inject() - val file = getFileByRemotePathUseCase.execute(GetFileByRemotePathUseCase.Params(account.name, ocUpload.remotePath)) - file.getDataOrNull()?.let { - it.copy( + val file = getFileByRemotePathUseCase.execute(GetFileByRemotePathUseCase.Params(account.name, ocTransfer.remotePath)) + file.getDataOrNull()?.let { ocFile -> + ocFile.copy( needsToUpdateThumbnail = true, etag = uploadFileOperation.etag, - length = (File(ocUpload.localPath).length()), + length = (File(ocTransfer.localPath).length()), lastSyncDateForData = currentTime, modifiedAtLastSyncForData = currentTime, etagInConflict = null @@ -153,17 +161,15 @@ class UploadFileFromFileSystemWorker( behavior = paramBehavior?.let { UploadBehavior.valueOf(it) } ?: return false lastModified = paramLastModified ?: return false uploadIdInStorageManager = paramUploadId.takeUnless { it == -1L } ?: return false - ocUpload = retrieveUploadInfoFromDatabase() ?: return false + ocTransfer = retrieveUploadInfoFromDatabase() ?: return false return true } - private fun retrieveUploadInfoFromDatabase(): OCUpload? { - val uploadStorageManager = UploadsStorageManager(appContext.contentResolver) - - val storedUploads = uploadStorageManager.allStoredUploads + private fun retrieveUploadInfoFromDatabase(): OCTransfer? { + val storedTransfers = transferRepository.getAllTransfers() - return storedUploads.find { uploadIdInStorageManager == it.uploadId }.also { + return storedTransfers.find { uploadIdInStorageManager == it.id }.also { if (it != null) { Timber.d("Upload with id ($uploadIdInStorageManager) has been found in database.") Timber.d("Upload info: $it") @@ -197,10 +203,10 @@ class UploadFileFromFileSystemWorker( } private fun checkNameCollisionOrGetAnAvailableOneInCase() { - if (ocUpload.isForceOverwrite) { + if (ocTransfer.forceOverwrite) { val getFileByRemotePathUseCase: GetFileByRemotePathUseCase by inject() - val useCaseResult = getFileByRemotePathUseCase.execute(GetFileByRemotePathUseCase.Params(ocUpload.accountName, ocUpload.remotePath)) + val useCaseResult = getFileByRemotePathUseCase.execute(GetFileByRemotePathUseCase.Params(ocTransfer.accountName, ocTransfer.remotePath)) eTagInConflict = useCaseResult.getDataOrNull()?.etagInConflict.orEmpty() @@ -292,23 +298,19 @@ class UploadFileFromFileSystemWorker( } private fun updateUploadsDatabaseWithResult(throwable: Throwable?) { - val uploadStorageManager = UploadsStorageManager(appContext.contentResolver) - - val ocUpload = OCUpload(fileSystemPath, uploadPath, account.name).apply { - uploadStatus = getUploadStatusForThrowable(throwable) - uploadEndTimestamp = System.currentTimeMillis() + transferRepository.updateTransferWhenFinished( + id = uploadIdInStorageManager, + status = getUploadStatusForThrowable(throwable), + transferEndTimestamp = System.currentTimeMillis(), lastResult = getUploadResultFromThrowable(throwable) - uploadId = uploadIdInStorageManager - } - - uploadStorageManager.updateUpload(ocUpload) + ) } - private fun getUploadStatusForThrowable(throwable: Throwable?): UploadsStorageManager.UploadStatus { + private fun getUploadStatusForThrowable(throwable: Throwable?): TransferStatus { return if (throwable == null) { - UploadsStorageManager.UploadStatus.UPLOAD_SUCCEEDED + TransferStatus.TRANSFER_SUCCEEDED } else { - UploadsStorageManager.UploadStatus.UPLOAD_FAILED + TransferStatus.TRANSFER_FAILED } } @@ -337,21 +339,21 @@ class UploadFileFromFileSystemWorker( ) } - private fun getUploadResultFromThrowable(throwable: Throwable?): UploadResult { - if (throwable == null) return UploadResult.UPLOADED + private fun getUploadResultFromThrowable(throwable: Throwable?): TransferResult { + if (throwable == null) return TransferResult.UPLOADED return when (throwable) { - is LocalFileNotFoundException -> UploadResult.FOLDER_ERROR - is NoConnectionWithServerException -> UploadResult.NETWORK_CONNECTION - is UnauthorizedException -> UploadResult.CREDENTIAL_ERROR - is FileNotFoundException -> UploadResult.FILE_NOT_FOUND - is ConflictException -> UploadResult.CONFLICT_ERROR - is ForbiddenException -> UploadResult.PRIVILEGES_ERROR - is ServiceUnavailableException -> UploadResult.SERVICE_UNAVAILABLE - is QuotaExceededException -> UploadResult.QUOTA_EXCEEDED - is SpecificUnsupportedMediaTypeException -> UploadResult.SPECIFIC_UNSUPPORTED_MEDIA_TYPE - is SSLRecoverablePeerUnverifiedException -> UploadResult.SSL_RECOVERABLE_PEER_UNVERIFIED - else -> UploadResult.UNKNOWN + is LocalFileNotFoundException -> TransferResult.FOLDER_ERROR + is NoConnectionWithServerException -> TransferResult.NETWORK_CONNECTION + is UnauthorizedException -> TransferResult.CREDENTIAL_ERROR + is FileNotFoundException -> TransferResult.FILE_NOT_FOUND + is ConflictException -> TransferResult.CONFLICT_ERROR + is ForbiddenException -> TransferResult.PRIVILEGES_ERROR + is ServiceUnavailableException -> TransferResult.SERVICE_UNAVAILABLE + is QuotaExceededException -> TransferResult.QUOTA_EXCEEDED + is SpecificUnsupportedMediaTypeException -> TransferResult.SPECIFIC_UNSUPPORTED_MEDIA_TYPE + is SSLRecoverablePeerUnverifiedException -> TransferResult.SSL_RECOVERABLE_PEER_UNVERIFIED + else -> TransferResult.UNKNOWN } } From 960bc62525faea2ae35e20c5c975bc347fff2ba0 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Tue, 12 Jul 2022 17:40:05 +0200 Subject: [PATCH 20/38] Move UploadFilesFromSystemUseCase to new arch --- .../uploads/UploadFilesFromSystemUseCase.kt | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSystemUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSystemUseCase.kt index 25803589acc..c9912a1d152 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSystemUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFilesFromSystemUseCase.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import androidx.work.Constraints @@ -23,11 +26,11 @@ import androidx.work.NetworkType import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import androidx.work.workDataOf -import com.owncloud.android.MainApp -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.camerauploads.model.UploadBehavior +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferStatus import com.owncloud.android.workers.UploadFileFromFileSystemWorker import timber.log.Timber import java.io.File @@ -46,6 +49,7 @@ import java.io.File */ class UploadFilesFromSystemUseCase( private val workManager: WorkManager, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params) { @@ -78,17 +82,18 @@ class UploadFilesFromSystemUseCase( uploadPath: String, accountName: String, ): Long { - val uploadStorageManager = UploadsStorageManager(MainApp.appContext.contentResolver) - - val ocUpload = OCUpload(localFile.absolutePath, uploadPath, accountName).apply { - fileSize = localFile.length() - isForceOverwrite = false + val ocTransfer = OCTransfer( + localPath = localFile.absolutePath, + remotePath = uploadPath, + accountName = accountName, + fileSize = localFile.length(), + status = TransferStatus.TRANSFER_QUEUED, + localBehaviour = UploadBehavior.MOVE.ordinal, + forceOverwrite = false, createdBy = UploadEnqueuedBy.ENQUEUED_BY_USER.ordinal - localAction = UploadBehavior.MOVE.ordinal - uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS - } + ) - return uploadStorageManager.storeUpload(ocUpload).also { + return transferRepository.storeTransfer(ocTransfer).also { Timber.i("Upload of $uploadPath has been stored in the uploads database with id: $it") } } From 574f772facce707b5acd4eb696f20ae2cdfd8d29 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Wed, 13 Jul 2022 10:43:43 +0200 Subject: [PATCH 21/38] Move CameraUploadsWorker to new arch --- .../android/workers/CameraUploadsWorker.kt | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/CameraUploadsWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/CameraUploadsWorker.kt index db8fc4dcc17..d034326e9c5 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/CameraUploadsWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/CameraUploadsWorker.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.workers import android.content.Context @@ -26,15 +29,15 @@ import androidx.work.CoroutineWorker import androidx.work.WorkManager import androidx.work.WorkerParameters import com.owncloud.android.R -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager -import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus import com.owncloud.android.domain.UseCaseResult import com.owncloud.android.domain.camerauploads.model.FolderBackUpConfiguration import com.owncloud.android.domain.camerauploads.model.UploadBehavior import com.owncloud.android.domain.camerauploads.usecases.GetCameraUploadsConfigurationUseCase import com.owncloud.android.domain.camerauploads.usecases.SavePictureUploadsConfigurationUseCase import com.owncloud.android.domain.camerauploads.usecases.SaveVideoUploadsConfigurationUseCase +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferStatus import com.owncloud.android.presentation.ui.settings.SettingsActivity import com.owncloud.android.usecases.transfers.uploads.UploadEnqueuedBy import com.owncloud.android.usecases.transfers.uploads.UploadFileFromContentUriUseCase @@ -69,6 +72,8 @@ class CameraUploadsWorker( private val getCameraUploadsConfigurationUseCase: GetCameraUploadsConfigurationUseCase by inject() + private val transferRepository: TransferRepository by inject() + override suspend fun doWork(): Result { when (val useCaseResult = getCameraUploadsConfigurationUseCase.execute(Unit)) { @@ -285,16 +290,18 @@ class CameraUploadsWorker( behavior: UploadBehavior, createdByWorker: Int ): Long { - val uploadStorageManager = UploadsStorageManager(appContext.contentResolver) - - val ocUpload = OCUpload(documentFile.uri.toString(), uploadPath, accountName).apply { - fileSize = documentFile.length() - isForceOverwrite = false + val ocTransfer = OCTransfer( + localPath = documentFile.uri.toString(), + remotePath = uploadPath, + accountName = accountName, + fileSize = documentFile.length(), + status = TransferStatus.TRANSFER_QUEUED, + localBehaviour = behavior.toLegacyLocalBehavior(), + forceOverwrite = false, createdBy = createdByWorker - localAction = behavior.toLegacyLocalBehavior() - uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS - } - return uploadStorageManager.storeUpload(ocUpload) + ) + + return transferRepository.storeTransfer(ocTransfer) } companion object { From 8d504b11aba1f9cdb433aee8b08b460561af0627 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Wed, 13 Jul 2022 14:28:44 +0200 Subject: [PATCH 22/38] Adapted every use of UploadFilesFromSystemUseCase to new arch --- .../dependecyinjection/UseCaseModule.kt | 4 +++- .../providers/DocumentsStorageProvider.kt | 4 +--- .../ui/activity/ConflictsResolveActivity.java | 7 +++++- .../ui/activity/UploadListActivity.java | 24 ++++++++++++++++--- .../adapter/ExpandableUploadListAdapter.java | 11 +++++++-- .../CopyAndUploadContentUrisTask.java | 8 ++++++- .../ui/fragment/UploadListFragment.java | 15 +++++++++++- .../RetryFailedUploadsForAccountUseCase.kt | 11 ++++++--- .../uploads/RetryFailedUploadsUseCase.kt | 11 ++++++--- .../uploads/RetryUploadFromSystemUseCase.kt | 8 ++++--- 10 files changed, 82 insertions(+), 21 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt index ec7a2972f18..5e11c17dca8 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt @@ -76,6 +76,7 @@ import com.owncloud.android.usecases.transfers.downloads.DownloadFileUseCase import com.owncloud.android.usecases.transfers.downloads.GetLiveDataForDownloadingFileUseCase import com.owncloud.android.usecases.transfers.downloads.GetLiveDataForFinishedDownloadsFromAccountUseCase import com.owncloud.android.usecases.transfers.uploads.CancelUploadForFileUseCase +import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromSystemUseCase import com.owncloud.android.usecases.transfers.uploads.UploadFileInConflictUseCase import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSAFUseCase import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase @@ -135,9 +136,10 @@ val useCaseModule = module { factory { GetLiveDataForDownloadingFileUseCase(get()) } factory { GetLiveDataForFinishedDownloadsFromAccountUseCase(get()) } factory { UploadFilesFromSAFUseCase(get(), get()) } - factory { UploadFilesFromSystemUseCase(get()) } + factory { UploadFilesFromSystemUseCase(get(), get()) } factory { UploadFileInConflictUseCase(get()) } factory { CancelUploadForFileUseCase(get()) } + factory { RetryUploadFromSystemUseCase(get(), get()) } // User factory { GetStoredQuotaUseCase(get()) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.kt index 7206e3ed75e..c9f8675c692 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.kt @@ -35,7 +35,6 @@ import android.os.ParcelFileDescriptor import android.preference.PreferenceManager import android.provider.DocumentsContract import android.provider.DocumentsProvider -import androidx.work.WorkManager import com.owncloud.android.MainApp import com.owncloud.android.R import com.owncloud.android.authentication.AccountUtils @@ -131,8 +130,7 @@ class DocumentsStorageProvider : DocumentsProvider() { // If only needs to upload that file if (uploadOnly) { ocFile.length = fileToOpen.length() - val workManager = WorkManager.getInstance(MainApp.appContext) - val uploadFilesUseCase = UploadFilesFromSystemUseCase(workManager) + val uploadFilesUseCase: UploadFilesFromSystemUseCase by inject() val uploadFilesUseCaseParams = UploadFilesFromSystemUseCase.Params( accountName = ocFile.owner, listOfLocalPaths = listOf(fileToOpen.path), diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java index 89594065df4..d52ba7e6fc9 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java @@ -24,6 +24,9 @@ import android.os.Bundle; import androidx.work.WorkManager; +import com.owncloud.android.data.OwncloudDatabase; +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource; +import com.owncloud.android.data.transfers.repository.OCTransferRepository; import com.owncloud.android.domain.files.model.OCFile; import com.owncloud.android.ui.dialog.ConflictsResolveDialog; import com.owncloud.android.ui.dialog.ConflictsResolveDialog.Decision; @@ -87,7 +90,9 @@ public void conflictDecisionMade(Decision decision) { ); uploadFileInConflictUseCase.execute(params); } else { - UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager); + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(this).transferDao())); + UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); ArrayList listOfPaths = new ArrayList<>(); listOfPaths.add(getFile().getStoragePath()); UploadFilesFromSystemUseCase.Params params = new UploadFilesFromSystemUseCase.Params( diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java index 81a0ee8178c..35a98b9ef1d 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java @@ -30,8 +30,12 @@ import android.view.View; import androidx.fragment.app.FragmentTransaction; +import androidx.work.WorkManager; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; +import com.owncloud.android.data.OwncloudDatabase; +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource; +import com.owncloud.android.data.transfers.repository.OCTransferRepository; import com.owncloud.android.datamodel.OCUpload; import com.owncloud.android.datamodel.UploadsStorageManager; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -39,6 +43,9 @@ import com.owncloud.android.operations.CheckCurrentCredentialsOperation; import com.owncloud.android.ui.fragment.UploadListFragment; import com.owncloud.android.usecases.transfers.uploads.RetryFailedUploadsForAccountUseCase; +import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromContentUriUseCase; +import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromSystemUseCase; +import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase; import com.owncloud.android.utils.MimetypeIconUtil; import timber.log.Timber; @@ -141,8 +148,13 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (account == null) { return; } - - RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this); + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(this).transferDao())); + RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this); + WorkManager workManager = WorkManager.getInstance(this); + UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(this, uploadFilesFromSystemUseCase); + RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); retryFailedUploadsForAccountUseCase.execute(new RetryFailedUploadsForAccountUseCase.Params(account.name)); } } @@ -164,7 +176,13 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe } else { // already updated -> just retry! - RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this); + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(this).transferDao())); + RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this); + WorkManager workManager = WorkManager.getInstance(this); + UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(this, uploadFilesFromSystemUseCase); + RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); retryFailedUploadsForAccountUseCase.execute(new RetryFailedUploadsForAccountUseCase.Params(account.name)); } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java index 54f50aadb25..5f01b38e601 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java @@ -44,6 +44,9 @@ import com.google.android.material.snackbar.Snackbar; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; +import com.owncloud.android.data.OwncloudDatabase; +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource; +import com.owncloud.android.data.transfers.repository.OCTransferRepository; import com.owncloud.android.datamodel.OCUpload; import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.datamodel.UploadsStorageManager; @@ -58,6 +61,7 @@ import com.owncloud.android.usecases.transfers.uploads.CancelUploadWithIdUseCase; import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromContentUriUseCase; import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromSystemUseCase; +import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase; import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.MimetypeIconUtil; import com.owncloud.android.utils.PreferenceUtils; @@ -340,9 +344,12 @@ private View getView(OCUpload[] uploadsItems, int position, View convertView, Vi public void onClick(View v) { File file = new File(upload.getLocalPath()); if (file.exists()) { - RetryUploadFromSystemUseCase retryUploadFromContentUriUseCase = new RetryUploadFromSystemUseCase(v.getContext()); + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(v.getContext()).transferDao())); + WorkManager workManager = WorkManager.getInstance(v.getContext()); + UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(v.getContext(), uploadFilesFromSystemUseCase); RetryUploadFromSystemUseCase.Params useCaseParams = new RetryUploadFromSystemUseCase.Params(upload.getUploadId()); - retryUploadFromContentUriUseCase.execute(useCaseParams); + retryUploadFromSystemUseCase.execute(useCaseParams); refreshView(); } else if (DocumentFile.isDocumentUri(v.getContext(), Uri.parse(upload.getLocalPath()))) { RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/asynctasks/CopyAndUploadContentUrisTask.java b/owncloudApp/src/main/java/com/owncloud/android/ui/asynctasks/CopyAndUploadContentUrisTask.java index 3faf585e5e7..12004270846 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/asynctasks/CopyAndUploadContentUrisTask.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/asynctasks/CopyAndUploadContentUrisTask.java @@ -30,6 +30,10 @@ import androidx.work.WorkManager; import com.owncloud.android.R; +import com.owncloud.android.data.OwncloudDatabase; +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource; +import com.owncloud.android.data.transfers.db.TransferDao; +import com.owncloud.android.data.transfers.repository.OCTransferRepository; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase; import com.owncloud.android.utils.FileStorageUtils; @@ -159,7 +163,9 @@ protected ResultCode doInBackground(Object[] params) { filesToUpload.add(fullTempPath); WorkManager workManager = WorkManager.getInstance(mAppContext); - UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager); + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(mAppContext).transferDao())); + UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); UploadFilesFromSystemUseCase.Params useCaseParams = new UploadFilesFromSystemUseCase.Params( account.name, filesToUpload, diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java index 6bbe6574bee..547a22bbf2e 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java @@ -26,12 +26,19 @@ import android.widget.ExpandableListView; import android.widget.ListView; +import androidx.work.WorkManager; import com.owncloud.android.R; +import com.owncloud.android.data.OwncloudDatabase; +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource; +import com.owncloud.android.data.transfers.repository.OCTransferRepository; import com.owncloud.android.datamodel.OCUpload; import com.owncloud.android.datamodel.UploadsStorageManager; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.adapter.ExpandableUploadListAdapter; import com.owncloud.android.usecases.transfers.uploads.RetryFailedUploadsUseCase; +import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromContentUriUseCase; +import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromSystemUseCase; +import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase; import kotlin.Unit; import timber.log.Timber; @@ -117,7 +124,13 @@ public void onClick(OptionsInUploadList option) { switch (option) { case RETRY_FAILED: - RetryFailedUploadsUseCase retryFailedUploadsUseCase = new RetryFailedUploadsUseCase(requireContext()); + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(requireContext()).transferDao())); + RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(requireContext()); + WorkManager workManager = WorkManager.getInstance(requireContext()); + UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(requireContext(), uploadFilesFromSystemUseCase); + RetryFailedUploadsUseCase retryFailedUploadsUseCase = new RetryFailedUploadsUseCase(requireContext(), retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); retryFailedUploadsUseCase.execute(Unit.INSTANCE); break; case CLEAR_FAILED: diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt index 6e42ec6f392..abd12ff7f64 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import android.content.Context @@ -28,6 +31,8 @@ import timber.log.Timber class RetryFailedUploadsForAccountUseCase( private val context: Context, + private val retryUploadFromContentUriUseCase: RetryUploadFromContentUriUseCase, + private val retryUploadFromSystemUseCase: RetryUploadFromSystemUseCase, ) : BaseUseCase() { override fun run(params: Params) { @@ -43,9 +48,9 @@ class RetryFailedUploadsForAccountUseCase( failedUploadsForAccount.forEach { upload -> if (isContentUri(context = context, upload = upload)) { - RetryUploadFromContentUriUseCase(context).execute(RetryUploadFromContentUriUseCase.Params(upload.uploadId)) + retryUploadFromContentUriUseCase.execute(RetryUploadFromContentUriUseCase.Params(upload.uploadId)) } else { - RetryUploadFromSystemUseCase(context).execute(RetryUploadFromSystemUseCase.Params(upload.uploadId)) + retryUploadFromSystemUseCase.execute(RetryUploadFromSystemUseCase.Params(upload.uploadId)) } } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt index b0e2480dc3b..6cce1620c75 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import android.content.Context @@ -28,6 +31,8 @@ import timber.log.Timber class RetryFailedUploadsUseCase( private val context: Context, + private val retryUploadFromContentUriUseCase: RetryUploadFromContentUriUseCase, + private val retryUploadFromSystemUseCase: RetryUploadFromSystemUseCase, ) : BaseUseCase() { override fun run(params: Unit) { @@ -41,9 +46,9 @@ class RetryFailedUploadsUseCase( } failedUploads.forEach { upload -> if (isContentUri(context = context, upload = upload)) { - RetryUploadFromContentUriUseCase(context).execute(RetryUploadFromContentUriUseCase.Params(upload.uploadId)) + retryUploadFromContentUriUseCase.execute(RetryUploadFromContentUriUseCase.Params(upload.uploadId)) } else { - RetryUploadFromSystemUseCase(context).execute(RetryUploadFromSystemUseCase.Params(upload.uploadId)) + retryUploadFromSystemUseCase.execute(RetryUploadFromSystemUseCase.Params(upload.uploadId)) } } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt index c8007de92c4..45ce4d19d0f 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt @@ -2,6 +2,8 @@ * ownCloud Android client application * * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón + * * Copyright (C) 2021 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify @@ -16,16 +18,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import android.content.Context -import androidx.work.WorkManager import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.files.model.OCFile.Companion.PATH_SEPARATOR class RetryUploadFromSystemUseCase( private val context: Context, + private val uploadFilesFromSystemUseCase: UploadFilesFromSystemUseCase, ) : BaseUseCase() { override fun run(params: Params) { @@ -37,8 +40,7 @@ class RetryUploadFromSystemUseCase( uploadToRetry ?: return - val workManager = WorkManager.getInstance(context) - UploadFilesFromSystemUseCase(workManager).execute( + uploadFilesFromSystemUseCase.execute( UploadFilesFromSystemUseCase.Params( accountName = uploadToRetry.accountName, listOfLocalPaths = listOf(uploadToRetry.localPath), From d023eda5a5aba952437cb281f04202c32913c2d4 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Wed, 13 Jul 2022 16:45:33 +0200 Subject: [PATCH 23/38] Changed main execution of UploadFilesFromSystemUseCase to IO thread --- .../dependecyinjection/ViewModelModule.kt | 2 +- .../viewmodels/transfers/TransfersViewModel.kt | 18 ++++++++++++++++++ .../android/ui/activity/FileDisplayActivity.kt | 9 ++++----- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt index 32b957fb212..328dc7aca50 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt @@ -88,5 +88,5 @@ val viewModelModule = module { viewModel { FileDetailsViewModel(get(), get(), get(), get(), get()) } viewModel { FileOperationsViewModel(get(), get(), get(), get(), get(), get(), get(), get()) } viewModel { MainFileListViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } - viewModel { TransfersViewModel(get(), get()) } + viewModel { TransfersViewModel(get(), get(), get()) } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt index 7110f47bb9e..bd14dbcda65 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt @@ -25,10 +25,12 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.owncloud.android.providers.CoroutinesDispatcherProvider import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSAFUseCase +import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase import kotlinx.coroutines.launch class TransfersViewModel( private val uploadFilesFromSAFUseCase: UploadFilesFromSAFUseCase, + private val uploadFilesFromSystemUseCase: UploadFilesFromSystemUseCase, private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider, ): ViewModel() { fun uploadFilesFromSAF( @@ -46,4 +48,20 @@ class TransfersViewModel( ) } } + + fun uploadFilesFromSystem( + accountName: String, + listOfLocalPaths: List, + uploadFolderPath: String + ) { + viewModelScope.launch(coroutinesDispatcherProvider.io) { + uploadFilesFromSystemUseCase.execute( + UploadFilesFromSystemUseCase.Params( + accountName = accountName, + listOfLocalPaths = listOfLocalPaths, + uploadFolderPath = uploadFolderPath + ) + ) + } + } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 6f5b340b1c1..84b8424cb05 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -541,11 +541,10 @@ class FileDisplayActivity : FileActivity(), remotePaths[j] = remotePathBase + File(filePaths[j]).name } - val uploadFilesFromSystemUseCase: UploadFilesFromSystemUseCase by inject() - uploadFilesFromSystemUseCase.execute( - UploadFilesFromSystemUseCase.Params( - accountName = account.name, listOfLocalPaths = filePaths.toList(), uploadFolderPath = remotePathBase!! - ) + transfersViewModel.uploadFilesFromSystem( + accountName = account.name, + listOfLocalPaths = filePaths.toList(), + uploadFolderPath = remotePathBase!! ) } else { From 6a54f94d8b4d05dbb75ce16d613f48368365ef8d Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Wed, 13 Jul 2022 18:14:04 +0200 Subject: [PATCH 24/38] Move UploadFileInConflictUseCase to new arch --- .../dependecyinjection/UseCaseModule.kt | 2 +- .../operations/SynchronizeFileOperation.java | 7 ++++- .../ui/activity/ConflictsResolveActivity.java | 4 ++- .../uploads/UploadFileInConflictUseCase.kt | 29 +++++++++++-------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt index 5e11c17dca8..fd0ac67a51d 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt @@ -137,7 +137,7 @@ val useCaseModule = module { factory { GetLiveDataForFinishedDownloadsFromAccountUseCase(get()) } factory { UploadFilesFromSAFUseCase(get(), get()) } factory { UploadFilesFromSystemUseCase(get(), get()) } - factory { UploadFileInConflictUseCase(get()) } + factory { UploadFileInConflictUseCase(get(), get()) } factory { CancelUploadForFileUseCase(get()) } factory { RetryUploadFromSystemUseCase(get(), get()) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java b/owncloudApp/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java index 0c6f6a5627d..da006f6a0cc 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java +++ b/owncloudApp/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java @@ -28,6 +28,9 @@ import android.content.Context; import androidx.work.WorkManager; +import com.owncloud.android.data.OwncloudDatabase; +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource; +import com.owncloud.android.data.transfers.repository.OCTransferRepository; import com.owncloud.android.domain.files.model.OCFile; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -229,7 +232,9 @@ protected RemoteOperationResult run(OwnCloudClient client) { */ private void requestForUpload(OCFile file) { WorkManager workManager = WorkManager.getInstance(mContext); - UploadFileInConflictUseCase uploadFileInConflictUseCase = new UploadFileInConflictUseCase(workManager); + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(mContext).transferDao())); + UploadFileInConflictUseCase uploadFileInConflictUseCase = new UploadFileInConflictUseCase(workManager, transferRepository); UploadFileInConflictUseCase.Params params = new UploadFileInConflictUseCase.Params( file.getOwner(), file.getStoragePath(), diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java index d52ba7e6fc9..2a17bdc14bf 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java @@ -82,7 +82,9 @@ public void conflictDecisionMade(Decision decision) { WorkManager workManager = WorkManager.getInstance(getApplicationContext()); if (forceOverwrite) { - UploadFileInConflictUseCase uploadFileInConflictUseCase = new UploadFileInConflictUseCase(workManager); + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(this).transferDao())); + UploadFileInConflictUseCase uploadFileInConflictUseCase = new UploadFileInConflictUseCase(workManager, transferRepository); UploadFileInConflictUseCase.Params params = new UploadFileInConflictUseCase.Params( getFile().getOwner(), getFile().getStoragePath(), diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFileInConflictUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFileInConflictUseCase.kt index e5a4e516ff8..2a4fc50f384 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFileInConflictUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFileInConflictUseCase.kt @@ -2,6 +2,8 @@ * ownCloud Android client application * * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón + * * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify @@ -16,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import androidx.work.Constraints @@ -23,11 +26,11 @@ import androidx.work.NetworkType import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import androidx.work.workDataOf -import com.owncloud.android.MainApp -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.camerauploads.model.UploadBehavior +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferStatus import com.owncloud.android.workers.UploadFileFromFileSystemWorker import timber.log.Timber import java.io.File @@ -42,6 +45,7 @@ import java.util.UUID */ class UploadFileInConflictUseCase( private val workManager: WorkManager, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params): UUID? { @@ -73,17 +77,18 @@ class UploadFileInConflictUseCase( uploadPath: String, accountName: String, ): Long { - val uploadStorageManager = UploadsStorageManager(MainApp.appContext.contentResolver) - - val ocUpload = OCUpload(localFile.absolutePath, uploadPath, accountName).apply { - fileSize = localFile.length() - isForceOverwrite = true + val ocTransfer = OCTransfer( + localPath = localFile.absolutePath, + remotePath = uploadPath, + accountName = accountName, + fileSize = localFile.length(), + status = TransferStatus.TRANSFER_QUEUED, + localBehaviour = UploadBehavior.COPY.ordinal, + forceOverwrite = true, createdBy = UploadEnqueuedBy.ENQUEUED_BY_USER.ordinal - localAction = UploadBehavior.COPY.ordinal - uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS - } + ) - return uploadStorageManager.storeUpload(ocUpload).also { + return transferRepository.storeTransfer(ocTransfer).also { Timber.i("Upload of $uploadPath has been stored in the uploads database with id: $it") } } From 83d1b3ac04eaf7e2a3f370171a4e81a1009ab7eb Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Wed, 13 Jul 2022 18:27:29 +0200 Subject: [PATCH 25/38] Move RetryUploadFromSystemUseCase to new arch --- .../android/ui/activity/UploadListActivity.java | 4 ++-- .../ui/adapter/ExpandableUploadListAdapter.java | 2 +- .../android/ui/fragment/UploadListFragment.java | 2 +- .../uploads/RetryUploadFromSystemUseCase.kt | 14 +++++++------- .../android/domain/transfers/model/OCTransfer.kt | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java index 35a98b9ef1d..4627216e93a 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java @@ -153,7 +153,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this); WorkManager workManager = WorkManager.getInstance(this); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); - RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(this, uploadFilesFromSystemUseCase); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); retryFailedUploadsForAccountUseCase.execute(new RetryFailedUploadsForAccountUseCase.Params(account.name)); } @@ -181,7 +181,7 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this); WorkManager workManager = WorkManager.getInstance(this); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); - RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(this, uploadFilesFromSystemUseCase); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); retryFailedUploadsForAccountUseCase.execute(new RetryFailedUploadsForAccountUseCase.Params(account.name)); } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java index 5f01b38e601..b7c8d3cce1a 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java @@ -347,7 +347,7 @@ public void onClick(View v) { OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(v.getContext()).transferDao())); WorkManager workManager = WorkManager.getInstance(v.getContext()); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); - RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(v.getContext(), uploadFilesFromSystemUseCase); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); RetryUploadFromSystemUseCase.Params useCaseParams = new RetryUploadFromSystemUseCase.Params(upload.getUploadId()); retryUploadFromSystemUseCase.execute(useCaseParams); refreshView(); diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java index 547a22bbf2e..176812a4dc7 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java @@ -129,7 +129,7 @@ public void onClick(OptionsInUploadList option) { RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(requireContext()); WorkManager workManager = WorkManager.getInstance(requireContext()); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); - RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(requireContext(), uploadFilesFromSystemUseCase); + RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); RetryFailedUploadsUseCase retryFailedUploadsUseCase = new RetryFailedUploadsUseCase(requireContext(), retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); retryFailedUploadsUseCase.execute(Unit.INSTANCE); break; diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt index 45ce4d19d0f..34a0fa1bf2e 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt @@ -21,21 +21,20 @@ package com.owncloud.android.usecases.transfers.uploads -import android.content.Context -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.files.model.OCFile.Companion.PATH_SEPARATOR +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.TransferStatus class RetryUploadFromSystemUseCase( - private val context: Context, private val uploadFilesFromSystemUseCase: UploadFilesFromSystemUseCase, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params) { - val uploadsStorageManager = UploadsStorageManager(context.contentResolver) - val failedUploads = uploadsStorageManager.failedUploads - val filteredUploads = failedUploads.filter { it.uploadId == params.uploadIdInStorageManager } + val failedUploads = transferRepository.getFailedTransfers() + val filteredUploads = failedUploads.filter { it.id == params.uploadIdInStorageManager } val uploadToRetry = filteredUploads.firstOrNull() uploadToRetry ?: return @@ -47,7 +46,8 @@ class RetryUploadFromSystemUseCase( uploadFolderPath = uploadToRetry.remotePath.trimEnd(PATH_SEPARATOR), ) ) - uploadsStorageManager.updateUpload(uploadToRetry.apply { uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS }) + + transferRepository.updateTransfer(uploadToRetry.apply { status = TransferStatus.TRANSFER_IN_PROGRESS }) } data class Params( diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt index 3d3a5469189..a789373cd20 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/OCTransfer.kt @@ -31,7 +31,7 @@ data class OCTransfer( val remotePath: String, val accountName: String, val fileSize: Long, - val status: TransferStatus, + var status: TransferStatus, val localBehaviour: Int, val forceOverwrite: Boolean, val transferEndTimestamp: Long? = null, From 3b842dd6a9e8e8fd76303fe3246e48a47e5956dd Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Wed, 13 Jul 2022 18:42:26 +0200 Subject: [PATCH 26/38] Move RetryUploadFromContentUriUseCase to new arch --- .../ui/activity/UploadListActivity.java | 4 ++-- .../adapter/ExpandableUploadListAdapter.java | 4 +++- .../ui/fragment/UploadListFragment.java | 2 +- .../RetryUploadFromContentUriUseCase.kt | 23 +++++++++++-------- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java index 4627216e93a..706633f2f65 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java @@ -150,7 +150,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } // Workaround... should be removed as soon as possible OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(this).transferDao())); - RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this); + RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this, transferRepository); WorkManager workManager = WorkManager.getInstance(this); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); @@ -178,7 +178,7 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe // already updated -> just retry! // Workaround... should be removed as soon as possible OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(this).transferDao())); - RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this); + RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(this, transferRepository); WorkManager workManager = WorkManager.getInstance(this); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java index b7c8d3cce1a..af1b8753677 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java @@ -352,8 +352,10 @@ public void onClick(View v) { retryUploadFromSystemUseCase.execute(useCaseParams); refreshView(); } else if (DocumentFile.isDocumentUri(v.getContext(), Uri.parse(upload.getLocalPath()))) { + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(v.getContext()).transferDao())); RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = - new RetryUploadFromContentUriUseCase(v.getContext()); + new RetryUploadFromContentUriUseCase(v.getContext(), transferRepository); RetryUploadFromContentUriUseCase.Params useCaseParams = new RetryUploadFromContentUriUseCase.Params( upload.getUploadId() ); diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java index 176812a4dc7..5f9f2d1423b 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java @@ -126,7 +126,7 @@ public void onClick(OptionsInUploadList option) { case RETRY_FAILED: // Workaround... should be removed as soon as possible OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(requireContext()).transferDao())); - RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(requireContext()); + RetryUploadFromContentUriUseCase retryUploadFromContentUriUseCase = new RetryUploadFromContentUriUseCase(requireContext(), transferRepository); WorkManager workManager = WorkManager.getInstance(requireContext()); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt index a4bdebf4468..243b2f0b8ca 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,24 +18,26 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import android.content.Context import androidx.core.net.toUri import androidx.work.WorkManager -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.camerauploads.model.UploadBehavior +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.TransferStatus class RetryUploadFromContentUriUseCase( private val context: Context, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params) { - val uploadsStorageManager = UploadsStorageManager(context.contentResolver) - val failedUploads = uploadsStorageManager.failedUploads - val filteredUploads = failedUploads.filter { it.uploadId == params.uploadIdInStorageManager } + val failedUploads = transferRepository.getFailedTransfers() + val filteredUploads = failedUploads.filter { it.id == params.uploadIdInStorageManager } val uploadToRetry = filteredUploads.firstOrNull() uploadToRetry ?: return @@ -43,15 +47,16 @@ class RetryUploadFromContentUriUseCase( UploadFileFromContentUriUseCase.Params( accountName = uploadToRetry.accountName, contentUri = uploadToRetry.localPath.toUri(), - lastModifiedInSeconds = (uploadToRetry.uploadEndTimestamp / 1000).toString(), - behavior = UploadBehavior.fromLegacyLocalBehavior(uploadToRetry.localAction).name, + lastModifiedInSeconds = (uploadToRetry.transferEndTimestamp?.div(1000)).toString(), + behavior = UploadBehavior.fromLegacyLocalBehavior(uploadToRetry.localBehaviour).name, uploadPath = uploadToRetry.remotePath, - uploadIdInStorageManager = uploadToRetry.uploadId, + uploadIdInStorageManager = uploadToRetry.id!!, wifiOnly = false, chargingOnly = false ) ) - uploadsStorageManager.updateUpload(uploadToRetry.apply { uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS }) + + transferRepository.updateTransfer(uploadToRetry.apply { status = TransferStatus.TRANSFER_IN_PROGRESS }) } data class Params( From 3d7bc4ba6b7ea6357a7c6dd50a9048024e49607d Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Thu, 14 Jul 2022 08:53:47 +0200 Subject: [PATCH 27/38] Move RetryFailedUploadsUseCase to new arch --- .../android/ui/fragment/UploadListFragment.java | 2 +- .../transfers/uploads/RetryFailedUploadsUseCase.kt | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java index 5f9f2d1423b..48b4ed47d5f 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/fragment/UploadListFragment.java @@ -130,7 +130,7 @@ public void onClick(OptionsInUploadList option) { WorkManager workManager = WorkManager.getInstance(requireContext()); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); - RetryFailedUploadsUseCase retryFailedUploadsUseCase = new RetryFailedUploadsUseCase(requireContext(), retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); + RetryFailedUploadsUseCase retryFailedUploadsUseCase = new RetryFailedUploadsUseCase(requireContext(), retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase, transferRepository); retryFailedUploadsUseCase.execute(Unit.INSTANCE); break; case CLEAR_FAILED: diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt index 6cce1620c75..10218edd749 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt @@ -27,18 +27,19 @@ import androidx.documentfile.provider.DocumentFile import com.owncloud.android.datamodel.OCUpload import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer import timber.log.Timber class RetryFailedUploadsUseCase( private val context: Context, private val retryUploadFromContentUriUseCase: RetryUploadFromContentUriUseCase, private val retryUploadFromSystemUseCase: RetryUploadFromSystemUseCase, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Unit) { - - val uploadsStorageManager = UploadsStorageManager(context.contentResolver) - val failedUploads = uploadsStorageManager.failedUploads + val failedUploads = transferRepository.getFailedTransfers() if (failedUploads.isEmpty()) { Timber.d("There are no failed uploads to retry.") @@ -46,14 +47,14 @@ class RetryFailedUploadsUseCase( } failedUploads.forEach { upload -> if (isContentUri(context = context, upload = upload)) { - retryUploadFromContentUriUseCase.execute(RetryUploadFromContentUriUseCase.Params(upload.uploadId)) + retryUploadFromContentUriUseCase.execute(RetryUploadFromContentUriUseCase.Params(upload.id!!)) } else { - retryUploadFromSystemUseCase.execute(RetryUploadFromSystemUseCase.Params(upload.uploadId)) + retryUploadFromSystemUseCase.execute(RetryUploadFromSystemUseCase.Params(upload.id!!)) } } } - private fun isContentUri(context: Context, upload: OCUpload): Boolean { + private fun isContentUri(context: Context, upload: OCTransfer): Boolean { return DocumentFile.isDocumentUri(context, Uri.parse(upload.localPath)) } From 40577d0a5caa54afcb56635f83d388addee45cb4 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Thu, 14 Jul 2022 08:57:09 +0200 Subject: [PATCH 28/38] Removed unused imports --- .../usecases/transfers/uploads/RetryFailedUploadsUseCase.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt index 10218edd749..5d140efcb90 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsUseCase.kt @@ -24,8 +24,6 @@ package com.owncloud.android.usecases.transfers.uploads import android.content.Context import android.net.Uri import androidx.documentfile.provider.DocumentFile -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.transfers.TransferRepository import com.owncloud.android.domain.transfers.model.OCTransfer From 34ba67d9921566a5539980eab79e507ed79b3f38 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Thu, 14 Jul 2022 09:25:03 +0200 Subject: [PATCH 29/38] Move RetryFailedUploadsForAccountUseCase to new arch --- .../android/ui/activity/UploadListActivity.java | 4 ++-- .../RetryFailedUploadsForAccountUseCase.kt | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java index 706633f2f65..3969893cd8c 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java @@ -154,7 +154,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { WorkManager workManager = WorkManager.getInstance(this); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); - RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); + RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase, transferRepository); retryFailedUploadsForAccountUseCase.execute(new RetryFailedUploadsForAccountUseCase.Params(account.name)); } } @@ -182,7 +182,7 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe WorkManager workManager = WorkManager.getInstance(this); UploadFilesFromSystemUseCase uploadFilesFromSystemUseCase = new UploadFilesFromSystemUseCase(workManager, transferRepository); RetryUploadFromSystemUseCase retryUploadFromSystemUseCase = new RetryUploadFromSystemUseCase(uploadFilesFromSystemUseCase, transferRepository); - RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase); + RetryFailedUploadsForAccountUseCase retryFailedUploadsForAccountUseCase = new RetryFailedUploadsForAccountUseCase(this, retryUploadFromContentUriUseCase, retryUploadFromSystemUseCase, transferRepository); retryFailedUploadsForAccountUseCase.execute(new RetryFailedUploadsForAccountUseCase.Params(account.name)); } diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt index abd12ff7f64..7e061f06e04 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryFailedUploadsForAccountUseCase.kt @@ -24,21 +24,20 @@ package com.owncloud.android.usecases.transfers.uploads import android.content.Context import android.net.Uri import androidx.documentfile.provider.DocumentFile -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase +import com.owncloud.android.domain.transfers.TransferRepository +import com.owncloud.android.domain.transfers.model.OCTransfer import timber.log.Timber class RetryFailedUploadsForAccountUseCase( private val context: Context, private val retryUploadFromContentUriUseCase: RetryUploadFromContentUriUseCase, private val retryUploadFromSystemUseCase: RetryUploadFromSystemUseCase, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params) { - - val uploadsStorageManager = UploadsStorageManager(context.contentResolver) - val failedUploads = uploadsStorageManager.failedUploads + val failedUploads = transferRepository.getFailedTransfers() val failedUploadsForAccount = failedUploads.filter { it.accountName == params.accountName } if (failedUploadsForAccount.isEmpty()) { @@ -48,14 +47,14 @@ class RetryFailedUploadsForAccountUseCase( failedUploadsForAccount.forEach { upload -> if (isContentUri(context = context, upload = upload)) { - retryUploadFromContentUriUseCase.execute(RetryUploadFromContentUriUseCase.Params(upload.uploadId)) + retryUploadFromContentUriUseCase.execute(RetryUploadFromContentUriUseCase.Params(upload.id!!)) } else { - retryUploadFromSystemUseCase.execute(RetryUploadFromSystemUseCase.Params(upload.uploadId)) + retryUploadFromSystemUseCase.execute(RetryUploadFromSystemUseCase.Params(upload.id!!)) } } } - private fun isContentUri(context: Context, upload: OCUpload): Boolean { + private fun isContentUri(context: Context, upload: OCTransfer): Boolean { return DocumentFile.isDocumentUri(context, Uri.parse(upload.localPath)) } From 439f743b9ad887cb6eadeb0b2b689d4ef9dd8bf3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Thu, 14 Jul 2022 09:37:57 +0200 Subject: [PATCH 30/38] Move CancelUploadWithIdUseCase to new arch --- .../adapter/ExpandableUploadListAdapter.java | 5 +++-- .../uploads/CancelUploadWithIdUseCase.kt | 21 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java index af1b8753677..8b6c19d53f1 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java @@ -312,8 +312,9 @@ private View getView(OCUpload[] uploadsItems, int position, View convertView, Vi rightButton.setImageResource(R.drawable.ic_action_cancel_grey); rightButton.setVisibility(View.VISIBLE); rightButton.setOnClickListener(v -> { - CancelUploadWithIdUseCase cancelUploadWithIdUseCase = new CancelUploadWithIdUseCase(WorkManager.getInstance(parent.getContext())); - cancelUploadWithIdUseCase.execute(new CancelUploadWithIdUseCase.Params(upload)); + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(v.getContext()).transferDao())); + CancelUploadWithIdUseCase cancelUploadWithIdUseCase = new CancelUploadWithIdUseCase(WorkManager.getInstance(parent.getContext()), transferRepository); + cancelUploadWithIdUseCase.execute(new CancelUploadWithIdUseCase.Params(upload.getUploadId())); refreshView(); }); diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadWithIdUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadWithIdUseCase.kt index 1b2f1a3a530..ee883235780 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadWithIdUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadWithIdUseCase.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,29 +18,28 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import androidx.work.WorkManager -import com.owncloud.android.MainApp -import com.owncloud.android.datamodel.OCUpload -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase +import com.owncloud.android.domain.transfers.TransferRepository import timber.log.Timber class CancelUploadWithIdUseCase( - private val workManager: WorkManager + private val workManager: WorkManager, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params) { - workManager.cancelAllWorkByTag(params.upload.uploadId.toString()) + workManager.cancelAllWorkByTag(params.uploadId.toString()) - val uploadsStorageManager = UploadsStorageManager(MainApp.appContext.contentResolver) - uploadsStorageManager.removeUpload(params.upload) + transferRepository.removeTransferById(params.uploadId) - Timber.i("Upload with id ${params.upload.uploadId} has been cancelled.") + Timber.i("Upload with id ${params.uploadId} has been cancelled.") } data class Params( - val upload: OCUpload, + val uploadId: Long, ) } From e40d536c5cb66c96316edd909242fee175fba11e Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Thu, 14 Jul 2022 09:46:02 +0200 Subject: [PATCH 31/38] Move CancelUploadsFromAccountUseCase to new arch --- .../ui/activity/ManageAccountsActivity.java | 13 ++++++++---- ....kt => CancelUploadsFromAccountUseCase.kt} | 20 ++++++++++--------- 2 files changed, 20 insertions(+), 13 deletions(-) rename owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/{CancelUploadFromAccountUseCase.kt => CancelUploadsFromAccountUseCase.kt} (66%) diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java index 1a7c795c110..726d4f11be6 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java @@ -42,6 +42,9 @@ import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; +import com.owncloud.android.data.OwncloudDatabase; +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource; +import com.owncloud.android.data.transfers.repository.OCTransferRepository; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.presentation.ui.authentication.AuthenticatorConstants; import com.owncloud.android.presentation.ui.authentication.LoginActivity; @@ -51,7 +54,7 @@ import com.owncloud.android.ui.dialog.RemoveAccountDialogFragment; import com.owncloud.android.ui.dialog.RemoveAccountDialogViewModel; import com.owncloud.android.ui.helpers.FileOperationsHelper; -import com.owncloud.android.usecases.transfers.uploads.CancelUploadFromAccountUseCase; +import com.owncloud.android.usecases.transfers.uploads.CancelUploadsFromAccountUseCase; import com.owncloud.android.usecases.transfers.downloads.CancelDownloadsForAccountUseCase; import com.owncloud.android.utils.PreferenceUtils; import kotlin.Lazy; @@ -294,10 +297,12 @@ public void run(AccountManagerFuture future) { if (future != null && future.isDone()) { Account account = new Account(mAccountBeingRemoved, MainApp.Companion.getAccountType()); if (!AccountUtils.exists(account.name, MainApp.Companion.getAppContext())) { + // Workaround... should be removed as soon as possible + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(this).transferDao())); // Cancel transfers of the removed account - CancelUploadFromAccountUseCase cancelUploadFromAccountUseCase = - new CancelUploadFromAccountUseCase(WorkManager.getInstance(getBaseContext())); - cancelUploadFromAccountUseCase.execute(new CancelUploadFromAccountUseCase.Params(account.name)); + CancelUploadsFromAccountUseCase cancelUploadsFromAccountUseCase = + new CancelUploadsFromAccountUseCase(WorkManager.getInstance(getBaseContext()), transferRepository); + cancelUploadsFromAccountUseCase.execute(new CancelUploadsFromAccountUseCase.Params(account.name)); CancelDownloadsForAccountUseCase cancelDownloadsForAccountUseCase = new CancelDownloadsForAccountUseCase(WorkManager.getInstance(getBaseContext())); diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadFromAccountUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadsFromAccountUseCase.kt similarity index 66% rename from owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadFromAccountUseCase.kt rename to owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadsFromAccountUseCase.kt index ceb465cca29..04dea853992 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadFromAccountUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadsFromAccountUseCase.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,25 +18,25 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import androidx.work.WorkManager -import com.owncloud.android.MainApp -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase +import com.owncloud.android.domain.transfers.TransferRepository import timber.log.Timber -class CancelUploadFromAccountUseCase( - private val workManager: WorkManager -) : BaseUseCase() { +class CancelUploadsFromAccountUseCase( + private val workManager: WorkManager, + private val transferRepository: TransferRepository, +) : BaseUseCase() { override fun run(params: Params) { workManager.cancelAllWorkByTag(params.accountName) - val uploadsStorageManager = UploadsStorageManager(MainApp.appContext.contentResolver) - uploadsStorageManager.removeUploads(params.accountName) + transferRepository.removeAllTransfersFromAccount(params.accountName) - Timber.i("Uploads of ${params.accountName} has been cancelled.") + Timber.i("Uploads of ${params.accountName} have been cancelled.") } data class Params( From b36cc051ba3866d236a496a909221be769c19071 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Thu, 14 Jul 2022 09:51:06 +0200 Subject: [PATCH 32/38] Move CancelUploadForFileUseCase to new arch --- .../android/dependecyinjection/UseCaseModule.kt | 2 +- .../uploads/CancelUploadForFileUseCase.kt | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt index fd0ac67a51d..e95bc62bda3 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt @@ -138,7 +138,7 @@ val useCaseModule = module { factory { UploadFilesFromSAFUseCase(get(), get()) } factory { UploadFilesFromSystemUseCase(get(), get()) } factory { UploadFileInConflictUseCase(get(), get()) } - factory { CancelUploadForFileUseCase(get()) } + factory { CancelUploadForFileUseCase(get(), get()) } factory { RetryUploadFromSystemUseCase(get(), get()) } // User diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt index 0cb8781815a..ec762eb9168 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2021 ownCloud GmbH. + * @author Juan Carlos Garrote Gascón + * + * Copyright (C) 2022 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -16,13 +18,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package com.owncloud.android.usecases.transfers.uploads import androidx.work.WorkManager import com.owncloud.android.MainApp -import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.files.model.OCFile +import com.owncloud.android.domain.transfers.TransferRepository import com.owncloud.android.extensions.getWorkInfoByTags import com.owncloud.android.workers.UploadFileFromContentUriWorker.Companion.TRANSFER_TAG_MANUAL_UPLOAD import timber.log.Timber @@ -32,16 +35,16 @@ import timber.log.Timber * policy and work that is already executing may continue to run. */ class CancelUploadForFileUseCase( - private val workManager: WorkManager + private val workManager: WorkManager, + private val transferRepository: TransferRepository, ) : BaseUseCase() { override fun run(params: Params) { val file = params.file - val uploadsStorageManager = UploadsStorageManager(MainApp.appContext.contentResolver) // Check if there are pending uploads for this file. // FirstOrNull because it should not be 2 uploads with same owner and remote path at the same time - val uploadForFile = uploadsStorageManager.currentAndPendingUploads.firstOrNull { + val uploadForFile = transferRepository.getCurrentAndPendingTransfers().firstOrNull { file.owner == it.accountName && file.remotePath == it.remotePath } @@ -51,7 +54,7 @@ class CancelUploadForFileUseCase( } val workersToCancel = - workManager.getWorkInfoByTags(listOf(TRANSFER_TAG_MANUAL_UPLOAD, uploadForFile.uploadId.toString(), file.owner)) + workManager.getWorkInfoByTags(listOf(TRANSFER_TAG_MANUAL_UPLOAD, uploadForFile.id.toString(), file.owner)) workersToCancel.forEach { // TODO: We need to check if the work is cancelled before finishing. From de04b77bc8b96336b3e16d81bc9f3425627e961b Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Thu, 14 Jul 2022 10:02:37 +0200 Subject: [PATCH 33/38] Clear old UploadsStorageManager code --- .../datamodel/UploadsStorageManager.java | 197 ------------------ .../adapter/ExpandableUploadListAdapter.java | 3 +- 2 files changed, 2 insertions(+), 198 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java b/owncloudApp/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java index 101d9f93e94..bb8634a2088 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java +++ b/owncloudApp/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java @@ -94,42 +94,6 @@ public UploadsStorageManager(ContentResolver contentResolver) { mContentResolver = contentResolver; } - /** - * Stores an upload object in DB. - * - * @param ocUpload Upload object to store - * @return upload id, -1 if the insert process fails. - */ - public long storeUpload(OCUpload ocUpload) { - Timber.v("Inserting " + ocUpload.getLocalPath() + " with status=" + ocUpload.getUploadStatus()); - - ContentValues cv = new ContentValues(); - cv.put(ProviderTableMeta.UPLOADS_LOCAL_PATH, ocUpload.getLocalPath()); - cv.put(ProviderTableMeta.UPLOADS_REMOTE_PATH, ocUpload.getRemotePath()); - cv.put(ProviderTableMeta.UPLOADS_ACCOUNT_NAME, ocUpload.getAccountName()); - cv.put(ProviderTableMeta.UPLOADS_FILE_SIZE, ocUpload.getFileSize()); - cv.put(ProviderTableMeta.UPLOADS_STATUS, ocUpload.getUploadStatus().value); - cv.put(ProviderTableMeta.UPLOADS_LOCAL_BEHAVIOUR, ocUpload.getLocalAction()); - cv.put(ProviderTableMeta.UPLOADS_FORCE_OVERWRITE, ocUpload.isForceOverwrite() ? 1 : 0); - cv.put(ProviderTableMeta.UPLOADS_IS_CREATE_REMOTE_FOLDER, ocUpload.createsRemoteFolder() ? 1 : 0); - cv.put(ProviderTableMeta.UPLOADS_LAST_RESULT, ocUpload.getLastResult().getValue()); - cv.put(ProviderTableMeta.UPLOADS_CREATED_BY, ocUpload.getCreatedBy()); - cv.put(ProviderTableMeta.UPLOADS_TRANSFER_ID, ocUpload.getTransferId()); - - Uri result = getDB().insert(ProviderTableMeta.CONTENT_URI_UPLOADS, cv); - - Timber.d("storeUpload returns with: " + result + " for file: " + ocUpload.getLocalPath()); - if (result == null) { - Timber.e("Failed to insert item " + ocUpload.getLocalPath() + " into upload db."); - return -1; - } else { - long new_id = Long.parseLong(result.getPathSegments().get(1)); - ocUpload.setUploadId(new_id); - notifyObserversNow(); - return new_id; - } - } - /** * Update an upload object in DB. * @@ -164,63 +128,6 @@ public int updateUpload(OCUpload ocUpload) { return result; } - private int updateUploadInternal(Cursor c, UploadStatus status, UploadResult result, String remotePath, - String localPath) { - int r = 0; - while (c.moveToNext()) { - // read upload object and update - OCUpload upload = createOCUploadFromCursor(c); - - String path = getStringFromColumnOrThrow(c, ProviderTableMeta.UPLOADS_LOCAL_PATH); - Timber.v("Updating " + path + " with status:" + status + " and result:" + (result == null ? "null" : - result.toString()) + " (old:" + upload.toFormattedString() + ")"); - - upload.setUploadStatus(status); - upload.setLastResult(result); - upload.setRemotePath(remotePath); - if (localPath != null) { - upload.setLocalPath(localPath); - } - upload.setUploadEndTimestamp(Calendar.getInstance().getTimeInMillis()); - - // store update upload object to db - r = updateUpload(upload); - } - - return r; - } - - /** - * Update upload status of file uniquely referenced by id. - * - * @param id upload id. - * @param status new status. - * @param result new result of upload operation - * @param remotePath path of the file to upload in the ownCloud storage - * @param localPath path of the file to upload in the device storage - * @return 1 if file status was updated, else 0. - */ - public int updateUploadStatus(long id, UploadStatus status, UploadResult result, String remotePath, - String localPath) { - int returnValue = 0; - Cursor c = getDB().query( - ProviderTableMeta.CONTENT_URI_UPLOADS, - null, - ProviderTableMeta._ID + "=?", - new String[]{String.valueOf(id)}, - null - ); - - if (c.getCount() != 1) { - Timber.e(c.getCount() + " items for id=" + id - + " available in UploadDb. Expected 1. Failed to update upload db."); - } else { - returnValue = updateUploadInternal(c, status, result, remotePath, localPath); - } - c.close(); - return returnValue; - } - /** * Should be called when some value of this DB was changed. All observers * are informed. @@ -231,64 +138,6 @@ public void notifyObserversNow() { notifyObservers(); } - /** - * Remove an upload from the uploads list, known its target account and remote path. - * - * @param upload Upload instance to remove from persisted storage. - * @return true when the upload was stored and could be removed. - */ - public int removeUpload(OCUpload upload) { - int result = getDB().delete( - ProviderTableMeta.CONTENT_URI_UPLOADS, - ProviderTableMeta._ID + "=?", - new String[]{Long.toString(upload.getUploadId())} - ); - Timber.d("delete returns " + result + " for upload " + upload); - if (result > 0) { - notifyObserversNow(); - } - return result; - } - - /** - * Remove an upload from the uploads list, known its target account and remote path. - * - * @param accountName Name of the OC account target of the upload to remove. - * @param remotePath Absolute path in the OC account target of the upload to remove. - * @return true when one or more upload entries were removed - */ - public int removeUpload(String accountName, String remotePath) { - int result = getDB().delete( - ProviderTableMeta.CONTENT_URI_UPLOADS, - ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=? AND " + ProviderTableMeta.UPLOADS_REMOTE_PATH + "=?", - new String[]{accountName, remotePath} - ); - Timber.d("delete returns " + result + " for file " + remotePath + " in " + accountName); - if (result > 0) { - notifyObserversNow(); - } - return result; - } - - /** - * Remove all the uploads of a given account from the uploads list. - * - * @param accountName Name of the OC account target of the uploads to remove. - * @return true when one or more upload entries were removed - */ - public int removeUploads(String accountName) { - int result = getDB().delete( - ProviderTableMeta.CONTENT_URI_UPLOADS, - ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=?", - new String[]{accountName} - ); - Timber.d("delete returns " + result + " for uploads in " + accountName); - if (result > 0) { - notifyObserversNow(); - } - return result; - } - public OCUpload[] getAllStoredUploads() { return getUploads(null, null, null); } @@ -368,19 +217,6 @@ public OCUpload[] getCurrentAndPendingUploads() { ); } - /** - * Get all failed uploads. - */ - public OCUpload[] getFailedUploads() { - return getUploads( - ProviderTableMeta.UPLOADS_STATUS + "== ?", - new String[]{ - String.valueOf(UploadStatus.UPLOAD_FAILED.value) - }, - null - ); - } - /** * Get all uploads which where successfully completed. */ @@ -442,37 +278,4 @@ public long clearSuccessfulUploads() { } return result; } - - /** - * Changes the status of any in progress upload from UploadStatus.UPLOAD_IN_PROGRESS - * to UploadStatus.UPLOAD_FAILED - * - * @return Number of uploads which status was changed. - */ - public int failInProgressUploads(UploadResult uploadResult) { - Timber.v("Updating state of any killed upload"); - - ContentValues cv = new ContentValues(); - cv.put(ProviderTableMeta.UPLOADS_STATUS, UploadStatus.UPLOAD_FAILED.getValue()); - cv.put( - ProviderTableMeta.UPLOADS_LAST_RESULT, - uploadResult != null ? uploadResult.getValue() : UploadResult.UNKNOWN.getValue() - ); - cv.put(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP, Calendar.getInstance().getTimeInMillis()); - - int result = getDB().update( - ProviderTableMeta.CONTENT_URI_UPLOADS, - cv, - ProviderTableMeta.UPLOADS_STATUS + "=?", - new String[]{String.valueOf(UploadStatus.UPLOAD_IN_PROGRESS.getValue())} - ); - - if (result == 0) { - Timber.v("No upload was killed"); - } else { - Timber.w("%s uploads where abruptly interrupted", result); - notifyObserversNow(); - } - return result; - } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java index 8b6c19d53f1..cc0878f7449 100755 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java @@ -323,7 +323,8 @@ private View getView(OCUpload[] uploadsItems, int position, View convertView, Vi rightButton.setImageResource(R.drawable.ic_action_delete_grey); rightButton.setVisibility(View.VISIBLE); rightButton.setOnClickListener(v -> { - mUploadsStorageManager.removeUpload(upload); + OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(v.getContext()).transferDao())); + transferRepository.removeTransferById(upload.getUploadId()); refreshView(); }); From dde20630c3d8f60926c9c02fc9a22de3e71a69be Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Fri, 15 Jul 2022 10:14:47 +0200 Subject: [PATCH 34/38] CR changes applied --- .../uploads/RetryUploadFromSystemUseCase.kt | 7 +- .../workers/UploadFileFromContentUriWorker.kt | 20 +----- .../workers/UploadFileFromFileSystemWorker.kt | 24 +------ .../datasources/LocalTransferDataSource.kt | 1 + .../OCLocalTransferDataSource.kt | 71 ++++++++++--------- .../android/data/transfers/db/TransferDao.kt | 8 +++ .../repository/OCTransferRepository.kt | 5 +- .../domain/transfers/TransferRepository.kt | 1 + .../domain/transfers/model/TransferResult.kt | 30 ++++++++ 9 files changed, 87 insertions(+), 80 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt index 34a0fa1bf2e..f32e98ebd49 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt @@ -32,10 +32,7 @@ class RetryUploadFromSystemUseCase( ) : BaseUseCase() { override fun run(params: Params) { - - val failedUploads = transferRepository.getFailedTransfers() - val filteredUploads = failedUploads.filter { it.id == params.uploadIdInStorageManager } - val uploadToRetry = filteredUploads.firstOrNull() + val uploadToRetry = transferRepository.getTransferById(params.uploadIdInStorageManager) uploadToRetry ?: return @@ -46,8 +43,6 @@ class RetryUploadFromSystemUseCase( uploadFolderPath = uploadToRetry.remotePath.trimEnd(PATH_SEPARATOR), ) ) - - transferRepository.updateTransfer(uploadToRetry.apply { status = TransferStatus.TRANSFER_IN_PROGRESS }) } data class Params( diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt index 9585fcba909..f58d2bd194b 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt @@ -188,7 +188,7 @@ class UploadFileFromContentUriWorker( id = uploadIdInStorageManager, status = getUploadStatusForThrowable(throwable), transferEndTimestamp = System.currentTimeMillis(), - lastResult = getUploadResultFromThrowable(throwable) + lastResult = TransferResult.fromThrowable(throwable) ) } @@ -225,24 +225,6 @@ class UploadFileFromContentUriWorker( ) } - private fun getUploadResultFromThrowable(throwable: Throwable?): TransferResult { - if (throwable == null) return TransferResult.UPLOADED - - return when (throwable) { - is LocalFileNotFoundException -> TransferResult.FOLDER_ERROR - is NoConnectionWithServerException -> TransferResult.NETWORK_CONNECTION - is UnauthorizedException -> TransferResult.CREDENTIAL_ERROR - is FileNotFoundException -> TransferResult.FILE_NOT_FOUND - is ConflictException -> TransferResult.CONFLICT_ERROR - is ForbiddenException -> TransferResult.PRIVILEGES_ERROR - is ServiceUnavailableException -> TransferResult.SERVICE_UNAVAILABLE - is QuotaExceededException -> TransferResult.QUOTA_EXCEEDED - is SpecificUnsupportedMediaTypeException -> TransferResult.SPECIFIC_UNSUPPORTED_MEDIA_TYPE - is SSLRecoverablePeerUnverifiedException -> TransferResult.SSL_RECOVERABLE_PEER_UNVERIFIED - else -> TransferResult.UNKNOWN - } - } - private fun getClientForThisUpload(): OwnCloudClient = SingleSessionManager.getDefaultSingleton() .getClientFor(OwnCloudAccount(AccountUtils.getOwnCloudAccountByName(appContext, account.name), appContext), appContext, SingleSessionManager.getConnectionValidator()) diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt index cec9f7868d6..ca1a7395d79 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt @@ -167,9 +167,7 @@ class UploadFileFromFileSystemWorker( } private fun retrieveUploadInfoFromDatabase(): OCTransfer? { - val storedTransfers = transferRepository.getAllTransfers() - - return storedTransfers.find { uploadIdInStorageManager == it.id }.also { + return transferRepository.getTransferById(uploadIdInStorageManager).also { if (it != null) { Timber.d("Upload with id ($uploadIdInStorageManager) has been found in database.") Timber.d("Upload info: $it") @@ -302,7 +300,7 @@ class UploadFileFromFileSystemWorker( id = uploadIdInStorageManager, status = getUploadStatusForThrowable(throwable), transferEndTimestamp = System.currentTimeMillis(), - lastResult = getUploadResultFromThrowable(throwable) + lastResult = TransferResult.fromThrowable(throwable) ) } @@ -339,24 +337,6 @@ class UploadFileFromFileSystemWorker( ) } - private fun getUploadResultFromThrowable(throwable: Throwable?): TransferResult { - if (throwable == null) return TransferResult.UPLOADED - - return when (throwable) { - is LocalFileNotFoundException -> TransferResult.FOLDER_ERROR - is NoConnectionWithServerException -> TransferResult.NETWORK_CONNECTION - is UnauthorizedException -> TransferResult.CREDENTIAL_ERROR - is FileNotFoundException -> TransferResult.FILE_NOT_FOUND - is ConflictException -> TransferResult.CONFLICT_ERROR - is ForbiddenException -> TransferResult.PRIVILEGES_ERROR - is ServiceUnavailableException -> TransferResult.SERVICE_UNAVAILABLE - is QuotaExceededException -> TransferResult.QUOTA_EXCEEDED - is SpecificUnsupportedMediaTypeException -> TransferResult.SPECIFIC_UNSUPPORTED_MEDIA_TYPE - is SSLRecoverablePeerUnverifiedException -> TransferResult.SSL_RECOVERABLE_PEER_UNVERIFIED - else -> TransferResult.UNKNOWN - } - } - private fun getClientForThisUpload(): OwnCloudClient = SingleSessionManager.getDefaultSingleton() .getClientFor(OwnCloudAccount(AccountUtils.getOwnCloudAccountByName(appContext, account.name), appContext), appContext) diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt index 0051b40f9da..c24bb4b929c 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/LocalTransferDataSource.kt @@ -36,6 +36,7 @@ interface LocalTransferDataSource { ) fun removeTransferById(id: Long) fun removeAllTransfersFromAccount(accountName: String) + fun getTransferById(id: Long): OCTransfer? fun getAllTransfers(): List fun getLastTransferFor(remotePath: String, accountName: String): OCTransfer? fun getCurrentAndPendingTransfers(): List diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt index 6208a460e3f..ccf07e1bf83 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt @@ -43,8 +43,12 @@ class OCLocalTransferDataSource( transferDao.updateTransferStatusWithId(id, TransferStatus.TRANSFER_IN_PROGRESS.value) } - override fun updateTransferWhenFinished(id: Long, status: TransferStatus, - transferEndTimestamp: Long, lastResult: TransferResult) { + override fun updateTransferWhenFinished( + id: Long, + status: TransferStatus, + transferEndTimestamp: Long, + lastResult: TransferResult + ) { transferDao.updateTransferWhenFinished(id, status.value, transferEndTimestamp, lastResult.value) } @@ -56,6 +60,10 @@ class OCLocalTransferDataSource( transferDao.deleteTransfersWithAccountName(accountName) } + override fun getTransferById(id: Long): OCTransfer? { + return transferDao.getTransferWithId(id)?.toModel() + } + override fun getAllTransfers(): List { return transferDao.getAllTransfers().map { it.toModel() } } @@ -90,34 +98,33 @@ class OCLocalTransferDataSource( transferDao.deleteTransfersWithStatus(TransferStatus.TRANSFER_SUCCEEDED.value) } - companion object { - private fun OCTransferEntity.toModel() = OCTransfer( - id = id, - localPath = localPath, - remotePath = remotePath, - accountName = accountName, - fileSize = fileSize, - status = TransferStatus.fromValue(status), - localBehaviour = localBehaviour, - forceOverwrite = forceOverwrite, - transferEndTimestamp = transferEndTimestamp, - lastResult = lastResult?.let { TransferResult.fromValue(it) }, - createdBy = createdBy, - transferId = transferId - ) - - private fun OCTransfer.toEntity() = OCTransferEntity( - localPath = localPath, - remotePath = remotePath, - accountName = accountName, - fileSize = fileSize, - status = status.value, - localBehaviour = localBehaviour, - forceOverwrite = forceOverwrite, - transferEndTimestamp = transferEndTimestamp, - lastResult = lastResult?.value, - createdBy = createdBy, - transferId = transferId - ).apply { this@toEntity.id?.let { this.id = it } } - } + private fun OCTransferEntity.toModel() = OCTransfer( + id = id, + localPath = localPath, + remotePath = remotePath, + accountName = accountName, + fileSize = fileSize, + status = TransferStatus.fromValue(status), + localBehaviour = localBehaviour, + forceOverwrite = forceOverwrite, + transferEndTimestamp = transferEndTimestamp, + lastResult = lastResult?.let { TransferResult.fromValue(it) }, + createdBy = createdBy, + transferId = transferId + ) + + private fun OCTransfer.toEntity() = OCTransferEntity( + localPath = localPath, + remotePath = remotePath, + accountName = accountName, + fileSize = fileSize, + status = status.value, + localBehaviour = localBehaviour, + forceOverwrite = forceOverwrite, + transferEndTimestamp = transferEndTimestamp, + lastResult = lastResult?.value, + createdBy = createdBy, + transferId = transferId + ).apply { this@toEntity.id?.let { this.id = it } } + } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt index 4a0b4511de3..9641d358592 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/db/TransferDao.kt @@ -28,6 +28,9 @@ import com.owncloud.android.data.ProviderMeta.ProviderTableMeta.TRANSFERS_TABLE_ @Dao abstract class TransferDao { + @Query(SELECT_TRANSFER_WITH_ID) + abstract fun getTransferWithId(id: Long): OCTransferEntity? + @Query(SELECT_LAST_TRANSFER_WITH_REMOTE_PATH_AND_ACCOUNT_NAME) abstract fun getLastTransferWithRemotePathAndAccountName(remotePath: String, accountName: String): OCTransferEntity? @@ -56,6 +59,11 @@ abstract class TransferDao { abstract fun deleteTransfersWithStatus(status: Int) companion object { + private const val SELECT_TRANSFER_WITH_ID = + "SELECT * " + + "FROM $TRANSFERS_TABLE_NAME " + + "WHERE id = :id" + private const val SELECT_LAST_TRANSFER_WITH_REMOTE_PATH_AND_ACCOUNT_NAME = "SELECT * " + "FROM $TRANSFERS_TABLE_NAME " + diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt index 0d02263d5d5..0e3dd89de7a 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt @@ -59,6 +59,9 @@ class OCTransferRepository( override fun removeAllTransfersFromAccount(accountName: String) = localTransferDataSource.removeAllTransfersFromAccount(accountName = accountName) + override fun getTransferById(id: Long): OCTransfer? = + localTransferDataSource.getTransferById(id = id) + override fun getAllTransfers(): List = localTransferDataSource.getAllTransfers() @@ -79,4 +82,4 @@ class OCTransferRepository( override fun clearSuccessfulTransfers() = localTransferDataSource.clearSuccessfulTransfers() -} \ No newline at end of file +} diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt index 68cbbf6ae4f..9ca4238ae1c 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/TransferRepository.kt @@ -36,6 +36,7 @@ interface TransferRepository { ) fun removeTransferById(id: Long) fun removeAllTransfersFromAccount(accountName: String) + fun getTransferById(id: Long): OCTransfer? fun getAllTransfers(): List fun getLastTransferFor(remotePath: String, accountName: String): OCTransfer? fun getCurrentAndPendingTransfers(): List diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt index 9127b19edc5..5986744fe4b 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/transfers/model/TransferResult.kt @@ -20,6 +20,17 @@ package com.owncloud.android.domain.transfers.model +import com.owncloud.android.domain.exceptions.ConflictException +import com.owncloud.android.domain.exceptions.FileNotFoundException +import com.owncloud.android.domain.exceptions.ForbiddenException +import com.owncloud.android.domain.exceptions.LocalFileNotFoundException +import com.owncloud.android.domain.exceptions.NoConnectionWithServerException +import com.owncloud.android.domain.exceptions.QuotaExceededException +import com.owncloud.android.domain.exceptions.SSLRecoverablePeerUnverifiedException +import com.owncloud.android.domain.exceptions.ServiceUnavailableException +import com.owncloud.android.domain.exceptions.SpecificUnsupportedMediaTypeException +import com.owncloud.android.domain.exceptions.UnauthorizedException + enum class TransferResult constructor(val value: Int) { UNKNOWN(value = -1), UPLOADED(value = 0), @@ -62,5 +73,24 @@ enum class TransferResult constructor(val value: Int) { 16 -> SPECIFIC_UNSUPPORTED_MEDIA_TYPE else -> UNKNOWN } + + fun fromThrowable(throwable: Throwable?): TransferResult { + if (throwable == null) return UPLOADED + + return when (throwable) { + is LocalFileNotFoundException -> FOLDER_ERROR + is NoConnectionWithServerException -> NETWORK_CONNECTION + is UnauthorizedException -> CREDENTIAL_ERROR + is FileNotFoundException -> FILE_NOT_FOUND + is ConflictException -> CONFLICT_ERROR + is ForbiddenException -> PRIVILEGES_ERROR + is ServiceUnavailableException -> SERVICE_UNAVAILABLE + is QuotaExceededException -> QUOTA_EXCEEDED + is SpecificUnsupportedMediaTypeException -> SPECIFIC_UNSUPPORTED_MEDIA_TYPE + is SSLRecoverablePeerUnverifiedException -> SSL_RECOVERABLE_PEER_UNVERIFIED + else -> UNKNOWN + } + } + } } From 86bc0c4ede16f4043806d6a57d11fd43430258a8 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Fri, 15 Jul 2022 10:18:25 +0200 Subject: [PATCH 35/38] Fixed Ktlint errors --- .../presentation/viewmodels/transfers/TransfersViewModel.kt | 2 +- .../com/owncloud/android/ui/activity/FileDisplayActivity.kt | 1 - .../usecases/transfers/uploads/CancelUploadForFileUseCase.kt | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt index bd14dbcda65..b6366e611c0 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/viewmodels/transfers/TransfersViewModel.kt @@ -32,7 +32,7 @@ class TransfersViewModel( private val uploadFilesFromSAFUseCase: UploadFilesFromSAFUseCase, private val uploadFilesFromSystemUseCase: UploadFilesFromSystemUseCase, private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider, -): ViewModel() { +) : ViewModel() { fun uploadFilesFromSAF( accountName: String, listOfContentUris: List, diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 84b8424cb05..510362e20a9 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -92,7 +92,6 @@ import com.owncloud.android.usecases.synchronization.SynchronizeFileUseCase import com.owncloud.android.usecases.transfers.DOWNLOAD_FINISH_MESSAGE import com.owncloud.android.usecases.transfers.downloads.DownloadFileUseCase import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSAFUseCase -import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase import com.owncloud.android.utils.Extras import com.owncloud.android.utils.PreferenceUtils import kotlinx.coroutines.CoroutineScope diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt index ec762eb9168..c6753ec3383 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/CancelUploadForFileUseCase.kt @@ -22,7 +22,6 @@ package com.owncloud.android.usecases.transfers.uploads import androidx.work.WorkManager -import com.owncloud.android.MainApp import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.domain.transfers.TransferRepository From ac578a713a2d8d15139ebf2329f1b35f402ca4ed Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Fri, 15 Jul 2022 10:23:52 +0200 Subject: [PATCH 36/38] Fixed some other Ktlint errors --- .../transfers/uploads/RetryUploadFromSystemUseCase.kt | 1 - .../android/workers/UploadFileFromContentUriWorker.kt | 8 -------- .../android/workers/UploadFileFromFileSystemWorker.kt | 8 -------- 3 files changed, 17 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt index f32e98ebd49..e1e898a0326 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt @@ -24,7 +24,6 @@ package com.owncloud.android.usecases.transfers.uploads import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.files.model.OCFile.Companion.PATH_SEPARATOR import com.owncloud.android.domain.transfers.TransferRepository -import com.owncloud.android.domain.transfers.model.TransferStatus class RetryUploadFromSystemUseCase( private val uploadFilesFromSystemUseCase: UploadFilesFromSystemUseCase, diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt index f58d2bd194b..849cd3ad199 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt @@ -33,15 +33,7 @@ import com.owncloud.android.R import com.owncloud.android.authentication.AccountUtils import com.owncloud.android.data.executeRemoteOperation import com.owncloud.android.domain.camerauploads.model.UploadBehavior -import com.owncloud.android.domain.exceptions.ConflictException -import com.owncloud.android.domain.exceptions.FileNotFoundException -import com.owncloud.android.domain.exceptions.ForbiddenException import com.owncloud.android.domain.exceptions.LocalFileNotFoundException -import com.owncloud.android.domain.exceptions.NoConnectionWithServerException -import com.owncloud.android.domain.exceptions.QuotaExceededException -import com.owncloud.android.domain.exceptions.SSLRecoverablePeerUnverifiedException -import com.owncloud.android.domain.exceptions.ServiceUnavailableException -import com.owncloud.android.domain.exceptions.SpecificUnsupportedMediaTypeException import com.owncloud.android.domain.exceptions.UnauthorizedException import com.owncloud.android.domain.transfers.TransferRepository import com.owncloud.android.domain.transfers.model.TransferResult diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt index ca1a7395d79..30eec9b1f7d 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt @@ -31,15 +31,7 @@ import com.owncloud.android.authentication.AccountUtils import com.owncloud.android.data.executeRemoteOperation import com.owncloud.android.domain.camerauploads.model.UploadBehavior import com.owncloud.android.domain.capabilities.usecases.GetStoredCapabilitiesUseCase -import com.owncloud.android.domain.exceptions.ConflictException -import com.owncloud.android.domain.exceptions.FileNotFoundException -import com.owncloud.android.domain.exceptions.ForbiddenException import com.owncloud.android.domain.exceptions.LocalFileNotFoundException -import com.owncloud.android.domain.exceptions.NoConnectionWithServerException -import com.owncloud.android.domain.exceptions.QuotaExceededException -import com.owncloud.android.domain.exceptions.SSLRecoverablePeerUnverifiedException -import com.owncloud.android.domain.exceptions.ServiceUnavailableException -import com.owncloud.android.domain.exceptions.SpecificUnsupportedMediaTypeException import com.owncloud.android.domain.exceptions.UnauthorizedException import com.owncloud.android.domain.files.model.OCFile.Companion.PATH_SEPARATOR import com.owncloud.android.domain.files.usecases.GetFileByRemotePathUseCase From 7fb840d429d7b3fe156760f4a672eab18bef296a Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Fri, 15 Jul 2022 12:11:15 +0200 Subject: [PATCH 37/38] Fixed more Ktlint errors --- .../datasources/implementation/OCLocalTransferDataSource.kt | 3 +-- .../android/data/transfers/repository/OCTransferRepository.kt | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt index ccf07e1bf83..fb5230441c3 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt @@ -23,14 +23,13 @@ package com.owncloud.android.data.transfers.datasources.implementation import com.owncloud.android.data.transfers.datasources.LocalTransferDataSource import com.owncloud.android.data.transfers.db.OCTransferEntity import com.owncloud.android.data.transfers.db.TransferDao -import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.domain.transfers.model.OCTransfer import com.owncloud.android.domain.transfers.model.TransferResult import com.owncloud.android.domain.transfers.model.TransferStatus class OCLocalTransferDataSource( private val transferDao: TransferDao -): LocalTransferDataSource { +) : LocalTransferDataSource { override fun storeTransfer(transfer: OCTransfer): Long { return transferDao.insert(transfer.toEntity()) } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt index 0e3dd89de7a..16103c337d5 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/repository/OCTransferRepository.kt @@ -28,7 +28,7 @@ import com.owncloud.android.domain.transfers.model.TransferStatus class OCTransferRepository( private val localTransferDataSource: LocalTransferDataSource -): TransferRepository { +) : TransferRepository { override fun storeTransfer(transfer: OCTransfer) = localTransferDataSource.storeTransfer(transfer = transfer) From e943e8e3317e7d49d27770ad61bd5a5ef624eeb6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote <57049315+JuancaG05@users.noreply.github.com> Date: Mon, 18 Jul 2022 10:37:46 +0200 Subject: [PATCH 38/38] Improvements on RetryUploadFromContentUriUseCase --- .../transfers/uploads/RetryUploadFromContentUriUseCase.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt index 243b2f0b8ca..23a8f3b8f68 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromContentUriUseCase.kt @@ -27,7 +27,6 @@ import androidx.work.WorkManager import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.camerauploads.model.UploadBehavior import com.owncloud.android.domain.transfers.TransferRepository -import com.owncloud.android.domain.transfers.model.TransferStatus class RetryUploadFromContentUriUseCase( private val context: Context, @@ -35,10 +34,7 @@ class RetryUploadFromContentUriUseCase( ) : BaseUseCase() { override fun run(params: Params) { - - val failedUploads = transferRepository.getFailedTransfers() - val filteredUploads = failedUploads.filter { it.id == params.uploadIdInStorageManager } - val uploadToRetry = filteredUploads.firstOrNull() + val uploadToRetry = transferRepository.getTransferById(params.uploadIdInStorageManager) uploadToRetry ?: return @@ -55,8 +51,6 @@ class RetryUploadFromContentUriUseCase( chargingOnly = false ) ) - - transferRepository.updateTransfer(uploadToRetry.apply { status = TransferStatus.TRANSFER_IN_PROGRESS }) } data class Params(