mirror of
https://github.com/nextcloud/android.git
synced 2024-12-20 16:02:01 +03:00
use folder not list of files to prevent exceed input data passing limit
Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
parent
b2b87a831e
commit
3ee4153baa
5 changed files with 31 additions and 56 deletions
|
@ -172,6 +172,6 @@ interface BackgroundJobManager {
|
||||||
fun startPeriodicallyOfflineOperation()
|
fun startPeriodicallyOfflineOperation()
|
||||||
fun scheduleInternal2WaySync(intervalMinutes: Long)
|
fun scheduleInternal2WaySync(intervalMinutes: Long)
|
||||||
fun cancelAllFilesDownloadJobs()
|
fun cancelAllFilesDownloadJobs()
|
||||||
fun syncFolder(files: List<OCFile>, folderId: Long)
|
fun syncFolder(folder: OCFile)
|
||||||
fun cancelSyncFolder(folderId: Long)
|
fun cancelSyncFolder(folderId: Long)
|
||||||
}
|
}
|
||||||
|
|
|
@ -716,9 +716,8 @@ 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(files: List<OCFile>, folderId: Long) {
|
override fun syncFolder(folder: OCFile) {
|
||||||
val tag = getSyncFolderTag(folderId)
|
val tag = getSyncFolderTag(folder.fileId)
|
||||||
val filePaths = files.map { it.decryptedRemotePath }
|
|
||||||
|
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
|
@ -726,7 +725,7 @@ internal class BackgroundJobManagerImpl(
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val data = Data.Builder()
|
val data = Data.Builder()
|
||||||
.putStringArray(SyncWorker.FILE_PATHS, filePaths.toTypedArray())
|
.putLong(SyncWorker.FOLDER_ID, folder.fileId)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val request = oneTimeRequestBuilder(SyncWorker::class, JOB_SYNC_FOLDER)
|
val request = oneTimeRequestBuilder(SyncWorker::class, JOB_SYNC_FOLDER)
|
||||||
|
|
|
@ -141,13 +141,7 @@ class FileDownloadHelper {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun syncFolder(files: List<OCFile>) {
|
fun syncFolder(folder: OCFile) {
|
||||||
if (files.isEmpty()) {
|
backgroundJobManager.syncFolder(folder)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val firstFile = files.first()
|
|
||||||
val topParentFileId = fileStorageManager.getTopParentId(firstFile)
|
|
||||||
backgroundJobManager.syncFolder(files, topParentFileId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import com.owncloud.android.operations.DownloadFileOperation
|
||||||
import com.owncloud.android.ui.helpers.FileOperationsHelper
|
import com.owncloud.android.ui.helpers.FileOperationsHelper
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.Collections
|
|
||||||
|
|
||||||
class SyncWorker(
|
class SyncWorker(
|
||||||
private val user: User,
|
private val user: User,
|
||||||
|
@ -33,19 +32,19 @@ class SyncWorker(
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "SyncWorker"
|
private const val TAG = "SyncWorker"
|
||||||
|
|
||||||
const val FILE_PATHS = "FILE_PATHS"
|
const val FOLDER_ID = "FOLDER_ID"
|
||||||
|
|
||||||
const val SYNC_WORKER_COMPLETION_BROADCAST = "SYNC_WORKER_COMPLETION_BROADCAST"
|
const val SYNC_WORKER_COMPLETION_BROADCAST = "SYNC_WORKER_COMPLETION_BROADCAST"
|
||||||
const val FILE_DOWNLOAD_COMPLETION_BROADCAST = "FILE_DOWNLOAD_COMPLETION_BROADCAST"
|
const val FILE_DOWNLOAD_COMPLETION_BROADCAST = "FILE_DOWNLOAD_COMPLETION_BROADCAST"
|
||||||
const val FILE_PATH = "FILE_PATH"
|
const val FILE_PATH = "FILE_PATH"
|
||||||
|
|
||||||
private var downloadingFilePaths = mutableListOf<String>()
|
private var files = mutableListOf<OCFile>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is used to add the sync icon next to the file in the folder.
|
* It is used to add the sync icon next to the file in the folder.
|
||||||
*/
|
*/
|
||||||
fun isDownloading(path: String): Boolean {
|
fun isDownloading(path: String): Boolean {
|
||||||
return downloadingFilePaths.contains(path)
|
return files.any { it.decryptedRemotePath == path }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,35 +60,36 @@ class SyncWorker(
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val filePaths = inputData.getStringArray(FILE_PATHS)
|
val folderID = inputData.getLong(FOLDER_ID, -1)
|
||||||
if (filePaths.isNullOrEmpty()) {
|
if (folderID == -1L) {
|
||||||
return@withContext Result.success()
|
return@withContext Result.failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
val storageManager = FileDataStorageManager(user, context.contentResolver)
|
val storageManager = FileDataStorageManager(user, context.contentResolver)
|
||||||
|
val folder = storageManager.getFileById(folderID) ?: return@withContext Result.failure()
|
||||||
val topParentPath = prepareDownloadingFilePathsAndGetTopParentPath(storageManager, filePaths)
|
files = ArrayList(getFiles(folder, storageManager)).apply {
|
||||||
|
// Add the topParentPath to mark the sync icon on the selected folder.
|
||||||
|
add(folder)
|
||||||
|
}
|
||||||
|
|
||||||
val client = getClient()
|
val client = getClient()
|
||||||
|
|
||||||
var result = true
|
var result = true
|
||||||
filePaths.forEachIndexed { index, path ->
|
files.forEachIndexed { index, file ->
|
||||||
if (isStopped) {
|
if (isStopped) {
|
||||||
notificationManager.dismiss()
|
notificationManager.dismiss()
|
||||||
return@withContext Result.failure()
|
return@withContext Result.failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
val file = storageManager.getFileByDecryptedRemotePath(path) ?: return@forEachIndexed
|
|
||||||
|
|
||||||
if (!checkDiskSize(file)) {
|
if (!checkDiskSize(file)) {
|
||||||
return@withContext Result.failure()
|
return@withContext Result.failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.showProgressNotification(file.fileName, index, filePaths.size)
|
notificationManager.showProgressNotification(file.fileName, index, files.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
val syncFileResult = syncFile(file, path, client)
|
val syncFileResult = syncFile(file, client)
|
||||||
if (!syncFileResult) {
|
if (!syncFileResult) {
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ class SyncWorker(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
downloadingFilePaths.remove(topParentPath)
|
files.remove(folder)
|
||||||
sendSyncWorkerCompletionBroadcast()
|
sendSyncWorkerCompletionBroadcast()
|
||||||
Log_OC.d(TAG, "SyncWorker completed")
|
Log_OC.d(TAG, "SyncWorker completed")
|
||||||
Result.success()
|
Result.success()
|
||||||
|
@ -115,27 +115,16 @@ class SyncWorker(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getFiles(folder: OCFile, storageManager: FileDataStorageManager): List<OCFile> =
|
||||||
|
storageManager.getFolderContent(folder, false)
|
||||||
|
.filter { !it.isFolder && !it.isDown }
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
private fun getClient(): OwnCloudClient {
|
private fun getClient(): OwnCloudClient {
|
||||||
val account = user.toOwnCloudAccount()
|
val account = user.toOwnCloudAccount()
|
||||||
return OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(account, context)
|
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 {
|
private suspend fun checkDiskSize(file: OCFile): Boolean {
|
||||||
val fileSizeInByte = file.fileLength
|
val fileSizeInByte = file.fileLength
|
||||||
val availableDiskSpace = FileOperationsHelper.getAvailableSpaceOnDevice()
|
val availableDiskSpace = FileOperationsHelper.getAvailableSpaceOnDevice()
|
||||||
|
@ -149,31 +138,25 @@ class SyncWorker(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
private fun syncFile(file: OCFile, path: String, client: OwnCloudClient): Boolean {
|
private fun syncFile(file: OCFile, client: OwnCloudClient): Boolean {
|
||||||
val operation = DownloadFileOperation(user, file, context).execute(client)
|
val operation = DownloadFileOperation(user, file, context).execute(client)
|
||||||
Log_OC.d(TAG, "Syncing file: " + file.decryptedRemotePath)
|
Log_OC.d(TAG, "Syncing file: " + file.decryptedRemotePath)
|
||||||
|
|
||||||
return if (operation.isSuccess) {
|
return if (operation.isSuccess) {
|
||||||
sendFileDownloadCompletionBroadcast(path)
|
sendFileDownloadCompletionBroadcast(file)
|
||||||
downloadingFilePaths.remove(path)
|
files.remove(file)
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTopParentPath(storageManager: FileDataStorageManager, firstFilePath: String): String {
|
|
||||||
val firstFile = storageManager.getFileByDecryptedRemotePath(firstFilePath)
|
|
||||||
val topParentFile = storageManager.getTopParent(firstFile)
|
|
||||||
return topParentFile.decryptedRemotePath
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is used to remove the sync icon next to the file in the folder.
|
* It is used to remove the sync icon next to the file in the folder.
|
||||||
*/
|
*/
|
||||||
private fun sendFileDownloadCompletionBroadcast(path: String) {
|
private fun sendFileDownloadCompletionBroadcast(file: OCFile) {
|
||||||
val intent = Intent(FILE_DOWNLOAD_COMPLETION_BROADCAST).apply {
|
val intent = Intent(FILE_DOWNLOAD_COMPLETION_BROADCAST).apply {
|
||||||
putExtra(FILE_PATH, path)
|
putExtra(FILE_PATH, file.decryptedRemotePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
|
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
|
||||||
|
|
|
@ -416,7 +416,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void prepareOpsFromLocalKnowledge() throws OperationCancelledException {
|
private void prepareOpsFromLocalKnowledge() throws OperationCancelledException {
|
||||||
List<OCFile> children = getStorageManager().getFolderContent(mLocalFolder, false);
|
List<OCFile> children = getStorageManager().getFolderContent(mLocalFolder, false);
|
||||||
for (OCFile child : children) {
|
for (OCFile child : children) {
|
||||||
|
@ -500,7 +499,7 @@ 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 {
|
||||||
fileDownloadHelper.syncFolder(mFilesForDirectDownload);
|
fileDownloadHelper.syncFolder(mLocalFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue