Skip to content

Commit

Permalink
Merge pull request #6071 from seadowg/auto-send-retty
Browse files Browse the repository at this point in the history
Add retry for auto send
  • Loading branch information
grzesiek2010 authored Apr 24, 2024
2 parents ac5d061 + 7e3648a commit d27f63e
Show file tree
Hide file tree
Showing 56 changed files with 594 additions and 438 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ class CoroutineAndWorkManagerScheduler(foregroundContext: CoroutineContext, back

constructor(workManager: WorkManager) : this(Dispatchers.Main, Dispatchers.IO, workManager) // Needed for Java construction

override fun networkDeferred(tag: String, spec: TaskSpec, inputData: Map<String, String>) {
override fun networkDeferred(tag: String, spec: TaskSpec, inputData: Map<String, String>, networkConstraint: Scheduler.NetworkType?) {
val constraintNetworkType = when (networkConstraint) {
Scheduler.NetworkType.WIFI -> NetworkType.UNMETERED
Scheduler.NetworkType.CELLULAR -> NetworkType.METERED
null -> NetworkType.CONNECTED
}

val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiredNetworkType(constraintNetworkType)
.build()

val workManagerInputData = Data.Builder().putAll(inputData).build()
Expand All @@ -34,7 +40,7 @@ class CoroutineAndWorkManagerScheduler(foregroundContext: CoroutineContext, back
workManager.beginUniqueWork(tag, ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest).enqueue()
}

override fun networkDeferred(tag: String, spec: TaskSpec, repeatPeriod: Long, inputData: Map<String, String>) {
override fun networkDeferredRepeat(tag: String, spec: TaskSpec, repeatPeriod: Long, inputData: Map<String, String>) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ open class CoroutineScheduler(private val foregroundContext: CoroutineContext, p
throw UnsupportedOperationException()
}

override fun networkDeferred(tag: String, spec: TaskSpec, inputData: Map<String, String>) {
override fun networkDeferred(tag: String, spec: TaskSpec, inputData: Map<String, String>, networkConstraint: Scheduler.NetworkType?) {
throw UnsupportedOperationException()
}

override fun networkDeferred(tag: String, spec: TaskSpec, repeatPeriod: Long, inputData: Map<String, String>) {
override fun networkDeferredRepeat(tag: String, spec: TaskSpec, repeatPeriod: Long, inputData: Map<String, String>) {
throw UnsupportedOperationException()
}

Expand Down
9 changes: 7 additions & 2 deletions async/src/main/java/org/odk/collect/async/Scheduler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ interface Scheduler {
* @param spec defines the task to be run
* @param inputData a map of input data that can be accessed by the task
*/
fun networkDeferred(tag: String, spec: TaskSpec, inputData: Map<String, String>)
fun networkDeferred(tag: String, spec: TaskSpec, inputData: Map<String, String>, networkConstraint: NetworkType? = null)

/**
* Schedule a task to run in the background repeatedly even if the app isn't running. The task
Expand All @@ -48,7 +48,7 @@ interface Scheduler {
* @param repeatPeriod the period between each run of the task
* @param inputData a map of input data that can be accessed by the task
*/
fun networkDeferred(
fun networkDeferredRepeat(
tag: String,
spec: TaskSpec,
repeatPeriod: Long,
Expand Down Expand Up @@ -77,6 +77,11 @@ interface Scheduler {
fun cancelAllDeferred()

fun <T> flowOnBackground(flow: Flow<T>): Flow<T>

enum class NetworkType {
WIFI,
CELLULAR
}
}

fun <T> Flow<T>.flowOnBackground(scheduler: Scheduler): Flow<T> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package org.odk.collect.android.feature.formentry.backgroundlocation;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import androidx.test.core.app.ApplicationProvider;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
Expand All @@ -25,8 +18,8 @@ public class SetGeopointActionTest {

@Test
public void locationCollectionSnackbar_ShouldBeDisplayedAtFormLaunch() {
onView(withId(com.google.android.material.R.id.snackbar_text))
.check(matches(withText(String.format(ApplicationProvider.getApplicationContext().getString(org.odk.collect.strings.R.string.background_location_enabled), "⋮"))));
rule.startInFormEntry()
.checkIsSnackbarWithMessageDisplayed(org.odk.collect.strings.R.string.background_location_enabled, "⋮");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,16 @@ class TestScheduler : Scheduler, CoroutineDispatcher() {
}
}

override fun networkDeferred(tag: String, spec: TaskSpec, inputData: Map<String, String>) {
override fun networkDeferred(
tag: String,
spec: TaskSpec,
inputData: Map<String, String>,
networkConstraint: Scheduler.NetworkType?
) {
deferredTasks.add(DeferredTask(tag, spec, null, inputData))
}

override fun networkDeferred(
override fun networkDeferredRepeat(
tag: String,
spec: TaskSpec,
repeatPeriod: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ class DeleteFormsActivity : LocalizedActivity() {
SavedFormListViewModel::class.java -> SavedFormListViewModel(
scheduler,
generalSettings,
instancesDataService
instancesDataService,
projectId
)

else -> throw IllegalArgumentException()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ public void onCreate(Bundle savedInstanceState) {
init();

BulkFinalizationViewModel bulkFinalizationViewModel = new BulkFinalizationViewModel(
projectsDataService.getCurrentProject().getUuid(),
scheduler,
instancesDataService,
settingsProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package org.odk.collect.android.application.initialization
import android.content.Context
import org.odk.collect.analytics.Analytics
import org.odk.collect.android.preferences.Defaults
import org.odk.collect.android.preferences.utilities.FormUpdateMode
import org.odk.collect.projects.Project
import org.odk.collect.projects.ProjectsRepository
import org.odk.collect.settings.SettingsProvider
import org.odk.collect.settings.enums.FormUpdateMode
import org.odk.collect.settings.keys.ProjectKeys

class UserPropertiesInitializer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,26 @@ import android.content.Context
import androidx.work.BackoffPolicy
import androidx.work.WorkerParameters
import org.odk.collect.android.injection.DaggerUtils
import org.odk.collect.android.instancemanagement.autosend.InstanceAutoSender
import org.odk.collect.android.projects.ProjectDependencyProviderFactory
import org.odk.collect.android.instancemanagement.InstancesDataService
import org.odk.collect.async.TaskSpec
import org.odk.collect.async.WorkerAdapter
import java.util.function.Supplier
import javax.inject.Inject

class AutoSendTaskSpec : TaskSpec {
@Inject
lateinit var instanceAutoSender: InstanceAutoSender

@Inject
lateinit var projectDependencyProviderFactory: ProjectDependencyProviderFactory
lateinit var instancesDataService: InstancesDataService

override val maxRetries: Int? = null
override val backoffPolicy: BackoffPolicy? = null
override val backoffDelay: Long? = null
override val backoffPolicy = BackoffPolicy.EXPONENTIAL
override val backoffDelay: Long = 60_000

override fun getTask(context: Context, inputData: Map<String, String>, isLastUniqueExecution: Boolean): Supplier<Boolean> {
DaggerUtils.getComponent(context).inject(this)
return Supplier {
val projectId = inputData[TaskData.DATA_PROJECT_ID]
if (projectId != null) {
instanceAutoSender.autoSendInstances(projectDependencyProviderFactory.create(projectId))
instancesDataService.autoSendInstances(projectId)
} else {
throw IllegalArgumentException("No project ID provided!")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package org.odk.collect.android.backgroundwork;

import static org.odk.collect.android.backgroundwork.BackgroundWorkUtils.getPeriodInMilliseconds;
import static org.odk.collect.android.preferences.utilities.SettingsUtils.getFormUpdateMode;
import static org.odk.collect.settings.enums.StringIdEnumUtils.getFormUpdateMode;
import static org.odk.collect.settings.keys.ProjectKeys.KEY_PERIODIC_FORM_UPDATES_CHECK;

import android.app.Application;

import org.jetbrains.annotations.NotNull;
import org.odk.collect.async.Scheduler;
import org.odk.collect.settings.SettingsProvider;
import org.odk.collect.settings.enums.AutoSend;
import org.odk.collect.settings.enums.StringIdEnumUtils;
import org.odk.collect.shared.settings.Settings;

import java.util.HashMap;
Expand All @@ -31,7 +33,7 @@ public void scheduleUpdates(String projectId) {
String period = generalSettings.getString(KEY_PERIODIC_FORM_UPDATES_CHECK);
long periodInMilliseconds = getPeriodInMilliseconds(period, application);

switch (getFormUpdateMode(application, generalSettings)) {
switch (getFormUpdateMode(generalSettings, application)) {
case MANUAL:
scheduler.cancelDeferred(getMatchExactlyTag(projectId));
scheduler.cancelDeferred(getAutoUpdateTag(projectId));
Expand All @@ -50,13 +52,13 @@ public void scheduleUpdates(String projectId) {
private void scheduleAutoUpdate(long periodInMilliseconds, String projectId) {
HashMap<String, String> inputData = new HashMap<>();
inputData.put(TaskData.DATA_PROJECT_ID, projectId);
scheduler.networkDeferred(getAutoUpdateTag(projectId), new AutoUpdateTaskSpec(), periodInMilliseconds, inputData);
scheduler.networkDeferredRepeat(getAutoUpdateTag(projectId), new AutoUpdateTaskSpec(), periodInMilliseconds, inputData);
}

private void scheduleMatchExactly(long periodInMilliseconds, String projectId) {
HashMap<String, String> inputData = new HashMap<>();
inputData.put(TaskData.DATA_PROJECT_ID, projectId);
scheduler.networkDeferred(getMatchExactlyTag(projectId), new SyncFormsTaskSpec(), periodInMilliseconds, inputData);
scheduler.networkDeferredRepeat(getMatchExactlyTag(projectId), new SyncFormsTaskSpec(), periodInMilliseconds, inputData);
}

@Override
Expand All @@ -67,9 +69,18 @@ public void cancelUpdates(String projectId) {

@Override
public void scheduleSubmit(String projectId) {
Scheduler.NetworkType networkType = null;
Settings settings = settingsProvider.getUnprotectedSettings(projectId);
AutoSend autoSendSetting = StringIdEnumUtils.getAutoSend(settings, application);
if (autoSendSetting == AutoSend.WIFI_ONLY) {
networkType = Scheduler.NetworkType.WIFI;
} else if (autoSendSetting == AutoSend.CELLULAR_ONLY) {
networkType = Scheduler.NetworkType.CELLULAR;
}

HashMap<String, String> inputData = new HashMap<>();
inputData.put(TaskData.DATA_PROJECT_ID, projectId);
scheduler.networkDeferred(getAutoSendTag(projectId), new AutoSendTaskSpec(), inputData);
scheduler.networkDeferred(getAutoSendTag(projectId), new AutoSendTaskSpec(), inputData, networkType);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import org.odk.collect.android.formmanagement.FormsDataService
import org.odk.collect.android.preferences.utilities.FormUpdateMode
import org.odk.collect.android.preferences.utilities.SettingsUtils
import org.odk.collect.async.Scheduler
import org.odk.collect.async.flowOnBackground
import org.odk.collect.forms.Form
import org.odk.collect.forms.FormSourceException
import org.odk.collect.forms.FormSourceException.AuthRequired
import org.odk.collect.forms.instances.InstancesRepository
import org.odk.collect.settings.enums.FormUpdateMode
import org.odk.collect.settings.enums.StringIdEnumUtils.getFormUpdateMode
import org.odk.collect.settings.keys.ProjectKeys
import org.odk.collect.shared.settings.Settings

Expand Down Expand Up @@ -85,10 +85,7 @@ class BlankFormListViewModel(
}

fun isMatchExactlyEnabled(): Boolean {
return SettingsUtils.getFormUpdateMode(
application,
generalSettings
) == FormUpdateMode.MATCH_EXACTLY
return generalSettings.getFormUpdateMode(application) == FormUpdateMode.MATCH_EXACTLY
}

fun isOutOfSyncWithServer(): LiveData<Boolean> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import org.odk.collect.shared.settings.Settings
class SavedFormListViewModel(
scheduler: Scheduler,
private val settings: Settings,
private val instancesDataService: InstancesDataService
private val instancesDataService: InstancesDataService,
val projectId: String
) : ViewModel() {

private val _sortOrder =
Expand Down Expand Up @@ -67,7 +68,7 @@ class SavedFormListViewModel(
val result = MutableLiveData<Consumable<Int>?>(null)
worker.immediate(
background = {
instancesDataService.deleteInstances(databaseIds)
instancesDataService.deleteInstances(projectId, databaseIds)
},
foreground = { instancesDeleted ->
if (instancesDeleted) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import org.odk.collect.settings.SettingsProvider
import org.odk.collect.settings.keys.ProtectedProjectKeys

class BulkFinalizationViewModel(
private val projectId: String,
private val scheduler: Scheduler,
private val instancesDataService: InstancesDataService,
private val settingsProvider: SettingsProvider
settingsProvider: SettingsProvider
) {
private val _finalizedForms = MutableLiveData<Consumable<FinalizeAllResult>>()
val finalizedForms: LiveData<Consumable<FinalizeAllResult>> = _finalizedForms
Expand All @@ -31,7 +32,7 @@ class BulkFinalizationViewModel(

scheduler.immediate(
background = {
instancesDataService.finalizeAllDrafts()
instancesDataService.finalizeAllDrafts(projectId)
},
foreground = {
_isFinalizing.value = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import org.odk.collect.android.configure.qr.QRCodeScannerFragment;
import org.odk.collect.android.configure.qr.QRCodeTabsActivity;
import org.odk.collect.android.configure.qr.ShowQRCodeFragment;
import org.odk.collect.android.tasks.InstanceUploaderTask;
import org.odk.collect.android.utilities.SavepointsRepositoryProvider;
import org.odk.collect.android.entities.EntitiesRepositoryProvider;
import org.odk.collect.android.external.AndroidShortcutsActivity;
import org.odk.collect.android.external.FormUriActivity;
Expand Down Expand Up @@ -65,17 +63,18 @@
import org.odk.collect.android.preferences.screens.ServerPreferencesFragment;
import org.odk.collect.android.preferences.screens.UserInterfacePreferencesFragment;
import org.odk.collect.android.projects.ManualProjectCreatorDialog;
import org.odk.collect.android.projects.ProjectResetter;
import org.odk.collect.android.projects.ProjectSettingsDialog;
import org.odk.collect.android.projects.ProjectsDataService;
import org.odk.collect.android.projects.QrCodeProjectCreatorDialog;
import org.odk.collect.android.storage.StoragePathProvider;
import org.odk.collect.android.tasks.DownloadFormListTask;
import org.odk.collect.android.tasks.InstanceUploaderTask;
import org.odk.collect.android.tasks.MediaLoadingTask;
import org.odk.collect.android.upload.InstanceUploader;
import org.odk.collect.android.utilities.AuthDialogUtility;
import org.odk.collect.android.utilities.FormsRepositoryProvider;
import org.odk.collect.android.utilities.InstancesRepositoryProvider;
import org.odk.collect.android.projects.ProjectResetter;
import org.odk.collect.android.utilities.SavepointsRepositoryProvider;
import org.odk.collect.android.utilities.ThemeUtils;
import org.odk.collect.android.widgets.QuestionWidget;
import org.odk.collect.android.widgets.items.SelectOneFromMapDialogFragment;
Expand Down Expand Up @@ -245,8 +244,6 @@ interface Builder {

void inject(FirstLaunchActivity firstLaunchActivity);

void inject(InstanceUploader instanceUploader);

void inject(FormUriActivity formUriActivity);

void inject(MapsPreferencesFragment mapsPreferencesFragment);
Expand Down
Loading

0 comments on commit d27f63e

Please sign in to comment.