Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Work Manager For File Transfer #12314

Closed

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
*/
package com.nextcloud.client.files.downloader

import android.content.ComponentName
import android.content.Context
import android.os.Handler
import android.os.Looper
import com.nextcloud.client.account.MockUser
import com.nextcloud.client.jobs.BackgroundJobManager
import com.owncloud.android.datamodel.OCFile
import io.mockk.MockKAnnotations
import io.mockk.every
Expand All @@ -36,7 +38,7 @@ import org.junit.Test

class TransferManagerConnectionTest {

lateinit var connection: TransferManagerConnection
private lateinit var connection: TransferManagerConnection

@MockK
lateinit var context: Context
Expand All @@ -54,16 +56,18 @@ class TransferManagerConnectionTest {
lateinit var secondStatusListener: (TransferManager.Status) -> Unit

@MockK
lateinit var binder: FileTransferService.Binder
lateinit var manager: FileTransferWorker.Manager

@MockK
lateinit var backgroundJobManager: BackgroundJobManager

val file get() = OCFile("/path")
val componentName = ComponentName("", FileTransferService::class.java.simpleName)
val user = MockUser()

@Before
fun setUp() {
MockKAnnotations.init(this, relaxed = true)
connection = TransferManagerConnection(context, user)
connection = TransferManagerConnection(backgroundJobManager, context, user)
}

@Test
Expand All @@ -76,47 +80,47 @@ class TransferManagerConnectionTest {

// WHEN
// service is bound
connection.onServiceConnected(componentName, binder)
connection.onBound(manager)

// THEN
// all listeners are passed to the service
val listeners = mutableListOf<(Transfer) -> Unit>()
verify { binder.registerTransferListener(capture(listeners)) }
verify { manager.registerTransferListener(capture(listeners)) }
assertEquals(listOf(firstDownloadListener, secondDownloadListener), listeners)
}

@Test
fun listeners_are_set_immediately_when_connected() {
// GIVEN
// service is bound
connection.onServiceConnected(componentName, binder)
connection.onBound(manager)

// WHEN
// listeners are added
connection.registerTransferListener(firstDownloadListener)

// THEN
// listener is forwarded to service
verify { binder.registerTransferListener(firstDownloadListener) }
verify { manager.registerTransferListener(firstDownloadListener) }
}

@Test
fun listeners_are_removed_when_unbinding() {
// GIVEN
// service is bound
// service has some listeners
connection.onServiceConnected(componentName, binder)
connection.onBound(manager)
connection.registerTransferListener(firstDownloadListener)
connection.registerTransferListener(secondDownloadListener)

// WHEN
// service unbound
connection.unbind()
connection.onUnbind()

// THEN
// listeners removed from service
verify { binder.removeTransferListener(firstDownloadListener) }
verify { binder.removeTransferListener(secondDownloadListener) }
verify { manager.removeTransferListener(firstDownloadListener) }
verify { manager.removeTransferListener(secondDownloadListener) }
}

@Test
Expand All @@ -136,22 +140,24 @@ class TransferManagerConnectionTest {
connection.enqueue(request2)
val download2 = Transfer(request2.uuid, TransferState.RUNNING, 50, request2.file, request1)

every { binder.getTransfer(request1.uuid) } returns download1
every { binder.getTransfer(request2.uuid) } returns download2
every { manager.getTransfer(request1.uuid) } returns download1
every { manager.getTransfer(request2.uuid) } returns download2

// WHEN
// service is bound
connection.onServiceConnected(componentName, binder)
connection.onBound(manager)

// THEN
// listeners receive current download state for pending downloads
val firstListenerNotifications = mutableListOf<Transfer>()
verify { firstDownloadListener(capture(firstListenerNotifications)) }
assertEquals(listOf(download1, download2), firstListenerNotifications)

val secondListenerNotifications = mutableListOf<Transfer>()
verify { secondDownloadListener(capture(secondListenerNotifications)) }
assertEquals(listOf(download1, download2), secondListenerNotifications)
Handler(Looper.getMainLooper()).postDelayed({
val firstListenerNotifications = mutableListOf<Transfer>()
verify { firstDownloadListener(capture(firstListenerNotifications)) }
assertEquals(listOf(download1, download2), firstListenerNotifications)

val secondListenerNotifications = mutableListOf<Transfer>()
verify { secondDownloadListener(capture(secondListenerNotifications)) }
assertEquals(listOf(download1, download2), secondListenerNotifications)
}, 100)
}

@Test
Expand All @@ -160,13 +166,13 @@ class TransferManagerConnectionTest {
// not bound
// has status listeners
val mockStatus: TransferManager.Status = mockk()
every { binder.status } returns mockStatus
every { manager.status } returns mockStatus
connection.registerStatusListener(firstStatusListener)
connection.registerStatusListener(secondStatusListener)

// WHEN
// service is bound
connection.onServiceConnected(componentName, binder)
connection.onBound(manager)

// THEN
// downloader status is delivered
Expand All @@ -182,19 +188,19 @@ class TransferManagerConnectionTest {

// WHEN
// service is bound
connection.onServiceConnected(componentName, binder)
connection.onBound(manager)

// THEN
// downloader status is not requested
verify(exactly = 0) { binder.status }
verify(exactly = 0) { manager.status }
}

@Test
fun not_running_if_not_connected() {
// GIVEN
// downloader is running
// connection not bound
every { binder.isRunning } returns true
every { manager.isRunning } returns true

// THEN
// not running
Expand All @@ -205,8 +211,8 @@ class TransferManagerConnectionTest {
fun is_running_from_binder_if_connected() {
// GIVEN
// service bound
every { binder.isRunning } returns true
connection.onServiceConnected(componentName, binder)
every { manager.isRunning } returns true
connection.onBound(manager)

// WHEN
// is runnign flag accessed
Expand All @@ -215,7 +221,7 @@ class TransferManagerConnectionTest {
// THEN
// call delegated to binder
assertTrue(isRunning)
verify(exactly = 1) { binder.isRunning }
verify(exactly = 1) { manager.isRunning }
}

@Test
Expand All @@ -227,11 +233,11 @@ class TransferManagerConnectionTest {
connection.enqueue(request)
val download = Transfer(request.uuid, TransferState.RUNNING, 50, request.file, request)
connection.registerTransferListener(firstDownloadListener)
every { binder.getTransfer(request.uuid) } returns download
every { manager.getTransfer(request.uuid) } returns download

// WHEN
// service is bound
connection.onServiceConnected(componentName, binder)
connection.onBound(manager)

// THEN
// missed updates not redelivered
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import com.nextcloud.android.sso.QueryParam
import org.junit.Assert.assertEquals
import org.junit.Test

class InputStreamBinderTest {
class InputStreamManagerTest {
@Test
fun convertMapToNVP() {
val source = mutableMapOf<String, String>()
Expand Down
4 changes: 0 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,6 @@
android:name=".files.services.FileDownloader"
android:foregroundServiceType="dataSync"
android:exported="false" />
<service
android:name="com.nextcloud.client.files.downloader.FileTransferService"
android:foregroundServiceType="dataSync"
android:exported="false" />
<service
android:name=".files.services.FileUploader"
android:foregroundServiceType="dataSync"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public class UserAccountManagerImpl implements UserAccountManager {
private static final String TAG = UserAccountManagerImpl.class.getSimpleName();
private static final String PREF_SELECT_OC_ACCOUNT = "select_oc_account";

private Context context;
private final Context context;
private AccountManager accountManager;

public static UserAccountManagerImpl fromContext(Context context) {
Expand Down Expand Up @@ -196,10 +196,10 @@ private User createUserFromAccount(@Nullable Account account) {
return null;
}

OwnCloudAccount ownCloudAccount = null;
OwnCloudAccount ownCloudAccount;
try {
ownCloudAccount = new OwnCloudAccount(account, context);
} catch (AccountUtils.AccountNotFoundException ex) {
} catch (Throwable t) {
return null;
}

Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/com/nextcloud/client/di/AppModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import com.nextcloud.client.core.ThreadPoolAsyncRunner;
import com.nextcloud.client.database.dao.ArbitraryDataDao;
import com.nextcloud.client.device.DeviceInfo;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.files.downloader.FileTransferHelper;
import com.nextcloud.client.logger.FileLogHandler;
import com.nextcloud.client.logger.Logger;
import com.nextcloud.client.logger.LoggerImpl;
Expand All @@ -50,6 +52,7 @@
import com.nextcloud.client.migrations.MigrationsManager;
import com.nextcloud.client.migrations.MigrationsManagerImpl;
import com.nextcloud.client.network.ClientFactory;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.client.notifications.AppNotificationManager;
import com.nextcloud.client.notifications.AppNotificationManagerImpl;
import com.nextcloud.client.preferences.AppPreferences;
Expand Down Expand Up @@ -246,6 +249,12 @@ AppNotificationManager notificationsManager(Context context,
viewThemeUtilsProvider.get());
}

@Provides
@Singleton
FileTransferHelper fileTransferHelper(ClientFactory clientFactory, FileDataStorageManager fileDataStorageManager, AsyncRunner runner, PowerManagementService powerManagementService, ConnectivityService connectivityService, UploadsStorageManager uploadsStorageManager) {
return new FileTransferHelper(clientFactory, fileDataStorageManager, runner, powerManagementService, connectivityService, uploadsStorageManager);
}

@Provides
LocalBroadcastManager localBroadcastManager(Context context) {
return LocalBroadcastManager.getInstance(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
import com.nextcloud.client.documentscan.DocumentScanActivity;
import com.nextcloud.client.editimage.EditImageActivity;
import com.nextcloud.client.etm.EtmActivity;
import com.nextcloud.client.files.downloader.FileTransferHelper;
import com.nextcloud.client.files.downloader.FileTransferWorker;
import com.nextcloud.client.etm.pages.EtmBackgroundJobsFragment;
import com.nextcloud.client.files.downloader.FileTransferService;
import com.nextcloud.client.jobs.BackgroundJobManagerImpl;
import com.nextcloud.client.jobs.NotificationWork;
import com.nextcloud.client.jobs.TestJob;
Expand Down Expand Up @@ -355,7 +356,7 @@ abstract class ComponentsModule {
abstract PlayerService playerService();

@ContributesAndroidInjector
abstract FileTransferService fileDownloaderService();
abstract FileTransferWorker fileTransferWorker();

@ContributesAndroidInjector
abstract FileSyncService fileSyncService();
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/java/com/nextcloud/client/etm/EtmViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import com.nextcloud.client.etm.pages.EtmBackgroundJobsFragment
import com.nextcloud.client.etm.pages.EtmFileTransferFragment
import com.nextcloud.client.etm.pages.EtmMigrations
import com.nextcloud.client.etm.pages.EtmPreferencesFragment
import com.nextcloud.client.files.downloader.FileTransferHelper
import com.nextcloud.client.files.downloader.FileTransferWorker
import com.nextcloud.client.files.downloader.TransferManagerConnection
import com.nextcloud.client.jobs.BackgroundJobManager
import com.nextcloud.client.jobs.JobInfo
Expand Down Expand Up @@ -109,7 +111,7 @@ class EtmViewModel @Inject constructor(
pageClass = EtmFileTransferFragment::class
)
)
val transferManagerConnection = TransferManagerConnection(context, accountManager.user)
val transferManagerConnection = TransferManagerConnection(backgroundJobManager, context, accountManager.user)

val preferences: Map<String, String> get() {
return defaultPreferences.all
Expand Down Expand Up @@ -150,6 +152,10 @@ class EtmViewModel @Inject constructor(
}
}

fun getManager(helper: FileTransferHelper): FileTransferWorker.Manager {
return helper.getTransferManager(context, currentUser)
}

fun onPageSelected(index: Int) {
if (index < pages.size) {
currentPage as MutableLiveData
Expand Down
Loading
Loading