Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ class BackgroundJobFactory @Inject constructor(
accountManager,
context,
viewThemeUtils.get(),
localBroadcastManager.get(),
params
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ interface BackgroundJobManager {
fun cancelFilesUploadJob(user: User)
fun isStartFileUploadJobScheduled(accountName: String): Boolean

fun cancelFilesDownloadJob(user: User, fileId: Long)
fun cancelFilesDownloadJob(accountName: String, fileId: Long)

@Suppress("LongParameterList")
fun startFileDownloadJob(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.utils.extensions.isWorkRunning
import com.nextcloud.utils.extensions.isWorkScheduled
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.datamodel.SyncedFolder
Expand Down Expand Up @@ -662,8 +661,8 @@ internal class BackgroundJobManagerImpl(
}
}

private fun startFileDownloadJobTag(user: User, fileId: Long): String =
JOB_FOLDER_DOWNLOAD + user.accountName + fileId
private fun startFileDownloadJobTag(accountName: String, fileId: Long): String =
JOB_FOLDER_DOWNLOAD + accountName + fileId

override fun startFileDownloadJob(
user: User,
Expand All @@ -674,7 +673,7 @@ internal class BackgroundJobManagerImpl(
packageName: String,
conflictUploadId: Long?
) {
val tag = startFileDownloadJobTag(user, file.fileId)
val tag = startFileDownloadJobTag(user.accountName, file.fileId)

val data = workDataOf(
FileDownloadWorker.ACCOUNT_NAME to user.accountName,
Expand Down Expand Up @@ -706,8 +705,8 @@ internal class BackgroundJobManagerImpl(
workManager.cancelJob(JOB_FILES_UPLOAD, user)
}

override fun cancelFilesDownloadJob(user: User, fileId: Long) {
workManager.cancelAllWorkByTag(startFileDownloadJobTag(user, fileId))
override fun cancelFilesDownloadJob(accountName: String, fileId: Long) {
workManager.cancelAllWorkByTag(startFileDownloadJobTag(accountName, fileId))
}

override fun startPdfGenerateAndUploadWork(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
*/
package com.nextcloud.client.jobs.download

import android.content.Context
import android.content.Intent
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.operations.DownloadFileOperation
import com.owncloud.android.ui.dialog.SendShareDialog
import com.owncloud.android.ui.fragment.OCFileListFragment

class FileDownloadBroadcastManager(
private val context: Context,
private val broadcastManager: LocalBroadcastManager
) {
companion object {
private const val TAG = "📣" + "FileDownloadBroadcastManager"

const val DOWNLOAD_ADDED = "DOWNLOAD_ADDED"
const val DOWNLOAD_FINISHED = "DOWNLOAD_FINISHED"
}

fun sendAdded(
accountName: String,
remotePath: String,
packageName: String,
fileId: Long?,
linkedToRemotePath: String?,
currentDownloadAccountName: String?
) {
Log_OC.d(TAG, "download added broadcast sent")

val intent = Intent(DOWNLOAD_ADDED).apply {
putExtra(FileDownloadWorker.EXTRA_ACCOUNT_NAME, accountName)
putExtra(FileDownloadWorker.EXTRA_REMOTE_PATH, remotePath)

fileId?.let {
putExtra(FileDownloadWorker.EXTRA_CURRENT_DOWNLOAD_FILE_ID, fileId)
}

currentDownloadAccountName?.let {
putExtra(FileDownloadWorker.EXTRA_CURRENT_DOWNLOAD_ACCOUNT_NAME, currentDownloadAccountName)
}

linkedToRemotePath?.let {
putExtra(FileDownloadWorker.EXTRA_LINKED_TO_PATH, linkedToRemotePath)
}
setPackage(packageName)
}

broadcastManager.sendBroadcast(intent)
}

fun sendFinished(
download: DownloadFileOperation,
downloadResult: RemoteOperationResult<*>,
unlinkedFromRemotePath: String?
) {
Log_OC.d(TAG, "download finish broadcast sent")

val intent = Intent(DOWNLOAD_FINISHED).apply {
putExtra(FileDownloadWorker.EXTRA_DOWNLOAD_RESULT, downloadResult.isSuccess)
putExtra(FileDownloadWorker.EXTRA_ACCOUNT_NAME, download.user.accountName)
putExtra(FileDownloadWorker.EXTRA_REMOTE_PATH, download.remotePath)
putExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR, download.behaviour)
putExtra(SendShareDialog.ACTIVITY_NAME, download.activityName)
putExtra(SendShareDialog.PACKAGE_NAME, download.packageName)
if (unlinkedFromRemotePath != null) {
putExtra(FileDownloadWorker.EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath)
}
setPackage(context.packageName)
}

broadcastManager.sendBroadcast(intent)
}

fun sendFinished(
accountName: String,
remotePath: String?,
packageName: String,
success: Boolean
) {
Log_OC.d(TAG, "download finish broadcast sent")

val intent = Intent(DOWNLOAD_FINISHED).apply {
putExtra(FileDownloadWorker.EXTRA_ACCOUNT_NAME, accountName)
putExtra(FileDownloadWorker.EXTRA_REMOTE_PATH, remotePath)
putExtra(FileDownloadWorker.EXTRA_DOWNLOAD_RESULT, success)
setPackage(packageName)
}

broadcastManager.sendBroadcast(intent)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,17 @@ class FileDownloadHelper {

files.forEach { file ->
FileDownloadWorker.cancelOperation(user.accountName, file.fileId)
backgroundJobManager.cancelFilesDownloadJob(user, file.fileId)
backgroundJobManager.cancelFilesDownloadJob(user.accountName, file.fileId)
}
}

fun cancelAllDownloadsForAccount(accountName: String?, currentDownload: DownloadFileOperation?) {
if (accountName == null || currentDownload == null) return

val currentUser = currentDownload.user
val currentFile = currentDownload.file

if (!currentUser.nameEquals(accountName)) {
fun cancelAllDownloadsForAccount(accountName: String, currentDownloadAccountName: String, fileId: Long) {
if (!accountName.equals(currentDownloadAccountName, true)) {
return
}

currentDownload.cancel()
FileDownloadWorker.cancelOperation(currentUser.accountName, currentFile.fileId)
backgroundJobManager.cancelFilesDownloadJob(currentUser, currentFile.fileId)
FileDownloadWorker.cancelOperation(currentDownloadAccountName, fileId)
backgroundJobManager.cancelFilesDownloadJob(currentDownloadAccountName, fileId)
}

fun saveFile(file: OCFile, currentDownload: DownloadFileOperation?, storageManager: FileDataStorageManager?) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,24 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

package com.nextcloud.client.jobs.download

import android.content.Context
import android.content.Intent
import com.nextcloud.client.account.User
import com.owncloud.android.authentication.AuthenticatorActivity
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.operations.DownloadFileOperation
import com.owncloud.android.ui.activity.FileActivity
import com.owncloud.android.ui.activity.FileDisplayActivity
import com.owncloud.android.ui.dialog.SendShareDialog
import com.owncloud.android.ui.fragment.OCFileListFragment
import com.owncloud.android.ui.preview.PreviewImageActivity
import com.owncloud.android.ui.preview.PreviewImageFragment

class FileDownloadIntents(private val context: Context) {

fun newDownloadIntent(download: DownloadFileOperation, linkedToRemotePath: String): Intent =
Intent(FileDownloadWorker.getDownloadAddedMessage()).apply {
putExtra(FileDownloadWorker.EXTRA_ACCOUNT_NAME, download.user.accountName)
putExtra(FileDownloadWorker.EXTRA_REMOTE_PATH, download.remotePath)
putExtra(FileDownloadWorker.EXTRA_LINKED_TO_PATH, linkedToRemotePath)
setPackage(context.packageName)
}

fun downloadFinishedIntent(
download: DownloadFileOperation,
downloadResult: RemoteOperationResult<*>,
unlinkedFromRemotePath: String?
): Intent = Intent(FileDownloadWorker.getDownloadFinishMessage()).apply {
putExtra(FileDownloadWorker.EXTRA_DOWNLOAD_RESULT, downloadResult.isSuccess)
putExtra(FileDownloadWorker.EXTRA_ACCOUNT_NAME, download.user.accountName)
putExtra(FileDownloadWorker.EXTRA_REMOTE_PATH, download.remotePath)
putExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR, download.behaviour)
putExtra(SendShareDialog.ACTIVITY_NAME, download.activityName)
putExtra(SendShareDialog.PACKAGE_NAME, download.packageName)
if (unlinkedFromRemotePath != null) {
putExtra(FileDownloadWorker.EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath)
}
setPackage(context.packageName)
}

fun credentialContentIntent(user: User): Intent = Intent(context, AuthenticatorActivity::class.java).apply {
putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, user.toPlatformAccount())
putExtra(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import com.nextcloud.client.account.User
import com.nextcloud.client.account.UserAccountManager
import com.nextcloud.model.WorkerState
import com.nextcloud.model.WorkerStateObserver
import com.nextcloud.utils.ForegroundServiceHelper
import com.nextcloud.utils.extensions.getPercent
import com.owncloud.android.R
Expand Down Expand Up @@ -50,7 +48,7 @@ import kotlin.random.Random
class FileDownloadWorker(
viewThemeUtils: ViewThemeUtils,
private val accountManager: UserAccountManager,
private var localBroadcastManager: LocalBroadcastManager,
localBroadcastManager: LocalBroadcastManager,
private val context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params),
Expand Down Expand Up @@ -83,18 +81,18 @@ class FileDownloadWorker(
const val EXTRA_REMOTE_PATH = "EXTRA_REMOTE_PATH"
const val EXTRA_LINKED_TO_PATH = "EXTRA_LINKED_TO_PATH"
const val EXTRA_ACCOUNT_NAME = "EXTRA_ACCOUNT_NAME"

fun getDownloadAddedMessage(): String = FileDownloadWorker::class.java.name + "DOWNLOAD_ADDED"

fun getDownloadFinishMessage(): String = FileDownloadWorker::class.java.name + "DOWNLOAD_FINISH"
const val EXTRA_CURRENT_DOWNLOAD_ACCOUNT_NAME = "EXTRA_CURRENT_DOWNLOAD_ACCOUNT_NAME"
const val EXTRA_CURRENT_DOWNLOAD_FILE_ID = "EXTRA_CURRENT_DOWNLOAD_FILE_ID"
}

private var currentDownload: DownloadFileOperation? = null

private var conflictUploadId: Long? = null
private var lastPercent = 0

private val fileDownloadBroadcastManager = FileDownloadBroadcastManager(context, localBroadcastManager)
private val intents = FileDownloadIntents(context)

private var notificationManager = DownloadNotificationManager(
Random.nextInt(),
context,
Expand Down Expand Up @@ -140,7 +138,6 @@ class FileDownloadWorker(
} finally {
Log_OC.d(TAG, "cleanup")
notificationManager.dismissNotification()
setIdleWorkerState()
}
}

Expand Down Expand Up @@ -168,14 +165,6 @@ class FileDownloadWorker(
ForegroundServiceType.DataSync
)

private fun setWorkerState(user: User?) {
WorkerStateObserver.send(WorkerState.FileDownloadStarted(user, currentDownload))
}

private fun setIdleWorkerState() {
WorkerStateObserver.send(WorkerState.FileDownloadCompleted(getCurrentFile()))
}

private fun removePendingDownload(accountName: String?) {
pendingDownloads.remove(accountName)
}
Expand Down Expand Up @@ -216,9 +205,14 @@ class FileDownloadWorker(
requestedDownloads.add(downloadKey)
}

linkedToRemotePath?.let {
localBroadcastManager.sendBroadcast(intents.newDownloadIntent(operation, linkedToRemotePath))
}
fileDownloadBroadcastManager.sendAdded(
operation.user.accountName,
operation.remotePath,
context.packageName,
operation.file.fileId,
linkedToRemotePath,
operation.user.accountName
)
}

requestedDownloads
Expand Down Expand Up @@ -266,7 +260,6 @@ class FileDownloadWorker(
return
}

setWorkerState(user)
Log_OC.d(TAG, "downloading: $downloadKey")

val isAccountExist = accountManager.exists(currentDownload?.user?.toPlatformAccount())
Expand Down Expand Up @@ -342,13 +335,11 @@ class FileDownloadWorker(
currentDownload?.run {
notifyDownloadResult(this, downloadResult)

val downloadFinishedIntent = intents.downloadFinishedIntent(
fileDownloadBroadcastManager.sendFinished(
this,
downloadResult,
removeResult.second
)

localBroadcastManager.sendBroadcast(downloadFinishedIntent)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

package com.nextcloud.client.jobs.folderDownload

import android.content.Context
import android.content.Intent
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.nextcloud.client.jobs.download.FileDownloadWorker
import com.owncloud.android.lib.common.utils.Log_OC

class FolderDownloadBroadcastManager(
private val context: Context,
private val broadcastManager: LocalBroadcastManager
) {
companion object {
private const val TAG = "📣" + "FolderDownloadBroadcastManager"

const val DOWNLOAD_ADDED = "DOWNLOAD_ADDED"
const val DOWNLOAD_FINISHED = "DOWNLOAD_FINISHED"

const val EXTRA_FILE_ID = "EXTRA_FILE_ID"
}

fun sendAdded(id: Long) {
Log_OC.d(TAG, "download added broadcast sent")

val intent = Intent(DOWNLOAD_ADDED).apply {
putExtra(EXTRA_FILE_ID, id)
}

broadcastManager.sendBroadcast(intent)
}

fun sendFinished(id: Long) {
Log_OC.d(TAG, "download finished broadcast sent")

val intent = Intent(DOWNLOAD_FINISHED).apply {
putExtra(EXTRA_FILE_ID, id)
}

broadcastManager.sendBroadcast(intent)
}
}
Loading
Loading