Skip to content

Commit

Permalink
simplify...
Browse files Browse the repository at this point in the history
Signed-off-by: alperozturk <[email protected]>
  • Loading branch information
alperozturk96 committed Dec 18, 2024
1 parent 7439bc3 commit 57990c8
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,5 @@ interface BackgroundJobManager {
fun scheduleInternal2WaySync(intervalMinutes: Long)
fun cancelAllFilesDownloadJobs()
fun syncFolder(files: List<OCFile>)
fun cancelSyncFolder()
}
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ internal class BackgroundJobManagerImpl(
workManager.enqueueUniquePeriodicWork(JOB_INTERNAL_TWO_WAY_SYNC, ExistingPeriodicWorkPolicy.UPDATE, request)
}

// TODO: Add tag for chosen folder
override fun syncFolder(files: List<OCFile>) {
val filePaths = files.map { it.decryptedRemotePath }

Expand All @@ -729,4 +730,9 @@ internal class BackgroundJobManagerImpl(

workManager.enqueueUniqueWork(JOB_SYNC_FOLDER, ExistingWorkPolicy.REPLACE, request)
}

// TODO: Add cancellation for chosen folder
override fun cancelSyncFolder() {
TODO("Not yet implemented")
}
}
141 changes: 89 additions & 52 deletions app/src/main/java/com/nextcloud/client/jobs/sync/SyncWorker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.nextcloud.client.account.User
import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.operations.DownloadFileOperation
import com.owncloud.android.ui.helpers.FileOperationsHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import java.util.Collections

class SyncWorker(
private val user: User,
Expand All @@ -37,7 +39,7 @@ class SyncWorker(
const val FILE_DOWNLOAD_COMPLETION_BROADCAST = "FILE_DOWNLOAD_COMPLETION_BROADCAST"
const val FILE_PATH = "FILE_PATH"

private var downloadingFilePaths = ArrayList<String>()
private var downloadingFilePaths = mutableListOf<String>()

/**
* It is used to add the sync icon next to the file in the folder.
Expand All @@ -49,85 +51,120 @@ class SyncWorker(

private val notificationManager = SyncWorkerNotificationManager(context)

@Suppress("DEPRECATION", "MagicNumber")
@Suppress("TooGenericExceptionCaught")
override suspend fun doWork(): Result {
Log_OC.d(TAG, "SyncWorker started")

withContext(Dispatchers.Main) {
notificationManager.showStartNotification()
}

return withContext(Dispatchers.IO) {
Log_OC.d(TAG, "SyncWorker started")
val filePaths = inputData.getStringArray(FILE_PATHS)

if (filePaths.isNullOrEmpty()) {
return@withContext Result.success()
}
try {
val filePaths = inputData.getStringArray(FILE_PATHS)
if (filePaths.isNullOrEmpty()) {
return@withContext Result.success()
}

val fileDataStorageManager = FileDataStorageManager(user, context.contentResolver)
val storageManager = FileDataStorageManager(user, context.contentResolver)

// Add the topParentPath to mark the sync icon on the selected folder.
val topParentPath = getTopParentPath(fileDataStorageManager, filePaths.first())
downloadingFilePaths = ArrayList(filePaths.toList()).apply {
add(topParentPath)
}
val topParentPath = prepareDownloadingFilePathsAndGetTopParentPath(storageManager, filePaths)

val account = user.toOwnCloudAccount()
val client = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(account, context)
val client = getClient()

var result = true
filePaths.forEachIndexed { index, path ->
if (isStopped) {
notificationManager.dismiss()
return@withContext Result.failure()
}
var result = true
filePaths.forEachIndexed { index, path ->
if (isStopped) {
notificationManager.dismiss()
return@withContext Result.failure()
}

fileDataStorageManager.getFileByDecryptedRemotePath(path)?.let { file ->
val fileSizeInByte = file.fileLength
val availableDiskSpace = FileOperationsHelper.getAvailableSpaceOnDevice()
val file = storageManager.getFileByDecryptedRemotePath(path) ?: return@forEachIndexed

// TODO check
if (availableDiskSpace < fileSizeInByte) {
notificationManager.showNotAvailableDiskSpace()
if (!checkDiskSize(file)) {
return@withContext Result.failure()
}

withContext(Dispatchers.Main) {
notificationManager.showProgressNotification(file.fileName, index, filePaths.size)
}

delay(1000)

val operation = DownloadFileOperation(user, file, context).execute(client)
Log_OC.d(TAG, "Syncing file: " + file.decryptedRemotePath)

if (operation.isSuccess) {
sendFileDownloadCompletionBroadcast(path)
downloadingFilePaths.remove(path)
} else {
val syncFileResult = syncFile(file, path, client)
if (!syncFileResult) {
result = false
}
}
}

withContext(Dispatchers.Main) {
notificationManager.showCompletionMessage(result)
}
withContext(Dispatchers.Main) {
notificationManager.showCompletionMessage(result)
}

if (result) {
downloadingFilePaths.remove(topParentPath)
sendSyncWorkerCompletionBroadcast()
Log_OC.d(TAG, "SyncWorker completed")
Result.success()
} else {
Log_OC.d(TAG, "SyncWorker failed")
if (result) {
downloadingFilePaths.remove(topParentPath)
sendSyncWorkerCompletionBroadcast()
Log_OC.d(TAG, "SyncWorker completed")
Result.success()
} else {
Log_OC.d(TAG, "SyncWorker failed")
Result.failure()
}
} catch (e: Exception) {
Log_OC.d(TAG, "SyncWorker failed reason: $e")
Result.failure()
}
}
}

private fun getTopParentPath(fileDataStorageManager: FileDataStorageManager, firstFilePath: String): String {
val firstFile = fileDataStorageManager.getFileByDecryptedRemotePath(firstFilePath)
val topParentFile = fileDataStorageManager.getTopParent(firstFile)
@Suppress("DEPRECATION")
private fun getClient(): OwnCloudClient {
val account = user.toOwnCloudAccount()
return OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(account, context)
}

/**
* Add the topParentPath to mark the sync icon on the selected folder.
*/
private fun prepareDownloadingFilePathsAndGetTopParentPath(
storageManager: FileDataStorageManager,
filePaths: Array<String>
): String {
val topParentPath = getTopParentPath(storageManager, filePaths.first())
downloadingFilePaths = Collections.synchronizedList(ArrayList(filePaths.toList())).apply {
add(topParentPath)
}

return topParentPath
}

private suspend fun checkDiskSize(file: OCFile): Boolean {
val fileSizeInByte = file.fileLength
val availableDiskSpace = FileOperationsHelper.getAvailableSpaceOnDevice()

return if (availableDiskSpace < fileSizeInByte) {
notificationManager.showNotAvailableDiskSpace()
false
} else {
true
}
}

@Suppress("DEPRECATION")
private fun syncFile(file: OCFile, path: String, client: OwnCloudClient): Boolean {
val operation = DownloadFileOperation(user, file, context).execute(client)
Log_OC.d(TAG, "Syncing file: " + file.decryptedRemotePath)

return if (operation.isSuccess) {
sendFileDownloadCompletionBroadcast(path)
downloadingFilePaths.remove(path)
true
} else {
false
}
}

private fun getTopParentPath(storageManager: FileDataStorageManager, firstFilePath: String): String {
val firstFile = storageManager.getFileByDecryptedRemotePath(firstFilePath)
val topParentFile = storageManager.getTopParent(firstFile)
return topParentFile.decryptedRemotePath
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,10 @@ public void cancelTransference(OCFile file) {
}
}

if (file.isFolder()) {
// TODO: Call cancellation function
}

if (FileDownloadHelper.Companion.instance().isDownloading(currentUser, file)) {
List<OCFile> files = fileActivity.getStorageManager().getAllFilesRecursivelyInsideFolder(file);
FileDownloadHelper.Companion.instance().cancelPendingOrCurrentDownloads(currentUser, files);
Expand Down

0 comments on commit 57990c8

Please sign in to comment.