瀏覽代碼

Fix cancel feature for individual file download inside folder

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 1 年之前
父節點
當前提交
51bb5893eb

+ 22 - 7
app/src/main/java/com/nextcloud/client/files/downloader/FileDownloadHelper.kt

@@ -21,6 +21,8 @@
 
 package com.nextcloud.client.files.downloader
 
+import android.content.Intent
+import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import com.nextcloud.client.account.User
 import com.nextcloud.client.jobs.BackgroundJobManager
 import com.owncloud.android.MainApp
@@ -66,19 +68,32 @@ class FileDownloadHelper {
 
     fun cancelPendingOrCurrentDownloads(user: User?, file: OCFile?) {
         if (user == null || file == null) return
-        FileDownloadWorker.cancelCurrentDownload(user, file)
+
+        sendCancelEvent(user, file)
         backgroundJobManager.cancelFilesDownloadJob(user, file)
     }
 
+    private fun sendCancelEvent(user: User, file: OCFile) {
+        val intent = Intent(FileDownloadWorker.CANCEL_EVENT).apply {
+            putExtra(FileDownloadWorker.EVENT_ACCOUNT_NAME, user.accountName)
+            putExtra(FileDownloadWorker.EVENT_FILE_ID, file.fileId)
+        }
+        LocalBroadcastManager.getInstance(MainApp.getAppContext()).sendBroadcast(intent)
+    }
+
     fun cancelAllDownloadsForAccount(accountName: String?, currentDownload: DownloadFileOperation?) {
-        if (currentDownload?.user?.nameEquals(accountName) == true) {
-            currentDownload.file?.let { file ->
-                FileDownloadWorker.cancelCurrentDownload(currentDownload.user, file)
-                backgroundJobManager.cancelFilesDownloadJob(currentDownload.user, file)
-            }
+        if (accountName == null || currentDownload == null) return
+
+        val currentUser = currentDownload.user
+        val currentFile = currentDownload.file
 
-            currentDownload.cancel()
+        if (!currentUser.nameEquals(accountName)) {
+            return
         }
+
+        currentDownload.cancel()
+        sendCancelEvent(currentUser, currentFile)
+        backgroundJobManager.cancelFilesDownloadJob(currentUser, currentFile)
     }
 
     fun saveFile(

+ 55 - 23
app/src/main/java/com/nextcloud/client/files/downloader/FileDownloadWorker.kt

@@ -25,7 +25,10 @@ import android.accounts.Account
 import android.accounts.AccountManager
 import android.accounts.OnAccountsUpdateListener
 import android.app.PendingIntent
+import android.content.BroadcastReceiver
 import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
 import androidx.core.util.component1
 import androidx.core.util.component2
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
@@ -55,7 +58,7 @@ import java.util.Vector
 
 @Suppress("LongParameterList", "TooManyFunctions")
 class FileDownloadWorker(
-    private val viewThemeUtils: ViewThemeUtils,
+    viewThemeUtils: ViewThemeUtils,
     private val accountManager: UserAccountManager,
     private var localBroadcastManager: LocalBroadcastManager,
     private val context: Context,
@@ -69,6 +72,10 @@ class FileDownloadWorker(
         private var pendingDownloadFileIds: ArrayList<Pair<String?, Long>> = arrayListOf()
         private val lock = Any()
 
+        const val CANCEL_EVENT = "CANCEL_EVENT"
+        const val EVENT_ACCOUNT_NAME = "EVENT_ACCOUNT_NAME"
+        const val EVENT_FILE_ID = "EVENT_FILE_ID"
+
         const val FILES_SEPARATOR = ","
         const val FOLDER_REMOTE_PATH = "FOLDER_REMOTE_PATH"
         const val FILE_REMOTE_PATH = "FILE_REMOTE_PATH"
@@ -91,14 +98,6 @@ class FileDownloadWorker(
             }
         }
 
-        fun cancelCurrentDownload(user: User, file: OCFile) {
-            synchronized(lock) {
-                if (currentDownload?.isActive(user, file) == true) {
-                    currentDownload?.cancel()
-                }
-            }
-        }
-
         fun getDownloadAddedMessage(): String {
             return FileDownloadWorker::class.java.name + "DOWNLOAD_ADDED"
         }
@@ -131,6 +130,7 @@ class FileDownloadWorker(
             val requestDownloads = getRequestDownloads()
 
             addAccountUpdateListener()
+            registerCancelEvent()
 
             requestDownloads.forEach {
                 downloadFile(it)
@@ -166,11 +166,37 @@ class FileDownloadWorker(
     }
 
     private fun setIdleWorkerState() {
-        pendingDownloads.all.clear()
         currentDownload = null
+        LocalBroadcastManager.getInstance(context).unregisterReceiver(cancelEventReceiver)
         WorkerStateLiveData.instance().setWorkState(WorkerState.Idle)
     }
 
+    private fun getEventPair(intent: Intent): Pair<String, Long>? {
+        val fileId = intent.getLongExtra(EVENT_FILE_ID, -1L)
+        val accountName = intent.getStringExtra(EVENT_ACCOUNT_NAME)
+
+        return if (fileId != -1L && accountName != null) {
+            Pair(accountName, fileId)
+        } else {
+            null
+        }
+    }
+
+    private fun registerCancelEvent() {
+        val filter = IntentFilter(CANCEL_EVENT)
+        LocalBroadcastManager.getInstance(context).registerReceiver(cancelEventReceiver, filter)
+    }
+
+    private val cancelEventReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+        override fun onReceive(context: Context, intent: Intent) {
+            val (accountName, fileId) = getEventPair(intent) ?: return
+
+            pendingDownloads.all.forEach {
+                it.value.payload?.cancel(accountName, fileId)
+            }
+        }
+    }
+
     private fun cancelAllDownloads() {
         pendingDownloads.all.forEach {
             it.value.payload?.cancel()
@@ -184,18 +210,15 @@ class FileDownloadWorker(
 
     @Suppress("MagicNumber")
     private fun showCompleteNotification() {
-        val result = getSuccessNotificationText()
-        notificationManager.showCompleteNotification(result)
-    }
-
-    private fun getSuccessNotificationText(): String {
-        return if (folder != null) {
+        val successText = if (folder != null) {
             context.getString(R.string.downloader_folder_downloaded, folder?.fileName)
         } else if (currentDownload?.file != null) {
             context.getString(R.string.downloader_file_downloaded, currentDownload?.file?.fileName)
         } else {
             context.getString(R.string.downloader_download_completed)
         }
+
+        notificationManager.showCompleteNotification(successText)
     }
 
     private fun getRequestDownloads(): AbstractList<String> {
@@ -398,15 +421,24 @@ class FileDownloadWorker(
     }
 
     private fun showFailedDownloadNotifications(result: RemoteOperationResult<*>) {
-        if (!result.isSuccess) {
-            val fileName = currentDownload?.file?.fileName ?: ""
-            notificationManager.showNewNotification(
-                context.getString(
-                    R.string.downloader_file_download_failed,
-                    fileName
-                )
+        if (result.isSuccess) {
+            return
+        }
+
+        val fileName = currentDownload?.file?.fileName ?: ""
+        val failMessage = if (result.isCancelled) {
+            context.getString(
+                R.string.downloader_file_download_cancelled,
+                fileName
+            )
+        } else {
+            context.getString(
+                R.string.downloader_file_download_failed,
+                fileName
             )
         }
+
+        notificationManager.showNewNotification(failMessage)
     }
 
     private fun notifyDownloadResult(

+ 3 - 6
app/src/main/java/com/owncloud/android/operations/DownloadFileOperation.java

@@ -99,13 +99,10 @@ public class DownloadFileOperation extends RemoteOperation {
         this(user, file, null, null, null, context, DownloadType.DOWNLOAD);
     }
 
-    public boolean isActive(User user, OCFile file) {
-        if (user == null || file == null) {
-            return false;
+    public void cancel(String accountName, long fileId) {
+        if (getFile().getFileId() == fileId && getUser().getAccountName().equals(accountName)) {
+            cancel();
         }
-
-        return getFile().getFileId() == file.getFileId() &&
-            getUser().getAccountName().equals(user.getAccountName());
     }
 
     public String getSavePath() {

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -175,6 +175,7 @@
     <string name="downloader_download_failed_ticker">Download failed</string>
     <string name="downloader_download_failed_content">Could not download %1$s</string>
     <string name="downloader_not_downloaded_yet">Not downloaded yet</string>
+    <string name="downloader_file_download_cancelled">%s file download cancelled</string>
     <string name="downloader_file_download_failed">Error occurred while downloading %s file</string>
     <string name="downloader_folder_downloaded">%s folder successfully downloaded</string>
     <string name="downloader_file_downloaded">%s file successfully downloaded</string>