From d983167976aad123e11b60c338eea26676ccbad1 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Fri, 30 Mar 2018 12:08:39 -0500 Subject: [PATCH] Option for background sync on unmetered conn only --- .../java/com/todoroo/astrid/data/Task.java | 58 +++++++++++++++++++ .../main/java/org/tasks/jobs/JobCreator.java | 6 +- .../main/java/org/tasks/jobs/JobManager.java | 37 +++++++----- .../org/tasks/receivers/PushReceiver.java | 46 ++++----------- .../sync/SynchronizationPreferences.java | 13 +++-- app/src/main/res/values/keys.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../res/xml/preferences_synchronization.xml | 18 ++++-- 8 files changed, 118 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/com/todoroo/astrid/data/Task.java b/app/src/main/java/com/todoroo/astrid/data/Task.java index aad200894..d59331397 100644 --- a/app/src/main/java/com/todoroo/astrid/data/Task.java +++ b/app/src/main/java/com/todoroo/astrid/data/Task.java @@ -977,6 +977,64 @@ public class Task implements Parcelable { return remoteId != null ? remoteId.equals(task.remoteId) : task.remoteId == null; } + public boolean googleTaskUpToDate(Task original) { + if (this == original) { + return true; + } + if (original == null) { + return false; + } + + if (title != null ? !title.equals(original.title) : original.title != null) { + return false; + } + if (dueDate != null ? !dueDate.equals(original.dueDate) : original.dueDate != null) { + return false; + } + if (completed != null ? !completed.equals(original.completed) : original.completed != null) { + return false; + } + if (deleted != null ? !deleted.equals(original.deleted) : original.deleted != null) { + return false; + } + return notes != null ? notes.equals(original.notes) : original.notes == null; + } + + public boolean caldavUpToDate(Task original) { + if (this == original) { + return true; + } + if (original == null) { + return false; + } + + if (title != null ? !title.equals(original.title) : original.title != null) { + return false; + } + if (importance != null ? !importance.equals(original.importance) + : original.importance != null) { + return false; + } + if (dueDate != null ? !dueDate.equals(original.dueDate) : original.dueDate != null) { + return false; + } + if (completed != null ? !completed.equals(original.completed) : original.completed != null) { + return false; + } + if (deleted != null ? !deleted.equals(original.deleted) : original.deleted != null) { + return false; + } + if (notes != null ? !notes.equals(original.notes) : original.notes != null) { + return false; + } + if (recurrence != null ? !recurrence.equals(original.recurrence) + : original.recurrence != null) { + return false; + } + return repeatUntil != null ? repeatUntil.equals(original.repeatUntil) + : original.repeatUntil == null; + } + public boolean isSaved() { return getId() != NO_ID; } diff --git a/app/src/main/java/org/tasks/jobs/JobCreator.java b/app/src/main/java/org/tasks/jobs/JobCreator.java index 802a3cd8f..08622cbee 100644 --- a/app/src/main/java/org/tasks/jobs/JobCreator.java +++ b/app/src/main/java/org/tasks/jobs/JobCreator.java @@ -14,6 +14,7 @@ import org.tasks.injection.ApplicationScope; import org.tasks.injection.ForApplication; import org.tasks.preferences.Preferences; import org.tasks.scheduling.RefreshScheduler; +import timber.log.Timber; @ApplicationScope public class JobCreator implements com.evernote.android.job.JobCreator { @@ -32,6 +33,7 @@ public class JobCreator implements com.evernote.android.job.JobCreator { static final String TAG_REFRESH = "tag_refresh"; static final String TAG_MIDNIGHT_REFRESH = "tag_midnight_refresh"; static final String TAG_NOTIFICATION = "tag_notification"; + static final String TAG_BACKGROUND_SYNC = "tag_background_sync"; static final String TAG_SYNC = "tag_sync"; @Inject @@ -57,6 +59,7 @@ public class JobCreator implements com.evernote.android.job.JobCreator { case TAG_NOTIFICATION: return new NotificationJob(preferences, notifier, notificationQueue); case TAG_SYNC: + case TAG_BACKGROUND_SYNC: return new SyncJob(caldavSynchronizer, googleTaskSynchronizer); case TAG_BACKUP: return new BackupJob(context, tasksJsonExporter, preferences); @@ -64,7 +67,8 @@ public class JobCreator implements com.evernote.android.job.JobCreator { case TAG_REFRESH: return new RefreshJob(refreshScheduler, localBroadcastManager); default: - throw new IllegalArgumentException("Unhandled tag: " + tag); + Timber.e("Unhandled tag: " + tag); + return null; } } } diff --git a/app/src/main/java/org/tasks/jobs/JobManager.java b/app/src/main/java/org/tasks/jobs/JobManager.java index 586dde6c0..32870aa65 100644 --- a/app/src/main/java/org/tasks/jobs/JobManager.java +++ b/app/src/main/java/org/tasks/jobs/JobManager.java @@ -10,6 +10,7 @@ import com.evernote.android.job.JobRequest.Builder; import com.evernote.android.job.JobRequest.NetworkType; import com.todoroo.astrid.gtasks.GtasksPreferenceService; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; import javax.inject.Inject; import org.tasks.R; import org.tasks.injection.ApplicationScope; @@ -64,38 +65,44 @@ public class JobManager { } public void updateBackgroundSync() { - updateBackgroundSync(false, false); + updateBackgroundSync(null, null, null); } - public void updateBackgroundSync(boolean forceAccountPresent, boolean forceBackgroundEnabled) { - boolean backgroundEnabled = - forceBackgroundEnabled || preferences.getBoolean(R.string.p_background_sync, true); - boolean accountsPresent = - forceAccountPresent || preferences.getBoolean(R.string.p_sync_caldav, false) || - !isEmpty(preferences.getStringValue(GtasksPreferenceService.PREF_USER_NAME)); - scheduleBackgroundSynchronization(backgroundEnabled && accountsPresent); + public void updateBackgroundSync(@Nullable Boolean forceAccountPresent, + @Nullable Boolean forceBackgroundEnabled, @Nullable Boolean forceOnlyOnUnmetered) { + boolean backgroundEnabled = forceBackgroundEnabled == null + ? preferences.getBoolean(R.string.p_background_sync, true) + : forceBackgroundEnabled; + boolean accountsPresent = forceAccountPresent == null + ? (preferences.getBoolean(R.string.sync_gtasks, false) || preferences.getBoolean(R.string.p_sync_caldav, false)) + : forceAccountPresent; + boolean onlyOnWifi = forceOnlyOnUnmetered == null + ? preferences.getBoolean(R.string.p_background_sync_unmetered_only, false) + : forceOnlyOnUnmetered; + scheduleBackgroundSynchronization(backgroundEnabled && accountsPresent, onlyOnWifi); } - private void scheduleBackgroundSynchronization(boolean enabled) { - Timber.d("background sync enabled: %s", enabled); + private void scheduleBackgroundSynchronization(boolean enabled, boolean onlyOnUnmetered) { + Timber.d("background sync enabled: %s, onlyOnUnmetered: %s", enabled, onlyOnUnmetered); if (enabled) { - new JobRequest.Builder(JobCreator.TAG_SYNC) - .setRequiredNetworkType(NetworkType.CONNECTED) - .setRequirementsEnforced(true) + new JobRequest.Builder(JobCreator.TAG_BACKGROUND_SYNC) .setPeriodic(TimeUnit.HOURS.toMillis(1)) + .setRequiredNetworkType(onlyOnUnmetered ? NetworkType.UNMETERED : NetworkType.CONNECTED) + .setRequirementsEnforced(true) .setUpdateCurrent(true) .build() .schedule(); } else { - jobManager.cancelAllForTag(JobCreator.TAG_SYNC); + jobManager.cancelAllForTag(JobCreator.TAG_BACKGROUND_SYNC); } } public void syncNow() { new JobRequest.Builder(JobCreator.TAG_SYNC) + .setExecutionWindow(TimeUnit.SECONDS.toMillis(1), TimeUnit.SECONDS.toMillis(5)) .setRequiredNetworkType(NetworkType.CONNECTED) .setRequirementsEnforced(true) - .setExecutionWindow(1, 5000) + .setUpdateCurrent(true) .build() .schedule(); } diff --git a/app/src/main/java/org/tasks/receivers/PushReceiver.java b/app/src/main/java/org/tasks/receivers/PushReceiver.java index 7de714665..71097c73e 100644 --- a/app/src/main/java/org/tasks/receivers/PushReceiver.java +++ b/app/src/main/java/org/tasks/receivers/PushReceiver.java @@ -1,11 +1,11 @@ package org.tasks.receivers; -import com.google.common.base.Strings; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; import javax.inject.Inject; import org.tasks.jobs.JobManager; import org.tasks.sync.SyncAdapters; +import timber.log.Timber; public class PushReceiver { @@ -19,45 +19,19 @@ public class PushReceiver { } public void push(Task task, Task original) { - if (!pushGoogleTasks(task, original)) { - pushCaldav(task, original); - } - } - - private boolean pushGoogleTasks(Task task, Task original) { - if (!syncAdapters.isGoogleTaskSyncEnabled()) { - return false; - } - - if (task.checkTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) { - return false; - } - - if (original == null || - !task.getTitle().equals(original.getTitle()) || - (Strings.isNullOrEmpty(task.getNotes()) - ? !Strings.isNullOrEmpty(original.getNotes()) - : !task.getNotes().equals(original.getNotes())) || - !task.getDueDate().equals(original.getDueDate()) || - !task.getCompletionDate().equals(original.getCompletionDate()) || - !task.getDeletionDate().equals(original.getDeletionDate()) || - task.checkAndClearTransitory(SyncFlags.FORCE_SYNC)) { - syncAdapters.syncNow(); - return true; - } - - return false; - } - - private void pushCaldav(Task task, Task original) { - if (!syncAdapters.isCaldavSyncEnabled()) { + boolean googleTaskSyncEnabled = syncAdapters.isGoogleTaskSyncEnabled(); + boolean caldavSyncEnabled = syncAdapters.isCaldavSyncEnabled(); + if (!(googleTaskSyncEnabled || caldavSyncEnabled)) { return; } - if (task.checkTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) { + Timber.d("Suppressed sync: %s", task); return; } - - jobManager.syncNow(); + if (task.checkAndClearTransitory(SyncFlags.FORCE_SYNC) || + (googleTaskSyncEnabled && !task.googleTaskUpToDate(original)) || + (caldavSyncEnabled && !task.caldavUpToDate(original))) { + jobManager.syncNow(); + } } } diff --git a/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java b/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java index 73ab3eb5b..5c6b4fe12 100644 --- a/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java +++ b/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java @@ -59,9 +59,8 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity { getString(R.string.p_sync_caldav)); caldavEnabled.setChecked(syncAdapters.isCaldavSyncEnabled()); caldavEnabled.setOnPreferenceChangeListener((preference, newValue) -> { - boolean enabled = ((boolean) newValue); - jobManager.updateBackgroundSync(enabled, false); - return enabled; + jobManager.updateBackgroundSync(((boolean) newValue), null, null); + return true; }); final CheckBoxPreference gtaskPreference = (CheckBoxPreference) findPreference( getString(R.string.sync_gtasks)); @@ -86,10 +85,14 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity { DateUtilities.getDateStringWithTime(SynchronizationPreferences.this, gtasksPreferenceService.getLastSyncDate()))); } + findPreference(getString(R.string.p_background_sync_unmetered_only)) + .setOnPreferenceChangeListener((preference, o) -> { + jobManager.updateBackgroundSync(null, null, (Boolean) o); + return true; + }); findPreference(getString(R.string.p_background_sync)) .setOnPreferenceChangeListener((preference, o) -> { - boolean enabled = (Boolean) o; - jobManager.updateBackgroundSync(false, enabled); + jobManager.updateBackgroundSync(null, (Boolean) o, null); return true; }); findPreference(getString(R.string.sync_SPr_forget_key)) diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index 9f1dc3c45..42f94d52e 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -295,5 +295,6 @@ strict_mode warned_play_services sync_caldav + background_sync_unmetered_only diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4548ef617..3543ed544 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -888,4 +888,5 @@ File %1$s contained %2$s.\n\n Help Calendar not found Connection failed + Only on unmetered connections diff --git a/app/src/main/res/xml/preferences_synchronization.xml b/app/src/main/res/xml/preferences_synchronization.xml index 4800df946..8c16f0fef 100644 --- a/app/src/main/res/xml/preferences_synchronization.xml +++ b/app/src/main/res/xml/preferences_synchronization.xml @@ -6,11 +6,6 @@ - - + + + + + +