added DEV version to repo
This commit is contained in:
parent
1ef725ef20
commit
23e673bfdf
2135 changed files with 97033 additions and 21206 deletions
|
|
@ -1,77 +1,49 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper_ozturk@proton.me>
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
package com.nextcloud.client.jobs.download
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.nextcloud.client.jobs.notification.WorkerNotificationManager
|
||||
import com.nextcloud.utils.numberFormatter.NumberFormatter
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.lib.resources.files.FileUtils
|
||||
import com.owncloud.android.operations.DownloadFileOperation
|
||||
import com.owncloud.android.ui.notifications.NotificationUtils
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils
|
||||
import java.io.File
|
||||
import java.security.SecureRandom
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class DownloadNotificationManager(
|
||||
private val id: Int,
|
||||
private val context: Context,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) {
|
||||
private var notification: Notification
|
||||
private var notificationBuilder: NotificationCompat.Builder
|
||||
private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
class DownloadNotificationManager(id: Int, private val context: Context, viewThemeUtils: ViewThemeUtils) :
|
||||
WorkerNotificationManager(id, context, viewThemeUtils, R.string.downloader_download_in_progress_ticker) {
|
||||
|
||||
private var lastPercent = -1
|
||||
|
||||
init {
|
||||
notificationBuilder = NotificationUtils.newNotificationBuilder(context, viewThemeUtils).apply {
|
||||
setContentTitle(context.getString(R.string.downloader_download_in_progress_ticker))
|
||||
setTicker(context.getString(R.string.downloader_download_in_progress_ticker))
|
||||
setSmallIcon(R.drawable.notification_icon)
|
||||
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_DOWNLOAD)
|
||||
}
|
||||
notificationBuilder.apply {
|
||||
setSound(null)
|
||||
setVibrate(null)
|
||||
setOnlyAlertOnce(true)
|
||||
setSilent(true)
|
||||
}
|
||||
|
||||
notification = notificationBuilder.build()
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun prepareForStart(operation: DownloadFileOperation) {
|
||||
notificationBuilder = NotificationUtils.newNotificationBuilder(context, viewThemeUtils).apply {
|
||||
setSmallIcon(R.drawable.notification_icon)
|
||||
setOngoing(true)
|
||||
currentOperationTitle = File(operation.savePath).name
|
||||
|
||||
notificationBuilder.run {
|
||||
setContentTitle(currentOperationTitle)
|
||||
setOngoing(false)
|
||||
setProgress(100, 0, operation.size < 0)
|
||||
setContentText(
|
||||
String.format(
|
||||
context.getString(R.string.downloader_download_in_progress), 0,
|
||||
File(operation.savePath).name
|
||||
)
|
||||
)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_DOWNLOAD)
|
||||
}
|
||||
|
||||
notificationManager.notify(
|
||||
id,
|
||||
this.build()
|
||||
)
|
||||
}
|
||||
|
||||
showNotification()
|
||||
}
|
||||
|
||||
fun prepareForResult() {
|
||||
|
|
@ -82,23 +54,21 @@ class DownloadNotificationManager(
|
|||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun updateDownloadProgress(filePath: String, percent: Int, totalToTransfer: Long) {
|
||||
notificationBuilder.run {
|
||||
setProgress(100, percent, totalToTransfer < 0)
|
||||
val fileName: String = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1)
|
||||
val text =
|
||||
String.format(context.getString(R.string.downloader_download_in_progress), percent, fileName)
|
||||
val title =
|
||||
context.getString(R.string.downloader_download_in_progress_ticker)
|
||||
updateNotificationText(title, text)
|
||||
fun updateDownloadProgress(percent: Int, totalToTransfer: Long) {
|
||||
// If downloads are so fast, no need to notify again.
|
||||
if (percent == lastPercent) {
|
||||
return
|
||||
}
|
||||
lastPercent = percent
|
||||
|
||||
val progressText = NumberFormatter.getPercentageText(percent)
|
||||
setProgress(percent, progressText, totalToTransfer < 0)
|
||||
showNotification()
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun dismissNotification() {
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
notificationManager.cancel(id)
|
||||
}, 2000)
|
||||
dismissNotification(2000)
|
||||
}
|
||||
|
||||
fun showNewNotification(text: String) {
|
||||
|
|
@ -106,24 +76,12 @@ class DownloadNotificationManager(
|
|||
|
||||
notificationBuilder.run {
|
||||
setProgress(0, 0, false)
|
||||
setContentTitle(null)
|
||||
setContentText(text)
|
||||
setContentTitle(text)
|
||||
setOngoing(false)
|
||||
notificationManager.notify(notifyId, this.build())
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateNotificationText(title: String?, text: String) {
|
||||
notificationBuilder.run {
|
||||
title?.let {
|
||||
setContentTitle(title)
|
||||
}
|
||||
|
||||
setContentText(text)
|
||||
notificationManager.notify(id, this.build())
|
||||
}
|
||||
}
|
||||
|
||||
fun setContentIntent(intent: Intent, flag: Int) {
|
||||
notificationBuilder.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
|
|
@ -134,12 +92,4 @@ class DownloadNotificationManager(
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun getId(): Int {
|
||||
return id
|
||||
}
|
||||
|
||||
fun getNotification(): Notification {
|
||||
return notificationBuilder.build()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2020 Chris Narkiewicz <hello@ezaquarii.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
package com.nextcloud.client.jobs.download
|
||||
|
||||
|
|
@ -45,9 +45,7 @@ class DownloadTask(
|
|||
private val clientProvider: () -> OwnCloudClient,
|
||||
private val contentResolver: ContentResolver
|
||||
) {
|
||||
fun create(): DownloadTask {
|
||||
return DownloadTask(context, contentResolver, clientProvider)
|
||||
}
|
||||
fun create(): DownloadTask = DownloadTask(context, contentResolver, clientProvider)
|
||||
}
|
||||
|
||||
// Unused progress, isCancelled arguments needed for TransferManagerTest
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper_ozturk@proton.me>
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
package com.nextcloud.client.jobs.download
|
||||
|
||||
enum class FileDownloadError {
|
||||
Failed, Cancelled
|
||||
Failed,
|
||||
Cancelled
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper_ozturk@proton.me>
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
package com.nextcloud.client.jobs.download
|
||||
|
||||
|
|
@ -30,10 +30,8 @@ class FileDownloadHelper {
|
|||
companion object {
|
||||
private var instance: FileDownloadHelper? = null
|
||||
|
||||
fun instance(): FileDownloadHelper {
|
||||
return instance ?: synchronized(this) {
|
||||
instance ?: FileDownloadHelper().also { instance = it }
|
||||
}
|
||||
fun instance(): FileDownloadHelper = instance ?: synchronized(this) {
|
||||
instance ?: FileDownloadHelper().also { instance = it }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,11 +48,13 @@ class FileDownloadHelper {
|
|||
val topParentId = fileStorageManager.getTopParentId(file)
|
||||
|
||||
val isJobScheduled = backgroundJobManager.isStartFileDownloadJobScheduled(user, file.fileId)
|
||||
return isJobScheduled || if (file.isFolder) {
|
||||
backgroundJobManager.isStartFileDownloadJobScheduled(user, topParentId)
|
||||
} else {
|
||||
FileDownloadWorker.isDownloading(user.accountName, file.fileId)
|
||||
}
|
||||
return isJobScheduled ||
|
||||
if (file.isFolder) {
|
||||
FileDownloadWorker.isDownloadingFolder(file.fileId) ||
|
||||
backgroundJobManager.isStartFileDownloadJobScheduled(user, topParentId)
|
||||
} else {
|
||||
FileDownloadWorker.isDownloading(user.accountName, file.fileId)
|
||||
}
|
||||
}
|
||||
|
||||
fun cancelPendingOrCurrentDownloads(user: User?, files: List<OCFile>?) {
|
||||
|
|
@ -81,11 +81,7 @@ class FileDownloadHelper {
|
|||
backgroundJobManager.cancelFilesDownloadJob(currentUser, currentFile.fileId)
|
||||
}
|
||||
|
||||
fun saveFile(
|
||||
file: OCFile,
|
||||
currentDownload: DownloadFileOperation?,
|
||||
storageManager: FileDataStorageManager?
|
||||
) {
|
||||
fun saveFile(file: OCFile, currentDownload: DownloadFileOperation?, storageManager: FileDataStorageManager?) {
|
||||
val syncDate = System.currentTimeMillis()
|
||||
|
||||
file.apply {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper_ozturk@proton.me>
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
package com.nextcloud.client.jobs.download
|
||||
|
||||
|
|
@ -22,63 +22,53 @@ import com.owncloud.android.ui.preview.PreviewImageFragment
|
|||
|
||||
class FileDownloadIntents(private val context: Context) {
|
||||
|
||||
fun newDownloadIntent(
|
||||
download: DownloadFileOperation,
|
||||
linkedToRemotePath: String
|
||||
): Intent {
|
||||
return Intent(FileDownloadWorker.getDownloadAddedMessage()).apply {
|
||||
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 {
|
||||
return 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)
|
||||
): 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 {
|
||||
return Intent(context, AuthenticatorActivity::class.java).apply {
|
||||
putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, user.toPlatformAccount())
|
||||
putExtra(
|
||||
AuthenticatorActivity.EXTRA_ACTION,
|
||||
AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN
|
||||
)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||
addFlags(Intent.FLAG_FROM_BACKGROUND)
|
||||
}
|
||||
fun credentialContentIntent(user: User): Intent = Intent(context, AuthenticatorActivity::class.java).apply {
|
||||
putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, user.toPlatformAccount())
|
||||
putExtra(
|
||||
AuthenticatorActivity.EXTRA_ACTION,
|
||||
AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN
|
||||
)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||
addFlags(Intent.FLAG_FROM_BACKGROUND)
|
||||
}
|
||||
|
||||
fun detailsIntent(operation: DownloadFileOperation?): Intent {
|
||||
return if (operation != null) {
|
||||
if (PreviewImageFragment.canBePreviewed(operation.file)) {
|
||||
Intent(context, PreviewImageActivity::class.java)
|
||||
} else {
|
||||
Intent(context, FileDisplayActivity::class.java)
|
||||
}.apply {
|
||||
putExtra(FileActivity.EXTRA_FILE, operation.file)
|
||||
putExtra(FileActivity.EXTRA_USER, operation.user)
|
||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
}
|
||||
fun detailsIntent(operation: DownloadFileOperation?): Intent = if (operation != null) {
|
||||
if (PreviewImageFragment.canBePreviewed(operation.file)) {
|
||||
Intent(context, PreviewImageActivity::class.java)
|
||||
} else {
|
||||
Intent()
|
||||
Intent(context, FileDisplayActivity::class.java)
|
||||
}.apply {
|
||||
putExtra(FileActivity.EXTRA_FILE, operation.file)
|
||||
putExtra(FileActivity.EXTRA_USER, operation.user)
|
||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
}
|
||||
} else {
|
||||
Intent()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper_ozturk@proton.me>
|
||||
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
package com.nextcloud.client.jobs.download
|
||||
|
||||
|
|
@ -16,13 +16,16 @@ import android.util.Pair
|
|||
import androidx.core.util.component1
|
||||
import androidx.core.util.component2
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import androidx.work.Worker
|
||||
import androidx.work.CoroutineWorker
|
||||
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.WorkerStateLiveData
|
||||
import com.nextcloud.utils.ForegroundServiceHelper
|
||||
import com.nextcloud.utils.extensions.getParentIdsOfSubfiles
|
||||
import com.nextcloud.utils.extensions.getPercent
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager
|
||||
import com.owncloud.android.datamodel.ForegroundServiceType
|
||||
|
|
@ -36,11 +39,14 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCo
|
|||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
import com.owncloud.android.operations.DownloadFileOperation
|
||||
import com.owncloud.android.operations.DownloadType
|
||||
import com.owncloud.android.ui.events.EventBusFactory
|
||||
import com.owncloud.android.ui.events.FileDownloadProgressEvent
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils
|
||||
import java.security.SecureRandom
|
||||
import java.util.AbstractList
|
||||
import java.util.Optional
|
||||
import java.util.Vector
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.random.Random
|
||||
|
||||
@Suppress("LongParameterList", "TooManyFunctions")
|
||||
class FileDownloadWorker(
|
||||
|
|
@ -49,12 +55,15 @@ class FileDownloadWorker(
|
|||
private var localBroadcastManager: LocalBroadcastManager,
|
||||
private val context: Context,
|
||||
params: WorkerParameters
|
||||
) : Worker(context, params), OnAccountsUpdateListener, OnDatatransferProgressListener {
|
||||
) : CoroutineWorker(context, params),
|
||||
OnAccountsUpdateListener,
|
||||
OnDatatransferProgressListener {
|
||||
|
||||
companion object {
|
||||
private val TAG = FileDownloadWorker::class.java.simpleName
|
||||
|
||||
private val pendingDownloads = IndexedForest<DownloadFileOperation>()
|
||||
private val pendingFolderDownloads: MutableSet<Long> = ConcurrentHashMap.newKeySet<Long>()
|
||||
|
||||
fun cancelOperation(accountName: String, fileId: Long) {
|
||||
pendingDownloads.all.forEach {
|
||||
|
|
@ -62,10 +71,12 @@ class FileDownloadWorker(
|
|||
}
|
||||
}
|
||||
|
||||
fun isDownloading(accountName: String, fileId: Long): Boolean {
|
||||
return pendingDownloads.all.any { it.value?.payload?.isMatching(accountName, fileId) == true }
|
||||
fun isDownloading(accountName: String, fileId: Long): Boolean = pendingDownloads.all.any {
|
||||
it.value?.payload?.isMatching(accountName, fileId) == true
|
||||
}
|
||||
|
||||
fun isDownloadingFolder(id: Long): Boolean = pendingFolderDownloads.contains(id)
|
||||
|
||||
const val FILE_REMOTE_PATH = "FILE_REMOTE_PATH"
|
||||
const val ACCOUNT_NAME = "ACCOUNT_NAME"
|
||||
const val BEHAVIOUR = "BEHAVIOUR"
|
||||
|
|
@ -73,19 +84,14 @@ class FileDownloadWorker(
|
|||
const val ACTIVITY_NAME = "ACTIVITY_NAME"
|
||||
const val PACKAGE_NAME = "PACKAGE_NAME"
|
||||
const val CONFLICT_UPLOAD_ID = "CONFLICT_UPLOAD_ID"
|
||||
|
||||
const val EXTRA_DOWNLOAD_RESULT = "EXTRA_DOWNLOAD_RESULT"
|
||||
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 {
|
||||
return FileDownloadWorker::class.java.name + "DOWNLOAD_ADDED"
|
||||
}
|
||||
fun getDownloadAddedMessage(): String = FileDownloadWorker::class.java.name + "DOWNLOAD_ADDED"
|
||||
|
||||
fun getDownloadFinishMessage(): String {
|
||||
return FileDownloadWorker::class.java.name + "DOWNLOAD_FINISH"
|
||||
}
|
||||
fun getDownloadFinishMessage(): String = FileDownloadWorker::class.java.name + "DOWNLOAD_FINISH"
|
||||
}
|
||||
|
||||
private var currentDownload: DownloadFileOperation? = null
|
||||
|
|
@ -95,7 +101,7 @@ class FileDownloadWorker(
|
|||
|
||||
private val intents = FileDownloadIntents(context)
|
||||
private var notificationManager = DownloadNotificationManager(
|
||||
SecureRandom().nextInt(),
|
||||
Random.nextInt(),
|
||||
context,
|
||||
viewThemeUtils
|
||||
)
|
||||
|
|
@ -110,18 +116,17 @@ class FileDownloadWorker(
|
|||
|
||||
private var downloadError: FileDownloadError? = null
|
||||
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
override fun doWork(): Result {
|
||||
return try {
|
||||
val requestDownloads = getRequestDownloads()
|
||||
addAccountUpdateListener()
|
||||
@Suppress("TooGenericExceptionCaught", "ReturnCount")
|
||||
override suspend fun doWork(): Result {
|
||||
val foregroundInfo = createWorkerForegroundInfo()
|
||||
setForeground(foregroundInfo)
|
||||
|
||||
val foregroundInfo = ForegroundServiceHelper.createWorkerForegroundInfo(
|
||||
notificationManager.getId(),
|
||||
notificationManager.getNotification(),
|
||||
ForegroundServiceType.DataSync
|
||||
)
|
||||
setForegroundAsync(foregroundInfo)
|
||||
return try {
|
||||
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()
|
||||
|
||||
requestDownloads.forEach {
|
||||
downloadFile(it)
|
||||
|
|
@ -132,43 +137,43 @@ class FileDownloadWorker(
|
|||
notificationManager.dismissNotification()
|
||||
}
|
||||
|
||||
setIdleWorkerState()
|
||||
|
||||
Log_OC.e(TAG, "FilesDownloadWorker successfully completed")
|
||||
Result.success()
|
||||
} catch (t: Throwable) {
|
||||
notificationManager.dismissNotification()
|
||||
notificationManager.showNewNotification(context.getString(R.string.downloader_unexpected_error))
|
||||
Log_OC.e(TAG, "Error caught at FilesDownloadWorker(): " + t.localizedMessage)
|
||||
setIdleWorkerState()
|
||||
Result.failure()
|
||||
} finally {
|
||||
Log_OC.e(TAG, "FilesDownloadWorker cleanup")
|
||||
notificationManager.dismissNotification()
|
||||
setIdleWorkerState()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStopped() {
|
||||
Log_OC.e(TAG, "FilesDownloadWorker stopped")
|
||||
|
||||
notificationManager.dismissNotification()
|
||||
setIdleWorkerState()
|
||||
|
||||
super.onStopped()
|
||||
}
|
||||
private fun createWorkerForegroundInfo(): ForegroundInfo = ForegroundServiceHelper.createWorkerForegroundInfo(
|
||||
notificationManager.getId(),
|
||||
notificationManager.getNotification(),
|
||||
ForegroundServiceType.DataSync
|
||||
)
|
||||
|
||||
private fun setWorkerState(user: User?) {
|
||||
WorkerStateLiveData.instance().setWorkState(WorkerState.Download(user, currentDownload))
|
||||
WorkerStateLiveData.instance().setWorkState(WorkerState.DownloadStarted(user, currentDownload))
|
||||
}
|
||||
|
||||
private fun setIdleWorkerState() {
|
||||
WorkerStateLiveData.instance().setWorkState(WorkerState.Idle)
|
||||
WorkerStateLiveData.instance().setWorkState(WorkerState.DownloadFinished(getCurrentFile()))
|
||||
}
|
||||
|
||||
private fun removePendingDownload(accountName: String?) {
|
||||
pendingDownloads.remove(accountName)
|
||||
}
|
||||
|
||||
private fun getRequestDownloads(): AbstractList<String> {
|
||||
setUser()
|
||||
val files = getFiles()
|
||||
private fun getRequestDownloads(ocFile: OCFile): AbstractList<String> {
|
||||
val files = getFiles(ocFile)
|
||||
val filesPaths = files.map { it.remotePath }
|
||||
val parentIdsOfSubFiles = fileDataStorageManager?.getParentIdsOfSubfiles(filesPaths) ?: listOf()
|
||||
pendingFolderDownloads.addAll(parentIdsOfSubFiles)
|
||||
|
||||
val downloadType = getDownloadType()
|
||||
|
||||
conflictUploadId = inputData.keyValueMap[CONFLICT_UPLOAD_ID] as Long?
|
||||
|
|
@ -221,15 +226,10 @@ class FileDownloadWorker(
|
|||
fileDataStorageManager = FileDataStorageManager(user, context.contentResolver)
|
||||
}
|
||||
|
||||
private fun getFiles(): List<OCFile> {
|
||||
val remotePath = inputData.keyValueMap[FILE_REMOTE_PATH] as String?
|
||||
val file = fileDataStorageManager?.getFileByEncryptedRemotePath(remotePath) ?: return listOf()
|
||||
|
||||
return if (file.isFolder) {
|
||||
fileDataStorageManager?.getAllFilesRecursivelyInsideFolder(file) ?: listOf()
|
||||
} else {
|
||||
listOf(file)
|
||||
}
|
||||
private fun getFiles(file: OCFile): List<OCFile> = if (file.isFolder) {
|
||||
fileDataStorageManager?.getAllFilesRecursivelyInsideFolder(file) ?: listOf()
|
||||
} else {
|
||||
listOf(file)
|
||||
}
|
||||
|
||||
private fun getDownloadType(): DownloadType? {
|
||||
|
|
@ -267,7 +267,12 @@ class FileDownloadWorker(
|
|||
return
|
||||
}
|
||||
|
||||
notifyDownloadStart(currentDownload!!)
|
||||
lastPercent = 0
|
||||
notificationManager.run {
|
||||
prepareForStart(currentDownload!!)
|
||||
setContentIntent(intents.detailsIntent(currentDownload!!), PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
var downloadResult: RemoteOperationResult<*>? = null
|
||||
try {
|
||||
val ocAccount = getOCAccountForDownload()
|
||||
|
|
@ -288,15 +293,6 @@ class FileDownloadWorker(
|
|||
}
|
||||
}
|
||||
|
||||
private fun notifyDownloadStart(download: DownloadFileOperation) {
|
||||
lastPercent = 0
|
||||
|
||||
notificationManager.run {
|
||||
prepareForStart(download)
|
||||
setContentIntent(intents.detailsIntent(download), PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun getOCAccountForDownload(): OwnCloudAccount {
|
||||
val currentDownloadAccount = currentDownload?.user?.toPlatformAccount()
|
||||
|
|
@ -350,6 +346,7 @@ class FileDownloadWorker(
|
|||
|
||||
private fun checkDownloadError(result: RemoteOperationResult<*>) {
|
||||
if (result.isSuccess || downloadError != null) {
|
||||
notificationManager.dismissNotification()
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -365,6 +362,7 @@ class FileDownloadWorker(
|
|||
FileDownloadError.Cancelled -> {
|
||||
context.getString(R.string.downloader_file_download_cancelled)
|
||||
}
|
||||
|
||||
FileDownloadError.Failed -> {
|
||||
context.getString(R.string.downloader_file_download_failed)
|
||||
}
|
||||
|
|
@ -373,10 +371,7 @@ class FileDownloadWorker(
|
|||
notificationManager.showNewNotification(text)
|
||||
}
|
||||
|
||||
private fun notifyDownloadResult(
|
||||
download: DownloadFileOperation,
|
||||
downloadResult: RemoteOperationResult<*>
|
||||
) {
|
||||
private fun notifyDownloadResult(download: DownloadFileOperation, downloadResult: RemoteOperationResult<*>) {
|
||||
if (downloadResult.isCancelled) {
|
||||
return
|
||||
}
|
||||
|
|
@ -404,6 +399,10 @@ class FileDownloadWorker(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private val minProgressUpdateInterval = 750
|
||||
private var lastUpdateTime = 0L
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
override fun onTransferProgress(
|
||||
progressRate: Long,
|
||||
|
|
@ -411,23 +410,25 @@ class FileDownloadWorker(
|
|||
totalToTransfer: Long,
|
||||
filePath: String
|
||||
) {
|
||||
val percent: Int = (100.0 * totalTransferredSoFar.toDouble() / totalToTransfer.toDouble()).toInt()
|
||||
val percent: Int = downloadProgressListener.getPercent(totalTransferredSoFar, totalToTransfer)
|
||||
val currentTime = System.currentTimeMillis()
|
||||
|
||||
if (percent != lastPercent) {
|
||||
if (percent != lastPercent && (currentTime - lastUpdateTime) >= minProgressUpdateInterval) {
|
||||
notificationManager.run {
|
||||
updateDownloadProgress(filePath, percent, totalToTransfer)
|
||||
updateDownloadProgress(percent, totalToTransfer)
|
||||
}
|
||||
lastUpdateTime = currentTime
|
||||
}
|
||||
|
||||
lastPercent = percent
|
||||
EventBusFactory.downloadProgressEventBus.post(FileDownloadProgressEvent(percent))
|
||||
}
|
||||
|
||||
// CHECK: Is this class still needed after conversion from Foreground Services to Worker?
|
||||
inner class FileDownloadProgressListener : OnDatatransferProgressListener {
|
||||
private val boundListeners: MutableMap<Long, OnDatatransferProgressListener> = HashMap()
|
||||
|
||||
fun isDownloading(user: User?, file: OCFile?): Boolean {
|
||||
return FileDownloadHelper.instance().isDownloading(user, file)
|
||||
}
|
||||
fun isDownloading(user: User?, file: OCFile?): Boolean = FileDownloadHelper.instance().isDownloading(user, file)
|
||||
|
||||
fun addDataTransferProgressListener(listener: OnDatatransferProgressListener?, file: OCFile?) {
|
||||
if (file == null || listener == null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue