From 006e12be74f137c18d8f83a82114ab6b278bc021 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 15 Dec 2025 09:07:23 +0100 Subject: [PATCH 1/8] fix(auto-upload): remove not-existing local files without restarting Signed-off-by: alperozturk # Conflicts: # app/src/main/java/com/nextcloud/client/jobs/autoUpload/FileSystemRepository.kt --- .../client/database/dao/FileSystemDao.kt | 12 ++++++++++++ .../client/jobs/autoUpload/AutoUploadWorker.kt | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt index 3dc90d77b318..17cc14e7dc02 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt @@ -19,6 +19,18 @@ interface FileSystemDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertOrReplace(filesystemEntity: FilesystemEntity) + @Query( + """ + DELETE FROM ${ProviderMeta.ProviderTableMeta.FILESYSTEM_TABLE_NAME} + WHERE ${ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH} = :localPath + AND ${ProviderMeta.ProviderTableMeta._ID} = :id + """ + ) + suspend fun deleteByLocalPathAndId( + localPath: String, + id: Int + ) + @Query( """ SELECT * diff --git a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt index e1fc93df33bc..2df77d2f164c 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt @@ -321,6 +321,15 @@ class AutoUploadWorker( try { var (uploadEntity, upload) = createEntityAndUpload(user, localPath, remotePath) + + // if local file deleted, upload cannot be or retriable thus needs to be removed + if (path.isEmpty() || !file.exists()) { + Log_OC.w(TAG, "detected not existing local file, removing entity") + repository.deleteByLocalPathAndId(path, id) + uploadsStorageManager.removeUpload(upload) + continue + } + try { // Insert/update to IN_PROGRESS state before starting upload val generatedId = uploadsStorageManager.uploadDao.insertOrReplace(uploadEntity) @@ -366,10 +375,10 @@ class AutoUploadWorker( "Exception uploadFiles during creating entity and upload, localPath: $localPath, " + "remotePath: $remotePath, exception: $e" ) + } finally { + // update last id so upload can continue where it left + lastId = id } - - // update last id so upload can continue where it left - lastId = id } } } From 530bcc017f5ffdf7ba6713c6dadaba67bc42bb05 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 15 Dec 2025 09:09:54 +0100 Subject: [PATCH 2/8] fix(auto-upload): remove not-existing local files without restarting Signed-off-by: alperozturk --- .../java/com/nextcloud/client/database/dao/FileSystemDao.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt index 17cc14e7dc02..91a03044afde 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileSystemDao.kt @@ -26,10 +26,7 @@ interface FileSystemDao { AND ${ProviderMeta.ProviderTableMeta._ID} = :id """ ) - suspend fun deleteByLocalPathAndId( - localPath: String, - id: Int - ) + suspend fun deleteByLocalPathAndId(localPath: String, id: Int) @Query( """ From e6fda09681674c545d82158f786c43e6f4870a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alper=20=C3=96zt=C3=BCrk?= <67455295+alperozturk96@users.noreply.github.com> Date: Mon, 15 Dec 2025 10:12:15 +0100 Subject: [PATCH 3/8] Update app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andy Scherzinger Signed-off-by: Alper Öztürk <67455295+alperozturk96@users.noreply.github.com> --- .../com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt index 2df77d2f164c..736e7550746e 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt @@ -324,7 +324,7 @@ class AutoUploadWorker( // if local file deleted, upload cannot be or retriable thus needs to be removed if (path.isEmpty() || !file.exists()) { - Log_OC.w(TAG, "detected not existing local file, removing entity") + Log_OC.w(TAG, "detected non-existing local file, removing entity") repository.deleteByLocalPathAndId(path, id) uploadsStorageManager.removeUpload(upload) continue From b7e3a2dd3935506f62ef7bbf460664bcf8317eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alper=20=C3=96zt=C3=BCrk?= <67455295+alperozturk96@users.noreply.github.com> Date: Mon, 15 Dec 2025 10:13:24 +0100 Subject: [PATCH 4/8] Apply suggestion from @alperozturk96 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alper Öztürk <67455295+alperozturk96@users.noreply.github.com> --- .../com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt index 736e7550746e..8484dca92950 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt @@ -322,7 +322,7 @@ class AutoUploadWorker( try { var (uploadEntity, upload) = createEntityAndUpload(user, localPath, remotePath) - // if local file deleted, upload cannot be or retriable thus needs to be removed + // if local file deleted, upload process cannot be started or retriable thus needs to be removed if (path.isEmpty() || !file.exists()) { Log_OC.w(TAG, "detected non-existing local file, removing entity") repository.deleteByLocalPathAndId(path, id) From 3b03877afcc30494f03047835972d3924dc14dd9 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 17 Dec 2025 08:51:14 +0100 Subject: [PATCH 5/8] fix: check deleted files for local behaviour delete Signed-off-by: alperozturk --- .../client/jobs/autoUpload/AutoUploadWorker.kt | 8 ++++++-- .../android/operations/UploadFileOperation.java | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt index 8484dca92950..b01d0643cb96 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt @@ -325,8 +325,7 @@ class AutoUploadWorker( // if local file deleted, upload process cannot be started or retriable thus needs to be removed if (path.isEmpty() || !file.exists()) { Log_OC.w(TAG, "detected non-existing local file, removing entity") - repository.deleteByLocalPathAndId(path, id) - uploadsStorageManager.removeUpload(upload) + deleteNonExistingFile(path, id, upload) continue } @@ -383,6 +382,11 @@ class AutoUploadWorker( } } + private suspend fun deleteNonExistingFile(path: String, id: Int, upload: OCUpload) { + repository.deleteByLocalPathAndId(path, id) + uploadsStorageManager.removeUpload(upload) + } + private fun createEntityAndUpload(user: User, localPath: String, remotePath: String): Pair { val (needsCharging, needsWifi, uploadAction) = getUploadSettings(syncedFolder) Log_OC.d(TAG, "creating oc upload for ${user.accountName}") diff --git a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java index 9bafd4fe593c..39e524594f5a 100644 --- a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java @@ -1283,6 +1283,19 @@ public void handleLocalBehaviour() { handleLocalBehaviour(temporalFile, expectedFile, originalFile, client); } + private void deleteNonExistingFile(File file) { + if (file.exists()) { + return; + } + + Log_OC.d(TAG, "deleting non-existing file from upload list and file list"); + + uploadsStorageManager.removeUpload(mOCUploadId); + + // some chunks can be uploaded and can still exists in db thus we have to remove it as well + getStorageManager().removeFile(mFile, true, true); + } + private void handleLocalBehaviour(File temporalFile, File expectedFile, File originalFile, @@ -1293,6 +1306,9 @@ private void handleLocalBehaviour(File temporalFile, Files.delete(originalFile.toPath()); } catch (IOException e) { Log_OC.e(TAG, "Could not delete original file: " + originalFile.getAbsolutePath(), e); + + // if file is not exists we should only delete from our app + deleteNonExistingFile(originalFile); } mFile.setStoragePath(""); getStorageManager().deleteFileInMediaScan(originalFile.getAbsolutePath()); From d94ca1fdea097daff71d9e56dd1fff44f2da1233 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 17 Dec 2025 09:13:33 +0100 Subject: [PATCH 6/8] fix: check deleted files for other local behaviour Signed-off-by: alperozturk --- .../android/operations/UploadFileOperation.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java index 39e524594f5a..f13c73704962 100644 --- a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java @@ -1300,15 +1300,21 @@ private void handleLocalBehaviour(File temporalFile, File expectedFile, File originalFile, OwnCloudClient client) { + + // only LOCAL_BEHAVIOUR_COPY not using original file + if (mLocalBehaviour != FileUploadWorker.LOCAL_BEHAVIOUR_COPY) { + // if file is not exists we should only delete from our app + deleteNonExistingFile(originalFile); + } + + Log_OC.d(TAG, "handling local behaviour for: " + originalFile.getName() + " behaviour: " + mLocalBehaviour); + switch (mLocalBehaviour) { case FileUploadWorker.LOCAL_BEHAVIOUR_DELETE: try { Files.delete(originalFile.toPath()); } catch (IOException e) { Log_OC.e(TAG, "Could not delete original file: " + originalFile.getAbsolutePath(), e); - - // if file is not exists we should only delete from our app - deleteNonExistingFile(originalFile); } mFile.setStoragePath(""); getStorageManager().deleteFileInMediaScan(originalFile.getAbsolutePath()); @@ -1321,6 +1327,9 @@ private void handleLocalBehaviour(File temporalFile, move(temporalFile, expectedFile); } catch (IOException e) { Log_OC.e(TAG, e.getMessage()); + + // handling non-existing file for local copy as well + deleteNonExistingFile(temporalFile); } } else if (originalFile != null) { try { From 082328e21f146bab28791debe6b4c306d6a3e8e0 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 17 Dec 2025 09:18:42 +0100 Subject: [PATCH 7/8] fix: check exception during auto upload for non-existing file Signed-off-by: alperozturk --- .../nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt index b01d0643cb96..b13ebabe7578 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt @@ -367,6 +367,12 @@ class AutoUploadWorker( "Exception during upload file, localPath: $localPath, remotePath: $remotePath," + " exception: $e" ) + + if (path.isEmpty() || !file.exists()) { + Log_OC.w(TAG, "detected non-existing local file, removing entity") + deleteNonExistingFile(path, id, upload) + continue + } } } catch (e: Exception) { Log_OC.e( From 683757716f4da01047b265b933841865be47146c Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 17 Dec 2025 11:10:43 +0100 Subject: [PATCH 8/8] fix git conflict Signed-off-by: alperozturk --- .../nextcloud/client/jobs/autoUpload/FileSystemRepository.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/FileSystemRepository.kt b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/FileSystemRepository.kt index 8cb6a74dc1ec..b322b1bc7fc4 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/FileSystemRepository.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/FileSystemRepository.kt @@ -28,6 +28,10 @@ class FileSystemRepository(private val dao: FileSystemDao, private val context: const val BATCH_SIZE = 50 } + suspend fun deleteByLocalPathAndId(path: String, id: Int) { + dao.deleteByLocalPathAndId(path, id) + } + suspend fun getFilePathsWithIds(syncedFolder: SyncedFolder, lastId: Int): List> { val syncedFolderId = syncedFolder.id.toString() Log_OC.d(TAG, "Fetching candidate files for syncedFolderId = $syncedFolderId")