improve file download worker

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2024-11-07 15:32:53 +01:00
parent aa77375ae3
commit 031a1b9c44
No known key found for this signature in database
GPG key ID: 4E577DC593B59BDF
2 changed files with 32 additions and 48 deletions

View file

@ -25,17 +25,8 @@ class DownloadNotificationManager(
) : WorkerNotificationManager(id, context, viewThemeUtils, R.string.downloader_download_in_progress_ticker) { ) : WorkerNotificationManager(id, context, viewThemeUtils, R.string.downloader_download_in_progress_ticker) {
@Suppress("MagicNumber") @Suppress("MagicNumber")
fun prepareForStart(operation: DownloadFileOperation, currentDownloadIndex: Int, totalDownloadSize: Int) { fun prepareForStart(operation: DownloadFileOperation) {
currentOperationTitle = if (totalDownloadSize > 1) { currentOperationTitle = File(operation.savePath).name
String.format(
context.getString(R.string.downloader_notification_manager_download_text),
currentDownloadIndex,
totalDownloadSize,
File(operation.savePath).name
)
} else {
File(operation.savePath).name
}
notificationBuilder.run { notificationBuilder.run {
setContentTitle(currentOperationTitle) setContentTitle(currentOperationTitle)

View file

@ -16,7 +16,8 @@ import android.util.Pair
import androidx.core.util.component1 import androidx.core.util.component1
import androidx.core.util.component2 import androidx.core.util.component2
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.work.Worker import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.nextcloud.client.account.User import com.nextcloud.client.account.User
import com.nextcloud.client.account.UserAccountManager import com.nextcloud.client.account.UserAccountManager
@ -38,10 +39,10 @@ import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.operations.DownloadFileOperation import com.owncloud.android.operations.DownloadFileOperation
import com.owncloud.android.operations.DownloadType import com.owncloud.android.operations.DownloadType
import com.owncloud.android.utils.theme.ViewThemeUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import java.security.SecureRandom
import java.util.AbstractList import java.util.AbstractList
import java.util.Optional import java.util.Optional
import java.util.Vector import java.util.Vector
import kotlin.random.Random
@Suppress("LongParameterList", "TooManyFunctions") @Suppress("LongParameterList", "TooManyFunctions")
class FileDownloadWorker( class FileDownloadWorker(
@ -50,7 +51,7 @@ class FileDownloadWorker(
private var localBroadcastManager: LocalBroadcastManager, private var localBroadcastManager: LocalBroadcastManager,
private val context: Context, private val context: Context,
params: WorkerParameters params: WorkerParameters
) : Worker(context, params), OnAccountsUpdateListener, OnDatatransferProgressListener { ) : CoroutineWorker(context, params), OnAccountsUpdateListener, OnDatatransferProgressListener {
companion object { companion object {
private val TAG = FileDownloadWorker::class.java.simpleName private val TAG = FileDownloadWorker::class.java.simpleName
@ -74,7 +75,6 @@ class FileDownloadWorker(
const val ACTIVITY_NAME = "ACTIVITY_NAME" const val ACTIVITY_NAME = "ACTIVITY_NAME"
const val PACKAGE_NAME = "PACKAGE_NAME" const val PACKAGE_NAME = "PACKAGE_NAME"
const val CONFLICT_UPLOAD_ID = "CONFLICT_UPLOAD_ID" const val CONFLICT_UPLOAD_ID = "CONFLICT_UPLOAD_ID"
const val EXTRA_DOWNLOAD_RESULT = "EXTRA_DOWNLOAD_RESULT" const val EXTRA_DOWNLOAD_RESULT = "EXTRA_DOWNLOAD_RESULT"
const val EXTRA_REMOTE_PATH = "EXTRA_REMOTE_PATH" const val EXTRA_REMOTE_PATH = "EXTRA_REMOTE_PATH"
const val EXTRA_LINKED_TO_PATH = "EXTRA_LINKED_TO_PATH" const val EXTRA_LINKED_TO_PATH = "EXTRA_LINKED_TO_PATH"
@ -96,7 +96,7 @@ class FileDownloadWorker(
private val intents = FileDownloadIntents(context) private val intents = FileDownloadIntents(context)
private var notificationManager = DownloadNotificationManager( private var notificationManager = DownloadNotificationManager(
SecureRandom().nextInt(), Random.nextInt(),
context, context,
viewThemeUtils viewThemeUtils
) )
@ -112,20 +112,19 @@ class FileDownloadWorker(
private var downloadError: FileDownloadError? = null private var downloadError: FileDownloadError? = null
@Suppress("TooGenericExceptionCaught") @Suppress("TooGenericExceptionCaught")
override fun doWork(): Result { override suspend fun doWork(): Result {
val foregroundInfo = createWorkerForegroundInfo()
setForeground(foregroundInfo)
return try { return try {
val requestDownloads = getRequestDownloads() setUser()
val remotePath = inputData.keyValueMap[FILE_REMOTE_PATH] as String? ?: return Result.failure()
val ocFile = fileDataStorageManager?.getFileByEncryptedRemotePath(remotePath) ?: return Result.failure()
val requestDownloads = getRequestDownloads(ocFile)
addAccountUpdateListener() addAccountUpdateListener()
val foregroundInfo = ForegroundServiceHelper.createWorkerForegroundInfo( requestDownloads.forEach {
notificationManager.getId(), downloadFile(it)
notificationManager.getNotification(),
ForegroundServiceType.DataSync
)
setForegroundAsync(foregroundInfo)
requestDownloads.forEachIndexed { currentDownloadIndex, requestedDownload ->
downloadFile(requestedDownload, currentDownloadIndex, requestDownloads.size)
} }
downloadError?.let { downloadError?.let {
@ -133,26 +132,25 @@ class FileDownloadWorker(
notificationManager.dismissNotification() notificationManager.dismissNotification()
} }
setIdleWorkerState()
Log_OC.e(TAG, "FilesDownloadWorker successfully completed") Log_OC.e(TAG, "FilesDownloadWorker successfully completed")
Result.success() Result.success()
} catch (t: Throwable) { } catch (t: Throwable) {
notificationManager.dismissNotification()
notificationManager.showNewNotification(context.getString(R.string.downloader_unexpected_error)) notificationManager.showNewNotification(context.getString(R.string.downloader_unexpected_error))
Log_OC.e(TAG, "Error caught at FilesDownloadWorker(): " + t.localizedMessage) Log_OC.e(TAG, "Error caught at FilesDownloadWorker(): " + t.localizedMessage)
setIdleWorkerState()
Result.failure() Result.failure()
} finally {
Log_OC.e(TAG, "FilesDownloadWorker cleanup")
notificationManager.dismissNotification()
setIdleWorkerState()
} }
} }
override fun onStopped() { private fun createWorkerForegroundInfo(): ForegroundInfo {
Log_OC.e(TAG, "FilesDownloadWorker stopped") return ForegroundServiceHelper.createWorkerForegroundInfo(
notificationManager.getId(),
notificationManager.dismissNotification() notificationManager.getNotification(),
setIdleWorkerState() ForegroundServiceType.DataSync
)
super.onStopped()
} }
private fun setWorkerState(user: User?) { private fun setWorkerState(user: User?) {
@ -167,9 +165,8 @@ class FileDownloadWorker(
pendingDownloads.remove(accountName) pendingDownloads.remove(accountName)
} }
private fun getRequestDownloads(): AbstractList<String> { private fun getRequestDownloads(ocFile: OCFile): AbstractList<String> {
setUser() val files = getFiles(ocFile)
val files = getFiles()
val downloadType = getDownloadType() val downloadType = getDownloadType()
conflictUploadId = inputData.keyValueMap[CONFLICT_UPLOAD_ID] as Long? conflictUploadId = inputData.keyValueMap[CONFLICT_UPLOAD_ID] as Long?
@ -222,10 +219,7 @@ class FileDownloadWorker(
fileDataStorageManager = FileDataStorageManager(user, context.contentResolver) fileDataStorageManager = FileDataStorageManager(user, context.contentResolver)
} }
private fun getFiles(): List<OCFile> { private fun getFiles(file: OCFile): List<OCFile> {
val remotePath = inputData.keyValueMap[FILE_REMOTE_PATH] as String?
val file = fileDataStorageManager?.getFileByEncryptedRemotePath(remotePath) ?: return listOf()
return if (file.isFolder) { return if (file.isFolder) {
fileDataStorageManager?.getAllFilesRecursivelyInsideFolder(file) ?: listOf() fileDataStorageManager?.getAllFilesRecursivelyInsideFolder(file) ?: listOf()
} else { } else {
@ -252,7 +246,7 @@ class FileDownloadWorker(
} }
@Suppress("TooGenericExceptionCaught", "DEPRECATION") @Suppress("TooGenericExceptionCaught", "DEPRECATION")
private fun downloadFile(downloadKey: String, currentDownloadIndex: Int, totalDownloadSize: Int) { private fun downloadFile(downloadKey: String) {
currentDownload = pendingDownloads.get(downloadKey) currentDownload = pendingDownloads.get(downloadKey)
if (currentDownload == null) { if (currentDownload == null) {
@ -269,9 +263,8 @@ class FileDownloadWorker(
} }
lastPercent = 0 lastPercent = 0
notificationManager.run { notificationManager.run {
prepareForStart(currentDownload!!, currentDownloadIndex + 1, totalDownloadSize) prepareForStart(currentDownload!!)
setContentIntent(intents.detailsIntent(currentDownload!!), PendingIntent.FLAG_IMMUTABLE) setContentIntent(intents.detailsIntent(currentDownload!!), PendingIntent.FLAG_IMMUTABLE)
} }