Преглед изворни кода

Merge pull request #6655 from nextcloud/ezaquarii/rename-downloader-to-transfer-manager

Rename Downloader to TransferManager
Tobias Kaminsky пре 4 година
родитељ
комит
5b22cbe038

+ 24 - 24
src/androidTest/java/com/nextcloud/client/files/downloader/DownloaderConnectionTest.kt → src/androidTest/java/com/nextcloud/client/files/downloader/TransferManagerConnectionTest.kt

@@ -34,9 +34,9 @@ import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
 
-class DownloaderConnectionTest {
+class TransferManagerConnectionTest {
 
-    lateinit var connection: DownloaderConnection
+    lateinit var connection: TransferManagerConnection
 
     @MockK
     lateinit var context: Context
@@ -48,10 +48,10 @@ class DownloaderConnectionTest {
     lateinit var secondDownloadListener: (Transfer) -> Unit
 
     @MockK
-    lateinit var firstStatusListener: (Downloader.Status) -> Unit
+    lateinit var firstStatusListener: (TransferManager.Status) -> Unit
 
     @MockK
-    lateinit var secondStatusListener: (Downloader.Status) -> Unit
+    lateinit var secondStatusListener: (TransferManager.Status) -> Unit
 
     @MockK
     lateinit var binder: DownloaderService.Binder
@@ -63,7 +63,7 @@ class DownloaderConnectionTest {
     @Before
     fun setUp() {
         MockKAnnotations.init(this, relaxed = true)
-        connection = DownloaderConnection(context, user)
+        connection = TransferManagerConnection(context, user)
     }
 
     @Test
@@ -71,8 +71,8 @@ class DownloaderConnectionTest {
         // GIVEN
         //      not connected
         //      listener is added
-        connection.registerDownloadListener(firstDownloadListener)
-        connection.registerDownloadListener(secondDownloadListener)
+        connection.registerTransferListener(firstDownloadListener)
+        connection.registerTransferListener(secondDownloadListener)
 
         // WHEN
         //      service is bound
@@ -81,7 +81,7 @@ class DownloaderConnectionTest {
         // THEN
         //      all listeners are passed to the service
         val listeners = mutableListOf<(Transfer) -> Unit>()
-        verify { binder.registerDownloadListener(capture(listeners)) }
+        verify { binder.registerTransferListener(capture(listeners)) }
         assertEquals(listOf(firstDownloadListener, secondDownloadListener), listeners)
     }
 
@@ -93,11 +93,11 @@ class DownloaderConnectionTest {
 
         // WHEN
         //      listeners are added
-        connection.registerDownloadListener(firstDownloadListener)
+        connection.registerTransferListener(firstDownloadListener)
 
         // THEN
         //      listener is forwarded to service
-        verify { binder.registerDownloadListener(firstDownloadListener) }
+        verify { binder.registerTransferListener(firstDownloadListener) }
     }
 
     @Test
@@ -106,8 +106,8 @@ class DownloaderConnectionTest {
         //      service is bound
         //      service has some listeners
         connection.onServiceConnected(componentName, binder)
-        connection.registerDownloadListener(firstDownloadListener)
-        connection.registerDownloadListener(secondDownloadListener)
+        connection.registerTransferListener(firstDownloadListener)
+        connection.registerTransferListener(secondDownloadListener)
 
         // WHEN
         //      service unbound
@@ -115,8 +115,8 @@ class DownloaderConnectionTest {
 
         // THEN
         //      listeners removed from service
-        verify { binder.removeDownloadListener(firstDownloadListener) }
-        verify { binder.removeDownloadListener(secondDownloadListener) }
+        verify { binder.removeTransferListener(firstDownloadListener) }
+        verify { binder.removeTransferListener(secondDownloadListener) }
     }
 
     @Test
@@ -125,19 +125,19 @@ class DownloaderConnectionTest {
         //      not bound
         //      has listeners
         //      download is scheduled and is progressing
-        connection.registerDownloadListener(firstDownloadListener)
-        connection.registerDownloadListener(secondDownloadListener)
+        connection.registerTransferListener(firstDownloadListener)
+        connection.registerTransferListener(secondDownloadListener)
 
         val request1 = Request(user, file)
-        connection.download(request1)
+        connection.enqueue(request1)
         val download1 = Transfer(request1.uuid, TransferState.RUNNING, 50, request1.file, request1)
 
         val request2 = Request(user, file)
-        connection.download(request2)
+        connection.enqueue(request2)
         val download2 = Transfer(request2.uuid, TransferState.RUNNING, 50, request2.file, request1)
 
-        every { binder.getDownload(request1.uuid) } returns download1
-        every { binder.getDownload(request2.uuid) } returns download2
+        every { binder.getTransfer(request1.uuid) } returns download1
+        every { binder.getTransfer(request2.uuid) } returns download2
 
         // WHEN
         //      service is bound
@@ -159,7 +159,7 @@ class DownloaderConnectionTest {
         // GIVEN
         //      not bound
         //      has status listeners
-        val mockStatus: Downloader.Status = mockk()
+        val mockStatus: TransferManager.Status = mockk()
         every { binder.status } returns mockStatus
         connection.registerStatusListener(firstStatusListener)
         connection.registerStatusListener(secondStatusListener)
@@ -224,10 +224,10 @@ class DownloaderConnectionTest {
         //      not bound
         //      some downloads requested without listener
         val request = Request(user, file)
-        connection.download(request)
+        connection.enqueue(request)
         val download = Transfer(request.uuid, TransferState.RUNNING, 50, request.file, request)
-        connection.registerDownloadListener(firstDownloadListener)
-        every { binder.getDownload(request.uuid) } returns download
+        connection.registerTransferListener(firstDownloadListener)
+        every { binder.getTransfer(request.uuid) } returns download
 
         // WHEN
         //      service is bound

+ 28 - 28
src/androidTest/java/com/nextcloud/client/files/downloader/DownloaderTest.kt → src/androidTest/java/com/nextcloud/client/files/downloader/TransferManagerTest.kt

@@ -41,15 +41,15 @@ import org.mockito.MockitoAnnotations
 
 @RunWith(Suite::class)
 @Suite.SuiteClasses(
-    DownloaderTest.Enqueue::class,
-    DownloaderTest.TransferStatusUpdates::class
+    TransferManagerTest.Enqueue::class,
+    TransferManagerTest.TransferStatusUpdates::class
 )
-class DownloaderTest {
+class TransferManagerTest {
 
     abstract class Base {
 
         companion object {
-            const val MAX_DOWNLOAD_THREADS = 4
+            const val MAX_TRANSFER_THREADS = 4
         }
 
         @MockK
@@ -67,7 +67,7 @@ class DownloaderTest {
          */
         lateinit var downloadTaskMocks: MutableList<DownloadTask>
         lateinit var runner: ManualAsyncRunner
-        lateinit var downloader: DownloaderImpl
+        lateinit var transferManager: TransferManagerImpl
 
         /**
          * Response value for all download tasks
@@ -86,10 +86,10 @@ class DownloaderTest {
             MockitoAnnotations.initMocks(this)
             downloadTaskMocks = mutableListOf()
             runner = ManualAsyncRunner()
-            downloader = DownloaderImpl(
+            transferManager = TransferManagerImpl(
                 runner = runner,
                 taskFactory = mockTaskFactory,
-                threads = MAX_DOWNLOAD_THREADS
+                threads = MAX_TRANSFER_THREADS
             )
             downloadTaskResult = true
             every { mockTaskFactory.create() } answers { createMockTask() }
@@ -120,11 +120,11 @@ class DownloaderTest {
             //      download is enqueued
             val file = OCFile("/path")
             val request = Request(user, file)
-            downloader.download(request)
+            transferManager.enqueue(request)
 
             // THEN
             //      download is started immediately
-            val download = downloader.getDownload(request.uuid)
+            val download = transferManager.getTransfer(request.uuid)
             assertEquals(TransferState.RUNNING, download?.state)
         }
 
@@ -132,11 +132,11 @@ class DownloaderTest {
         fun enqueued_downloads_are_pending_if_running_queue_is_full() {
             // GIVEN
             //      downloader is downloading max simultaneous files
-            for (i in 0 until MAX_DOWNLOAD_THREADS) {
+            for (i in 0 until MAX_TRANSFER_THREADS) {
                 val file = OCFile("/running/download/path/$i")
                 val request = Request(user, file)
-                downloader.download(request)
-                val runningDownload = downloader.getDownload(request.uuid)
+                transferManager.enqueue(request)
+                val runningDownload = transferManager.getTransfer(request.uuid)
                 assertEquals(runningDownload?.state, TransferState.RUNNING)
             }
 
@@ -144,11 +144,11 @@ class DownloaderTest {
             //      another download is enqueued
             val file = OCFile("/path")
             val request = Request(user, file)
-            downloader.download(request)
+            transferManager.enqueue(request)
 
             // THEN
             //      download is pending
-            val download = downloader.getDownload(request.uuid)
+            val download = transferManager.getTransfer(request.uuid)
             assertEquals(TransferState.PENDING, download?.state)
         }
     }
@@ -166,8 +166,8 @@ class DownloaderTest {
             //      download is running
             //      download is being observed
             val downloadUpdates = mutableListOf<Transfer>()
-            downloader.registerDownloadListener { downloadUpdates.add(it) }
-            downloader.download(Request(user, file))
+            transferManager.registerTransferListener { downloadUpdates.add(it) }
+            transferManager.enqueue(Request(user, file))
 
             // WHEN
             //      download task finishes successfully
@@ -185,8 +185,8 @@ class DownloaderTest {
             //      download is running
             //      download is being observed
             val downloadUpdates = mutableListOf<Transfer>()
-            downloader.registerDownloadListener { downloadUpdates.add(it) }
-            downloader.download(Request(user, file))
+            transferManager.registerTransferListener { downloadUpdates.add(it) }
+            transferManager.enqueue(Request(user, file))
 
             // WHEN
             //      download task fails
@@ -204,8 +204,8 @@ class DownloaderTest {
             // GIVEN
             //      download is running
             val downloadUpdates = mutableListOf<Transfer>()
-            downloader.registerDownloadListener { downloadUpdates.add(it) }
-            downloader.download(Request(user, file))
+            transferManager.registerTransferListener { downloadUpdates.add(it) }
+            transferManager.enqueue(Request(user, file))
 
             // WHEN
             //      download progress updated 4 times before completion
@@ -232,13 +232,13 @@ class DownloaderTest {
         fun download_task_is_created_only_for_running_downloads() {
             // WHEN
             //      multiple downloads are enqueued
-            for (i in 0 until MAX_DOWNLOAD_THREADS * 2) {
-                downloader.download(Request(user, file))
+            for (i in 0 until MAX_TRANSFER_THREADS * 2) {
+                transferManager.enqueue(Request(user, file))
             }
 
             // THEN
             //      download task is created only for running downloads
-            assertEquals(MAX_DOWNLOAD_THREADS, downloadTaskMocks.size)
+            assertEquals(MAX_TRANSFER_THREADS, downloadTaskMocks.size)
         }
     }
 
@@ -253,11 +253,11 @@ class DownloaderTest {
             //      download is enqueued
             val file = OCFile("/path/to/file")
             val request = Request(user, file)
-            downloader.download(request)
+            transferManager.enqueue(request)
 
             // THEN
             //      is running changes
-            assertTrue(downloader.isRunning)
+            assertTrue(transferManager.isRunning)
         }
 
         @Test
@@ -266,8 +266,8 @@ class DownloaderTest {
             //      a download is in progress
             val file = OCFile("/path/to/file")
             val request = Request(user, file)
-            downloader.download(request)
-            assertTrue(downloader.isRunning)
+            transferManager.enqueue(request)
+            assertTrue(transferManager.isRunning)
 
             // WHEN
             //      download is processed
@@ -275,7 +275,7 @@ class DownloaderTest {
 
             // THEN
             //      downloader is not running
-            assertFalse(downloader.isRunning)
+            assertFalse(transferManager.isRunning)
         }
     }
 }

+ 2 - 2
src/main/java/com/nextcloud/client/etm/EtmViewModel.kt

@@ -35,7 +35,7 @@ import com.nextcloud.client.etm.pages.EtmBackgroundJobsFragment
 import com.nextcloud.client.etm.pages.EtmDownloaderFragment
 import com.nextcloud.client.etm.pages.EtmMigrations
 import com.nextcloud.client.etm.pages.EtmPreferencesFragment
-import com.nextcloud.client.files.downloader.DownloaderConnection
+import com.nextcloud.client.files.downloader.TransferManagerConnection
 import com.nextcloud.client.jobs.BackgroundJobManager
 import com.nextcloud.client.jobs.JobInfo
 import com.nextcloud.client.migrations.MigrationInfo
@@ -109,7 +109,7 @@ class EtmViewModel @Inject constructor(
             pageClass = EtmDownloaderFragment::class
         )
     )
-    val downloaderConnection = DownloaderConnection(context, accountManager.user)
+    val downloaderConnection = TransferManagerConnection(context, accountManager.user)
 
     val preferences: Map<String, String> get() {
         return defaultPreferences.all

+ 4 - 4
src/main/java/com/nextcloud/client/etm/pages/EtmDownloaderFragment.kt

@@ -14,7 +14,7 @@ import androidx.recyclerview.widget.RecyclerView
 import com.nextcloud.client.etm.EtmBaseFragment
 import com.nextcloud.client.files.downloader.Direction
 import com.nextcloud.client.files.downloader.Transfer
-import com.nextcloud.client.files.downloader.Downloader
+import com.nextcloud.client.files.downloader.TransferManager
 import com.nextcloud.client.files.downloader.Request
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.OCFile
@@ -51,7 +51,7 @@ class EtmDownloaderFragment : EtmBaseFragment() {
 
         private var downloads = listOf<Transfer>()
 
-        fun setStatus(status: Downloader.Status) {
+        fun setStatus(status: TransferManager.Status) {
             downloads = listOf(status.pending, status.running, status.completed).flatten().reversed()
             notifyDataSetChanged()
         }
@@ -130,10 +130,10 @@ class EtmDownloaderFragment : EtmBaseFragment() {
             Direction.DOWNLOAD,
             true
         )
-        vm.downloaderConnection.download(request)
+        vm.downloaderConnection.enqueue(request)
     }
 
-    private fun onDownloaderStatusChanged(status: Downloader.Status) {
+    private fun onDownloaderStatusChanged(status: TransferManager.Status) {
         adapter.setStatus(status)
     }
 }

+ 8 - 8
src/main/java/com/nextcloud/client/files/downloader/DownloaderService.kt

@@ -56,13 +56,13 @@ class DownloaderService : Service() {
     }
 
     /**
-     * Binder forwards [Downloader] API calls to selected instance of downloader.
+     * Binder forwards [TransferManager] API calls to selected instance of downloader.
      */
     class Binder(
-        downloader: DownloaderImpl,
+        downloader: TransferManagerImpl,
         service: DownloaderService
     ) : LocalBinder<DownloaderService>(service),
-        Downloader by downloader
+        TransferManager by downloader
 
     @Inject
     lateinit var notificationsManager: AppNotificationManager
@@ -79,7 +79,7 @@ class DownloaderService : Service() {
 
     val isRunning: Boolean get() = downloaders.any { it.value.isRunning }
 
-    private val downloaders: MutableMap<String, DownloaderImpl> = mutableMapOf()
+    private val downloaders: MutableMap<String, TransferManagerImpl> = mutableMapOf()
 
     override fun onCreate() {
         AndroidInjection.inject(this)
@@ -99,7 +99,7 @@ class DownloaderService : Service() {
 
         val request = intent.getParcelableExtra(EXTRA_REQUEST) as Request
         val downloader = getDownloader(request.user)
-        downloader.download(request)
+        downloader.enqueue(request)
 
         logger.d(TAG, "Enqueued new download: ${request.uuid} ${request.file.remotePath}")
 
@@ -136,7 +136,7 @@ class DownloaderService : Service() {
         logger.d(TAG, "Stopping downloader service")
     }
 
-    private fun getDownloader(user: User): DownloaderImpl {
+    private fun getDownloader(user: User): TransferManagerImpl {
         val existingDownloader = downloaders[user.accountName]
         return if (existingDownloader != null) {
             existingDownloader
@@ -146,8 +146,8 @@ class DownloaderService : Service() {
                 { clientFactory.create(user) },
                 contentResolver
             )
-            val newDownloader = DownloaderImpl(runner, downloadTaskFactory)
-            newDownloader.registerDownloadListener(this::onDownloadUpdate)
+            val newDownloader = TransferManagerImpl(runner, downloadTaskFactory)
+            newDownloader.registerTransferListener(this::onDownloadUpdate)
             downloaders[user.accountName] = newDownloader
             newDownloader
         }

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

@@ -20,8 +20,7 @@
 package com.nextcloud.client.files.downloader
 
 import com.owncloud.android.datamodel.OCFile
-import java.lang.IllegalStateException
-import java.util.TreeMap
+import java.util.LinkedHashMap
 import java.util.UUID
 import kotlin.math.max
 import kotlin.math.min
@@ -46,9 +45,9 @@ internal class Registry(
     private val onTransferChanged: (Transfer) -> Unit,
     private val maxRunning: Int = 2
 ) {
-    private val pendingQueue = TreeMap<UUID, Transfer>()
-    private val runningQueue = TreeMap<UUID, Transfer>()
-    private val completedQueue = TreeMap<UUID, Transfer>()
+    private val pendingQueue = LinkedHashMap<UUID, Transfer>()
+    private val runningQueue = LinkedHashMap<UUID, Transfer>()
+    private val completedQueue = LinkedHashMap<UUID, Transfer>()
 
     val isRunning: Boolean get() = pendingQueue.size > 0 || runningQueue.size > 0
 
@@ -80,7 +79,7 @@ internal class Registry(
     fun startNext() {
         val freeThreads = max(0, maxRunning - runningQueue.size)
         for (i in 0 until min(freeThreads, pendingQueue.size)) {
-            val key = pendingQueue.firstKey()
+            val key = pendingQueue.keys.first()
             val pendingTransfer = pendingQueue.remove(key) ?: throw IllegalStateException("Transfer $key not found")
             val runningTransfer = pendingTransfer.copy(state = TransferState.RUNNING)
             runningQueue[key] = runningTransfer

+ 20 - 20
src/main/java/com/nextcloud/client/files/downloader/Downloader.kt → src/main/java/com/nextcloud/client/files/downloader/TransferManager.kt

@@ -22,10 +22,10 @@ package com.nextcloud.client.files.downloader
 import com.owncloud.android.datamodel.OCFile
 import java.util.UUID
 
-interface Downloader {
+interface TransferManager {
 
     /**
-     * Snapshot of downloader status. All data is immutable and can be safely shared.
+     * Snapshot of transfer manager status. All data is immutable and can be safely shared.
      */
     data class Status(
         val pending: List<Transfer>,
@@ -38,27 +38,27 @@ interface Downloader {
     }
 
     /**
-     * True if downloader has any pending or running downloads.
+     * True if transfer manager has any pending or running transfers.
      */
     val isRunning: Boolean
 
     /**
-     * Status snapshot of all downloads.
+     * Status snapshot of all transfers.
      */
     val status: Status
 
     /**
-     * Register download progress listener. Registration is idempotent - listener can be registered only once.
+     * Register transfer progress listener. Registration is idempotent - listener can be registered only once.
      */
-    fun registerDownloadListener(listener: (Transfer) -> Unit)
+    fun registerTransferListener(listener: (Transfer) -> Unit)
 
     /**
      * Removes registered listener if exists.
      */
-    fun removeDownloadListener(listener: (Transfer) -> Unit)
+    fun removeTransferListener(listener: (Transfer) -> Unit)
 
     /**
-     * Register downloader status listener. Registration is idempotent - listener can be registered only once.
+     * Register transfer manager status listener. Registration is idempotent - listener can be registered only once.
      */
     fun registerStatusListener(listener: (Status) -> Unit)
 
@@ -68,31 +68,31 @@ interface Downloader {
     fun removeStatusListener(listener: (Status) -> Unit)
 
     /**
-     * Adds download request to pending queue and returns immediately.
+     * Adds transfer request to pending queue and returns immediately.
      *
-     * @param request Download request
+     * @param request Transfer request
      */
-    fun download(request: Request)
+    fun enqueue(request: Request)
 
     /**
-     * Find download status by UUID.
+     * Find transfer status by UUID.
      *
      * @param uuid Download process uuid
-     * @return download status or null if not found
+     * @return transfer status or null if not found
      */
-    fun getDownload(uuid: UUID): Transfer?
+    fun getTransfer(uuid: UUID): Transfer?
 
     /**
-     * Query user's downloader for a download status. It performs linear search
-     * of all queues and returns first download matching [OCFile.remotePath].
+     * Query user's transfer manager for a transfer status. It performs linear search
+     * of all queues and returns first transfer matching [OCFile.remotePath].
      *
-     * Since there can be multiple downloads with identical file in downloader's queues,
+     * Since there can be multiple transfers with identical file in the queues,
      * order of search matters.
      *
-     * It looks for pending downloads first, then running and completed queue last.
+     * It looks for pending transfers first, then running and completed queue last.
      *
      * @param file Downloaded file
-     * @return download status or null, if download does not exist
+     * @return transfer status or null, if transfer does not exist
      */
-    fun getDownload(file: OCFile): Transfer?
+    fun getTransfer(file: OCFile): Transfer?
 }

+ 34 - 31
src/main/java/com/nextcloud/client/files/downloader/DownloaderConnection.kt → src/main/java/com/nextcloud/client/files/downloader/TransferManagerConnection.kt

@@ -27,47 +27,50 @@ import com.nextcloud.client.core.LocalConnection
 import com.owncloud.android.datamodel.OCFile
 import java.util.UUID
 
-class DownloaderConnection(context: Context, val user: User) : LocalConnection<DownloaderService>(context), Downloader {
+class TransferManagerConnection(
+    context: Context,
+    val user: User
+) : LocalConnection<DownloaderService>(context), TransferManager {
 
-    private var downloadListeners: MutableSet<(Transfer) -> Unit> = mutableSetOf()
-    private var statusListeners: MutableSet<(Downloader.Status) -> Unit> = mutableSetOf()
+    private var transferListeners: MutableSet<(Transfer) -> Unit> = mutableSetOf()
+    private var statusListeners: MutableSet<(TransferManager.Status) -> Unit> = mutableSetOf()
     private var binder: DownloaderService.Binder? = null
-    private val downloadsRequiringStatusRedelivery: MutableSet<UUID> = mutableSetOf()
+    private val transfersRequiringStatusRedelivery: MutableSet<UUID> = mutableSetOf()
 
     override val isRunning: Boolean
         get() = binder?.isRunning ?: false
 
-    override val status: Downloader.Status
-        get() = binder?.status ?: Downloader.Status.EMPTY
+    override val status: TransferManager.Status
+        get() = binder?.status ?: TransferManager.Status.EMPTY
 
-    override fun getDownload(uuid: UUID): Transfer? = binder?.getDownload(uuid)
+    override fun getTransfer(uuid: UUID): Transfer? = binder?.getTransfer(uuid)
 
-    override fun getDownload(file: OCFile): Transfer? = binder?.getDownload(file)
+    override fun getTransfer(file: OCFile): Transfer? = binder?.getTransfer(file)
 
-    override fun download(request: Request) {
+    override fun enqueue(request: Request) {
         val intent = DownloaderService.createDownloadIntent(context, request)
         context.startService(intent)
-        if (!isConnected && downloadListeners.size > 0) {
-            downloadsRequiringStatusRedelivery.add(request.uuid)
+        if (!isConnected && transferListeners.size > 0) {
+            transfersRequiringStatusRedelivery.add(request.uuid)
         }
     }
 
-    override fun registerDownloadListener(listener: (Transfer) -> Unit) {
-        downloadListeners.add(listener)
-        binder?.registerDownloadListener(listener)
+    override fun registerTransferListener(listener: (Transfer) -> Unit) {
+        transferListeners.add(listener)
+        binder?.registerTransferListener(listener)
     }
 
-    override fun removeDownloadListener(listener: (Transfer) -> Unit) {
-        downloadListeners.remove(listener)
-        binder?.removeDownloadListener(listener)
+    override fun removeTransferListener(listener: (Transfer) -> Unit) {
+        transferListeners.remove(listener)
+        binder?.removeTransferListener(listener)
     }
 
-    override fun registerStatusListener(listener: (Downloader.Status) -> Unit) {
+    override fun registerStatusListener(listener: (TransferManager.Status) -> Unit) {
         statusListeners.add(listener)
         binder?.registerStatusListener(listener)
     }
 
-    override fun removeStatusListener(listener: (Downloader.Status) -> Unit) {
+    override fun removeStatusListener(listener: (TransferManager.Status) -> Unit) {
         statusListeners.remove(listener)
         binder?.removeStatusListener(listener)
     }
@@ -79,8 +82,8 @@ class DownloaderConnection(context: Context, val user: User) : LocalConnection<D
     override fun onBound(binder: IBinder) {
         super.onBound(binder)
         this.binder = binder as DownloaderService.Binder
-        downloadListeners.forEach { listener ->
-            binder.registerDownloadListener(listener)
+        transferListeners.forEach { listener ->
+            binder.registerTransferListener(listener)
         }
         statusListeners.forEach { listener ->
             binder.registerStatusListener(listener)
@@ -89,23 +92,23 @@ class DownloaderConnection(context: Context, val user: User) : LocalConnection<D
     }
 
     /**
-     * Since binding and download start are both asynchronous and the order
-     * is not guaranteed, some downloads might already finish when service is bound,
+     * Since binding and transfer start are both asynchronous and the order
+     * is not guaranteed, some transfers might already finish when service is bound,
      * resulting in lost notifications.
      *
-     * Deliver all updates for pending downloads that were scheduled
-     * before service has been bound.
+     * Deliver all updates for pending transfers that were scheduled
+     * before service was bound.
      */
     private fun deliverMissedUpdates() {
-        val downloadUpdates = downloadsRequiringStatusRedelivery.mapNotNull { uuid ->
-            binder?.getDownload(uuid)
+        val transferUpdates = transfersRequiringStatusRedelivery.mapNotNull { uuid ->
+            binder?.getTransfer(uuid)
         }
-        downloadListeners.forEach { listener ->
-            downloadUpdates.forEach { update ->
+        transferListeners.forEach { listener ->
+            transferUpdates.forEach { update ->
                 listener.invoke(update)
             }
         }
-        downloadsRequiringStatusRedelivery.clear()
+        transfersRequiringStatusRedelivery.clear()
 
         if (statusListeners.isNotEmpty()) {
             binder?.status?.let { status ->
@@ -116,7 +119,7 @@ class DownloaderConnection(context: Context, val user: User) : LocalConnection<D
 
     override fun onUnbind() {
         super.onUnbind()
-        downloadListeners.forEach { binder?.removeDownloadListener(it) }
+        transferListeners.forEach { binder?.removeTransferListener(it) }
         statusListeners.forEach { binder?.removeStatusListener(it) }
     }
 }

+ 29 - 26
src/main/java/com/nextcloud/client/files/downloader/DownloaderImpl.kt → src/main/java/com/nextcloud/client/files/downloader/TransferManagerImpl.kt

@@ -27,21 +27,21 @@ import com.owncloud.android.datamodel.OCFile
 import java.util.UUID
 
 /**
- * Per-user file downloader.
+ * Per-user file transfer manager.
  *
- * All notifications are performed on main thread. All download processes are run
+ * All notifications are performed on main thread. All transfer processes are run
  * in the background.
  *
  * @param runner Background task runner. It is important to provide runner that is not shared with UI code.
  * @param taskFactory Download task factory
- * @param threads maximum number of concurrent download processes
+ * @param threads maximum number of concurrent transfer processes
  */
-@Suppress("LongParameterList") // download operations requires those resources
-class DownloaderImpl(
+@Suppress("LongParameterList") // transfer operations requires those resources
+class TransferManagerImpl(
     private val runner: AsyncRunner,
     private val taskFactory: DownloadTask.Factory,
     threads: Int = 1
-) : Downloader {
+) : TransferManager {
 
     companion object {
         const val PROGRESS_PERCENTAGE_MAX = 100
@@ -50,51 +50,54 @@ class DownloaderImpl(
     }
 
     private val registry = Registry(
-        onStartTransfer = this::onStartDownload,
-        onTransferChanged = this::onDownloadUpdate,
+        onStartTransfer = this::onStartTransfer,
+        onTransferChanged = this::onTransferUpdate,
         maxRunning = threads
     )
-    private val downloadListeners: MutableSet<(Transfer) -> Unit> = mutableSetOf()
-    private val statusListeners: MutableSet<(Downloader.Status) -> Unit> = mutableSetOf()
+    private val transferListeners: MutableSet<(Transfer) -> Unit> = mutableSetOf()
+    private val statusListeners: MutableSet<(TransferManager.Status) -> Unit> = mutableSetOf()
 
     override val isRunning: Boolean get() = registry.isRunning
 
-    override val status: Downloader.Status
-        get() = Downloader.Status(
+    override val status: TransferManager.Status
+        get() = TransferManager.Status(
             pending = registry.pending,
             running = registry.running,
             completed = registry.completed
         )
 
-    override fun registerDownloadListener(listener: (Transfer) -> Unit) {
-        downloadListeners.add(listener)
+    override fun registerTransferListener(listener: (Transfer) -> Unit) {
+        transferListeners.add(listener)
     }
 
-    override fun removeDownloadListener(listener: (Transfer) -> Unit) {
-        downloadListeners.remove(listener)
+    override fun removeTransferListener(listener: (Transfer) -> Unit) {
+        transferListeners.remove(listener)
     }
 
-    override fun registerStatusListener(listener: (Downloader.Status) -> Unit) {
+    override fun registerStatusListener(listener: (TransferManager.Status) -> Unit) {
         statusListeners.add(listener)
     }
 
-    override fun removeStatusListener(listener: (Downloader.Status) -> Unit) {
+    override fun removeStatusListener(listener: (TransferManager.Status) -> Unit) {
         statusListeners.remove(listener)
     }
 
-    override fun download(request: Request) {
+    override fun enqueue(request: Request) {
         registry.add(request)
         registry.startNext()
     }
 
-    override fun getDownload(uuid: UUID): Transfer? = registry.getTransfer(uuid)
+    override fun getTransfer(uuid: UUID): Transfer? = registry.getTransfer(uuid)
 
-    override fun getDownload(file: OCFile): Transfer? = registry.getTransfer(file)
+    override fun getTransfer(file: OCFile): Transfer? = registry.getTransfer(file)
 
-    private fun onStartDownload(uuid: UUID, request: Request) {
-        val downloadTask = createDownloadTask(request)
+    private fun onStartTransfer(uuid: UUID, request: Request) {
+        val transferTask = when (request.type) {
+            Direction.DOWNLOAD -> createDownloadTask(request)
+            Direction.UPLOAD -> createDownloadTask(request) // plug a hole for now - uploads are not supported
+        }
         runner.postTask(
-            task = downloadTask,
+            task = transferTask,
             onProgress = { progress: Int -> registry.progress(uuid, progress) },
             onResult = { result -> registry.complete(uuid, result.success, result.file); registry.startNext() },
             onError = { registry.complete(uuid, false); registry.startNext() }
@@ -115,8 +118,8 @@ class DownloaderImpl(
         }
     }
 
-    private fun onDownloadUpdate(transfer: Transfer) {
-        downloadListeners.forEach { it.invoke(transfer) }
+    private fun onTransferUpdate(transfer: Transfer) {
+        transferListeners.forEach { it.invoke(transfer) }
         if (statusListeners.isNotEmpty()) {
             val status = this.status
             statusListeners.forEach { it.invoke(status) }

+ 5 - 5
src/main/java/com/owncloud/android/ui/fragment/contactsbackup/ContactListFragment.java

@@ -60,7 +60,7 @@ import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.files.downloader.Direction;
 import com.nextcloud.client.files.downloader.Transfer;
 import com.nextcloud.client.files.downloader.TransferState;
-import com.nextcloud.client.files.downloader.DownloaderConnection;
+import com.nextcloud.client.files.downloader.TransferManagerConnection;
 import com.nextcloud.client.files.downloader.Request;
 import com.nextcloud.client.jobs.BackgroundJobManager;
 import com.nextcloud.client.network.ClientFactory;
@@ -151,7 +151,7 @@ public class ContactListFragment extends FileFragment implements Injectable {
     @Inject UserAccountManager accountManager;
     @Inject ClientFactory clientFactory;
     @Inject BackgroundJobManager backgroundJobManager;
-    private DownloaderConnection fileDownloader;
+    private TransferManagerConnection fileDownloader;
 
     public static ContactListFragment newInstance(OCFile file, User user) {
         ContactListFragment frag = new ContactListFragment();
@@ -213,12 +213,12 @@ public class ContactListFragment extends FileFragment implements Injectable {
         ocFile = getArguments().getParcelable(FILE_NAME);
         setFile(ocFile);
         user = getArguments().getParcelable(USER);
-        fileDownloader = new DownloaderConnection(getActivity(), user);
-        fileDownloader.registerDownloadListener(this::onDownloadUpdate);
+        fileDownloader = new TransferManagerConnection(getActivity(), user);
+        fileDownloader.registerTransferListener(this::onDownloadUpdate);
         fileDownloader.bind();
         if (!ocFile.isDown()) {
             Request request = new Request(user, ocFile, Direction.DOWNLOAD);
-            fileDownloader.download(request);
+            fileDownloader.enqueue(request);
         } else {
             loadContactsTask.execute();
         }