Skip to content
Merged
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 @@ -18,6 +18,7 @@ import androidx.work.ListenableWorker
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.Operation
import androidx.work.OutOfQuotaPolicy
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkInfo
import androidx.work.WorkManager
Expand Down Expand Up @@ -500,6 +501,7 @@ internal class BackgroundJobManagerImpl(
TimeUnit.SECONDS
)
.setInputData(arguments)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build()

workManager.enqueueUniquePeriodicWork(
Expand Down Expand Up @@ -681,6 +683,7 @@ internal class BackgroundJobManagerImpl(
.addTag(tag)
.setInputData(dataBuilder.build())
.setConstraints(constraints)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build()
}

Expand Down Expand Up @@ -728,6 +731,7 @@ internal class BackgroundJobManagerImpl(
val request = oneTimeRequestBuilder(FileDownloadWorker::class, JOB_FILES_DOWNLOAD, user)
.addTag(tag)
.setInputData(data)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build()

// Since for each file new FileDownloadWorker going to be scheduled,
Expand Down Expand Up @@ -839,6 +843,7 @@ internal class BackgroundJobManagerImpl(
.addTag(JOB_DOWNLOAD_FOLDER)
.setInputData(data)
.setConstraints(constraints)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build()

workManager.enqueueUniqueWork(JOB_DOWNLOAD_FOLDER, ExistingWorkPolicy.APPEND_OR_REPLACE, request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.content.Context
import android.content.res.Resources
import androidx.exifinterface.media.ExifInterface
import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import com.nextcloud.client.account.User
import com.nextcloud.client.account.UserAccountManager
Expand Down Expand Up @@ -52,7 +53,7 @@ import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone

@Suppress("LongParameterList", "TooManyFunctions")
@Suppress("LongParameterList", "TooManyFunctions", "TooGenericExceptionCaught")
class AutoUploadWorker(
private val context: Context,
params: WorkerParameters,
Expand All @@ -78,16 +79,14 @@ class AutoUploadWorker(
private lateinit var syncedFolder: SyncedFolder
private val notificationManager = AutoUploadNotificationManager(context, viewThemeUtils, NOTIFICATION_ID)

@Suppress("TooGenericExceptionCaught", "ReturnCount")
@Suppress("ReturnCount")
override suspend fun doWork(): Result {
return try {
val syncFolderId = inputData.getLong(SYNCED_FOLDER_ID, -1)
syncedFolder = syncedFolderProvider.getSyncedFolderByID(syncFolderId)
?.takeIf { it.isEnabled } ?: return Result.failure()

// initial notification
val notification = createNotification(context.getString(R.string.upload_files))
updateForegroundInfo(notification)
trySetForeground()

/**
* Receives from [com.nextcloud.client.jobs.ContentObserverWork.checkAndTriggerAutoUpload]
Expand All @@ -110,17 +109,42 @@ class AutoUploadWorker(
}
}

override suspend fun getForegroundInfo(): ForegroundInfo {
val notification = createNotification(
context.getString(R.string.upload_files)
)

return ForegroundServiceHelper.createWorkerForegroundInfo(
NOTIFICATION_ID,
notification,
ForegroundServiceType.DataSync
)
}

private fun updateNotification() {
getStartNotificationTitle()?.let { (localFolderName, remoteFolderName) ->
val startNotification = createNotification(
context.getString(
R.string.auto_upload_worker_start_text,
localFolderName,
remoteFolderName
try {
val startNotification = createNotification(
context.getString(
R.string.auto_upload_worker_start_text,
localFolderName,
remoteFolderName
)
)
)

notificationManager.showNotification(startNotification)
notificationManager.showNotification(startNotification)
} catch (e: Exception) {
Log_OC.w(TAG, "⚠️ Could not update notification: ${e.message}")
}
}
}

private suspend fun trySetForeground() {
try {
val notification = createNotification(context.getString(R.string.upload_files))
updateForegroundInfo(notification)
} catch (e: Exception) {
Log_OC.w(TAG, "⚠️ Could not set foreground service: ${e.message}")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import java.util.Optional
import java.util.Vector
import kotlin.random.Random

@Suppress("LongParameterList", "TooManyFunctions")
@Suppress("LongParameterList", "TooManyFunctions", "TooGenericExceptionCaught")
class FileDownloadWorker(
viewThemeUtils: ViewThemeUtils,
private val accountManager: UserAccountManager,
Expand All @@ -58,7 +58,7 @@ class FileDownloadWorker(
OnDatatransferProgressListener {

companion object {
private val TAG = FileDownloadWorker::class.java.simpleName
private const val TAG = "🗄️" + "FileDownloadWorker"

private val pendingDownloads = IndexedForest<DownloadFileOperation>()

Expand Down Expand Up @@ -111,10 +111,9 @@ class FileDownloadWorker(

private var downloadError: FileDownloadError? = null

@Suppress("TooGenericExceptionCaught", "ReturnCount")
@Suppress("ReturnCount")
override suspend fun doWork(): Result {
val foregroundInfo = createWorkerForegroundInfo()
setForeground(foregroundInfo)
trySetForeground()

return try {
setUser()
Expand All @@ -132,19 +131,37 @@ class FileDownloadWorker(
notificationManager.dismissNotification()
}

Log_OC.e(TAG, "FilesDownloadWorker successfully completed")
Log_OC.d(TAG, "successfully completed")
Result.success()
} catch (t: Throwable) {
notificationManager.showNewNotification(context.getString(R.string.downloader_unexpected_error))
Log_OC.e(TAG, "Error caught at FilesDownloadWorker(): " + t.localizedMessage)
Log_OC.e(TAG, "exception: " + t.localizedMessage)
Result.failure()
} finally {
Log_OC.e(TAG, "FilesDownloadWorker cleanup")
Log_OC.d(TAG, "cleanup")
notificationManager.dismissNotification()
setIdleWorkerState()
}
}

override suspend fun getForegroundInfo(): ForegroundInfo {
val notification = notificationManager.getNotification()
return ForegroundServiceHelper.createWorkerForegroundInfo(
notificationManager.getId(),
notification,
ForegroundServiceType.DataSync
)
}

private suspend fun trySetForeground() {
try {
val foregroundInfo = createWorkerForegroundInfo()
setForeground(foregroundInfo)
} catch (e: Exception) {
Log_OC.w(TAG, "⚠️ Could not set foreground service: ${e.message}")
}
}

private fun createWorkerForegroundInfo(): ForegroundInfo = ForegroundServiceHelper.createWorkerForegroundInfo(
notificationManager.getId(),
notificationManager.getNotification(),
Expand Down Expand Up @@ -250,7 +267,7 @@ class FileDownloadWorker(
}

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

val isAccountExist = accountManager.exists(currentDownload?.user?.toPlatformAccount())
if (!isAccountExist) {
Expand All @@ -277,7 +294,7 @@ class FileDownloadWorker(
}
}
} catch (e: Exception) {
Log_OC.e(TAG, "Error downloading", e)
Log_OC.e(TAG, "exception downloading file: ", e)
downloadResult = RemoteOperationResult<Any?>(e)
} finally {
cleanupDownloadProcess(downloadResult)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package com.nextcloud.client.jobs.folderDownload

import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import com.nextcloud.client.account.UserAccountManager
import com.nextcloud.client.jobs.download.FileDownloadHelper
Expand All @@ -24,7 +25,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.concurrent.ConcurrentHashMap

@Suppress("LongMethod")
@Suppress("LongMethod", "TooGenericExceptionCaught")
class FolderDownloadWorker(
private val accountManager: UserAccountManager,
private val context: Context,
Expand All @@ -45,7 +46,7 @@ class FolderDownloadWorker(
private var notificationManager: FolderDownloadWorkerNotificationManager? = null
private lateinit var storageManager: FileDataStorageManager

@Suppress("TooGenericExceptionCaught", "ReturnCount", "DEPRECATION")
@Suppress("ReturnCount", "DEPRECATION")
override suspend fun doWork(): Result {
val folderID = inputData.getLong(FOLDER_ID, -1)
if (folderID == -1L) {
Expand Down Expand Up @@ -76,8 +77,7 @@ class FolderDownloadWorker(

Log_OC.d(TAG, "🕒 started for ${user.accountName} downloading ${folder.fileName}")

val foregroundInfo = notificationManager?.getForegroundInfo(folder) ?: return Result.failure()
setForeground(foregroundInfo)
trySetForeground(folder)

pendingDownloads.add(folder.fileId)

Expand All @@ -96,7 +96,7 @@ class FolderDownloadWorker(
}

withContext(Dispatchers.Main) {
notificationManager?.showProgressNotification(
getNotificationManager().showProgressNotification(
folder.fileName,
file.fileName,
index,
Expand All @@ -118,7 +118,7 @@ class FolderDownloadWorker(
}

withContext(Dispatchers.Main) {
notificationManager?.showCompletionMessage(folder.fileName, result)
getNotificationManager().showCompletionMessage(folder.fileName, result)
}

if (result) {
Expand All @@ -133,11 +133,44 @@ class FolderDownloadWorker(
Result.failure()
} finally {
pendingDownloads.remove(folder.fileId)
notificationManager?.dismiss()
getNotificationManager().dismiss()
}
}
}

@Suppress("ReturnCount")
override suspend fun getForegroundInfo(): ForegroundInfo {
return try {
val folderID = inputData.getLong(FOLDER_ID, -1)
val accountName = inputData.getString(ACCOUNT_NAME)

if (folderID == -1L || accountName == null || !::storageManager.isInitialized) {
return createDefaultForegroundInfo()
}

val folder = storageManager.getFileById(folderID) ?: return createDefaultForegroundInfo()

return getNotificationManager().getForegroundInfo(folder)
} catch (e: Exception) {
Log_OC.w(TAG, "⚠️ Error getting foreground info: ${e.message}")
createDefaultForegroundInfo()
}
}

private fun getNotificationManager(): FolderDownloadWorkerNotificationManager =
notificationManager ?: FolderDownloadWorkerNotificationManager(context, viewThemeUtils)

private fun createDefaultForegroundInfo(): ForegroundInfo = getNotificationManager().getDefaultForegroundInfo()

private suspend fun trySetForeground(folder: OCFile) {
try {
val foregroundInfo = getNotificationManager().getForegroundInfo(folder)
setForeground(foregroundInfo)
} catch (e: Exception) {
Log_OC.w(TAG, "⚠️ Could not set foreground service: ${e.message}")
}
}

private fun getOCFile(operation: DownloadFileOperation): OCFile? {
val file = operation.file?.fileId?.let { storageManager.getFileById(it) }
?: storageManager.getFileByDecryptedRemotePath(operation.file?.remotePath)
Expand All @@ -158,7 +191,7 @@ class FolderDownloadWorker(
val availableDiskSpace = FileOperationsHelper.getAvailableSpaceOnDevice()

return if (availableDiskSpace < fileSizeInByte) {
notificationManager?.showNotAvailableDiskSpace()
getNotificationManager().showNotAvailableDiskSpace()
false
} else {
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.core.app.NotificationCompat
import androidx.work.ForegroundInfo
import com.nextcloud.client.jobs.notification.WorkerNotificationManager
import com.nextcloud.utils.ForegroundServiceHelper
Expand Down Expand Up @@ -70,11 +71,24 @@ class FolderDownloadWorkerNotificationManager(private val context: Context, view
)
}

@Suppress("MagicNumber")
fun showProgressNotification(folderName: String, filename: String, currentIndex: Int, totalFileSize: Int) {
val currentFileIndex = (currentIndex + 1)
val description = context.getString(R.string.folder_download_counter, currentFileIndex, totalFileSize, filename)
val progress = (currentFileIndex * MAX_PROGRESS) / totalFileSize
val notification = getNotification(title = folderName, description = description, progress = progress)
val notification = notificationBuilder.apply {
setContentTitle(folderName)
setContentText(description)
setProgress(100, progress, false)
clearActions()
addAction(
android.R.drawable.ic_menu_close_clear_cancel,
context.getString(R.string.common_cancel),
getCancelPendingIntent()
)
setOngoing(true)
setAutoCancel(false)
}.build()
notificationManager.notify(NOTIFICATION_ID, notification)
}

Expand Down Expand Up @@ -110,4 +124,21 @@ class FolderDownloadWorkerNotificationManager(private val context: Context, view
fun dismiss() {
notificationManager.cancel(NOTIFICATION_ID)
}

fun getDefaultForegroundInfo(): ForegroundInfo {
val notification = createDefaultNotification()
return ForegroundServiceHelper.createWorkerForegroundInfo(
NOTIFICATION_ID,
notification,
ForegroundServiceType.DataSync
)
}

private fun createDefaultNotification(): Notification =
NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_DOWNLOAD)
.setContentTitle(context.getString(R.string.downloader_download_in_progress_ticker))
.setSmallIcon(R.drawable.ic_sync)
.setOngoing(true)
.setSilent(true)
.build()
}
Loading
Loading