add sync worker

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2024-11-29 16:52:11 +01:00 committed by Alper Öztürk
parent 6ecd83f987
commit 722ef51860
6 changed files with 96 additions and 2 deletions

View file

@ -24,6 +24,7 @@ import com.nextcloud.client.documentscan.GeneratePdfFromImagesWork
import com.nextcloud.client.integrations.deck.DeckApi import com.nextcloud.client.integrations.deck.DeckApi
import com.nextcloud.client.jobs.download.FileDownloadWorker import com.nextcloud.client.jobs.download.FileDownloadWorker
import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker
import com.nextcloud.client.jobs.sync.SyncWorker
import com.nextcloud.client.jobs.upload.FileUploadWorker import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.logger.Logger import com.nextcloud.client.logger.Logger
import com.nextcloud.client.network.ConnectivityService import com.nextcloud.client.network.ConnectivityService
@ -98,6 +99,7 @@ class BackgroundJobFactory @Inject constructor(
TestJob::class -> createTestJob(context, workerParameters) TestJob::class -> createTestJob(context, workerParameters)
OfflineOperationsWorker::class -> createOfflineOperationsWorker(context, workerParameters) OfflineOperationsWorker::class -> createOfflineOperationsWorker(context, workerParameters)
InternalTwoWaySyncWork::class -> createInternalTwoWaySyncWork(context, workerParameters) InternalTwoWaySyncWork::class -> createInternalTwoWaySyncWork(context, workerParameters)
SyncWorker::class -> createSyncWorker(context, workerParameters)
else -> null // caller falls back to default factory else -> null // caller falls back to default factory
} }
} }
@ -301,4 +303,12 @@ class BackgroundJobFactory @Inject constructor(
preferences preferences
) )
} }
private fun createSyncWorker(context: Context, params: WorkerParameters): SyncWorker {
return SyncWorker(
accountManager.user,
context,
params
)
}
} }

View file

@ -174,4 +174,5 @@ interface BackgroundJobManager {
fun startPeriodicallyOfflineOperation() fun startPeriodicallyOfflineOperation()
fun scheduleInternal2WaySync(intervalMinutes: Long) fun scheduleInternal2WaySync(intervalMinutes: Long)
fun cancelAllFilesDownloadJobs() fun cancelAllFilesDownloadJobs()
fun syncFolder(filePaths: List<String>)
} }

View file

@ -27,6 +27,7 @@ import com.nextcloud.client.di.Injectable
import com.nextcloud.client.documentscan.GeneratePdfFromImagesWork import com.nextcloud.client.documentscan.GeneratePdfFromImagesWork
import com.nextcloud.client.jobs.download.FileDownloadWorker import com.nextcloud.client.jobs.download.FileDownloadWorker
import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker
import com.nextcloud.client.jobs.sync.SyncWorker
import com.nextcloud.client.jobs.upload.FileUploadWorker import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.preferences.AppPreferences import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.utils.extensions.isWorkRunning import com.nextcloud.utils.extensions.isWorkRunning
@ -85,7 +86,7 @@ internal class BackgroundJobManagerImpl(
const val JOB_PERIODIC_OFFLINE_OPERATIONS = "periodic_offline_operations" const val JOB_PERIODIC_OFFLINE_OPERATIONS = "periodic_offline_operations"
const val JOB_PERIODIC_HEALTH_STATUS = "periodic_health_status" const val JOB_PERIODIC_HEALTH_STATUS = "periodic_health_status"
const val JOB_IMMEDIATE_HEALTH_STATUS = "immediate_health_status" const val JOB_IMMEDIATE_HEALTH_STATUS = "immediate_health_status"
const val JOB_SYNC_FOLDER = "sync_folder"
const val JOB_INTERNAL_TWO_WAY_SYNC = "internal_two_way_sync" const val JOB_INTERNAL_TWO_WAY_SYNC = "internal_two_way_sync"
const val JOB_TEST = "test_job" const val JOB_TEST = "test_job"
@ -717,4 +718,16 @@ internal class BackgroundJobManagerImpl(
workManager.enqueueUniquePeriodicWork(JOB_INTERNAL_TWO_WAY_SYNC, ExistingPeriodicWorkPolicy.UPDATE, request) workManager.enqueueUniquePeriodicWork(JOB_INTERNAL_TWO_WAY_SYNC, ExistingPeriodicWorkPolicy.UPDATE, request)
} }
override fun syncFolder(filePaths: List<String>) {
val data = Data.Builder()
.putStringArray(SyncWorker.FILE_PATHS, filePaths.toTypedArray())
.build()
val request = oneTimeRequestBuilder(SyncWorker::class, JOB_SYNC_FOLDER)
.setInputData(data)
.build()
workManager.enqueueUniqueWork(JOB_SYNC_FOLDER, ExistingWorkPolicy.REPLACE, request)
}
} }

View file

@ -141,4 +141,8 @@ class FileDownloadHelper {
conflictUploadId conflictUploadId
) )
} }
fun syncFolder(filePaths: List<String>) {
backgroundJobManager.syncFolder(filePaths)
}
} }

View file

@ -0,0 +1,63 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.client.jobs.sync
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.nextcloud.client.account.User
import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.operations.DownloadFileOperation
class SyncWorker(
private val user: User,
private val context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
companion object {
const val FILE_PATHS = "FILE_PATHS"
private const val TAG = "SyncWorker"
}
@Suppress("DEPRECATION")
override suspend fun doWork(): Result {
Log_OC.d(TAG, "SyncWorker started")
val filePaths = inputData.getStringArray(FILE_PATHS)
if (filePaths.isNullOrEmpty()) {
return Result.failure()
}
val fileDataStorageManager = FileDataStorageManager(user, context.contentResolver)
val account = user.toOwnCloudAccount()
val client = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(account, context)
var result = true
filePaths.forEach { path ->
fileDataStorageManager.getFileByDecryptedRemotePath(path)?.let { file ->
val operation = DownloadFileOperation(user, file, context).execute(client)
Log_OC.d(TAG, "Syncing file: " + file.decryptedRemotePath)
if (!operation.isSuccess) {
result = false
}
}
}
return if (result) {
Log_OC.d(TAG, "SyncWorker completed")
Result.success()
} else {
Log_OC.d(TAG, "SyncWorker failed")
Result.failure()
}
}
}

View file

@ -40,6 +40,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Vector; import java.util.Vector;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@ -500,7 +501,9 @@ public class SynchronizeFolderOperation extends SyncOperation {
Log_OC.d(TAG, "Exception caught at startDirectDownloads" + e); Log_OC.d(TAG, "Exception caught at startDirectDownloads" + e);
} }
} else { } else {
mFilesForDirectDownload.forEach(file -> fileDownloadHelper.downloadFile(user, file)); final var filePaths = new ArrayList<String>();
mFilesForDirectDownload.forEach(file -> filePaths.add(file.getDecryptedRemotePath()));
fileDownloadHelper.syncFolder(filePaths);
} }
} }