Browse Source

Fix serializable data limit crash

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 1 year ago
parent
commit
b2b94ff4cc

+ 6 - 5
app/src/main/java/com/nextcloud/client/files/downloader/FileDownloadHelper.kt

@@ -62,19 +62,19 @@ class FileDownloadHelper {
 
         return backgroundJobManager.isStartFileDownloadJobScheduled(
             user,
-            file
+            file.remotePath
         )
     }
 
     fun cancelPendingOrCurrentDownloads(user: User?, file: OCFile?) {
         if (user == null || file == null) return
-        backgroundJobManager.cancelFilesDownloadJob(user, file)
+        backgroundJobManager.cancelFilesDownloadJob(user, file.remotePath)
     }
 
     fun cancelAllDownloadsForAccount(accountName: String?, currentDownload: DownloadFileOperation) {
         if (currentDownload.user.nameEquals(accountName)) {
             currentDownload.file?.let { file ->
-                backgroundJobManager.cancelFilesDownloadJob(currentDownload.user, file)
+                backgroundJobManager.cancelFilesDownloadJob(currentDownload.user, file.remotePath)
             }
 
             currentDownload.cancel()
@@ -122,7 +122,8 @@ class FileDownloadHelper {
     }
 
     fun downloadFolder(folder: OCFile, user: User, files: List<OCFile>) {
-        backgroundJobManager.startFolderDownloadJob(folder, user, files)
+        val filesPath = files.map { it.remotePath }
+        backgroundJobManager.startFolderDownloadJob(folder.remotePath, user, filesPath)
     }
 
     fun downloadFile(user: User, file: OCFile) {
@@ -141,7 +142,7 @@ class FileDownloadHelper {
     ) {
         backgroundJobManager.startFileDownloadJob(
             user,
-            ocFile,
+            ocFile.remotePath,
             behaviour,
             downloadType,
             activityName,

+ 35 - 17
app/src/main/java/com/nextcloud/client/files/downloader/FileDownloadWorker.kt

@@ -31,8 +31,6 @@ import androidx.core.util.component2
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import androidx.work.Worker
 import androidx.work.WorkerParameters
-import com.google.gson.Gson
-import com.google.gson.reflect.TypeToken
 import com.nextcloud.client.account.User
 import com.nextcloud.client.account.UserAccountManager
 import com.nextcloud.java.util.Optional
@@ -68,11 +66,12 @@ class FileDownloadWorker(
     companion object {
         private val TAG = FileDownloadWorker::class.java.simpleName
 
+        const val FILES_SEPARATOR = ","
         const val WORKER_TAG = "WORKER_TAG"
-        const val FOLDER = "FOLDER"
+        const val FOLDER_PATH = "FOLDER_PATH"
         const val USER_NAME = "USER"
-        const val FILE = "FILE"
-        const val FILES = "FILES"
+        const val FILE_PATH = "FILE_PATH"
+        const val FILES_PATH = "FILES_PATH"
         const val BEHAVIOUR = "BEHAVIOUR"
         const val DOWNLOAD_TYPE = "DOWNLOAD_TYPE"
         const val ACTIVITY_NAME = "ACTIVITY_NAME"
@@ -102,11 +101,11 @@ class FileDownloadWorker(
     private var downloadProgressListener = FileDownloadProgressListener()
     private var currentUser = Optional.empty<User>()
     private var storageManager: FileDataStorageManager? = null
+    private var fileDataStorageManager: FileDataStorageManager? = null
     private var downloadClient: OwnCloudClient? = null
     private var user: User? = null
     private var folder: OCFile? = null
     private var isAnyOperationFailed = true
-    private val gson = Gson()
     private var workerTag: String? = null
     private val pendingDownloads = IndexedForest<DownloadFileOperation>()
 
@@ -118,6 +117,7 @@ class FileDownloadWorker(
             notificationManager.init()
             addAccountUpdateListener()
 
+            setWorkerState(user)
             requestDownloads.forEach {
                 downloadFile(it)
             }
@@ -146,8 +146,8 @@ class FileDownloadWorker(
         super.onStopped()
     }
 
-    private fun setWorkerState(user: User?, file: DownloadFileOperation?) {
-        val worker = DownloadWorkerState(workerTag ?: "", user, file)
+    private fun setWorkerState(user: User?) {
+        val worker = DownloadWorkerState(workerTag ?: "", user, pendingDownloads)
         DownloadWorkerStateLiveData.instance().addWorker(worker)
     }
 
@@ -160,13 +160,14 @@ class FileDownloadWorker(
     }
 
     private fun getRequestDownloads(): AbstractList<String> {
+        setUser()
+        setFolder()
         val files = getFiles()
         val downloadType = getDownloadType()
-        setUser()
 
         workerTag = inputData.keyValueMap[WORKER_TAG] as String? ?: ""
-        folder = gson.fromJson(inputData.keyValueMap[FOLDER] as? String, OCFile::class.java) ?: null
         conflictUploadId = inputData.keyValueMap[CONFLICT_UPLOAD_ID] as Long?
+
         val behaviour = inputData.keyValueMap[BEHAVIOUR] as String? ?: ""
         val activityName = inputData.keyValueMap[ACTIVITY_NAME] as String? ?: ""
         val packageName = inputData.keyValueMap[PACKAGE_NAME] as String? ?: ""
@@ -220,18 +221,36 @@ class FileDownloadWorker(
     private fun setUser() {
         val accountName = inputData.keyValueMap[USER_NAME] as String
         user = accountManager.getUser(accountName).get()
+        fileDataStorageManager = FileDataStorageManager(user, context.contentResolver)
+    }
+
+    private fun setFolder() {
+        val folderPath = inputData.keyValueMap[FOLDER_PATH] as? String?
+        if (folderPath != null) {
+            folder = storageManager?.getFileByEncryptedRemotePath(folderPath)
+        }
     }
 
     private fun getFiles(): List<OCFile> {
-        val filesJson = inputData.keyValueMap[FILES] as String?
+        val result = arrayListOf<OCFile>()
 
-        return if (filesJson != null) {
-            val ocFileListType = object : TypeToken<ArrayList<OCFile>>() {}.type
-            gson.fromJson(filesJson, ocFileListType)
+        val filesPath = inputData.keyValueMap[FILES_PATH] as String?
+        val filesPathList = filesPath?.split(FILES_SEPARATOR)
+
+        if (filesPathList != null) {
+            filesPathList.forEach {
+                fileDataStorageManager?.getFileByEncryptedRemotePath(it)?.let { file ->
+                    result.add(file)
+                }
+            }
         } else {
-            val file = gson.fromJson(inputData.keyValueMap[FILE] as String, OCFile::class.java)
-            listOf(file)
+            val remotePath = inputData.keyValueMap[FILE_PATH] as String
+            fileDataStorageManager?.getFileByEncryptedRemotePath(remotePath)?.let { file ->
+                result.add(file)
+            }
         }
+
+        return result
     }
 
     private fun getDownloadType(): DownloadType? {
@@ -261,7 +280,6 @@ class FileDownloadWorker(
         }
 
         Log_OC.e(TAG, "FilesDownloadWorker downloading: $downloadKey")
-        setWorkerState(user, currentDownload)
 
         val isAccountExist = accountManager.exists(currentDownload?.user?.toPlatformAccount())
         if (!isAccountExist) {

+ 5 - 5
app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt

@@ -145,14 +145,14 @@ interface BackgroundJobManager {
     fun getFileUploads(user: User): LiveData<List<JobInfo>>
     fun cancelFilesUploadJob(user: User)
 
-    fun cancelFilesDownloadJob(user: User, file: OCFile)
+    fun cancelFilesDownloadJob(user: User, path: String)
 
-    fun isStartFileDownloadJobScheduled(user: User, file: OCFile): Boolean
+    fun isStartFileDownloadJobScheduled(user: User, path: String): Boolean
 
     @Suppress("LongParameterList")
     fun startFileDownloadJob(
         user: User,
-        file: OCFile,
+        filePath: String,
         behaviour: String,
         downloadType: DownloadType?,
         activityName: String,
@@ -161,9 +161,9 @@ interface BackgroundJobManager {
     )
 
     fun startFolderDownloadJob(
-        folder: OCFile,
+        folderPath: String,
         user: User,
-        files: List<OCFile>
+        filesPath: List<String>
     )
 
     fun startPdfGenerateAndUploadWork(user: User, uploadFolder: String, imagePaths: List<String>, pdfPath: String)

+ 13 - 13
app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt

@@ -511,23 +511,23 @@ internal class BackgroundJobManagerImpl(
         workManager.enqueueUniqueWork(JOB_FILES_UPLOAD + user.accountName, ExistingWorkPolicy.KEEP, request)
     }
 
-    private fun startFileDownloadJobTag(user: User, file: OCFile): String {
-        return JOB_FILES_DOWNLOAD + user.accountName + file.fileId
+    private fun startFileDownloadJobTag(user: User, path: String): String {
+        return JOB_FILES_DOWNLOAD + user.accountName + path
     }
 
-    override fun isStartFileDownloadJobScheduled(user: User, file: OCFile): Boolean {
-        return workManager.isWorkScheduled(startFileDownloadJobTag(user, file))
+    override fun isStartFileDownloadJobScheduled(user: User, path: String): Boolean {
+        return workManager.isWorkScheduled(startFileDownloadJobTag(user, path))
     }
 
-    override fun startFolderDownloadJob(folder: OCFile, user: User, files: List<OCFile>) {
+    override fun startFolderDownloadJob(folderPath: String, user: User, filesPath: List<String>) {
         val data = workDataOf(
             FileDownloadWorker.USER_NAME to user.accountName,
-            FileDownloadWorker.FOLDER to gson.toJson(folder),
-            FileDownloadWorker.FILES to gson.toJson(files),
+            FileDownloadWorker.FOLDER_PATH to folderPath,
+            FileDownloadWorker.FILES_PATH to filesPath.joinToString(FileDownloadWorker.FILES_SEPARATOR),
             FileDownloadWorker.DOWNLOAD_TYPE to DownloadType.DOWNLOAD.toString()
         )
 
-        val tag = startFileDownloadJobTag(user, folder)
+        val tag = startFileDownloadJobTag(user, folderPath)
 
         val request = oneTimeRequestBuilder(FileDownloadWorker::class, JOB_FILES_DOWNLOAD, user)
             .addTag(tag)
@@ -540,19 +540,19 @@ internal class BackgroundJobManagerImpl(
 
     override fun startFileDownloadJob(
         user: User,
-        file: OCFile,
+        filePath: String,
         behaviour: String,
         downloadType: DownloadType?,
         activityName: String,
         packageName: String,
         conflictUploadId: Long?
     ) {
-        val tag = startFileDownloadJobTag(user, file)
+        val tag = startFileDownloadJobTag(user, filePath)
 
         val data = workDataOf(
             FileDownloadWorker.WORKER_TAG to tag,
             FileDownloadWorker.USER_NAME to user.accountName,
-            FileDownloadWorker.FILE to gson.toJson(file),
+            FileDownloadWorker.FILE_PATH to filePath,
             FileDownloadWorker.BEHAVIOUR to behaviour,
             FileDownloadWorker.DOWNLOAD_TYPE to downloadType.toString(),
             FileDownloadWorker.ACTIVITY_NAME to activityName,
@@ -577,8 +577,8 @@ internal class BackgroundJobManagerImpl(
         workManager.cancelJob(JOB_FILES_UPLOAD, user)
     }
 
-    override fun cancelFilesDownloadJob(user: User, file: OCFile) {
-        workManager.cancelAllWorkByTag(startFileDownloadJobTag(user, file))
+    override fun cancelFilesDownloadJob(user: User, path: String) {
+        workManager.cancelAllWorkByTag(startFileDownloadJobTag(user, path))
     }
 
     override fun startPdfGenerateAndUploadWork(

+ 18 - 0
app/src/main/java/com/nextcloud/model/DownloadWorkerStateLiveData.kt

@@ -22,11 +22,29 @@
 package com.nextcloud.model
 
 import androidx.lifecycle.LiveData
+import com.nextcloud.client.account.User
+import com.owncloud.android.datamodel.OCFile
 
 class DownloadWorkerStateLiveData private constructor() : LiveData<ArrayList<DownloadWorkerState>>() {
 
     private var workers: ArrayList<DownloadWorkerState> = arrayListOf()
 
+    fun isDownloading(user: User?, file: OCFile?): Boolean {
+        if (user == null || file == null) {
+            return false
+        }
+
+        var result = false
+
+        workers.forEach { downloadState ->
+            downloadState.pendingDownloads?.all?.forEach { download ->
+                result = download.value?.payload?.file?.fileId == file.fileId
+            }
+        }
+
+        return result
+    }
+
     fun removeWorker(tag: String) {
         workers.forEach {
             if (it.tag == tag) {

+ 2 - 1
app/src/main/java/com/nextcloud/model/WorkerState.kt

@@ -22,6 +22,7 @@
 package com.nextcloud.model
 
 import com.nextcloud.client.account.User
+import com.owncloud.android.files.services.IndexedForest
 import com.owncloud.android.operations.DownloadFileOperation
 
-data class DownloadWorkerState(var tag: String, var user: User?, var currentDownload: DownloadFileOperation?)
+data class DownloadWorkerState(var tag: String, var user: User?, var pendingDownloads: IndexedForest<DownloadFileOperation>?)

+ 0 - 15
app/src/main/java/com/nextcloud/utils/extensions/ContextExtensions.kt

@@ -24,11 +24,9 @@ package com.nextcloud.utils.extensions
 import android.annotation.SuppressLint
 import android.content.BroadcastReceiver
 import android.content.Context
-import android.content.ContextWrapper
 import android.content.Intent
 import android.content.IntentFilter
 import android.os.Build
-import androidx.lifecycle.LifecycleOwner
 import com.owncloud.android.datamodel.ReceiverFlag
 
 @SuppressLint("UnspecifiedRegisterReceiverFlag")
@@ -39,16 +37,3 @@ fun Context.registerBroadcastReceiver(receiver: BroadcastReceiver?, filter: Inte
         registerReceiver(receiver, filter)
     }
 }
-
-fun Context.lifecycleOwner(): LifecycleOwner? {
-    var curContext = this
-    var maxDepth = 20
-    while (maxDepth-- > 0 && curContext !is LifecycleOwner) {
-        curContext = (curContext as ContextWrapper).baseContext
-    }
-    return if (curContext is LifecycleOwner) {
-        curContext
-    } else {
-        null
-    }
-}

+ 7 - 3
app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -54,6 +54,7 @@ import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.files.services.IndexedForest;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.UserInfo;
 import com.owncloud.android.lib.common.utils.Log_OC;
@@ -411,10 +412,13 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
     private void cancelAllDownloadsForAccount() {
         for (DownloadWorkerState workerState : downloadWorkerStates) {
             User currentUser =  workerState.getUser();
-            DownloadFileOperation currentDownload = workerState.getCurrentDownload();
+            IndexedForest<DownloadFileOperation> pendingDownloads = workerState.getPendingDownloads();
 
-            if (currentUser != null && currentDownload != null) {
-                FileDownloadHelper.Companion.instance().cancelAllDownloadsForAccount(currentUser.getAccountName(), currentDownload);
+            if (currentUser != null && pendingDownloads != null) {
+                pendingDownloads.getAll().values().forEach((value) -> {
+                    DownloadFileOperation operation = value.getPayload();
+                    FileDownloadHelper.Companion.instance().cancelAllDownloadsForAccount(currentUser.getAccountName(), operation);
+                });
             }
         }
     }

+ 1 - 18
app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt

@@ -36,7 +36,6 @@ import com.nextcloud.client.files.downloader.FileDownloadHelper
 import com.nextcloud.client.preferences.AppPreferences
 import com.nextcloud.model.DownloadWorkerStateLiveData
 import com.nextcloud.utils.extensions.createRoundedOutline
-import com.nextcloud.utils.extensions.lifecycleOwner
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.OCFile
@@ -76,11 +75,6 @@ class OCFileListDelegate(
     fun setHighlightedItem(highlightedItem: OCFile?) {
         this.highlightedItem = highlightedItem
     }
-    private var isDownloading = false
-
-    init {
-        isDownloading()
-    }
 
     fun isCheckedFile(file: OCFile): Boolean {
         return checkedFiles.contains(file)
@@ -346,24 +340,13 @@ class OCFileListDelegate(
         }
     }
 
-    // FIXME
-    private fun isDownloading() {
-        context.lifecycleOwner()?.let {
-            DownloadWorkerStateLiveData.instance().observe(it) { downloadWorkerStates ->
-                downloadWorkerStates.forEach { state ->
-                    isDownloading = FileDownloadHelper.instance().isDownloading(user, state.currentDownload?.file)
-                }
-            }
-        }
-    }
-
     private fun showLocalFileIndicator(file: OCFile, gridViewHolder: ListGridImageViewHolder) {
         val operationsServiceBinder = transferServiceGetter.operationsServiceBinder
         val fileUploaderBinder = transferServiceGetter.fileUploaderBinder
 
         val icon: Int? = when {
             operationsServiceBinder?.isSynchronizing(user, file) == true ||
-                isDownloading ||
+                DownloadWorkerStateLiveData.instance().isDownloading(user, file) ||
                 fileUploaderBinder?.isUploading(user, file) == true -> {
                 // synchronizing, downloading or uploading
                 R.drawable.ic_synchronizing